Revision: 13815
Author:   [email protected]
Date:     Mon Mar  4 08:05:12 2013
Log:      Make sure builtin functions don't rely on __proto__.

This makes sure that none of the builtin functions rely on the __proto__
accessor which can now be monkey-patched by applications. Instead use a
separate %SetPrototype() intrinsic or object literals to do the job.

[email protected]

Review URL: https://codereview.chromium.org/12385082
http://code.google.com/p/v8/source/detail?r=13815

Modified:
 /branches/bleeding_edge/src/apinatives.js
 /branches/bleeding_edge/src/arm/full-codegen-arm.cc
 /branches/bleeding_edge/src/array.js
 /branches/bleeding_edge/src/d8.js
 /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc
 /branches/bleeding_edge/src/math.js
 /branches/bleeding_edge/src/messages.js
 /branches/bleeding_edge/src/mips/full-codegen-mips.cc
 /branches/bleeding_edge/src/objects.h
 /branches/bleeding_edge/src/proxy.js
 /branches/bleeding_edge/src/runtime.cc
 /branches/bleeding_edge/src/runtime.h
 /branches/bleeding_edge/src/v8natives.js
 /branches/bleeding_edge/src/x64/full-codegen-x64.cc

=======================================
--- /branches/bleeding_edge/src/apinatives.js   Mon Feb 20 05:48:24 2012
+++ /branches/bleeding_edge/src/apinatives.js   Mon Mar  4 08:05:12 2013
@@ -90,7 +90,7 @@
       // internal ToBoolean doesn't handle that!
       if (!(typeof parent === 'undefined')) {
         var parent_fun = Instantiate(parent);
-        fun.prototype.__proto__ = parent_fun.prototype;
+        %SetPrototype(fun.prototype, parent_fun.prototype);
       }
       ConfigureTemplateInstance(fun, data);
     } catch (e) {
=======================================
--- /branches/bleeding_edge/src/arm/full-codegen-arm.cc Fri Mar 1 05:28:55 2013 +++ /branches/bleeding_edge/src/arm/full-codegen-arm.cc Mon Mar 4 08:05:12 2013
@@ -1646,8 +1646,6 @@
           }
           break;
         }
-        // Fall through.
-      case ObjectLiteral::Property::PROTOTYPE:
         // Duplicate receiver on stack.
         __ ldr(r0, MemOperand(sp));
         __ push(r0);
@@ -1661,6 +1659,18 @@
           __ Drop(3);
         }
         break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        // Duplicate receiver on stack.
+        __ ldr(r0, MemOperand(sp));
+        __ push(r0);
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetPrototype, 2);
+        } else {
+          __ Drop(2);
+        }
+        break;
+
       case ObjectLiteral::Property::GETTER:
         accessor_table.lookup(key)->second->getter = value;
         break;
