Index: src/v8natives.js |
diff --git a/src/v8natives.js b/src/v8natives.js |
index 137b758b911375de50ae6e2467e08b949fec67f9..03d1585a041acc0f973da82c3269a1b374a45c8f 100644 |
--- a/src/v8natives.js |
+++ b/src/v8natives.js |
@@ -75,12 +75,48 @@ function InstallFunctions(object, attributes, functions) { |
// functions on String.prototype etc. and then restore the old function |
// with delete. See http://code.google.com/p/chromium/issues/detail?id=1717 |
function InstallFunctionsOnHiddenPrototype(object, attributes, functions) { |
+ %CheckIsBootstrapping(); |
var hidden_prototype = new $Object(); |
%SetHiddenPrototype(object, hidden_prototype); |
InstallFunctions(hidden_prototype, attributes, functions); |
} |
+// Prevents changes to the prototype of a built-infunction. |
+// The "prototype" property of the function object is made non-configurable, |
+// and the prototype object is made non-extensible. The latter prevents |
+// changing the __proto__ property. |
+function SetUpLockedPrototype(constructor, fields, methods) { |
+ %CheckIsBootstrapping(); |
+ var prototype = constructor.prototype; |
+ // Install functions first, because this function is used to initialize |
+ // PropertyDescriptor itself. |
+ var property_count = (methods.length >> 1) + (fields ? fields.length : 0); |
+ if (property_count >= 4) { |
+ %OptimizeObjectForAddingMultipleProperties(prototype, property_count); |
+ } |
+ if (fields) { |
+ for (var i = 0; i < fields.length; i++) { |
+ %SetProperty(prototype, fields[i], void 0, DONT_ENUM | DONT_DELETE); |
+ } |
+ } |
+ for (var i = 0; i < methods.length; i += 2) { |
+ var key = methods[i]; |
+ var f = methods[i + 1]; |
+ %SetProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY); |
+ %SetNativeFlag(f); |
+ } |
+ prototype.__proto__ = null; |
+ %PreventExtensions(prototype); |
+ %ToFastProperties(prototype); |
+ |
+ var desc = GetOwnProperty(constructor, "prototype"); |
+ desc.setWritable(false); |
+ desc.setConfigurable(false); |
+ DefineOwnProperty(constructor, "prototype", desc, false); |
+} |
+ |
+ |
// ---------------------------------------------------------------------------- |
@@ -171,8 +207,9 @@ function GlobalEval(x) { |
// ---------------------------------------------------------------------------- |
- |
-function SetupGlobal() { |
+// Set up global object. |
+function SetUpGlobal() { |
+ %CheckIsBootstrapping(); |
// ECMA 262 - 15.1.1.1. |
%SetProperty(global, "NaN", $NaN, DONT_ENUM | DONT_DELETE); |
@@ -182,7 +219,7 @@ function SetupGlobal() { |
// ECMA-262 - 15.1.1.3. |
%SetProperty(global, "undefined", void 0, DONT_ENUM | DONT_DELETE); |
- // Setup non-enumerable function on the global object. |
+ // Set up non-enumerable function on the global object. |
InstallFunctions(global, DONT_ENUM, $Array( |
"isNaN", GlobalIsNaN, |
"isFinite", GlobalIsFinite, |
@@ -192,8 +229,7 @@ function SetupGlobal() { |
)); |
} |
-SetupGlobal(); |
- |
+SetUpGlobal(); |
// ---------------------------------------------------------------------------- |
// Boolean (first part of definition) |
@@ -490,106 +526,83 @@ function PropertyDescriptor() { |
this.hasSetter_ = false; |
} |
-PropertyDescriptor.prototype.__proto__ = null; |
- |
-PropertyDescriptor.prototype.toString = function() { |
- return "[object PropertyDescriptor]"; |
-}; |
- |
-PropertyDescriptor.prototype.setValue = function(value) { |
- this.value_ = value; |
- this.hasValue_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.getValue = function() { |
- return this.value_; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasValue = function() { |
- return this.hasValue_; |
-} |
- |
- |
-PropertyDescriptor.prototype.setEnumerable = function(enumerable) { |
- this.enumerable_ = enumerable; |
- this.hasEnumerable_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.isEnumerable = function () { |
- return this.enumerable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasEnumerable = function() { |
- return this.hasEnumerable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.setWritable = function(writable) { |
- this.writable_ = writable; |
- this.hasWritable_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.isWritable = function() { |
- return this.writable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasWritable = function() { |
- return this.hasWritable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.setConfigurable = function(configurable) { |
- this.configurable_ = configurable; |
- this.hasConfigurable_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasConfigurable = function() { |
- return this.hasConfigurable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.isConfigurable = function() { |
- return this.configurable_; |
-} |
- |
- |
-PropertyDescriptor.prototype.setGet = function(get) { |
- this.get_ = get; |
- this.hasGetter_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.getGet = function() { |
- return this.get_; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasGetter = function() { |
- return this.hasGetter_; |
-} |
- |
- |
-PropertyDescriptor.prototype.setSet = function(set) { |
- this.set_ = set; |
- this.hasSetter_ = true; |
-} |
- |
- |
-PropertyDescriptor.prototype.getSet = function() { |
- return this.set_; |
-} |
- |
- |
-PropertyDescriptor.prototype.hasSetter = function() { |
- return this.hasSetter_; |
-} |
+SetUpLockedPrototype(PropertyDescriptor, $Array( |
+ "value_", |
+ "hasValue_", |
+ "writable_", |
+ "hasWritable_", |
+ "enumerable_", |
+ "hasEnumerable_", |
+ "configurable_", |
+ "hasConfigurable_", |
+ "get_", |
+ "hasGetter_", |
+ "set_", |
+ "hasSetter_" |
+ ), $Array( |
+ "toString", function() { |
+ return "[object PropertyDescriptor]"; |
+ }, |
+ "setValue", function(value) { |
+ this.value_ = value; |
+ this.hasValue_ = true; |
+ }, |
+ "getValue", function() { |
+ return this.value_; |
+ }, |
+ "hasValue", function() { |
+ return this.hasValue_; |
+ }, |
+ "setEnumerable", function(enumerable) { |
+ this.enumerable_ = enumerable; |
+ this.hasEnumerable_ = true; |
+ }, |
+ "isEnumerable", function () { |
+ return this.enumerable_; |
+ }, |
+ "hasEnumerable", function() { |
+ return this.hasEnumerable_; |
+ }, |
+ "setWritable", function(writable) { |
+ this.writable_ = writable; |
+ this.hasWritable_ = true; |
+ }, |
+ "isWritable", function() { |
+ return this.writable_; |
+ }, |
+ "hasWritable", function() { |
+ return this.hasWritable_; |
+ }, |
+ "setConfigurable", function(configurable) { |
+ this.configurable_ = configurable; |
+ this.hasConfigurable_ = true; |
+ }, |
+ "hasConfigurable", function() { |
+ return this.hasConfigurable_; |
+ }, |
+ "isConfigurable", function() { |
+ return this.configurable_; |
+ }, |
+ "setGet", function(get) { |
+ this.get_ = get; |
+ this.hasGetter_ = true; |
+ }, |
+ "getGet", function() { |
+ return this.get_; |
+ }, |
+ "hasGetter", function() { |
+ return this.hasGetter_; |
+ }, |
+ "setSet", function(set) { |
+ this.set_ = set; |
+ this.hasSetter_ = true; |
+ }, |
+ "getSet", function() { |
+ return this.set_; |
+ }, |
+ "hasSetter", function() { |
+ return this.hasSetter_; |
+ })); |
// Converts an array returned from Runtime_GetOwnProperty to an actual |
@@ -1177,10 +1190,11 @@ function ObjectIsExtensible(obj) { |
%SetExpectedNumberOfProperties($Object, 4); |
// ---------------------------------------------------------------------------- |
+// Object |
- |
-function SetupObject() { |
- // Setup non-enumerable functions on the Object.prototype object. |
+function SetUpObject() { |
+ %CheckIsBootstrapping(); |
+ // Set Up non-enumerable functions on the Object.prototype object. |
InstallFunctions($Object.prototype, DONT_ENUM, $Array( |
"toString", ObjectToString, |
"toLocaleString", ObjectToLocaleString, |
@@ -1210,8 +1224,7 @@ function SetupObject() { |
)); |
} |
-SetupObject(); |
- |
+SetUpObject(); |
// ---------------------------------------------------------------------------- |
// Boolean |
@@ -1242,14 +1255,16 @@ function BooleanValueOf() { |
// ---------------------------------------------------------------------------- |
-function SetupBoolean() { |
+function SetUpBoolean () { |
+ %CheckIsBootstrapping(); |
InstallFunctions($Boolean.prototype, DONT_ENUM, $Array( |
"toString", BooleanToString, |
"valueOf", BooleanValueOf |
)); |
} |
-SetupBoolean(); |
+SetUpBoolean(); |
+ |
// ---------------------------------------------------------------------------- |
// Number |
@@ -1363,9 +1378,10 @@ function NumberToPrecision(precision) { |
// ---------------------------------------------------------------------------- |
-function SetupNumber() { |
+function SetUpNumber() { |
+ %CheckIsBootstrapping(); |
%OptimizeObjectForAddingMultipleProperties($Number.prototype, 8); |
- // Setup the constructor property on the Number prototype object. |
+ // Set up the constructor property on the Number prototype object. |
%SetProperty($Number.prototype, "constructor", $Number, DONT_ENUM); |
%OptimizeObjectForAddingMultipleProperties($Number, 5); |
@@ -1394,7 +1410,7 @@ function SetupNumber() { |
DONT_ENUM | DONT_DELETE | READ_ONLY); |
%ToFastProperties($Number); |
- // Setup non-enumerable functions on the Number prototype object. |
+ // Set up non-enumerable functions on the Number prototype object. |
InstallFunctions($Number.prototype, DONT_ENUM, $Array( |
"toString", NumberToString, |
"toLocaleString", NumberToLocaleString, |
@@ -1405,7 +1421,7 @@ function SetupNumber() { |
)); |
} |
-SetupNumber(); |
+SetUpNumber(); |
// ---------------------------------------------------------------------------- |
@@ -1534,11 +1550,12 @@ function NewFunction(arg1) { // length == 1 |
// ---------------------------------------------------------------------------- |
-function SetupFunction() { |
+function SetUpFunction() { |
+ %CheckIsBootstrapping(); |
InstallFunctions($Function.prototype, DONT_ENUM, $Array( |
"bind", FunctionBind, |
"toString", FunctionToString |
)); |
} |
-SetupFunction(); |
+SetUpFunction(); |