ECMA 262 Implementations test.

A

Asen Bozhilov

I write for own usage simple test for some case in ES
implementations.

var ESImplement = {
_global : this,

functionStatement : function()
{
var code = [
'{',
'function f(){}',
'}'
].join('');

try {
eval(code);
return true;
}catch(e) {}
return false;
},

namedFunctionExpression : function()
{
var NFE;
return typeof NFE == 'undefined';
(function NFE(){});
},

variableObjectPrototype : function()
{
Object.prototype.x = true;
var x = false,
f = function(){
return x;
};
f = f();
delete Object.prototype.x;
return f;
},

globalObjectPrototype : function()
{
Object.prototype.x = true;
var x = false;
with(this._global)
{
var res = x;
}
delete Object.prototype.x;
return res;
},

objectLiteralUseObjectConstructor : function()
{
var o = Object,
res = true;
Object = null;
try {
({});
res = false;
}catch(e){}
Object = o;
return res;
},

arrayLiteralUseArrayConstructor : function()
{
var a = Array,
res = true;
Array = null;
try {
([]);
res = false;
}catch(e){};
Array = a;
return res;
},

forInToObjectExpression : function()
{
try {
for(var i in null);
return false;
}catch(e) {}
return true;
}
};

var IO = {
println : function(str)
{
if (typeof window != 'undefined' && typeof document !=
'undefined')
{
window.document.writeln(str);
}
else if (typeof WScript != 'undefined')
{
WScript.Echo(str);
}
else if (typeof println == 'function')
{
println(str);
}
}
};

Any suggestions, correction and addition are welcome.

Interesting part is `variableObjectPrototype` in DMDScript
implementation. They used object with [[Prototype]] which refer
`Object.prototype`. DMD have the same behavior and with Global
Object.

Regards.
 
D

Dmitry A. Soshnikov

  objectLiteralUseObjectConstructor : function()
  {
    var o = Object,
      res = true;
    Object = null;
    try {
      ({});
      res = false;
    }catch(e){}
    Object = o;
    return res;
  },

"Object" as name binding - is just name binding, Object - as an object
constructor - is an object in memory. Name binding is not so
essential, so from ES-3 "as if by the expression new Object()" still
stands.

alert({}.constructor === o); // true
  arrayLiteralUseArrayConstructor : function()
  {
    var a = Array,
      res = true;
    Array = null;
    try {
      ([]);
      res = false;
    }catch(e){};
    Array = a;
    return res;
  },

The same, object for Array is still in memory, name binding is not
essential, at least in ES-3.

alert([].constructor === a); // true
  forInToObjectExpression : function()
  {
    try {
      for(var i in null);
      return false;
    }catch(e) {}
    return true;
  }

};

All current implementations know about this, this "bug" has some
justifications in implementation source codes, but I think, roots of
such issue (not conforming to 12.6.4, ES-3) goes to similar
psychological case as for typeof null == 'object' which is taken by
the "hardcoded" table (11.4.3. ES-3). That was just ideological
thoughts of B.Eich, but easily (if there where no such thoughts) and
`typeof null' could be 'null' and `for..in' could throw an TypeError.

Interesting part is `variableObjectPrototype` in DMDScript
implementation. They used object with [[Prototype]] which refer
`Object.prototype`. DMD have the same behavior and with Global
Object.

Also older versions of Spidermonkey and Blackberry have such
implementation, but you know this.

P.S.> small additions:
functionStatement : function()

For anonymous FE there's a code convention to put space after
`function' keyword (the same like for named FE and FD).

function test() {} // there's space, there's name

funtion () {} // there's space, just name is gone

It also prevents cases when `function()' can be treated as function
call where there should be no (by convention sure, but not by the
grammar) space after function name.

That's suggestion, you can use it or not.

/ds
 
A

Asen Bozhilov

Dmitry said:
"Object" as name binding - is just name binding, Object - as an object
constructor - is an object in memory. Name binding is not so
essential, so from ES-3 "as if by the expression new Object()" still
stands.

DMD implementation:

Object = null;
({});

Exception: primitive Null has no Construct method

How can you explain next lines in Spider/Trace Monkey?:

var o = new Object();
o.testProp = true;
window.alert(o.__count__); //1
window.alert(o.hasOwnProperty('__count__')); //true
window.alert(o.propertyIsEnumerable('__count__')); //false
o.__count__ = -1;
window.alert(o.__count__ === -1); //false
window.alert(delete o.__count__); //false

Nonstandard property `__count__` has {DontEnum}, {DontDelete} and
{ReadOnly} attributes. All right, but if i define property with name
`__count__` in object literal expression.

var o = {testProp : true, __count__ : 10};
window.alert(o.__count__); //10
window.alert(o.hasOwnProperty('__count__')); //true
window.alert(o.propertyIsEnumerable('__count__')); //true
o.__count__ = -1;
window.alert(o.__count__ === -1); //true

window.alert(delete o.__count__); //true
window.alert(o.__count__); //1

The last two lines showed, extended implementation of internal [[Put]]
(P, V) and [[Delete]](P) for a native objects in Spider/Trace Monkey
versions which support `__count__` property.
 
D

Dmitry A. Soshnikov

DMD implementation:

Object = null;
({});

Exception: primitive Null has no Construct method

Yeah, the same is in Spidermonkey 1.7:

Object = null;
({}) // TypeError: Object is not a constructor

Object = Number;
({}) // 0

Regardless DMDScript and Spidermonkey 1.7 in other implementations
"Object" - as name binding - is name binding and bound to new value:

alert(Object === null); // true

But that Object constructor in memory is still stands:

alert(({}).constructor); // native Object

Object = Number;

alert(({}).constructor); // native Object

It's even hard to say which implementations is more logical. From one
viewpoint assignment should bound name binding with new object in
memory and in this case after `Object = null' and if there's no any
reference to "Object" name should be ReferenceError:

delete Object;
alert(Object); // Object is not defined

But it seems not useful for object initializer, so they leaved `{}'
for original Object constructor which is still in memory (just name
binding is deleted, just name binding is set to `null'), so even after
deletion:

alert(({}).constructor); // native Object

How can you explain next lines in Spider/Trace Monkey?:

The same as in JScript in IE's implementation with some host-objects,
e.g. `navigator' property which I already mentioned here:

alert(navigator); // [object], OK
alert(navigator.userAgent); // exactly that object we expect

// now use variable declaration
// using [eval] which should not
// set {DontDelete}

eval('var navigator;');
alert(navigator); // undefined, OK

// set new value
navigator = 10;
alert(navigator); // 10, OK

// remove it from the base object
// as navigator has no {DontDelete}
delete navigator;

alert(navigator); // [object], ;)

// and exactly restored main
// [navigator] host object
alert(navigator.userAgent);

My explanation (which is guess as I can't see sources of JScript
implementation) of this: <URL:
http://groups.google.ru/group/comp....ea/6fdf6014742a3cf3?hl=en&q=#c1572441853282c6>

So, behavior of Spidermonkey's `__count__' could be similar and it's
normal as this property is not standard.
The last two lines showed, extended implementation of internal [[Put]]
(P, V) and [[Delete]](P) for a native objects in Spider/Trace Monkey
versions which support `__count__` property.

And also [[Get]]. When reading property ([[Get]] method is called) -
if some property is user-defined - one behavior, if not - the other.

/ds
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,764
Messages
2,569,567
Members
45,041
Latest member
RomeoFarnh

Latest Threads

Top