| Index: src/v8natives.js
|
| ===================================================================
|
| --- src/v8natives.js (revision 427)
|
| +++ src/v8natives.js (working copy)
|
| @@ -25,7 +25,6 @@
|
| // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
| // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
|
| -
|
| // This file relies on the fact that the following declarations have been made
|
| //
|
| // in runtime.js:
|
| @@ -39,36 +38,41 @@
|
| // in math.js:
|
| // const $floor = MathFloor
|
|
|
| +const $isNaN = GlobalIsNaN;
|
| +const $isFinite = GlobalIsFinite;
|
|
|
| -// ECMA 262 - 15.1.1.1.
|
| -%SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
|
| +// ----------------------------------------------------------------------------
|
|
|
|
|
| -// ECMA-262 - 15.1.1.2.
|
| -%SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
|
| +// Helper function used to install functions on objects.
|
| +function InstallFunctions(object, attributes, functions) {
|
| + for (var i = 0; i < functions.length; i += 2) {
|
| + var key = functions[i];
|
| + var f = functions[i + 1];
|
| + %FunctionSetName(f, key);
|
| + %SetProperty(object, key, f, attributes);
|
| + }
|
| +}
|
|
|
|
|
| -// ECMA-262 - 15.1.1.3.
|
| -%SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
|
| +// ----------------------------------------------------------------------------
|
|
|
|
|
| // ECMA 262 - 15.1.4
|
| -function $isNaN(number) {
|
| +function GlobalIsNaN(number) {
|
| var n = ToNumber(number);
|
| return NUMBER_IS_NAN(n);
|
| }
|
| -%SetProperty(global, "isNaN", $isNaN, DONT_ENUM);
|
|
|
|
|
| // ECMA 262 - 15.1.5
|
| -function $isFinite(number) {
|
| +function GlobalIsFinite(number) {
|
| return %NumberIsFinite(ToNumber(number));
|
| }
|
| -%SetProperty(global, "isFinite", $isFinite, DONT_ENUM);
|
|
|
|
|
| // ECMA-262 - 15.1.2.2
|
| -%SetProperty(global, "parseInt", function(string, radix) {
|
| +function GlobalParseInt(string, radix) {
|
| if (radix === void 0) {
|
| radix = 0;
|
| // Some people use parseInt instead of Math.floor. This
|
| @@ -89,16 +93,64 @@
|
| return $NaN;
|
| }
|
| return %StringParseInt(ToString(string), radix);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 - 15.1.2.3
|
| -%SetProperty(global, "parseFloat", function(string) {
|
| +function GlobalParseFloat(string) {
|
| return %StringParseFloat(ToString(string));
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| +function GlobalEval(x) {
|
| + if (!IS_STRING(x)) return x;
|
| +
|
| + var f = %CompileString(x, 0, true);
|
| + if (!IS_FUNCTION(f)) return f;
|
| +
|
| + return f.call(%EvalReceiver(this));
|
| +}
|
| +
|
| +
|
| +// execScript for IE compatibility.
|
| +function GlobalExecScript(expr, lang) {
|
| + // NOTE: We don't care about the character casing.
|
| + if (!lang || /javascript/i.test(lang)) {
|
| + var f = %CompileString(ToString(expr), 0, false);
|
| + f.call(global);
|
| + }
|
| + return null;
|
| +}
|
| +
|
| +
|
| // ----------------------------------------------------------------------------
|
| +
|
| +
|
| +function SetupGlobal() {
|
| + // ECMA 262 - 15.1.1.1.
|
| + %SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE);
|
| +
|
| + // ECMA-262 - 15.1.1.2.
|
| + %SetProperty(global, "Infinity", 1/0, DONT_ENUM | DONT_DELETE);
|
| +
|
| + // ECMA-262 - 15.1.1.3.
|
| + %SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE);
|
| +
|
| + // Setup non-enumerable function on the global object.
|
| + InstallFunctions(global, DONT_ENUM, $Array(
|
| + "isNaN", GlobalIsNaN,
|
| + "isFinite", GlobalIsFinite,
|
| + "parseInt", GlobalParseInt,
|
| + "parseFloat", GlobalParseFloat,
|
| + "eval", GlobalEval,
|
| + "execScript", GlobalExecScript
|
| + ));
|
| +}
|
| +
|
| +SetupGlobal();
|
| +
|
| +
|
| +// ----------------------------------------------------------------------------
|
| // Boolean (first part of definition)
|
|
|
|
|
| @@ -119,49 +171,50 @@
|
|
|
| $Object.prototype.constructor = $Object;
|
|
|
| -%SetProperty($Object.prototype, "toString", function() {
|
| +// ECMA-262 - 15.2.4.2
|
| +function ObjectToString() {
|
| var c = %ClassOf(this);
|
| // Hide Arguments from the outside.
|
| if (c === 'Arguments') c = 'Object';
|
| return "[object " + c + "]";
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -// ECMA-262, section 15.2.4.3, page 84.
|
| -%SetProperty($Object.prototype, "toLocaleString", function() {
|
| +// ECMA-262 - 15.2.4.3
|
| +function ObjectToLocaleString() {
|
| return this.toString();
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -// ECMA-262, section 15.2.4.4, page 85.
|
| -%SetProperty($Object.prototype, "valueOf", function() {
|
| +// ECMA-262 - 15.2.4.4
|
| +function ObjectValueOf() {
|
| return this;
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -// ECMA-262, section 15.2.4.5, page 85.
|
| -%SetProperty($Object.prototype, "hasOwnProperty", function(V) {
|
| +// ECMA-262 - 15.2.4.5
|
| +function ObjectHasOwnProperty(V) {
|
| return %HasLocalProperty(ToObject(this), ToString(V));
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -// ECMA-262, section 15.2.4.6, page 85.
|
| -%SetProperty($Object.prototype, "isPrototypeOf", function(V) {
|
| +// ECMA-262 - 15.2.4.6
|
| +function ObjectIsPrototypeOf(V) {
|
| if (!IS_OBJECT(V) && !IS_FUNCTION(V)) return false;
|
| return %IsInPrototypeChain(this, V);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -// ECMA-262, section 15.2.4.6, page 85.
|
| -%SetProperty($Object.prototype, "propertyIsEnumerable", function(V) {
|
| +// ECMA-262 - 15.2.4.6
|
| +function ObjectPropertyIsEnumerable(V) {
|
| if (this == null) return false;
|
| if (!IS_OBJECT(this) && !IS_FUNCTION(this)) return false;
|
| return %IsPropertyEnumerable(this, ToString(V));
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // Extensions for providing property getters and setters.
|
| -%SetProperty($Object.prototype, "__defineGetter__", function(name, fun) {
|
| +function ObjectDefineGetter(name, fun) {
|
| if (this == null) {
|
| throw new $TypeError('Object.prototype.__defineGetter__: this is Null');
|
| }
|
| @@ -170,19 +223,18 @@
|
| 'Object.prototype.__defineGetter__: Expecting function');
|
| }
|
| return %DefineAccessor(ToObject(this), ToString(name), GETTER, fun);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -
|
| -%SetProperty($Object.prototype, "__lookupGetter__", function(name) {
|
| +function ObjectLookupGetter(name) {
|
| if (this == null) {
|
| throw new $TypeError('Object.prototype.__lookupGetter__: this is Null');
|
| }
|
| return %LookupAccessor(ToObject(this), ToString(name), GETTER);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -%SetProperty($Object.prototype, "__defineSetter__", function(name, fun) {
|
| +function ObjectDefineSetter(name, fun) {
|
| if (this == null) {
|
| throw new $TypeError('Object.prototype.__defineSetter__: this is Null');
|
| }
|
| @@ -191,15 +243,15 @@
|
| 'Object.prototype.__defineSetter__: Expecting function');
|
| }
|
| return %DefineAccessor(ToObject(this), ToString(name), SETTER, fun);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -%SetProperty($Object.prototype, "__lookupSetter__", function(name) {
|
| +function ObjectLookupSetter(name) {
|
| if (this == null) {
|
| throw new $TypeError('Object.prototype.__lookupSetter__: this is Null');
|
| }
|
| return %LookupAccessor(ToObject(this), ToString(name), SETTER);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| %SetCode($Object, function(x) {
|
| @@ -214,51 +266,61 @@
|
|
|
|
|
| // ----------------------------------------------------------------------------
|
| -// Global stuff...
|
|
|
| -%SetProperty(global, "eval", function(x) {
|
| - if (!IS_STRING(x)) return x;
|
|
|
| - var f = %CompileString(x, 0, true);
|
| - if (!IS_FUNCTION(f)) return f;
|
| +function SetupObject() {
|
| + // Setup non-enumerable functions on the Object.prototype object.
|
| + InstallFunctions($Object.prototype, DONT_ENUM, $Array(
|
| + "toString", ObjectToString,
|
| + "toLocaleString", ObjectToLocaleString,
|
| + "valueOf", ObjectValueOf,
|
| + "hasOwnProperty", ObjectHasOwnProperty,
|
| + "isPrototypeOf", ObjectIsPrototypeOf,
|
| + "propertyIsEnumerable", ObjectPropertyIsEnumerable,
|
| + "__defineGetter__", ObjectDefineGetter,
|
| + "__lookupGetter__", ObjectLookupGetter,
|
| + "__defineSetter__", ObjectDefineSetter,
|
| + "__lookupSetter__", ObjectLookupSetter
|
| + ));
|
| +}
|
|
|
| - return f.call(%EvalReceiver(this));
|
| -}, DONT_ENUM);
|
| +SetupObject();
|
|
|
|
|
| -// execScript for IE compatibility.
|
| -%SetProperty(global, "execScript", function(expr, lang) {
|
| - // NOTE: We don't care about the character casing.
|
| - if (!lang || /javascript/i.test(lang)) {
|
| - var f = %CompileString(ToString(expr), 0, false);
|
| - f.call(global);
|
| - }
|
| - return null;
|
| -}, DONT_ENUM);
|
| -
|
| -
|
| // ----------------------------------------------------------------------------
|
| // Boolean
|
|
|
| -%SetProperty($Boolean.prototype, "toString", function() {
|
| +function BooleanToString() {
|
| // NOTE: Both Boolean objects and values can enter here as
|
| // 'this'. This is not as dictated by ECMA-262.
|
| if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean')
|
| throw new $TypeError('Boolean.prototype.toString is not generic');
|
| return ToString(%_ValueOf(this));
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| -%SetProperty($Boolean.prototype, "valueOf", function() {
|
| +function BooleanValueOf() {
|
| // NOTE: Both Boolean objects and values can enter here as
|
| // 'this'. This is not as dictated by ECMA-262.
|
| if (!IS_BOOLEAN(this) && %ClassOf(this) !== 'Boolean')
|
| throw new $TypeError('Boolean.prototype.valueOf is not generic');
|
| return %_ValueOf(this);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ----------------------------------------------------------------------------
|
| +
|
| +
|
| +function SetupBoolean() {
|
| + InstallFunctions($Boolean.prototype, DONT_ENUM, $Array(
|
| + "toString", BooleanToString,
|
| + "valueOf", BooleanValueOf
|
| + ));
|
| +}
|
| +
|
| +SetupBoolean();
|
| +
|
| +// ----------------------------------------------------------------------------
|
| // Number
|
|
|
| // Set the Number function and constructor.
|
| @@ -273,34 +335,8 @@
|
|
|
| %FunctionSetPrototype($Number, new $Number(0));
|
|
|
| -%SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
|
| -
|
| -// ECMA-262 section 15.7.3.1.
|
| -%SetProperty($Number,
|
| - "MAX_VALUE",
|
| - 1.7976931348623157e+308,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| -// ECMA-262 section 15.7.3.2.
|
| -%SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| -// ECMA-262 section 15.7.3.3.
|
| -%SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| -// ECMA-262 section 15.7.3.4.
|
| -%SetProperty($Number,
|
| - "NEGATIVE_INFINITY",
|
| - -1/0,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| -// ECMA-262 section 15.7.3.5.
|
| -%SetProperty($Number,
|
| - "POSITIVE_INFINITY",
|
| - 1/0,
|
| - DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| -
|
| // ECMA-262 section 15.7.4.2.
|
| -%SetProperty($Number.prototype, "toString", function(radix) {
|
| +function NumberToString(radix) {
|
| // NOTE: Both Number objects and values can enter here as
|
| // 'this'. This is not as dictated by ECMA-262.
|
| var number = this;
|
| @@ -322,38 +358,38 @@
|
| }
|
| // Convert the number to a string in the given radix.
|
| return %NumberToRadixString(number, radix);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 section 15.7.4.3
|
| -%SetProperty($Number.prototype, "toLocaleString", function() {
|
| +function NumberToLocaleString() {
|
| return this.toString();
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 section 15.7.4.4
|
| -%SetProperty($Number.prototype, "valueOf", function() {
|
| +function NumberValueOf() {
|
| // NOTE: Both Number objects and values can enter here as
|
| // 'this'. This is not as dictated by ECMA-262.
|
| if (!IS_NUMBER(this) && %ClassOf(this) !== 'Number')
|
| throw new $TypeError('Number.prototype.valueOf is not generic');
|
| return %_ValueOf(this);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 section 15.7.4.5
|
| -%SetProperty($Number.prototype, "toFixed", function(fractionDigits) {
|
| +function NumberToFixed(fractionDigits) {
|
| var f = TO_INTEGER(fractionDigits);
|
| if (f < 0 || f > 20) {
|
| throw new $RangeError("toFixed() digits argument must be between 0 and 20");
|
| }
|
| var x = ToNumber(this);
|
| return %NumberToFixed(x, f);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 section 15.7.4.6
|
| -%SetProperty($Number.prototype, "toExponential", function(fractionDigits) {
|
| +function NumberToExponential(fractionDigits) {
|
| var f = -1;
|
| if (!IS_UNDEFINED(fractionDigits)) {
|
| f = TO_INTEGER(fractionDigits);
|
| @@ -363,11 +399,11 @@
|
| }
|
| var x = ToNumber(this);
|
| return %NumberToExponential(x, f);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ECMA-262 section 15.7.4.7
|
| -%SetProperty($Number.prototype, "toPrecision", function(precision) {
|
| +function NumberToPrecision(precision) {
|
| if (IS_UNDEFINED(precision)) return ToString(%_ValueOf(this));
|
| var p = TO_INTEGER(precision);
|
| if (p < 1 || p > 21) {
|
| @@ -375,15 +411,59 @@
|
| }
|
| var x = ToNumber(this);
|
| return %NumberToPrecision(x, p);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| // ----------------------------------------------------------------------------
|
| +
|
| +function SetupNumber() {
|
| + // Setup the constructor property on the Number prototype object.
|
| + %SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM);
|
| +
|
| + // ECMA-262 section 15.7.3.1.
|
| + %SetProperty($Number,
|
| + "MAX_VALUE",
|
| + 1.7976931348623157e+308,
|
| + DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| +
|
| + // ECMA-262 section 15.7.3.2.
|
| + %SetProperty($Number, "MIN_VALUE", 5e-324, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| +
|
| + // ECMA-262 section 15.7.3.3.
|
| + %SetProperty($Number, "NaN", $NaN, DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| +
|
| + // ECMA-262 section 15.7.3.4.
|
| + %SetProperty($Number,
|
| + "NEGATIVE_INFINITY",
|
| + -1/0,
|
| + DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| +
|
| + // ECMA-262 section 15.7.3.5.
|
| + %SetProperty($Number,
|
| + "POSITIVE_INFINITY",
|
| + 1/0,
|
| + DONT_ENUM | DONT_DELETE | READ_ONLY);
|
| +
|
| + // Setup non-enumerable functions on the Number prototype object.
|
| + InstallFunctions($Number.prototype, DONT_ENUM, $Array(
|
| + "toString", NumberToString,
|
| + "toLocaleString", NumberToLocaleString,
|
| + "valueOf", NumberValueOf,
|
| + "toFixed", NumberToFixed,
|
| + "toExponential", NumberToExponential,
|
| + "toPrecision", NumberToPrecision
|
| + ));
|
| +}
|
| +
|
| +SetupNumber();
|
| +
|
| +
|
| +
|
| +// ----------------------------------------------------------------------------
|
| // Function
|
|
|
| $Function.prototype.constructor = $Function;
|
|
|
| -
|
| function FunctionSourceString(func) {
|
| // NOTE: Both Function objects and values can enter here as
|
| // 'func'. This is not as dictated by ECMA-262.
|
| @@ -412,9 +492,9 @@
|
| }
|
|
|
|
|
| -%SetProperty($Function.prototype, "toString", function() {
|
| +function FunctionToString() {
|
| return FunctionSourceString(this);
|
| -}, DONT_ENUM);
|
| +}
|
|
|
|
|
| function NewFunction(arg1) { // length == 1
|
| @@ -443,3 +523,14 @@
|
| }
|
|
|
| %SetCode($Function, NewFunction);
|
| +
|
| +// ----------------------------------------------------------------------------
|
| +
|
| +function SetupFunction() {
|
| + InstallFunctions($Function.prototype, DONT_ENUM, $Array(
|
| + "toString", FunctionToString
|
| + ));
|
| +}
|
| +
|
| +SetupFunction();
|
| +
|
|
|