Fix bug in forced-deletion of globals.

When inling functions across contexts in optimized code and using
ForceDelete from the API to delete a DontDelete global property we
can end up returning the hole value instead of throwing a ReferenceError
as expected after accessing a deleted global variable.

BUG=v8:2092
TEST=test/cctest/test-api/InlinedFunctionAcrossContexts
Review URL: https://chromiumcodereview.appspot.com/10035060

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11396 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent a0d67fd9
......@@ -2813,9 +2813,13 @@ bool v8::Object::ForceDelete(v8::Handle<Value> key) {
i::Handle<i::JSObject> self = Utils::OpenHandle(this);
i::Handle<i::Object> key_obj = Utils::OpenHandle(*key);
// When turning on access checks for a global object deoptimize all functions
// as optimized code does not always handle access checks.
i::Deoptimizer::DeoptimizeGlobalObject(*self);
// When deleting a property on the global object using ForceDelete
// deoptimize all functions as optimized code does not check for the hole
// value with DontDelete properties. We have to deoptimize all contexts
// because of possible cross-context inlined functions.
if (self->IsJSGlobalProxy() || self->IsGlobalObject()) {
i::Deoptimizer::DeoptimizeAll();
}
EXCEPTION_PREAMBLE(isolate);
i::Handle<i::Object> obj = i::ForceDeleteProperty(self, key_obj);
......
......@@ -12376,6 +12376,46 @@ THREADED_TEST(ForceDeleteIC) {
}
TEST(InlinedFunctionAcrossContexts) {
i::FLAG_allow_natives_syntax = true;
v8::HandleScope outer_scope;
v8::Persistent<v8::Context> ctx1 = v8::Context::New();
v8::Persistent<v8::Context> ctx2 = v8::Context::New();
ctx1->Enter();
{
v8::HandleScope inner_scope;
CompileRun("var G = 42; function foo() { return G; }");
v8::Local<v8::Value> foo = ctx1->Global()->Get(v8_str("foo"));
ctx2->Enter();
ctx2->Global()->Set(v8_str("o"), foo);
v8::Local<v8::Value> res = CompileRun(
"function f() { return o(); }"
"for (var i = 0; i < 10; ++i) f();"
"%OptimizeFunctionOnNextCall(f);"
"f();");
CHECK_EQ(42, res->Int32Value());
ctx2->Exit();
v8::Handle<v8::String> G_property = v8::String::New("G");
CHECK(ctx1->Global()->ForceDelete(G_property));
ctx2->Enter();
ExpectString(
"(function() {"
" try {"
" return f();"
" } catch(e) {"
" return e.toString();"
" }"
" })()",
"ReferenceError: G is not defined");
ctx2->Exit();
ctx1->Exit();
ctx1.Dispose();
}
ctx2.Dispose();
}
v8::Persistent<Context> calling_context0;
v8::Persistent<Context> calling_context1;
v8::Persistent<Context> calling_context2;
......@@ -16407,4 +16447,3 @@ TEST(SecondaryStubCache) {
TEST(PrimaryStubCache) {
StubCacheHelper(false);
}
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