| Index: test/cctest/test-api.cc
|
| ===================================================================
|
| --- test/cctest/test-api.cc (revision 796)
|
| +++ test/cctest/test-api.cc (working copy)
|
| @@ -4018,6 +4018,30 @@
|
| }
|
|
|
|
|
| +THREADED_TEST(Eval) {
|
| + v8::HandleScope scope;
|
| + LocalContext current;
|
| +
|
| + // Test that un-aliased eval uses local context.
|
| + Local<Script> script =
|
| + Script::Compile(v8_str("foo = 0;"
|
| + "(function() {"
|
| + " var foo = 2;"
|
| + " return eval('foo');"
|
| + "})();"));
|
| + Local<Value> result = script->Run();
|
| + CHECK_EQ(2, result->Int32Value());
|
| +
|
| + // Test that un-aliased eval has right this.
|
| + script =
|
| + Script::Compile(v8_str("function MyObject() { this.self = eval('this'); }"
|
| + "var o = new MyObject();"
|
| + "o === o.self"));
|
| + result = script->Run();
|
| + CHECK(result->IsTrue());
|
| +}
|
| +
|
| +
|
| THREADED_TEST(CrossEval) {
|
| v8::HandleScope scope;
|
| LocalContext other;
|
| @@ -4039,45 +4063,62 @@
|
| CHECK(!current->Global()->Has(v8_str("foo")));
|
|
|
| // Check that writing to non-existing properties introduces them in
|
| - // the current context.
|
| + // the other context.
|
| script =
|
| Script::Compile(v8_str("other.eval('na = 1234')"));
|
| script->Run();
|
| - CHECK_EQ(1234, current->Global()->Get(v8_str("na"))->Int32Value());
|
| - CHECK(!other->Global()->Has(v8_str("na")));
|
| + CHECK_EQ(1234, other->Global()->Get(v8_str("na"))->Int32Value());
|
| + CHECK(!current->Global()->Has(v8_str("na")));
|
|
|
| - // Check that variables in current context are visible in other
|
| - // context. This must include local variables.
|
| + // Check that global variables in current context are not visible in other
|
| + // context.
|
| + v8::TryCatch try_catch;
|
| script =
|
| - Script::Compile(v8_str("var bar = 42;"
|
| - "(function() { "
|
| - " var baz = 87;"
|
| - " return other.eval('bar + baz');"
|
| - "})();"));
|
| + Script::Compile(v8_str("var bar = 42; other.eval('bar');"));
|
| Local<Value> result = script->Run();
|
| - CHECK_EQ(42 + 87, result->Int32Value());
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
|
|
| + // Check that local variables in current context are not visible in other
|
| + // context.
|
| + script =
|
| + Script::Compile(v8_str("(function() { "
|
| + " var baz = 87;"
|
| + " return other.eval('baz');"
|
| + "})();"));
|
| + result = script->Run();
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
| +
|
| // Check that global variables in the other environment are visible
|
| // when evaluting code.
|
| other->Global()->Set(v8_str("bis"), v8_num(1234));
|
| script = Script::Compile(v8_str("other.eval('bis')"));
|
| CHECK_EQ(1234, script->Run()->Int32Value());
|
| + CHECK(!try_catch.HasCaught());
|
|
|
| - // Check that the 'this' pointer isn't touched as a result of
|
| - // calling eval across environments.
|
| + // Check that the 'this' pointer points to the global object evaluating
|
| + // code.
|
| + other->Global()->Set(v8_str("t"), other->Global());
|
| + script = Script::Compile(v8_str("other.eval('this == t')"));
|
| + result = script->Run();
|
| + CHECK(result->IsTrue());
|
| + CHECK(!try_catch.HasCaught());
|
| +
|
| + // Check that variables introduced in with-statement are not visible in
|
| + // other context.
|
| script =
|
| - Script::Compile(v8_str("var t = this; other.eval('this == t')"));
|
| + Script::Compile(v8_str("with({x:2}){other.eval('x')}"));
|
| result = script->Run();
|
| - CHECK(result->IsBoolean());
|
| - CHECK(result->BooleanValue());
|
| + CHECK(try_catch.HasCaught());
|
| + try_catch.Reset();
|
|
|
| - // Check that doing a cross eval works from within a global
|
| - // with-statement.
|
| + // Check that you cannot use 'eval.call' with another object than the
|
| + // current global object.
|
| script =
|
| - Script::Compile(v8_str("other.y = 1;"
|
| - "with({x:2}){other.eval('x+y')}"));
|
| + Script::Compile(v8_str("other.y = 1; eval.call(other, 'y')"));
|
| result = script->Run();
|
| - CHECK_EQ(3, result->Int32Value());
|
| + CHECK(try_catch.HasCaught());
|
| }
|
|
|
|
|
| @@ -5214,3 +5255,69 @@
|
| Local<Value> value = CompileRun("obj.x");
|
| CHECK(value->BooleanValue());
|
| }
|
| +
|
| +
|
| +static String::ExternalStringResource* SymbolCallback(const char* chars,
|
| + size_t length) {
|
| + uint16_t* buffer = i::NewArray<uint16_t>(length + 1);
|
| + for (size_t i = 0; i < length; i++) {
|
| + buffer[i] = chars[i];
|
| + }
|
| + buffer[length] = '\0';
|
| + return new TestResource(buffer);
|
| +}
|
| +
|
| +
|
| +static v8::Handle<Value> ExternalSymbolGetter(Local<String> name,
|
| + const AccessorInfo& info) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CHECK(!name->Equals(v8_str("externalSymbol722")) || name->IsExternal());
|
| + return v8::True();
|
| +}
|
| +
|
| +
|
| +static void ExternalSymbolSetter(Local<String> name,
|
| + Local<Value> value,
|
| + const AccessorInfo&) {
|
| + ApiTestFuzzer::Fuzz();
|
| + CHECK(!name->Equals(v8_str("externalSymbol722")) || name->IsExternal());
|
| +}
|
| +
|
| +
|
| +THREADED_TEST(ExternalSymbols) {
|
| + TestResource::dispose_count = 0;
|
| + v8::V8::SetExternalSymbolCallback(SymbolCallback);
|
| + v8::HandleScope scope;
|
| + LocalContext context;
|
| + Local<ObjectTemplate> templ = ObjectTemplate::New();
|
| + // Use a bizare name so that the name does not clash with names used
|
| + // in natives files. If running with snapshots enabled, variable
|
| + // names used in the native files will be normal symbols instead of
|
| + // external ones. Also, make sure that the bizare name is used from
|
| + // JavaScript code before using it from C++ code.
|
| + Local<Value> value =
|
| + CompileRun("var o = { externalSymbol722: 42 }; o.externalSymbol722");
|
| + CHECK_EQ(42, value->Int32Value());
|
| + templ->SetAccessor(v8_str("externalSymbol722"),
|
| + ExternalSymbolGetter,
|
| + ExternalSymbolSetter);
|
| + context->Global()->Set(v8_str("obj"), templ->NewInstance());
|
| + value = CompileRun("obj.externalSymbol722");
|
| + CHECK_EQ(true, value->BooleanValue());
|
| + value = CompileRun("obj.externalSymbol722 = 42");
|
| + v8::V8::SetExternalSymbolCallback(NULL);
|
| +}
|
| +
|
| +
|
| +// This test verifies that pre-compilation (aka preparsing) can be called
|
| +// without initializing the whole VM. Thus we cannot run this test in a
|
| +// multi-threaded setup.
|
| +TEST(PreCompile) {
|
| + // TODO(155): This test would break without the initialization of V8. This is
|
| + // a workaround for now to make this test not fail.
|
| + v8::V8::Initialize();
|
| + const char *script = "function foo(a) { return a+1; }";
|
| + v8::ScriptData *sd = v8::ScriptData::PreCompile(script, strlen(script));
|
| + CHECK_NE(sd->Length(), 0);
|
| + CHECK_NE(sd->Data(), NULL);
|
| +}
|
|
|