Commit baf0ec31 authored by littledan's avatar littledan Committed by Commit bot

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}
parent 5ce97606
......@@ -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());
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment