Issues with LambdaS5
-
Setting fields syntax form
obj[name=value]
is parsed aslet (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
orundefined
? Paper suggestsundefined
, code suggestsnull
. -
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 specifiesundefined
), 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
-
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
-
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.