Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(192)

Unified Diff: src/objects.cc

Issue 2108203002: Implement immutable prototype chains (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: simplify Created 4 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index defde30c44468f4b6190a14dabddcce05dd1284a..9feea5091c860fe0bb06d66591e93595f6e3b4c3 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -8681,6 +8681,17 @@ Handle<Map> Map::CopyNormalized(Handle<Map> map,
return result;
}
+// Return an immutable prototype exotic object version of the input map.
+// This is not cached in the transition tree because it is only used on
Toon Verwaest 2016/06/30 15:35:33 The comment is a little inaccurate. The JS_GLOBAL_
Dan Ehrenberg 2016/06/30 23:12:41 Changed the comment; WDYT?
+// the global object, and excluding it saves memory on the map transition
+// tree.
+
+// static
+Handle<Map> Map::TransitionToImmutableProto(Handle<Map> map) {
+ Handle<Map> new_map = Map::Copy(map, "ImmutablePrototype");
+ new_map->set_immutable_proto(true);
+ return new_map;
+}
Handle<Map> Map::CopyInitialMap(Handle<Map> map, int instance_size,
int in_object_properties,
@@ -14973,6 +14984,13 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
// Nothing to do if prototype is already set.
if (map->prototype() == *value) return Just(true);
+ bool immutable_proto = object->map()->is_immutable_proto();
+ if (immutable_proto) {
+ RETURN_FAILURE(
+ isolate, should_throw,
+ NewTypeError(MessageTemplate::kImmutablePrototypeSet, object));
+ }
+
// From 8.6.2 Object Internal Methods
// ...
// In addition, if [[Extensible]] is false the value of the [[Class]] and
@@ -15024,6 +15042,45 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
return Just(true);
}
+// static
+Maybe<bool> JSObject::SetImmutableProto(Handle<JSObject> object,
+ bool from_javascript,
+ ShouldThrow should_throw) {
+ Isolate* isolate = object->GetIsolate();
+
+ if (from_javascript) {
Toon Verwaest 2016/06/30 15:35:33 I guess this shouldn't be possible? So shouldn't b
Dan Ehrenberg 2016/06/30 23:12:41 Good point, nicer to not have that code. I include
+ if (object->IsAccessCheckNeeded() &&
+ !isolate->MayAccess(handle(isolate->context()), object)) {
+ isolate->ReportFailedAccessCheck(object);
+ RETURN_VALUE_IF_SCHEDULED_EXCEPTION(isolate, Nothing<bool>());
+ RETURN_FAILURE(isolate, should_throw,
+ NewTypeError(MessageTemplate::kNoAccess));
+ }
+ } else {
+ DCHECK(!object->IsAccessCheckNeeded());
+ }
+
+ Handle<JSObject> real_receiver = object;
+ if (from_javascript) {
+ // Find the first object in the chain whose prototype object is not
+ // hidden.
+ PrototypeIterator iter(isolate, real_receiver, kStartAtPrototype,
+ PrototypeIterator::END_AT_NON_HIDDEN);
+ while (!iter.IsAtEnd()) {
+ // Casting to JSObject is fine because hidden prototypes are never
+ // JSProxies.
+ real_receiver = PrototypeIterator::GetCurrent<JSObject>(iter);
+ iter.Advance();
+ }
+ }
+ Handle<Map> map(real_receiver->map());
+
+ // Nothing to do if prototype is already set.
+ if (map->is_immutable_proto()) return Just(true);
+ Handle<Map> new_map = Map::TransitionToImmutableProto(map);
+ object->set_map(*new_map);
+ return Just(true);
+}
void JSObject::EnsureCanContainElements(Handle<JSObject> object,
Arguments* args,

Powered by Google App Engine
This is Rietveld 408576698