Add unit test for r11818.

R=rossberg@chromium.org
TEST=cctest/test-decls/ExistsInHiddenPrototype

Review URL: https://chromiumcodereview.appspot.com/10628002

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@11896 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 030ac76b
...@@ -1318,8 +1318,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) { ...@@ -1318,8 +1318,9 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DeclareGlobals) {
Object* obj = *global; Object* obj = *global;
do { do {
JSObject::cast(obj)->LocalLookup(*name, &lookup); JSObject::cast(obj)->LocalLookup(*name, &lookup);
if (lookup.IsProperty()) break;
obj = obj->GetPrototype(); obj = obj->GetPrototype();
} while (!lookup.IsFound() && obj->IsJSObject() && } while (obj->IsJSObject() &&
JSObject::cast(obj)->map()->is_hidden_prototype()); JSObject::cast(obj)->map()->is_hidden_prototype());
} else { } else {
global->Lookup(*name, &lookup); global->Lookup(*name, &lookup);
......
...@@ -72,6 +72,10 @@ class DeclarationContext { ...@@ -72,6 +72,10 @@ class DeclarationContext {
void InitializeIfNeeded(); void InitializeIfNeeded();
// Perform optional initialization steps on the context after it has
// been created. Defaults to none but may be overwritten.
virtual void PostInitializeContext(Handle<Context> context) {}
// Get the holder for the interceptor. Default to the instance template // Get the holder for the interceptor. Default to the instance template
// but may be overwritten. // but may be overwritten.
virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) { virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
...@@ -120,6 +124,7 @@ void DeclarationContext::InitializeIfNeeded() { ...@@ -120,6 +124,7 @@ void DeclarationContext::InitializeIfNeeded() {
context_ = Context::New(0, function->InstanceTemplate(), Local<Value>()); context_ = Context::New(0, function->InstanceTemplate(), Local<Value>());
context_->Enter(); context_->Enter();
is_initialized_ = true; is_initialized_ = true;
PostInitializeContext(context_);
} }
...@@ -536,9 +541,9 @@ TEST(ExistsInPrototype) { ...@@ -536,9 +541,9 @@ TEST(ExistsInPrototype) {
{ ExistsInPrototypeContext context; { ExistsInPrototypeContext context;
context.Check("var x; x", context.Check("var x; x",
0, // get
0, 0,
0, // declaration 0,
0,
EXPECT_RESULT, Undefined()); EXPECT_RESULT, Undefined());
} }
...@@ -546,7 +551,7 @@ TEST(ExistsInPrototype) { ...@@ -546,7 +551,7 @@ TEST(ExistsInPrototype) {
context.Check("var x = 0; x", context.Check("var x = 0; x",
0, 0,
0, 0,
0, // declaration 0,
EXPECT_RESULT, Number::New(0)); EXPECT_RESULT, Number::New(0));
} }
...@@ -554,7 +559,7 @@ TEST(ExistsInPrototype) { ...@@ -554,7 +559,7 @@ TEST(ExistsInPrototype) {
context.Check("const x; x", context.Check("const x; x",
0, 0,
0, 0,
0, // declaration 0,
EXPECT_RESULT, Undefined()); EXPECT_RESULT, Undefined());
} }
...@@ -562,7 +567,7 @@ TEST(ExistsInPrototype) { ...@@ -562,7 +567,7 @@ TEST(ExistsInPrototype) {
context.Check("const x = 0; x", context.Check("const x = 0; x",
0, 0,
0, 0,
0, // declaration 0,
EXPECT_RESULT, Number::New(0)); EXPECT_RESULT, Number::New(0));
} }
} }
...@@ -591,7 +596,88 @@ TEST(AbsentInPrototype) { ...@@ -591,7 +596,88 @@ TEST(AbsentInPrototype) {
context.Check("if (false) { var x = 0; }; x", context.Check("if (false) { var x = 0; }; x",
0, 0,
0, 0,
0, // declaration 0,
EXPECT_RESULT, Undefined()); EXPECT_RESULT, Undefined());
} }
} }
class ExistsInHiddenPrototypeContext: public DeclarationContext {
public:
ExistsInHiddenPrototypeContext() {
hidden_proto_ = FunctionTemplate::New();
hidden_proto_->SetHiddenPrototype(true);
}
protected:
virtual v8::Handle<Integer> Query(Local<String> key) {
// Let it seem that the property exists in the hidden prototype object.
return Integer::New(v8::None);
}
// Install the hidden prototype after the global object has been created.
virtual void PostInitializeContext(Handle<Context> context) {
Local<Object> global_object = context->Global();
Local<Object> hidden_proto = hidden_proto_->GetFunction()->NewInstance();
context->DetachGlobal();
context->Global()->SetPrototype(hidden_proto);
context->ReattachGlobal(global_object);
}
// Use the hidden prototype as the holder for the interceptors.
virtual Local<ObjectTemplate> GetHolder(Local<FunctionTemplate> function) {
return hidden_proto_->InstanceTemplate();
}
private:
Local<FunctionTemplate> hidden_proto_;
};
TEST(ExistsInHiddenPrototype) {
i::FLAG_es52_globals = true;
HandleScope scope;
{ ExistsInHiddenPrototypeContext context;
context.Check("var x; x",
1, // access
0,
2, // declaration + initialization
EXPECT_EXCEPTION); // x is not defined!
}
{ ExistsInHiddenPrototypeContext context;
context.Check("var x = 0; x",
1, // access
1, // initialization
2, // declaration + initialization
EXPECT_RESULT, Number::New(0));
}
{ ExistsInHiddenPrototypeContext context;
context.Check("function x() { }; x",
0,
0,
0,
EXPECT_RESULT);
}
// TODO(mstarzinger): The semantics of global const is vague.
{ ExistsInHiddenPrototypeContext context;
context.Check("const x; x",
0,
0,
1, // (re-)declaration
EXPECT_RESULT, Undefined());
}
// TODO(mstarzinger): The semantics of global const is vague.
{ ExistsInHiddenPrototypeContext context;
context.Check("const x = 0; x",
0,
0,
1, // (re-)declaration
EXPECT_RESULT, Number::New(0));
}
}
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