=======================================
--- /branches/bleeding_edge/src/array.js        Fri Feb 15 07:20:05 2013
+++ /branches/bleeding_edge/src/array.js        Mon Mar  4 08:05:12 2013
@@ -885,7 +885,7 @@
   // of a prototype property.
   var CopyFromPrototype = function CopyFromPrototype(obj, length) {
     var max = 0;
-    for (var proto = obj.__proto__; proto; proto = proto.__proto__) {
+ for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, length);
       if (indices.length > 0) {
         if (indices[0] == -1) {
@@ -916,7 +916,7 @@
   // where a prototype of obj has an element. I.e., shadow all prototype
   // elements in that range.
   var ShadowPrototypeElements = function(obj, from, to) {
-    for (var proto = obj.__proto__; proto; proto = proto.__proto__) {
+ for (var proto = %GetPrototype(obj); proto; proto = %GetPrototype(proto)) {
       var indices = %GetArrayKeys(proto, to);
       if (indices.length > 0) {
         if (indices[0] == -1) {
@@ -986,7 +986,7 @@
     }
     for (i = length - num_holes; i < length; i++) {
// For compatability with Webkit, do not expose elements in the prototype.
-      if (i in obj.__proto__) {
+      if (i in %GetPrototype(obj)) {
         obj[i] = void 0;
       } else {
         delete obj[i];
=======================================
--- /branches/bleeding_edge/src/d8.js   Wed Jan 16 07:44:26 2013
+++ /branches/bleeding_edge/src/d8.js   Mon Mar  4 08:05:12 2013
@@ -71,7 +71,7 @@
         result.push(name);
       }
     }
-    current = ToInspectableObject(current.__proto__);
+    current = ToInspectableObject(Object.getPrototypeOf(current));
   }
   return result;
 }
=======================================
--- /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Fri Mar 1 05:28:55 2013 +++ /branches/bleeding_edge/src/ia32/full-codegen-ia32.cc Mon Mar 4 08:05:12 2013
@@ -1601,8 +1601,6 @@
           }
           break;
         }
-        // Fall through.
-      case ObjectLiteral::Property::PROTOTYPE:
         __ push(Operand(esp, 0));  // Duplicate receiver.
         VisitForStackValue(key);
         VisitForStackValue(value);
@@ -1612,6 +1610,15 @@
         } else {
           __ Drop(3);
         }
+        break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ push(Operand(esp, 0));  // Duplicate receiver.
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetPrototype, 2);
+        } else {
+          __ Drop(2);
+        }
         break;
       case ObjectLiteral::Property::GETTER:
         accessor_table.lookup(key)->second->getter = value;
=======================================
--- /branches/bleeding_edge/src/math.js Thu Dec  6 05:13:38 2012
+++ /branches/bleeding_edge/src/math.js Mon Mar  4 08:05:12 2013
@@ -37,7 +37,7 @@
 function MathConstructor() {}
 %FunctionSetInstanceClassName(MathConstructor, 'Math');
 var $Math = new MathConstructor();
-$Math.__proto__ = $Object.prototype;
+%SetPrototype($Math, $Object.prototype);
 %SetProperty(global, "Math", $Math, DONT_ENUM);

 // ECMA 262 - 15.8.2.1
=======================================
--- /branches/bleeding_edge/src/messages.js     Fri Mar  1 06:50:14 2013
+++ /branches/bleeding_edge/src/messages.js     Mon Mar  4 08:05:12 2013
@@ -1208,7 +1208,7 @@
 function GetPropertyWithoutInvokingMonkeyGetters(error, name) {
   // Climb the prototype chain until we find the holder.
   while (error && !%HasLocalProperty(error, name)) {
-    error = error.__proto__;
+    error = %GetPrototype(error);
   }
   if (error === null) return void 0;
   if (!IS_OBJECT(error)) return error[name];
=======================================
--- /branches/bleeding_edge/src/mips/full-codegen-mips.cc Mon Mar 4 06:45:39 2013 +++ /branches/bleeding_edge/src/mips/full-codegen-mips.cc Mon Mar 4 08:05:12 2013
@@ -1654,8 +1654,6 @@
           }
           break;
         }
-        // Fall through.
-      case ObjectLiteral::Property::PROTOTYPE:
         // Duplicate receiver on stack.
         __ lw(a0, MemOperand(sp));
         __ push(a0);
@@ -1668,6 +1666,17 @@
         } else {
           __ Drop(3);
         }
+        break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        // Duplicate receiver on stack.
+        __ lw(a0, MemOperand(sp));
+        __ push(a0);
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetPrototype, 2);
+        } else {
+          __ Drop(2);
+        }
         break;
       case ObjectLiteral::Property::GETTER:
         accessor_table.lookup(key)->second->getter = value;
=======================================
--- /branches/bleeding_edge/src/objects.h       Mon Mar  4 07:00:57 2013
+++ /branches/bleeding_edge/src/objects.h       Mon Mar  4 08:05:12 2013
@@ -4872,7 +4872,7 @@
   inline bool function_with_prototype();

   // Tells whether the instance with this map should be ignored by the
-  // __proto__ accessor.
+  // Object.getPrototypeOf() function and the __proto__ accessor.
   inline void set_is_hidden_prototype() {
     set_bit_field(bit_field() | (1 << kIsHiddenPrototype));
   }
