Allow immutable prototype templates to inherit
To enable the global object prototype chain to be frozen, all objects in the chain need to be marked as immutable prototype exotic objects. However, a bug in the previous implementation of immutable prototype exotic objects left the check in place when initially setting up the object, which made it impossible to allow inheritance chains. This patch removes that mistaken check. BUG=v8:5149 Review-Url: https://codereview.chromium.org/2449163004 Cr-Commit-Position: refs/heads/master@{#40702}
This commit is contained in:
parent
5ce9760672
commit
baf0ec31ec
@ -437,9 +437,7 @@ MaybeHandle<JSFunction> InstantiateFunction(Isolate* isolate,
|
||||
JSObject::GetProperty(parent_instance,
|
||||
isolate->factory()->prototype_string()),
|
||||
JSFunction);
|
||||
MAYBE_RETURN(JSObject::SetPrototype(prototype, parent_prototype, false,
|
||||
Object::THROW_ON_ERROR),
|
||||
MaybeHandle<JSFunction>());
|
||||
JSObject::ForceSetPrototype(prototype, parent_prototype);
|
||||
}
|
||||
}
|
||||
Handle<JSFunction> function = ApiNatives::CreateApiFunction(
|
||||
|
@ -25939,3 +25939,41 @@ TEST(EvalInAccessCheckedContext) {
|
||||
CHECK_EQ(42, x_value->Int32Value(context1).FromJust());
|
||||
context1->Exit();
|
||||
}
|
||||
|
||||
THREADED_TEST(ImmutableProtoWithParent) {
|
||||
LocalContext context;
|
||||
v8::Isolate* isolate = context->GetIsolate();
|
||||
v8::HandleScope handle_scope(isolate);
|
||||
|
||||
Local<v8::FunctionTemplate> parent = v8::FunctionTemplate::New(isolate);
|
||||
|
||||
Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
|
||||
templ->Inherit(parent);
|
||||
templ->PrototypeTemplate()->SetImmutableProto();
|
||||
|
||||
Local<v8::Function> function =
|
||||
templ->GetFunction(context.local()).ToLocalChecked();
|
||||
Local<v8::Object> instance =
|
||||
function->NewInstance(context.local()).ToLocalChecked();
|
||||
Local<v8::Object> prototype =
|
||||
instance->Get(context.local(), v8_str("__proto__"))
|
||||
.ToLocalChecked()
|
||||
->ToObject(context.local())
|
||||
.ToLocalChecked();
|
||||
|
||||
// Look up the prototype
|
||||
Local<v8::Value> original_proto =
|
||||
prototype->Get(context.local(), v8_str("__proto__")).ToLocalChecked();
|
||||
|
||||
// Setting the prototype (e.g., to null) throws
|
||||
CHECK(
|
||||
prototype->SetPrototype(context.local(), v8::Null(isolate)).IsNothing());
|
||||
|
||||
// The original prototype is still there
|
||||
Local<Value> new_proto =
|
||||
prototype->Get(context.local(), v8_str("__proto__")).ToLocalChecked();
|
||||
CHECK(new_proto->IsObject());
|
||||
CHECK(new_proto.As<v8::Object>()
|
||||
->Equals(context.local(), original_proto)
|
||||
.FromJust());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user