Commit 3a5c6933 authored by littledan's avatar littledan Committed by Commit bot

Allow the global object to be frozen through the global template

This patch fixes two bugs in V8 to allow the global object to have a frozen proto:
- The immutable prototype map check is done on the map of the "real receiver",
  the one that's found after the hidden prototype traversal, rather than
  the object that SetPrototype is called on.
- The immutable prototype bit from the ObjectTemplate used to instantiate
  the global object, as passed to Context::New, is respected when instantiating
  the global object.

R=adamk
BUG=v8:5149

Review-Url: https://codereview.chromium.org/2474843003
Cr-Commit-Position: refs/heads/master@{#40778}
parent 75f14738
...@@ -613,10 +613,12 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( ...@@ -613,10 +613,12 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
} }
int internal_field_count = 0; int internal_field_count = 0;
bool immutable_proto = false;
if (!obj->instance_template()->IsUndefined(isolate)) { if (!obj->instance_template()->IsUndefined(isolate)) {
Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>( Handle<ObjectTemplateInfo> instance_template = Handle<ObjectTemplateInfo>(
ObjectTemplateInfo::cast(obj->instance_template())); ObjectTemplateInfo::cast(obj->instance_template()));
internal_field_count = instance_template->internal_field_count(); internal_field_count = instance_template->internal_field_count();
immutable_proto = instance_template->immutable_proto();
} }
// TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing // TODO(svenpanne) Kill ApiInstanceType and refactor things by generalizing
...@@ -676,6 +678,8 @@ Handle<JSFunction> ApiNatives::CreateApiFunction( ...@@ -676,6 +678,8 @@ Handle<JSFunction> ApiNatives::CreateApiFunction(
map->set_is_constructor(true); map->set_is_constructor(true);
} }
if (immutable_proto) map->set_immutable_proto(true);
return result; return result;
} }
......
...@@ -15553,7 +15553,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object, ...@@ -15553,7 +15553,7 @@ Maybe<bool> JSObject::SetPrototype(Handle<JSObject> object,
// Nothing to do if prototype is already set. // Nothing to do if prototype is already set.
if (map->prototype() == *value) return Just(true); if (map->prototype() == *value) return Just(true);
bool immutable_proto = object->map()->is_immutable_proto(); bool immutable_proto = map->is_immutable_proto();
if (immutable_proto) { if (immutable_proto) {
RETURN_FAILURE( RETURN_FAILURE(
isolate, should_throw, isolate, should_throw,
......
...@@ -25978,3 +25978,44 @@ TEST(InternalFieldsOnGlobalProxy) { ...@@ -25978,3 +25978,44 @@ TEST(InternalFieldsOnGlobalProxy) {
v8::Local<v8::Object> global = context->Global(); v8::Local<v8::Object> global = context->Global();
CHECK_EQ(1, global->InternalFieldCount()); CHECK_EQ(1, global->InternalFieldCount());
} }
THREADED_TEST(ImmutableProtoGlobal) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
global_template->SetImmutableProto();
v8::Local<Context> context = Context::New(isolate, 0, global_template);
Context::Scope context_scope(context);
v8::Local<Value> result = CompileRun(
"global = this;"
"(function() {"
" try {"
" global.__proto__ = {};"
" return 0;"
" } catch (e) {"
" return 1;"
" }"
"})()");
CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 1))
.FromJust());
}
THREADED_TEST(MutableProtoGlobal) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope handle_scope(isolate);
Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate);
v8::Local<Context> context = Context::New(isolate, 0, global_template);
Context::Scope context_scope(context);
v8::Local<Value> result = CompileRun(
"global = this;"
"(function() {"
" try {"
" global.__proto__ = {};"
" return 0;"
" } catch (e) {"
" return 1;"
" }"
"})()");
CHECK(result->Equals(context, v8::Integer::New(CcTest::isolate(), 0))
.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