Reviewers: rossberg,

Message:
PTAL

Description:
[strong] Implement per-object restrictions behaviour for prototype setting

Implements the strong mode proposal's restrictions on the ability of user code
to modify the prototype of strong objects.

Setting the strong bit is still wip, so this change will only affect those
objects that have the bit correctly set (currently only function). The tests
reflect this, and will be expanded as more objects can be marked as strong.

BUG=v8:3956
LOG=N

Please review this at https://codereview.chromium.org/1143623002/

Base URL: https://chromium.googlesource.com/v8/v8.git@master

Affected files (+71, -0 lines):
  M src/messages.h
  M src/objects.cc
  A test/mjsunit/strong/object-set-prototype.js


Index: src/messages.h
diff --git a/src/messages.h b/src/messages.h
index 4d8b459c5dcb6f32bcf9e8f6ec7155efe254dd6e..1b000ec3d3dc5e671b262c7ea09916a4392fbfde 100644
--- a/src/messages.h
+++ b/src/messages.h
@@ -249,6 +249,7 @@ class CallSite {
T(StrongArity, \ "In strong mode, calling a function with too few arguments is deprecated") \ T(StrongImplicitCast, "In strong mode, implicit conversions are deprecated") \ + T(StrongSetProto, "Cannot set internal prototype of strong object %") \ T(SymbolKeyFor, "% is not a symbol") \ T(SymbolToPrimitive, \ "Cannot convert a Symbol wrapper object to a primitive value") \
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 5bd67af52d6cdeb7f49d286314e0beb48389487b..0817cddf6e0d20c781f5267525df5bb2d18bc1da 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -12607,6 +12607,13 @@ MaybeHandle<Object> JSObject::SetPrototype(Handle<JSObject> object,
 #endif

   Isolate* isolate = object->GetIsolate();
+  // Strong objects may not have their prototype set via __proto__ or
+  // setPrototypeOf.
+  if (from_javascript && object->map()->is_strong()) {
+    THROW_NEW_ERROR(isolate,
+                    NewTypeError(MessageTemplate::kStrongSetProto, object),
+                    Object);
+  }
   Heap* heap = isolate->heap();
   // Silently ignore the change if value is not a JSObject or null.
   // SpiderMonkey behaves this way.
Index: test/mjsunit/strong/object-set-prototype.js
diff --git a/test/mjsunit/strong/object-set-prototype.js b/test/mjsunit/strong/object-set-prototype.js
new file mode 100644
index 0000000000000000000000000000000000000000..d19f6bc86dd69ee9ebe6f0c4e2a1c280414c2fd5
--- /dev/null
+++ b/test/mjsunit/strong/object-set-prototype.js
@@ -0,0 +1,63 @@
+// Copyright 2015 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --strong-mode --allow-natives-syntax
+
+// TODO(conradw): Track implementation of strong bit for other objects, add
+// tests.
+
+var sloppyFunction = function(){};
+var strictFunction = function(){"use strict";};
+var strongFunction = function(){"use strong";};
+
+var setProtoBuiltin = function(o){Object.setPrototypeOf(o, {})};
+var setProtoProperty = function(o){o.__proto__ = {}};
+
+var sloppyObjects = [sloppyFunction];
+
+var strictObjects = [strictFunction];
+
+var strongObjects = [strongFunction];
+
+var nonStrongObjects = sloppyObjects.concat(strictObjects);
+
+var setProtoFuncs = [setProtoBuiltin, setProtoProperty];
+
+for (var setProtoFunc of setProtoFuncs) {
+  for (var o of nonStrongObjects) {
+    assertDoesNotThrow(function(){setProtoFunc(o)});
+    %OptimizeFunctionOnNextCall(setProtoFunc);
+    assertDoesNotThrow(function(){setProtoFunc(o)});
+    %DeoptimizeFunction(setProtoFunc);
+    assertDoesNotThrow(function(){setProtoFunc(o)});
+  }
+  for (var o of strongObjects) {
+    assertThrows(function(){setProtoFunc(o)}, TypeError);
+    %OptimizeFunctionOnNextCall(setProtoFunc);
+    assertThrows(function(){setProtoFunc(o)}, TypeError);
+    %DeoptimizeFunction(setProtoFunc);
+    assertThrows(function(){setProtoFunc(o)}, TypeError);
+  }
+}
+
+//TODO(conradw): Uncomment this once object literals can be strong
+/*
+var declareObjectLiteralWithProtoSloppy =
+  function() { return {__proto__: {}}; };
+
+var declareObjectLiteralWithProtoStrong =
+  function() {"use strong"; return {__proto__: {}}; };
+
+assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+%OptimizeFunctionOnNextCall(declareObjectLiteralWithProtoSloppy);
+assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+%DeoptimizeFunction(declareObjectLiteralWithProtoSloppy);
+assertDoesNotThrow(declareObjectLiteralWithProtoSloppy);
+
+assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+%OptimizeFunctionOnNextCall(declareObjectLiteralWithProtoStrong);
+assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+%DeoptimizeFunction(declareObjectLiteralWithProtoStrong);
+assertDoesNotThrow(declareObjectLiteralWithProtoStrong);
+*/


--
--
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/d/optout.

Reply via email to