=======================================
--- /branches/bleeding_edge/src/proxy.js        Mon Mar  4 07:00:57 2013
+++ /branches/bleeding_edge/src/proxy.js        Mon Mar  4 08:05:12 2013
@@ -77,8 +77,7 @@
   return function() {
     var proto = this.prototype
     if (!IS_SPEC_OBJECT(proto)) proto = $Object.prototype
-    var obj = new $Object()
-    obj.__proto__ = proto
+    var obj = { __proto__: proto };
     var result = %Apply(callTrap, obj, arguments, 0, %_ArgumentsLength());
     return IS_SPEC_OBJECT(result) ? result : obj
   }
=======================================
--- /branches/bleeding_edge/src/runtime.cc      Mon Mar  4 07:00:57 2013
+++ /branches/bleeding_edge/src/runtime.cc      Mon Mar  4 08:05:12 2013
@@ -973,6 +973,15 @@
            JSObject::cast(obj)->map()->is_hidden_prototype());
   return obj;
 }
+
+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_SetPrototype) {
+  NoHandleAllocation ha(isolate);
+  ASSERT(args.length() == 2);
+  CONVERT_ARG_CHECKED(JSReceiver, input_obj, 0);
+  CONVERT_ARG_CHECKED(Object, prototype, 1);
+  return input_obj->SetPrototype(prototype, true);
+}


 RUNTIME_FUNCTION(MaybeObject*, Runtime_IsInPrototypeChain) {
=======================================
--- /branches/bleeding_edge/src/runtime.h       Fri Mar  1 05:28:55 2013
+++ /branches/bleeding_edge/src/runtime.h       Mon Mar  4 08:05:12 2013
@@ -67,6 +67,7 @@
   F(GetDefaultReceiver, 1, 1) \
   \
   F(GetPrototype, 1, 1) \
+  F(SetPrototype, 2, 1) \
   F(IsInPrototypeChain, 2, 1) \
   \
   F(GetOwnProperty, 2, 1) \
=======================================
--- /branches/bleeding_edge/src/v8natives.js    Mon Mar  4 07:00:57 2013
+++ /branches/bleeding_edge/src/v8natives.js    Mon Mar  4 08:05:12 2013
@@ -94,7 +94,7 @@
     %SetProperty(prototype, key, f, DONT_ENUM | DONT_DELETE | READ_ONLY);
     %SetNativeFlag(f);
   }
-  prototype.__proto__ = null;
+  %SetPrototype(prototype, null);
   %ToFastProperties(prototype);
 }

@@ -1074,8 +1074,7 @@
   if (!IS_SPEC_OBJECT(proto) && proto !== null) {
     throw MakeTypeError("proto_object_or_null", [proto]);
   }
-  var obj = new $Object();
-  obj.__proto__ = proto;
+  var obj = { __proto__: proto };
   if (!IS_UNDEFINED(properties)) ObjectDefineProperties(obj, properties);
   return obj;
 }
=======================================
--- /branches/bleeding_edge/src/x64/full-codegen-x64.cc Fri Mar 1 05:28:55 2013 +++ /branches/bleeding_edge/src/x64/full-codegen-x64.cc Mon Mar 4 08:05:12 2013
@@ -1626,8 +1626,6 @@
           }
           break;
         }
-        // Fall through.
-      case ObjectLiteral::Property::PROTOTYPE:
         __ push(Operand(rsp, 0));  // Duplicate receiver.
         VisitForStackValue(key);
         VisitForStackValue(value);
@@ -1637,6 +1635,15 @@
         } else {
           __ Drop(3);
         }
+        break;
+      case ObjectLiteral::Property::PROTOTYPE:
+        __ push(Operand(rsp, 0));  // Duplicate receiver.
+        VisitForStackValue(value);
+        if (property->emit_store()) {
+          __ CallRuntime(Runtime::kSetPrototype, 2);
+        } else {
+          __ Drop(2);
+        }
         break;
       case ObjectLiteral::Property::GETTER:
         accessor_table.lookup(key)->second->getter = value;

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to