Issues with LambdaS5

Marek Materzok edited this page Dec 16, 2015 · 56 revisions

Semantics problems

  • Setting fields syntax form obj[name=value] is parsed as let (v=value) {obj[name=v, {[] "0": {#value: v, #writable: true}}]} - this is very strange!

  • Setter functions for obj[name=value,arg] only receive name and arg, value is not passed

  • Trying to create a new field on an unextensible object returns undefined - it would be more consistent with the rest of semantics to throw some exception

  • What should be the default value of obj<#code> - null or undefined? Paper suggests undefined, code suggests null.

  • Should obj<#code> be allowed to be anything other than a closure if defined?

  • obj<#primval> is "unset" by default in the code (the paper specifies undefined), but it seems there is no value in that, this complicates semantics.

  • try e1 finally e2 returns the value of e1 in the semantics, and value of e2 in the interpreter.

  • Interpreter does not check the object's 'extensible' property when shadowing a field -- the check is in the semantics.

  • Undefined getters/setters are not handled - the following program crashes:

      var o = { set x(v) {} }; o.x
    

    ES5: 8.12.3 1, 8.12.4 2.a.i 7.a; ES6: 9.1.8 7, 9.1.9 8

    New test created: get-getter-undefined.js

  • The following program returns 1 instead of 2:

      var x = {set y(v) { return 1 }};
      x.y = 2
    

    ES5: 11.13.1 6, ES6: 12.14.4 11

Desugaring bugs

  • The following program returns 3 instead of 2 in S5:

      var o = {x: 0};
      function f() { o.x++; return o };
      (f()).x += 1
    

    ES5: 11.13.2 2, ES6: 12.14.4 2

  • The following program prints just A instead of A B:

      switch(1) {default: print("A"); case 2: print("B")}
    

    ES5: ???, ES6: 13.12.9 12

  • This program returns 1:

      "use strict"; var x = {get a() { var y = 1; return y; }}; x.a
    

    This program throws an exception in S5:

      "use strict"; if (false) y = 0; var x = {get a() { var y = 1; return y; }}; x.a
    

    Implementation-related bug.

  • This program returns 1 in S5, should return 5:

      a: for (var x = 1; x < 5; x+=1) { continue a }; x
    

    Labeled continue was not implemented; it worked like break.

  • This program returns 1 in S5, should return undefined:

      var x = 1
    

    ES5: 12.2, ES6: 13.3.2.4

    New test created: var-empty-completion.js

  • This program returns 1 in S5, should return 0:

      function f(x) {x = 0; return arguments[0] }; f(1)
    

    This is fine for strict mode, but wrong for sloppy mode.

  • This program returns 1 in S5, should return 2:

      var x = 1; try { throw 1 } catch (e) { (function() { e = 2 })(); x = e }; x
    
  • This program returns 120 in S5, should throw an exception:

      var x = function f (a) { var f; if (a == 0) return 1; else return a * f(a-1) }; x(5)
    

    ES5 10.4.3 5, 10.5

  • This program returns "null" instead of "object":

      typeof null
    

    ES5 11.4.3, ES6 12.5.6

    Tested by: 11.4.3_A3.2 (null.js)

  • This program fails in S5 instead of returning true:

      function x() {}
      x == x
    

    ES5 11.9.3 1.f, ES6 7.2.12 3.a

  • This program gives "numbernumber", should give "numberobject":

      "use strict";
      Number.prototype.f = function () { return typeof this };
      var x = 1;
      var y = new Number(2);
      x.f() + y.f()
    

    ES5 10.4.3 1, ES6 9.2.1.2 5

    Tested by: 10.4.3-1-1-s

  • The arguments object is often not the real arguments object, as defined by the spec. For example, this program returns undefined instead of 0:

      var obj = {get f() { return arguments.length }};
      obj.f
    
  • The new operator does not check if the constructor argument is an object. This program fails instead of throwing TypeError:

      new 1
    

    ES5 11.2.2 3, ES6 7.2.4 & 12.3.3.1.1 8

    Tested by: S11.2.2_A3_T1

  • The delete operator only works on objects. The following program crashes instead of returning true:

      var x = 1; delete x.a
    

    ES5 11.4.1 4.a, ES6 12.5.4.2 5.b

    New test created: delete-primitive-field.js

  • Deleting an nonexistent property returns false instead of true:

      var x = {}; delete x.a
    

    ES5 8.12.7 2, ES6 9.1.10 4

    Tested by: S8.12.7_A2_T1, S8.12.7_A2_T2

  • Deleting a nonconfigurable property fails instead of returning false:

      var x = {a:1}; Object.seal(x); delete x.a
    

    ES5 8.12.7 5, ES6 9.1.10 6

    Tested by: 11.4.1-4.a-3

  • Deleting a nonconfigurable property in strict mode fails instead of throwing TypeError:

      "use strict"; var x = {a:1}; Object.seal(x); delete x.a
    

    ES5 8.12.7 4, ES6 12.5.4.2 5.e

    Tested by: 11.4.1-4.a-3-s

  • Deleting a non-reference expression does not evaluate it - the following program does not throw:

      delete ((function f() { throw 1 })())
    

    ES5 11.4.1 1, ES6 12.5.4.2 1

    New test created: delete-expr-evaluated.js

  • Adding new fields to a binding object in the with statement does not make new variables visible:

      var x = {};
      with (x) { x.b=1; b }
    
  • Getters and setters created using object literals are unconfigurable in S5, but they should be configurable.

      var x = {get f(){}};
      Object.getOwnPropertyDescriptor(x,"f").configurable
    

    ES5 11.1.5, ES6 14.3.9

  • S5 improperly distinguishes calling/constructing. The following program returns a string object instead of a string:

      var obj = {f:String}
      obj.f(1)
    
  • Number.toString does not throw the right exception when called with a wrong radix:

      1..toString(-1)
    

    ES5 15.7.4.2, ES6 20.1.3.6 7

  • Object.hasOwnProperty does not call ToString on its argument. Following program fails:

      Object.hasOwnProperty(1)
    

    ES5 15.2.4.5 1, ES6 19.1.3.2 1

  • Elisions in array literals do not result in the respective indexes being undefined. The following program gives "true,true,true,false" instead of "true,false,true,false":

      var x = [1,,3,]
      print(x.hasOwnProperty("0"));
      print(x.hasOwnProperty("1"));
      print(x.hasOwnProperty("2"));
      print(x.hasOwnProperty("3"))
    
  • Recursive function definition does not get an immutable binding. The following program gives 0 instead of a function:

      f = function f() { f = 0; return f };
      print(f())
    
  • The same problem is also in strict mode, if one uses eval. This program should throw TypeError, but returns 0 in S5:

      "use strict";
      var f = function f() { eval("f = 0"); return f };
      print(f())
    
  • Eval in non-strict mode does not handle the variable environment correctly in S5. The following program should return 2, it throws in S5:

      try { throw 1 } catch (x) { eval("var y = 2") }; y
    
  • Function redefinition is handled incorrectly. The following program does not crash, it should throw TypeError:

      Object.defineProperty(this, 'f', {
        value: 42,
        writable: true,
        enumerable: false,
        configurable: false
      });
      eval("function f(){}")
    
  • Array length change works incorrectly when the array has unconfigurable fields. The following program crashes the interpreter (it should give 2):

      x=[1,2,3];
      Object.defineProperty(x,1,{configurable:false});
      x.length=0;
      x.length
    
  • Array length change does not work using defineProperty (this should give undefined, it gives 3):

      x=[1,2,3];
      Object.defineProperty(x,"length",{value:1});
      x[2]
    
  • The bind objects do not realize isinstanceof properly. The following program throws instead of returning true:

      function f(){};
      var o = new f();
      var fb = f.bind();
      o instanceof fb
    

Environment bugs

  • These programs returns 9 instead of 6:

      (new Array(3, 2, 1, 0)).reduceRight(function(a, b) { return a + b; });
    
      (new Array(0, 1, 2, 3)).reduceRight(function(a, b) { return a + b; });
    
  • This program returns 6 instead of 3:

      (new Array(0, 0, 0, 0)).reduceRight(function(a, b, i) { return a + b + i; });
    
  • Prototypes for native errors did not have the correct class and message fields.

  • Invalid prototypes for error constructors: error prototypes instead of function prototypes were used. The following program should give true, in S5 it gives false.

      TypeError.constructor === Function.constructor
    
  • Undefined length property for many built-in function objects.

Clone this wiki locally
You can’t perform that action at this time.
You signed in with another tab or window. Reload to refresh your session. You signed out in another tab or window. Reload to refresh your session.
Press h to open a hovercard with more details.