Update V8 to r6101 as required by WebKit r74534
Change-Id: I7f84af8dd732f11898fd644b2c2b1538914cb78d
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 4af0c52..9539973 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -814,79 +814,6 @@
}
-static void* expected_ptr;
-static v8::Handle<v8::Value> callback(const v8::Arguments& args) {
- void* ptr = v8::External::Unwrap(args.Data());
- CHECK_EQ(expected_ptr, ptr);
- return v8::Boolean::New(true);
-}
-
-
-static void TestExternalPointerWrapping() {
- v8::HandleScope scope;
- LocalContext env;
-
- v8::Handle<v8::Value> data = v8::External::Wrap(expected_ptr);
-
- v8::Handle<v8::Object> obj = v8::Object::New();
- obj->Set(v8_str("func"),
- v8::FunctionTemplate::New(callback, data)->GetFunction());
- env->Global()->Set(v8_str("obj"), obj);
-
- CHECK(CompileRun(
- "function foo() {\n"
- " for (var i = 0; i < 13; i++) obj.func();\n"
- "}\n"
- "foo(), true")->BooleanValue());
-}
-
-
-THREADED_TEST(ExternalWrap) {
- // Check heap allocated object.
- int* ptr = new int;
- expected_ptr = ptr;
- TestExternalPointerWrapping();
- delete ptr;
-
- // Check stack allocated object.
- int foo;
- expected_ptr = &foo;
- TestExternalPointerWrapping();
-
- // Check not aligned addresses.
- const int n = 100;
- char* s = new char[n];
- for (int i = 0; i < n; i++) {
- expected_ptr = s + i;
- TestExternalPointerWrapping();
- }
-
- delete[] s;
-
- // Check several invalid addresses.
- expected_ptr = reinterpret_cast<void*>(1);
- TestExternalPointerWrapping();
-
- expected_ptr = reinterpret_cast<void*>(0xdeadbeef);
- TestExternalPointerWrapping();
-
- expected_ptr = reinterpret_cast<void*>(0xdeadbeef + 1);
- TestExternalPointerWrapping();
-
-#if defined(V8_HOST_ARCH_X64)
- // Check a value with a leading 1 bit in x64 Smi encoding.
- expected_ptr = reinterpret_cast<void*>(0x400000000);
- TestExternalPointerWrapping();
-
- expected_ptr = reinterpret_cast<void*>(0xdeadbeefdeadbeef);
- TestExternalPointerWrapping();
-
- expected_ptr = reinterpret_cast<void*>(0xdeadbeefdeadbeef + 1);
- TestExternalPointerWrapping();
-#endif
-}
-
-
THREADED_TEST(FindInstanceInPrototypeChain) {
v8::HandleScope scope;
LocalContext env;
@@ -4417,47 +4344,167 @@
}
+static int StrCmp16(uint16_t* a, uint16_t* b) {
+ while (true) {
+ if (*a == 0 && *b == 0) return 0;
+ if (*a != *b) return 0 + *a - *b;
+ a++;
+ b++;
+ }
+}
+
+
+static int StrNCmp16(uint16_t* a, uint16_t* b, int n) {
+ while (true) {
+ if (n-- == 0) return 0;
+ if (*a == 0 && *b == 0) return 0;
+ if (*a != *b) return 0 + *a - *b;
+ a++;
+ b++;
+ }
+}
+
+
THREADED_TEST(StringWrite) {
v8::HandleScope scope;
v8::Handle<String> str = v8_str("abcde");
+ // abc<Icelandic eth><Unicode snowman>.
+ v8::Handle<String> str2 = v8_str("abc\303\260\342\230\203");
+
+ CHECK_EQ(5, str2->Length());
char buf[100];
+ char utf8buf[100];
+ uint16_t wbuf[100];
int len;
+ int charlen;
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, sizeof(utf8buf), &charlen);
+ CHECK_EQ(len, 9);
+ CHECK_EQ(charlen, 5);
+ CHECK_EQ(strcmp(utf8buf, "abc\303\260\342\230\203"), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 8, &charlen);
+ CHECK_EQ(len, 8);
+ CHECK_EQ(charlen, 5);
+ CHECK_EQ(strncmp(utf8buf, "abc\303\260\342\230\203\1", 9), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 7, &charlen);
+ CHECK_EQ(len, 5);
+ CHECK_EQ(charlen, 4);
+ CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 6, &charlen);
+ CHECK_EQ(len, 5);
+ CHECK_EQ(charlen, 4);
+ CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 5, &charlen);
+ CHECK_EQ(len, 5);
+ CHECK_EQ(charlen, 4);
+ CHECK_EQ(strncmp(utf8buf, "abc\303\260\1", 5), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 4, &charlen);
+ CHECK_EQ(len, 3);
+ CHECK_EQ(charlen, 3);
+ CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 3, &charlen);
+ CHECK_EQ(len, 3);
+ CHECK_EQ(charlen, 3);
+ CHECK_EQ(strncmp(utf8buf, "abc\1", 4), 0);
+
+ memset(utf8buf, 0x1, sizeof(utf8buf));
+ len = str2->WriteUtf8(utf8buf, 2, &charlen);
+ CHECK_EQ(len, 2);
+ CHECK_EQ(charlen, 2);
+ CHECK_EQ(strncmp(utf8buf, "ab\1", 3), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf);
CHECK_EQ(len, 5);
- CHECK_EQ(strncmp("abcde\0", buf, 6), 0);
+ len = str->Write(wbuf);
+ CHECK_EQ(len, 5);
+ CHECK_EQ(strcmp("abcde", buf), 0);
+ uint16_t answer1[] = {'a', 'b', 'c', 'd', 'e', '\0'};
+ CHECK_EQ(StrCmp16(answer1, wbuf), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 4);
CHECK_EQ(len, 4);
+ len = str->Write(wbuf, 0, 4);
+ CHECK_EQ(len, 4);
CHECK_EQ(strncmp("abcd\1", buf, 5), 0);
+ uint16_t answer2[] = {'a', 'b', 'c', 'd', 0x101};
+ CHECK_EQ(StrNCmp16(answer2, wbuf, 5), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 5);
CHECK_EQ(len, 5);
+ len = str->Write(wbuf, 0, 5);
+ CHECK_EQ(len, 5);
CHECK_EQ(strncmp("abcde\1", buf, 6), 0);
+ uint16_t answer3[] = {'a', 'b', 'c', 'd', 'e', 0x101};
+ CHECK_EQ(StrNCmp16(answer3, wbuf, 6), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 0, 6);
CHECK_EQ(len, 5);
- CHECK_EQ(strncmp("abcde\0", buf, 6), 0);
+ len = str->Write(wbuf, 0, 6);
+ CHECK_EQ(len, 5);
+ CHECK_EQ(strcmp("abcde", buf), 0);
+ uint16_t answer4[] = {'a', 'b', 'c', 'd', 'e', '\0'};
+ CHECK_EQ(StrCmp16(answer4, wbuf), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, -1);
CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("e\0", buf, 2), 0);
+ len = str->Write(wbuf, 4, -1);
+ CHECK_EQ(len, 1);
+ CHECK_EQ(strcmp("e", buf), 0);
+ uint16_t answer5[] = {'e', '\0'};
+ CHECK_EQ(StrCmp16(answer5, wbuf), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 6);
CHECK_EQ(len, 1);
- CHECK_EQ(strncmp("e\0", buf, 2), 0);
+ len = str->Write(wbuf, 4, 6);
+ CHECK_EQ(len, 1);
+ CHECK_EQ(strcmp("e", buf), 0);
+ CHECK_EQ(StrCmp16(answer5, wbuf), 0);
memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
len = str->WriteAscii(buf, 4, 1);
CHECK_EQ(len, 1);
+ len = str->Write(wbuf, 4, 1);
+ CHECK_EQ(len, 1);
CHECK_EQ(strncmp("e\1", buf, 2), 0);
+ uint16_t answer6[] = {'e', 0x101};
+ CHECK_EQ(StrNCmp16(answer6, wbuf, 2), 0);
+
+ memset(buf, 0x1, sizeof(buf));
+ memset(wbuf, 0x1, sizeof(wbuf));
+ len = str->WriteAscii(buf, 3, 1);
+ CHECK_EQ(len, 1);
+ len = str->Write(wbuf, 3, 1);
+ CHECK_EQ(len, 1);
+ CHECK_EQ(strncmp("d\1", buf, 2), 0);
+ uint16_t answer7[] = {'d', 0x101};
+ CHECK_EQ(StrNCmp16(answer7, wbuf, 2), 0);
}
@@ -5133,13 +5180,11 @@
}
-static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false };
static bool NamedAccessBlocker(Local<v8::Object> global,
Local<Value> name,
v8::AccessType type,
Local<Value> data) {
- return Context::GetCurrent()->Global()->Equals(global) ||
- allowed_access_type[type];
+ return Context::GetCurrent()->Global()->Equals(global);
}
@@ -5147,8 +5192,7 @@
uint32_t key,
v8::AccessType type,
Local<Value> data) {
- return Context::GetCurrent()->Global()->Equals(global) ||
- allowed_access_type[type];
+ return Context::GetCurrent()->Global()->Equals(global);
}
@@ -5180,7 +5224,7 @@
}
-TEST(AccessControl) {
+THREADED_TEST(AccessControl) {
v8::HandleScope handle_scope;
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
@@ -5206,27 +5250,6 @@
v8::Handle<v8::Object> global0 = context0->Global();
- // Define a property with JS getter and setter.
- CompileRun(
- "function getter() { return 'getter'; };\n"
- "function setter() { return 'setter'; }\n"
- "Object.defineProperty(this, 'js_accessor_p', {get:getter, set:setter})");
-
- Local<Value> getter = global0->Get(v8_str("getter"));
- Local<Value> setter = global0->Get(v8_str("setter"));
-
- // And define normal element.
- global0->Set(239, v8_str("239"));
-
- // Define an element with JS getter and setter.
- CompileRun(
- "function el_getter() { return 'el_getter'; };\n"
- "function el_setter() { return 'el_setter'; };\n"
- "Object.defineProperty(this, '42', {get: el_getter, set: el_setter});");
-
- Local<Value> el_getter = global0->Get(v8_str("el_getter"));
- Local<Value> el_setter = global0->Get(v8_str("el_setter"));
-
v8::HandleScope scope1;
v8::Persistent<Context> context1 = Context::New();
@@ -5235,187 +5258,40 @@
v8::Handle<v8::Object> global1 = context1->Global();
global1->Set(v8_str("other"), global0);
- // Access blocked property.
- CompileRun("other.blocked_prop = 1");
-
- ExpectUndefined("other.blocked_prop");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
- ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')");
-
- // Enable ACCESS_HAS
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.blocked_prop");
- // ... and now we can get the descriptor...
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'blocked_prop').value");
- // ... and enumerate the property.
- ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')");
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Access blocked element.
- CompileRun("other[239] = 1");
-
- ExpectUndefined("other[239]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')");
- ExpectFalse("propertyIsEnumerable.call(other, '239')");
-
- // Enable ACCESS_HAS
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[239]");
- // ... and now we can get the descriptor...
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value");
- // ... and enumerate the property.
- ExpectTrue("propertyIsEnumerable.call(other, '239')");
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Access a property with JS accessor.
- CompileRun("other.js_accessor_p = 2");
-
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')");
-
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_GET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
-
- ExpectString("other.js_accessor_p", "getter");
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other.js_accessor_p");
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other.js_accessor_p", "getter");
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
- ExpectObject(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
- ExpectUndefined(
- "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Access an element with JS accessor.
- CompileRun("other[42] = 2");
-
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')");
-
- // Enable ACCESS_HAS.
- allowed_access_type[v8::ACCESS_HAS] = true;
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_GET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
-
- ExpectString("other[42]", "el_getter");
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectUndefined("other[42]");
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
- // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
- allowed_access_type[v8::ACCESS_HAS] = true;
- allowed_access_type[v8::ACCESS_GET] = true;
- allowed_access_type[v8::ACCESS_SET] = true;
-
- ExpectString("other[42]", "el_getter");
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
- ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
- ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
-
- allowed_access_type[v8::ACCESS_SET] = false;
- allowed_access_type[v8::ACCESS_GET] = false;
- allowed_access_type[v8::ACCESS_HAS] = false;
-
v8::Handle<Value> value;
+ // Access blocked property
+ value = v8_compile("other.blocked_prop = 1")->Run();
+ value = v8_compile("other.blocked_prop")->Run();
+ CHECK(value->IsUndefined());
+
+ value = v8_compile("propertyIsEnumerable.call(other, 'blocked_prop')")->Run();
+ CHECK(value->IsFalse());
+
// Access accessible property
- value = CompileRun("other.accessible_prop = 3");
+ value = v8_compile("other.accessible_prop = 3")->Run();
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
CHECK_EQ(3, g_echo_value);
- value = CompileRun("other.accessible_prop");
+ value = v8_compile("other.accessible_prop")->Run();
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value = CompileRun(
- "Object.getOwnPropertyDescriptor(other, 'accessible_prop').value");
- CHECK(value->IsNumber());
- CHECK_EQ(3, value->Int32Value());
-
- value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')");
+ value =
+ v8_compile("propertyIsEnumerable.call(other, 'accessible_prop')")->Run();
CHECK(value->IsTrue());
// Enumeration doesn't enumerate accessors from inaccessible objects in
// the prototype chain even if the accessors are in themselves accessible.
- value =
+ Local<Value> result =
CompileRun("(function(){var obj = {'__proto__':other};"
"for (var p in obj)"
" if (p == 'accessible_prop' || p == 'blocked_prop') {"
" return false;"
" }"
"return true;})()");
- CHECK(value->IsTrue());
+ CHECK(result->IsTrue());
context1->Exit();
context0->Exit();
@@ -5922,6 +5798,22 @@
instance_template->Set(v8_str("f"),
v8::FunctionTemplate::New(InstanceFunctionCallback));
+ // The script to check how Crankshaft compiles missing global function
+ // invocations. function g is not defined and should throw on call.
+ const char* script =
+ "function wrapper(call) {"
+ " var x = 0, y = 1;"
+ " for (var i = 0; i < 1000; i++) {"
+ " x += i * 100;"
+ " y += i * 100;"
+ " }"
+ " if (call) g();"
+ "}"
+ "for (var i = 0; i < 17; i++) wrapper(false);"
+ "var thrown = 0;"
+ "try { wrapper(true); } catch (e) { thrown = 1; };"
+ "thrown";
+
{
LocalContext env(NULL, instance_template);
// Hold on to the global object so it can be used again in another
@@ -5932,6 +5824,8 @@
CHECK_EQ(42, value->Int32Value());
value = Script::Compile(v8_str("f()"))->Run();
CHECK_EQ(12, value->Int32Value());
+ value = Script::Compile(v8_str(script))->Run();
+ CHECK_EQ(1, value->Int32Value());
}
{
@@ -5941,6 +5835,48 @@
CHECK_EQ(42, value->Int32Value());
value = Script::Compile(v8_str("f()"))->Run();
CHECK_EQ(12, value->Int32Value());
+ value = Script::Compile(v8_str(script))->Run();
+ CHECK_EQ(1, value->Int32Value());
+ }
+}
+
+
+THREADED_TEST(CallKnownGlobalReceiver) {
+ v8::HandleScope handle_scope;
+
+ Local<Value> global_object;
+
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New();
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+
+ // The script to check that we leave global object not
+ // global object proxy on stack when we deoptimize from inside
+ // arguments evaluation.
+ // To provoke error we need to both force deoptimization
+ // from arguments evaluation and to force CallIC to take
+ // CallIC_Miss code path that can't cope with global proxy.
+ const char* script =
+ "function bar(x, y) { try { } finally { } }"
+ "function baz(x) { try { } finally { } }"
+ "function bom(x) { try { } finally { } }"
+ "function foo(x) { bar([x], bom(2)); }"
+ "for (var i = 0; i < 10000; i++) foo(1);"
+ "foo";
+
+ Local<Value> foo;
+ {
+ LocalContext env(NULL, instance_template);
+ // Hold on to the global object so it can be used again in another
+ // environment initialization.
+ global_object = env->Global();
+ foo = Script::Compile(v8_str(script))->Run();
+ }
+
+ {
+ // Create new environment reusing the global object.
+ LocalContext env(NULL, instance_template, global_object);
+ env->Global()->Set(v8_str("foo"), foo);
+ Local<Value> value = Script::Compile(v8_str("foo()"))->Run();
}
}
@@ -8915,6 +8851,105 @@
}
+v8::Handle<v8::String> a;
+v8::Handle<v8::String> h;
+
+static bool NamedGetAccessBlockAandH(Local<v8::Object> obj,
+ Local<Value> name,
+ v8::AccessType type,
+ Local<Value> data) {
+ return !(name->Equals(a) || name->Equals(h));
+}
+
+
+THREADED_TEST(TurnOnAccessCheckAndRecompile) {
+ v8::HandleScope handle_scope;
+
+ // Create an environment with access check to the global object disabled by
+ // default. When the registered access checker will block access to properties
+ // a and h
+ a = v8_str("a");
+ h = v8_str("h");
+ v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
+ global_template->SetAccessCheckCallbacks(NamedGetAccessBlockAandH,
+ IndexedGetAccessBlocker,
+ v8::Handle<v8::Value>(),
+ false);
+ v8::Persistent<Context> context = Context::New(NULL, global_template);
+ Context::Scope context_scope(context);
+
+ // Set up a property and a number of functions.
+ context->Global()->Set(v8_str("a"), v8_num(1));
+ static const char* source = "function f1() {return a;}"
+ "function f2() {return a;}"
+ "function g1() {return h();}"
+ "function g2() {return h();}"
+ "function h() {return 1;}";
+
+ CompileRun(source);
+ Local<Function> f1;
+ Local<Function> f2;
+ Local<Function> g1;
+ Local<Function> g2;
+ Local<Function> h;
+ f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1")));
+ f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2")));
+ g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1")));
+ g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2")));
+ h = Local<Function>::Cast(context->Global()->Get(v8_str("h")));
+
+ // Get the global object.
+ v8::Handle<v8::Object> global = context->Global();
+
+ // Call f1 one time and f2 a number of times. This will ensure that f1 still
+ // uses the runtime system to retreive property a whereas f2 uses global load
+ // inline cache.
+ CHECK(f1->Call(global, 0, NULL)->Equals(v8_num(1)));
+ for (int i = 0; i < 4; i++) {
+ CHECK(f2->Call(global, 0, NULL)->Equals(v8_num(1)));
+ }
+
+ // Same for g1 and g2.
+ CHECK(g1->Call(global, 0, NULL)->Equals(v8_num(1)));
+ for (int i = 0; i < 4; i++) {
+ CHECK(g2->Call(global, 0, NULL)->Equals(v8_num(1)));
+ }
+
+ // Detach the global and turn on access check now blocking access to property
+ // a and function h.
+ context->DetachGlobal();
+ context->Global()->TurnOnAccessCheck();
+
+ // Failing access check to property get results in undefined.
+ CHECK(f1->Call(global, 0, NULL)->IsUndefined());
+ CHECK(f2->Call(global, 0, NULL)->IsUndefined());
+
+ // Failing access check to function call results in exception.
+ CHECK(g1->Call(global, 0, NULL).IsEmpty());
+ CHECK(g2->Call(global, 0, NULL).IsEmpty());
+
+ // No failing access check when just returning a constant.
+ CHECK(h->Call(global, 0, NULL)->Equals(v8_num(1)));
+
+ // Now compile the source again. And get the newly compiled functions, except
+ // for h for which access is blocked.
+ CompileRun(source);
+ f1 = Local<Function>::Cast(context->Global()->Get(v8_str("f1")));
+ f2 = Local<Function>::Cast(context->Global()->Get(v8_str("f2")));
+ g1 = Local<Function>::Cast(context->Global()->Get(v8_str("g1")));
+ g2 = Local<Function>::Cast(context->Global()->Get(v8_str("g2")));
+ CHECK(context->Global()->Get(v8_str("h"))->IsUndefined());
+
+ // Failing access check to property get results in undefined.
+ CHECK(f1->Call(global, 0, NULL)->IsUndefined());
+ CHECK(f2->Call(global, 0, NULL)->IsUndefined());
+
+ // Failing access check to function call results in exception.
+ CHECK(g1->Call(global, 0, NULL).IsEmpty());
+ CHECK(g2->Call(global, 0, NULL).IsEmpty());
+}
+
+
// 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.
@@ -10766,7 +10801,9 @@
// Tests the C++ StackTrace API.
-THREADED_TEST(CaptureStackTrace) {
+// TODO(3074796): Reenable this as a THREADED_TEST once it passes.
+// THREADED_TEST(CaptureStackTrace) {
+TEST(CaptureStackTrace) {
v8::HandleScope scope;
v8::Handle<v8::String> origin = v8::String::New("capture-stack-trace-test");
Local<ObjectTemplate> templ = ObjectTemplate::New();