Skip to content

Instantly share code, notes, and snippets.

@DmitrySoshnikov
Created August 20, 2010 09:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DmitrySoshnikov/539974 to your computer and use it in GitHub Desktop.
Save DmitrySoshnikov/539974 to your computer and use it in GitHub Desktop.
/**
* Abstract representation of ES3
* or ES5-non-strict sharing of
* passed formal parameters and
* corresponding indexes of the
* arguments object
*
* Implemented in ES5, non-strict
* tested in BESEN rev. 109
*
* @author Dmitry A. Soshnikov (C) 2010
*/
print("==Exact===\n");
function foo(a, b) {
print(arguments.length); // 1
print(arguments.callee.length); // 2
print(a); // 10
arguments[0] = 20;
print(a); // 20
a = 30;
print(arguments[0]); // 30
b = 100;
print(arguments[1]); // undefined
delete a; // false
delete arguments[0]; // true
print(arguments[0]); // undefined
print(a); // 30
arguments[0] = 50;
print(arguments[0]); // 50
print(a); // 30
a = 40;
print(a); // 40
print(arguments[0]); // 50
}
// call function, passing
// only first parameter
foo(10);
// Abstract description of handling
// variable/activation object in ES3, for details see:
// http://dmitrysoshnikov.com/ecmascript/chapter-2-variable-object/
print("\n==Abstract===\n");
// 1. Entering the context stage
var AO = Object.defineProperties({}, {
arguments: {
value: Object.defineProperties({}, {
// create accessor only for the
// passed argument - "a", index 0
0: {
get: function getA() {
return AO.a;
},
set: function setA(value) {
AO.a = value;
},
configurable: true
},
// length is a number of
// the actual arguments passed
length: {value: 1, writable: true, configurable: true},
// current function
callee: {value: foo, writable: true, configurable: true}
})
},
// create formal parameters
a: {value: 10, writable: true},
b: {value: undefined, writable: true},
});
// 2. Code execution stage
// use with to emulate identifier
// resolution in function's AO
with (AO) {
print(arguments.length); // 1
print(arguments.callee.length); // 2
print(a); // 10
arguments[0] = 20;
print(a); // 20
a = 30;
print(arguments[0]); // 30
// "b" is not passed to
// function, so it's not shared
b = 100;
print(arguments[1]); // undefined, as should be
// can't delete formal parameter,
// because it's not configurable
// {DontDelete} == true ES3,
// [[Configurable]] == false ES5
delete a; // false
// but can delete corresponding
// arguments' property; however,
// deleting it, we lose accessor
delete arguments[0]; // true
print(arguments[0]); // undefined
print(a); // 30
// arguments[0] now is a
// simple data property
arguments[0] = 50;
print(arguments[0]); // 50
print(a); // 30
a = 40;
print(a); // 40
print(arguments[0]); // 50
}
// This correct behavior currently
// is broken in Chrome, for details
// see http://code.google.com/p/chromium/issues/detail?id=52484
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment