| Index: test/cctest/test-api.cc
|
| ===================================================================
|
| --- test/cctest/test-api.cc (revision 1004)
|
| +++ test/cctest/test-api.cc (working copy)
|
| @@ -1810,6 +1810,21 @@
|
| }
|
|
|
|
|
| +THREADED_TEST(EvalInTryFinally) {
|
| + v8::HandleScope scope;
|
| + LocalContext context;
|
| + v8::TryCatch try_catch;
|
| + CompileRun("(function() {"
|
| + " try {"
|
| + " eval('asldkf (*&^&*^');"
|
| + " } finally {"
|
| + " return;"
|
| + " }"
|
| + "})()");
|
| + CHECK(!try_catch.HasCaught());
|
| +}
|
| +
|
| +
|
| // This test works by making a stack of alternating JavaScript and C
|
| // activations. These activations set up exception handlers with regular
|
| // intervals, one interval for C activations and another for JavaScript
|
| @@ -3666,30 +3681,82 @@
|
| v8::Handle<Value> value;
|
|
|
| // Check that the named access-control function is called every time.
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj.prop = 1;")->Run();
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj.prop;"
|
| - "obj.prop")->Run();
|
| + CompileRun("function testProp(obj) {"
|
| + " for (var i = 0; i < 10; i++) obj.prop = 1;"
|
| + " for (var j = 0; j < 10; j++) obj.prop;"
|
| + " return obj.prop"
|
| + "}");
|
| + value = CompileRun("testProp(obj)");
|
| CHECK(value->IsNumber());
|
| CHECK_EQ(1, value->Int32Value());
|
| CHECK_EQ(21, named_access_count);
|
|
|
| // Check that the named access-control function is called every time.
|
| - value = v8_compile("var p = 'prop';")->Run();
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj[p] = 1;")->Run();
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj[p];"
|
| - "obj[p]")->Run();
|
| + CompileRun("var p = 'prop';"
|
| + "function testKeyed(obj) {"
|
| + " for (var i = 0; i < 10; i++) obj[p] = 1;"
|
| + " for (var j = 0; j < 10; j++) obj[p];"
|
| + " return obj[p];"
|
| + "}");
|
| + // Use obj which requires access checks. No inline caching is used
|
| + // in that case.
|
| + value = CompileRun("testKeyed(obj)");
|
| CHECK(value->IsNumber());
|
| CHECK_EQ(1, value->Int32Value());
|
| CHECK_EQ(42, named_access_count);
|
| + // Force the inline caches into generic state and try again.
|
| + CompileRun("testKeyed({ a: 0 })");
|
| + CompileRun("testKeyed({ b: 0 })");
|
| + value = CompileRun("testKeyed(obj)");
|
| + CHECK(value->IsNumber());
|
| + CHECK_EQ(1, value->Int32Value());
|
| + CHECK_EQ(63, named_access_count);
|
|
|
| // Check that the indexed access-control function is called every time.
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj[0] = 1;")->Run();
|
| - value = v8_compile("for (var i = 0; i < 10; i++) obj[0];"
|
| - "obj[0]")->Run();
|
| + CompileRun("function testIndexed(obj) {"
|
| + " for (var i = 0; i < 10; i++) obj[0] = 1;"
|
| + " for (var j = 0; j < 10; j++) obj[0];"
|
| + " return obj[0]"
|
| + "}");
|
| + value = CompileRun("testIndexed(obj)");
|
| CHECK(value->IsNumber());
|
| CHECK_EQ(1, value->Int32Value());
|
| CHECK_EQ(21, indexed_access_count);
|
| + // Force the inline caches into generic state.
|
| + CompileRun("testIndexed(new Array(1))");
|
| + // Test that the indexed access check is called.
|
| + value = CompileRun("testIndexed(obj)");
|
| + CHECK(value->IsNumber());
|
| + CHECK_EQ(1, value->Int32Value());
|
| + CHECK_EQ(42, indexed_access_count);
|
|
|
| + // Check that the named access check is called when invoking
|
| + // functions on an object that requires access checks.
|
| + CompileRun("obj.f = function() {}");
|
| + CompileRun("function testCallNormal(obj) {"
|
| + " for (var i = 0; i < 10; i++) obj.f();"
|
| + "}");
|
| + CompileRun("testCallNormal(obj)");
|
| + CHECK_EQ(74, named_access_count);
|
| +
|
| + // Force obj into slow case.
|
| + value = CompileRun("delete obj.prop");
|
| + CHECK(value->BooleanValue());
|
| + // Force inline caches into dictionary probing mode.
|
| + CompileRun("var o = { x: 0 }; delete o.x; testProp(o);");
|
| + // Test that the named access check is called.
|
| + value = CompileRun("testProp(obj);");
|
| + CHECK(value->IsNumber());
|
| + CHECK_EQ(1, value->Int32Value());
|
| + CHECK_EQ(96, named_access_count);
|
| +
|
| + // Force the call inline cache into dictionary probing mode.
|
| + CompileRun("o.f = function() {}; testCallNormal(o)");
|
| + // Test that the named access check is still called for each
|
| + // invocation of the function.
|
| + value = CompileRun("testCallNormal(obj)");
|
| + CHECK_EQ(106, named_access_count);
|
| +
|
| context1->Exit();
|
| context0->Exit();
|
| context1.Dispose();
|
| @@ -5380,6 +5447,24 @@
|
| }
|
|
|
|
|
| +// This tests that access check information remains on the global
|
| +// object template when creating contexts.
|
| +THREADED_TEST(AccessControlRepeatedContextCreation) {
|
| + v8::HandleScope handle_scope;
|
| + v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
|
| + global_template->SetAccessCheckCallbacks(NamedSetAccessBlocker,
|
| + IndexedSetAccessBlocker);
|
| + i::Handle<i::ObjectTemplateInfo> internal_template =
|
| + v8::Utils::OpenHandle(*global_template);
|
| + CHECK(!internal_template->constructor()->IsUndefined());
|
| + i::Handle<i::FunctionTemplateInfo> constructor(
|
| + i::FunctionTemplateInfo::cast(internal_template->constructor()));
|
| + CHECK(!constructor->access_check_info()->IsUndefined());
|
| + v8::Persistent<Context> context0 = Context::New(NULL, global_template);
|
| + CHECK(!constructor->access_check_info()->IsUndefined());
|
| +}
|
| +
|
| +
|
| static String::ExternalStringResource* SymbolCallback(const char* chars,
|
| size_t length) {
|
| uint16_t* buffer = i::NewArray<uint16_t>(length + 1);
|
|
|