Update V8 to version 4.1.0.21
This is a cherry-pick of all commits up to and including the
4.1.0.21 cherry-pick in Chromium.
Original commit message:
Version 4.1.0.21 (cherry-pick)
Merged 206e9136bde0f2b5ae8cb77afbb1e7833e5bd412
Unlink pages from the space page list after evacuation.
BUG=430201
LOG=N
R=jkummerow@chromium.org
Review URL: https://codereview.chromium.org/953813002
Cr-Commit-Position: refs/branch-heads/4.1@{#22}
Cr-Branched-From: 2e08d2a7aa9d65d269d8c57aba82eb38a8cb0a18-refs/heads/candidates@{#25353}
---
FPIIM-449
Change-Id: I8c23c7bbb70772b4858fe8a47b64fa97ee0d1f8c
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 0e80384..06cf553 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -185,7 +185,8 @@
}
-static void TestSignature(const char* loop_js, Local<Value> receiver) {
+static void TestSignature(const char* loop_js, Local<Value> receiver,
+ v8::Isolate* isolate) {
i::ScopedVector<char> source(200);
i::SNPrintF(source,
"for (var i = 0; i < 10; i++) {"
@@ -202,7 +203,7 @@
CHECK_EQ(10, signature_callback_count);
} else {
CHECK_EQ(v8_str("TypeError: Illegal invocation"),
- try_catch.Exception()->ToString());
+ try_catch.Exception()->ToString(isolate));
}
}
@@ -267,17 +268,17 @@
i::SNPrintF(
source, "var test_object = %s; test_object", test_objects[i]);
Local<Value> test_object = CompileRun(source.start());
- TestSignature("test_object.prop();", test_object);
- TestSignature("test_object.accessor;", test_object);
- TestSignature("test_object[accessor_key];", test_object);
- TestSignature("test_object.accessor = 1;", test_object);
- TestSignature("test_object[accessor_key] = 1;", test_object);
+ TestSignature("test_object.prop();", test_object, isolate);
+ TestSignature("test_object.accessor;", test_object, isolate);
+ TestSignature("test_object[accessor_key];", test_object, isolate);
+ TestSignature("test_object.accessor = 1;", test_object, isolate);
+ TestSignature("test_object[accessor_key] = 1;", test_object, isolate);
if (i >= bad_signature_start_offset) test_object = Local<Value>();
- TestSignature("test_object.prop_sig();", test_object);
- TestSignature("test_object.accessor_sig;", test_object);
- TestSignature("test_object[accessor_sig_key];", test_object);
- TestSignature("test_object.accessor_sig = 1;", test_object);
- TestSignature("test_object[accessor_sig_key] = 1;", test_object);
+ TestSignature("test_object.prop_sig();", test_object, isolate);
+ TestSignature("test_object.accessor_sig;", test_object, isolate);
+ TestSignature("test_object[accessor_sig_key];", test_object, isolate);
+ TestSignature("test_object.accessor_sig = 1;", test_object, isolate);
+ TestSignature("test_object[accessor_sig_key] = 1;", test_object, isolate);
}
}
@@ -356,7 +357,7 @@
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::Primitive> undef = v8::Undefined(isolate);
- Local<String> undef_str = undef->ToString();
+ Local<String> undef_str = undef->ToString(isolate);
char* value = i::NewArray<char>(undef_str->Utf8Length() + 1);
undef_str->WriteUtf8(value);
CHECK_EQ(0, strcmp(value, "undefined"));
@@ -742,6 +743,58 @@
}
+class RandomLengthResource : public v8::String::ExternalStringResource {
+ public:
+ explicit RandomLengthResource(int length) : length_(length) {}
+ virtual const uint16_t* data() const { return string_; }
+ virtual size_t length() const { return length_; }
+
+ private:
+ uint16_t string_[10];
+ int length_;
+};
+
+
+class RandomLengthOneByteResource
+ : public v8::String::ExternalOneByteStringResource {
+ public:
+ explicit RandomLengthOneByteResource(int length) : length_(length) {}
+ virtual const char* data() const { return string_; }
+ virtual size_t length() const { return length_; }
+
+ private:
+ char string_[10];
+ int length_;
+};
+
+
+THREADED_TEST(NewExternalForVeryLongString) {
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::TryCatch try_catch;
+ RandomLengthOneByteResource r(1 << 30);
+ v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+ CHECK(str.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ("RangeError: Invalid string length", *exception_value);
+ }
+
+ {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+ v8::TryCatch try_catch;
+ RandomLengthResource r(1 << 30);
+ v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), &r);
+ CHECK(str.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ String::Utf8Value exception_value(try_catch.Exception());
+ CHECK_EQ("RangeError: Invalid string length", *exception_value);
+ }
+}
+
+
THREADED_TEST(ScavengeExternalString) {
i::FLAG_stress_compaction = false;
i::FLAG_gc_global = false;
@@ -934,7 +987,7 @@
// If CPU profiler is active check that when API callback is invoked
// VMState is set to EXTERNAL.
if (isolate->cpu_profiler()->is_profiling()) {
- CHECK_EQ(i::EXTERNAL, isolate->current_vm_state());
+ CHECK_EQ(v8::EXTERNAL, isolate->current_vm_state());
CHECK(isolate->external_callback_scope());
CHECK_EQ(callback, isolate->external_callback_scope()->callback());
}
@@ -1181,7 +1234,8 @@
THREADED_PROFILED_TEST(FastReturnValues) {
LocalContext env;
- v8::HandleScope scope(CcTest::isolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::Handle<v8::Value> value;
// check int32_t and uint32_t
int32_t int_values[] = {
@@ -1206,13 +1260,13 @@
// check double
value = TestFastReturnValues<double>();
CHECK(value->IsNumber());
- CHECK_EQ(kFastReturnValueDouble, value->ToNumber()->Value());
+ CHECK_EQ(kFastReturnValueDouble, value->ToNumber(isolate)->Value());
// check bool values
for (int i = 0; i < 2; i++) {
fast_return_value_bool = i == 0;
value = TestFastReturnValues<bool>();
CHECK(value->IsBoolean());
- CHECK_EQ(fast_return_value_bool, value->ToBoolean()->Value());
+ CHECK_EQ(fast_return_value_bool, value->ToBoolean(isolate)->Value());
}
// check oddballs
ReturnValueOddball oddballs[] = {
@@ -1542,6 +1596,34 @@
}
+THREADED_TEST(IsGeneratorFunctionOrObject) {
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ CompileRun("function *gen() { yield 1; }\nfunction func() {}");
+ v8::Handle<Value> gen = CompileRun("gen");
+ v8::Handle<Value> genObj = CompileRun("gen()");
+ v8::Handle<Value> object = CompileRun("{a:42}");
+ v8::Handle<Value> func = CompileRun("func");
+
+ CHECK(gen->IsGeneratorFunction());
+ CHECK(gen->IsFunction());
+ CHECK(!gen->IsGeneratorObject());
+
+ CHECK(!genObj->IsGeneratorFunction());
+ CHECK(!genObj->IsFunction());
+ CHECK(genObj->IsGeneratorObject());
+
+ CHECK(!object->IsGeneratorFunction());
+ CHECK(!object->IsFunction());
+ CHECK(!object->IsGeneratorObject());
+
+ CHECK(!func->IsGeneratorFunction());
+ CHECK(func->IsFunction());
+ CHECK(!func->IsGeneratorObject());
+}
+
+
THREADED_TEST(ArgumentsObject) {
LocalContext env;
v8::HandleScope scope(env->GetIsolate());
@@ -1904,7 +1986,7 @@
int echo_named_call_count;
-static void EchoNamedProperty(Local<String> name,
+static void EchoNamedProperty(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK_EQ(v8_str("data"), info.Data());
@@ -1946,18 +2028,41 @@
SimpleAccessorSetter(Local<String>::Cast(sym->Name()), value, info);
}
-void EmptyInterceptorGetter(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+void SymbolAccessorGetterReturnsDefault(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CHECK(name->IsSymbol());
+ Local<Symbol> sym = Local<Symbol>::Cast(name);
+ if (sym->Name()->IsUndefined()) return;
+ info.GetReturnValue().Set(info.Data());
}
-void EmptyInterceptorSetter(Local<String> name,
- Local<Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+static void ThrowingSymbolAccessorGetter(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ info.GetReturnValue().Set(info.GetIsolate()->ThrowException(name));
}
-void InterceptorGetter(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- // Intercept names that start with 'interceptor_'.
+
+void EmptyInterceptorGetter(Local<Name> name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyInterceptorSetter(Local<Name> name, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyGenericInterceptorGetter(
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void EmptyGenericInterceptorSetter(
+ Local<Name> name, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {}
+
+
+void StringInterceptorGetter(
+ Local<String> name,
+ const v8::PropertyCallbackInfo<v8::Value>&
+ info) { // Intercept names that start with 'interceptor_'.
String::Utf8Value utf8(name);
char* name_str = *utf8;
char prefix[] = "interceptor_";
@@ -1969,9 +2074,9 @@
info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i)));
}
-void InterceptorSetter(Local<String> name,
- Local<Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+
+void StringInterceptorSetter(Local<String> name, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
// Intercept accesses that set certain integer values, for which the name does
// not start with 'accessor_'.
String::Utf8Value utf8(name);
@@ -1990,6 +2095,57 @@
}
}
+void InterceptorGetter(Local<Name> generic_name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ if (generic_name->IsSymbol()) return;
+ StringInterceptorGetter(Local<String>::Cast(generic_name), info);
+}
+
+void InterceptorSetter(Local<Name> generic_name, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ if (generic_name->IsSymbol()) return;
+ StringInterceptorSetter(Local<String>::Cast(generic_name), value, info);
+}
+
+void GenericInterceptorGetter(Local<Name> generic_name,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<String> str;
+ if (generic_name->IsSymbol()) {
+ Local<Value> name = Local<Symbol>::Cast(generic_name)->Name();
+ if (name->IsUndefined()) return;
+ str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name));
+ } else {
+ Local<String> name = Local<String>::Cast(generic_name);
+ String::Utf8Value utf8(name);
+ char* name_str = *utf8;
+ if (*name_str == '_') return;
+ str = String::Concat(v8_str("_str_"), name);
+ }
+
+ Handle<Object> self = Handle<Object>::Cast(info.This());
+ info.GetReturnValue().Set(self->Get(str));
+}
+
+void GenericInterceptorSetter(Local<Name> generic_name, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<String> str;
+ if (generic_name->IsSymbol()) {
+ Local<Value> name = Local<Symbol>::Cast(generic_name)->Name();
+ if (name->IsUndefined()) return;
+ str = String::Concat(v8_str("_sym_"), Local<String>::Cast(name));
+ } else {
+ Local<String> name = Local<String>::Cast(generic_name);
+ String::Utf8Value utf8(name);
+ char* name_str = *utf8;
+ if (*name_str == '_') return;
+ str = String::Concat(v8_str("_str_"), name);
+ }
+
+ Handle<Object> self = Handle<Object>::Cast(info.This());
+ self->Set(str, value);
+ info.GetReturnValue().Set(value);
+}
+
void AddAccessor(Handle<FunctionTemplate> templ,
Handle<String> name,
v8::AccessorGetterCallback getter,
@@ -2011,6 +2167,13 @@
templ->PrototypeTemplate()->SetAccessor(name, getter, setter);
}
+void AddInterceptor(Handle<FunctionTemplate> templ,
+ v8::GenericNamedPropertyGetterCallback getter,
+ v8::GenericNamedPropertySetterCallback setter) {
+ templ->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(getter, setter));
+}
+
THREADED_TEST(EmptyInterceptorDoesNotShadowAccessors) {
v8::HandleScope scope(CcTest::isolate());
@@ -2030,6 +2193,62 @@
}
+THREADED_TEST(LegacyInterceptorDoesNotSeeSymbols) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+ Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
+ v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age"));
+
+ child->Inherit(parent);
+ AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter);
+ AddInterceptor(child, StringInterceptorGetter, StringInterceptorSetter);
+
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ env->Global()->Set(v8_str("age"), age);
+ CompileRun(
+ "var child = new Child;"
+ "child[age] = 10;");
+ ExpectInt32("child[age]", 10);
+ ExpectBoolean("child.hasOwnProperty('age')", false);
+ ExpectBoolean("child.hasOwnProperty('accessor_age')", true);
+}
+
+
+THREADED_TEST(GenericInterceptorDoesSeeSymbols) {
+ LocalContext env;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate);
+ Handle<FunctionTemplate> child = FunctionTemplate::New(isolate);
+ v8::Local<v8::Symbol> age = v8::Symbol::New(isolate, v8_str("age"));
+ v8::Local<v8::Symbol> anon = v8::Symbol::New(isolate);
+
+ child->Inherit(parent);
+ AddAccessor(parent, age, SymbolAccessorGetter, SymbolAccessorSetter);
+ AddInterceptor(child, GenericInterceptorGetter, GenericInterceptorSetter);
+
+ env->Global()->Set(v8_str("Child"), child->GetFunction());
+ env->Global()->Set(v8_str("age"), age);
+ env->Global()->Set(v8_str("anon"), anon);
+ CompileRun(
+ "var child = new Child;"
+ "child[age] = 10;");
+ ExpectInt32("child[age]", 10);
+ ExpectInt32("child._sym_age", 10);
+
+ // Check that it also sees strings.
+ CompileRun("child.foo = 47");
+ ExpectInt32("child.foo", 47);
+ ExpectInt32("child._str_foo", 47);
+
+ // Check that the interceptor can punt (in this case, on anonymous symbols).
+ CompileRun("child[anon] = 31337");
+ ExpectInt32("child[anon]", 31337);
+}
+
+
THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -2275,9 +2494,8 @@
v8::HandleScope scope(CcTest::isolate());
v8::Handle<v8::FunctionTemplate> templ =
v8::FunctionTemplate::New(CcTest::isolate());
- templ->InstanceTemplate()->SetNamedPropertyHandler(EchoNamedProperty,
- 0, 0, 0, 0,
- v8_str("data"));
+ templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ EchoNamedProperty, 0, 0, 0, 0, v8_str("data")));
LocalContext env;
env->Global()->Set(v8_str("obj"),
templ->GetFunction()->NewInstance());
@@ -2312,9 +2530,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
- templ->InstanceTemplate()->SetIndexedPropertyHandler(EchoIndexedProperty,
- 0, 0, 0, 0,
- v8_num(637));
+ templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ EchoIndexedProperty, 0, 0, 0, 0, v8_num(637)));
LocalContext env;
env->Global()->Set(v8_str("obj"),
templ->GetFunction()->NewInstance());
@@ -2334,8 +2551,7 @@
}
static void CheckThisNamedPropertyHandler(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
@@ -2352,8 +2568,7 @@
void CheckThisNamedPropertySetter(
- Local<String> property,
- Local<Value> value,
+ Local<Name> property, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter));
ApiTestFuzzer::Fuzz();
@@ -2370,8 +2585,7 @@
void CheckThisNamedPropertyQuery(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
@@ -2388,8 +2602,7 @@
void CheckThisNamedPropertyDeleter(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Boolean>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info) {
CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter));
ApiTestFuzzer::Fuzz();
CHECK(info.This()->Equals(bottom));
@@ -2419,19 +2632,15 @@
// Set up a prototype chain with three interceptors.
v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
- templ->InstanceTemplate()->SetIndexedPropertyHandler(
- CheckThisIndexedPropertyHandler,
- CheckThisIndexedPropertySetter,
- CheckThisIndexedPropertyQuery,
- CheckThisIndexedPropertyDeleter,
- CheckThisIndexedPropertyEnumerator);
+ templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter,
+ CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter,
+ CheckThisIndexedPropertyEnumerator));
- templ->InstanceTemplate()->SetNamedPropertyHandler(
- CheckThisNamedPropertyHandler,
- CheckThisNamedPropertySetter,
- CheckThisNamedPropertyQuery,
- CheckThisNamedPropertyDeleter,
- CheckThisNamedPropertyEnumerator);
+ templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter,
+ CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter,
+ CheckThisNamedPropertyEnumerator));
bottom = templ->GetFunction()->NewInstance();
Local<v8::Object> top = templ->GetFunction()->NewInstance();
@@ -2463,8 +2672,7 @@
static void PrePropertyHandlerGet(
- Local<String> key,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre"));
@@ -2473,8 +2681,7 @@
static void PrePropertyHandlerQuery(
- Local<String> key,
- const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) {
if (v8_str("pre")->Equals(key)) {
info.GetReturnValue().Set(static_cast<int32_t>(v8::None));
}
@@ -2485,9 +2692,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate);
- desc->InstanceTemplate()->SetNamedPropertyHandler(PrePropertyHandlerGet,
- 0,
- PrePropertyHandlerQuery);
+ desc->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ PrePropertyHandlerGet, 0, PrePropertyHandlerQuery));
LocalContext env(NULL, desc->InstanceTemplate());
CompileRun("var pre = 'Object: pre'; var on = 'Object: on';");
v8::Handle<Value> result_pre = CompileRun("pre");
@@ -2560,16 +2766,17 @@
static void ThrowingPropertyHandlerGet(
- Local<String> key,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ // Since this interceptor is used on "with" objects, the runtime will look up
+ // @@unscopables. Punt.
+ if (key->IsSymbol()) return;
ApiTestFuzzer::Fuzz();
info.GetReturnValue().Set(info.GetIsolate()->ThrowException(key));
}
static void ThrowingPropertyHandlerSet(
- Local<String> key,
- Local<Value>,
+ Local<Name> key, Local<Value>,
const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetIsolate()->ThrowException(key);
info.GetReturnValue().SetUndefined(); // not the same as empty handle
@@ -2580,8 +2787,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
- obj->SetNamedPropertyHandler(ThrowingPropertyHandlerGet,
- ThrowingPropertyHandlerSet);
+ obj->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet));
LocalContext env;
env->Global()->Set(v8_str("obj"), obj->NewInstance());
v8::Handle<Value> otto = CompileRun(
@@ -2749,6 +2956,16 @@
}
+THREADED_TEST(GetIsolate) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::Object> obj = v8::Object::New(isolate);
+ CHECK_EQ(isolate, obj->GetIsolate());
+ CHECK_EQ(isolate, CcTest::global()->GetIsolate());
+}
+
+
THREADED_TEST(IdentityHash) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -2813,6 +3030,53 @@
}
+TEST(SymbolIdentityHash) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ {
+ Local<v8::Symbol> symbol = v8::Symbol::New(isolate);
+ int hash = symbol->GetIdentityHash();
+ int hash1 = symbol->GetIdentityHash();
+ CHECK_EQ(hash, hash1);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ int hash3 = symbol->GetIdentityHash();
+ CHECK_EQ(hash, hash3);
+ }
+
+ {
+ v8::Handle<v8::Symbol> js_symbol =
+ CompileRun("Symbol('foo')").As<v8::Symbol>();
+ int hash = js_symbol->GetIdentityHash();
+ int hash1 = js_symbol->GetIdentityHash();
+ CHECK_EQ(hash, hash1);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ int hash3 = js_symbol->GetIdentityHash();
+ CHECK_EQ(hash, hash3);
+ }
+}
+
+
+TEST(StringIdentityHash) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ Local<v8::String> str = v8::String::NewFromUtf8(isolate, "str1");
+ int hash = str->GetIdentityHash();
+ int hash1 = str->GetIdentityHash();
+ CHECK_EQ(hash, hash1);
+ CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
+ int hash3 = str->GetIdentityHash();
+ CHECK_EQ(hash, hash3);
+
+ Local<v8::String> str2 = v8::String::NewFromUtf8(isolate, "str1");
+ int hash4 = str2->GetIdentityHash();
+ CHECK_EQ(hash, hash4);
+}
+
+
THREADED_TEST(SymbolProperties) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
@@ -3195,6 +3459,24 @@
}
+THREADED_TEST(ArrayBuffer_DisableNeuter) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope handle_scope(isolate);
+
+ i::ScopedVector<uint8_t> my_data(100);
+ memset(my_data.start(), 0, 100);
+ Local<v8::ArrayBuffer> ab =
+ v8::ArrayBuffer::New(isolate, my_data.start(), 100);
+ CHECK(ab->IsNeuterable());
+
+ i::Handle<i::JSArrayBuffer> buf = v8::Utils::OpenHandle(*ab);
+ buf->set_is_neuterable(false);
+
+ CHECK(!ab->IsNeuterable());
+}
+
+
static void CheckDataViewIsNeutered(v8::Handle<v8::DataView> dv) {
CHECK_EQ(0, static_cast<int>(dv->ByteLength()));
CHECK_EQ(0, static_cast<int>(dv->ByteOffset()));
@@ -3411,7 +3693,7 @@
static bool interceptor_for_hidden_properties_called;
static void InterceptorForHiddenProperties(
- Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
interceptor_for_hidden_properties_called = true;
}
@@ -3428,7 +3710,8 @@
// Associate an interceptor with an object and start setting hidden values.
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
- instance_templ->SetNamedPropertyHandler(InterceptorForHiddenProperties);
+ instance_templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorForHiddenProperties));
Local<v8::Function> function = fun_templ->GetFunction();
Local<v8::Object> obj = function->NewInstance();
CHECK(obj->SetHiddenValue(key, v8::Integer::New(isolate, 2302)));
@@ -4144,6 +4427,45 @@
}
+THREADED_TEST(WeakRootsSurviveTwoRoundsOfGC) {
+ LocalContext env;
+ v8::Isolate* iso = env->GetIsolate();
+ HandleScope scope(iso);
+
+ WeakCallCounter counter(1234);
+
+ WeakCallCounterAndPersistent<Value> weak_obj(&counter);
+
+ // Create a weak object that references a internalized string.
+ {
+ HandleScope scope(iso);
+ weak_obj.handle.Reset(iso, Object::New(iso));
+ weak_obj.handle.SetWeak(&weak_obj, &WeakPointerCallback);
+ CHECK(weak_obj.handle.IsWeak());
+ Local<Object>::New(iso, weak_obj.handle.As<Object>())->Set(
+ v8_str("x"),
+ String::NewFromUtf8(iso, "magic cookie", String::kInternalizedString));
+ }
+ // Do a single full GC
+ i::Isolate* i_iso = reinterpret_cast<v8::internal::Isolate*>(iso);
+ i::Heap* heap = i_iso->heap();
+ heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+
+ // We should have received the weak callback.
+ CHECK_EQ(1, counter.NumberOfWeakCalls());
+
+ // Check that the string is still alive.
+ {
+ HandleScope scope(iso);
+ i::MaybeHandle<i::String> magic_string =
+ i::StringTable::LookupStringIfExists(
+ i_iso,
+ v8::Utils::OpenHandle(*String::NewFromUtf8(iso, "magic cookie")));
+ magic_string.Check();
+ }
+}
+
+
// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
// on the buildbots, so was made non-threaded for the time being.
TEST(ApiObjectGroupsCycleForScavenger) {
@@ -4266,13 +4588,14 @@
TEST(TryCatchCustomException) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
v8::TryCatch try_catch;
CompileRun("function CustomError() { this.a = 'b'; }"
"(function f() { throw new CustomError(); })();");
CHECK(try_catch.HasCaught());
- CHECK(try_catch.Exception()->ToObject()->
- Get(v8_str("a"))->Equals(v8_str("b")));
+ CHECK(try_catch.Exception()->ToObject(isolate)->Get(v8_str("a"))->Equals(
+ v8_str("b")));
}
@@ -4766,49 +5089,51 @@
THREADED_TEST(ConversionNumber) {
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
// Very large number.
CompileRun("var obj = Math.pow(2,32) * 1237;");
Local<Value> obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(5312874545152.0, obj->ToNumber()->Value());
- CHECK_EQ(0, obj->ToInt32()->Value());
- CHECK(0u == obj->ToUint32()->Value()); // NOLINT - no CHECK_EQ for unsigned.
+ CHECK_EQ(5312874545152.0, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(0, obj->ToInt32(isolate)->Value());
+ CHECK(0u ==
+ obj->ToUint32(isolate)->Value()); // NOLINT - no CHECK_EQ for unsigned.
// Large number.
CompileRun("var obj = -1234567890123;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(-1234567890123.0, obj->ToNumber()->Value());
- CHECK_EQ(-1912276171, obj->ToInt32()->Value());
- CHECK(2382691125u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(-1234567890123.0, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(-1912276171, obj->ToInt32(isolate)->Value());
+ CHECK(2382691125u == obj->ToUint32(isolate)->Value()); // NOLINT
// Small positive integer.
CompileRun("var obj = 42;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(42.0, obj->ToNumber()->Value());
- CHECK_EQ(42, obj->ToInt32()->Value());
- CHECK(42u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(42.0, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(42, obj->ToInt32(isolate)->Value());
+ CHECK(42u == obj->ToUint32(isolate)->Value()); // NOLINT
// Negative integer.
CompileRun("var obj = -37;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(-37.0, obj->ToNumber()->Value());
- CHECK_EQ(-37, obj->ToInt32()->Value());
- CHECK(4294967259u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(-37.0, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(-37, obj->ToInt32(isolate)->Value());
+ CHECK(4294967259u == obj->ToUint32(isolate)->Value()); // NOLINT
// Positive non-int32 integer.
CompileRun("var obj = 0x81234567;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(2166572391.0, obj->ToNumber()->Value());
- CHECK_EQ(-2128394905, obj->ToInt32()->Value());
- CHECK(2166572391u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(2166572391.0, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(-2128394905, obj->ToInt32(isolate)->Value());
+ CHECK(2166572391u == obj->ToUint32(isolate)->Value()); // NOLINT
// Fraction.
CompileRun("var obj = 42.3;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(42.3, obj->ToNumber()->Value());
- CHECK_EQ(42, obj->ToInt32()->Value());
- CHECK(42u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(42.3, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(42, obj->ToInt32(isolate)->Value());
+ CHECK(42u == obj->ToUint32(isolate)->Value()); // NOLINT
// Large negative fraction.
CompileRun("var obj = -5726623061.75;");
obj = env->Global()->Get(v8_str("obj"));
- CHECK_EQ(-5726623061.75, obj->ToNumber()->Value());
- CHECK_EQ(-1431655765, obj->ToInt32()->Value());
- CHECK(2863311531u == obj->ToUint32()->Value()); // NOLINT
+ CHECK_EQ(-5726623061.75, obj->ToNumber(isolate)->Value());
+ CHECK_EQ(-1431655765, obj->ToInt32(isolate)->Value());
+ CHECK(2863311531u == obj->ToUint32(isolate)->Value()); // NOLINT
}
@@ -4873,29 +5198,29 @@
"var obj = new TestClass();");
Local<Value> obj = env->Global()->Get(v8_str("obj"));
- v8::TryCatch try_catch;
+ v8::TryCatch try_catch(isolate);
- Local<Value> to_string_result = obj->ToString();
+ Local<Value> to_string_result = obj->ToString(isolate);
CHECK(to_string_result.IsEmpty());
CheckUncle(&try_catch);
- Local<Value> to_number_result = obj->ToNumber();
+ Local<Value> to_number_result = obj->ToNumber(isolate);
CHECK(to_number_result.IsEmpty());
CheckUncle(&try_catch);
- Local<Value> to_integer_result = obj->ToInteger();
+ Local<Value> to_integer_result = obj->ToInteger(isolate);
CHECK(to_integer_result.IsEmpty());
CheckUncle(&try_catch);
- Local<Value> to_uint32_result = obj->ToUint32();
+ Local<Value> to_uint32_result = obj->ToUint32(isolate);
CHECK(to_uint32_result.IsEmpty());
CheckUncle(&try_catch);
- Local<Value> to_int32_result = obj->ToInt32();
+ Local<Value> to_int32_result = obj->ToInt32(isolate);
CHECK(to_int32_result.IsEmpty());
CheckUncle(&try_catch);
- Local<Value> to_object_result = v8::Undefined(isolate)->ToObject();
+ Local<Value> to_object_result = v8::Undefined(isolate)->ToObject(isolate);
CHECK(to_object_result.IsEmpty());
CHECK(try_catch.HasCaught());
try_catch.Reset();
@@ -4931,7 +5256,7 @@
}
v8::HandleScope scope(args.GetIsolate());
v8::TryCatch try_catch;
- Local<Value> result = CompileRun(args[0]->ToString());
+ Local<Value> result = CompileRun(args[0]->ToString(args.GetIsolate()));
CHECK(!try_catch.HasCaught() || result.IsEmpty());
args.GetReturnValue().Set(try_catch.HasCaught());
}
@@ -5980,7 +6305,7 @@
}
-static void XPropertyGetter(Local<String> property,
+static void XPropertyGetter(Local<Name> property,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(info.Data()->IsUndefined());
@@ -5992,7 +6317,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(XPropertyGetter);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
Local<Script> script = v8_compile("obj.x");
@@ -6007,7 +6332,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(XPropertyGetter);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
LocalContext context;
// Create an object with a named interceptor.
context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance());
@@ -6041,7 +6366,7 @@
context1->Enter();
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(XPropertyGetter);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter));
// Create an object with a named interceptor.
v8::Local<v8::Object> object = templ->NewInstance();
context1->Global()->Set(v8_str("interceptor_obj"), object);
@@ -6076,8 +6401,7 @@
static void SetXOnPrototypeGetter(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
// Set x on the prototype object and do not handle the get request.
v8::Handle<v8::Value> proto = info.Holder()->GetPrototype();
proto.As<v8::Object>()->Set(v8_str("x"),
@@ -6094,7 +6418,8 @@
v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_template
= function_template->InstanceTemplate();
- instance_template->SetNamedPropertyHandler(SetXOnPrototypeGetter);
+ instance_template->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(SetXOnPrototypeGetter));
LocalContext context;
context->Global()->Set(v8_str("F"), function_template->GetFunction());
// Create an instance of F and introduce a map transition for x.
@@ -6130,8 +6455,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IndexedPropertyGetter,
- IndexedPropertySetter);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ IndexedPropertyGetter, IndexedPropertySetter));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
Local<Script> getter_script = v8_compile(
@@ -6196,11 +6521,9 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(UnboxedDoubleIndexedPropertyGetter,
- UnboxedDoubleIndexedPropertySetter,
- 0,
- 0,
- UnboxedDoubleIndexedPropertyEnumerator);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ UnboxedDoubleIndexedPropertyGetter, UnboxedDoubleIndexedPropertySetter, 0,
+ 0, UnboxedDoubleIndexedPropertyEnumerator));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
// When obj is created, force it to be Stored in a FastDoubleArray.
@@ -6210,7 +6533,7 @@
"for (x in obj) {key_count++;};"
"obj;");
Local<Value> result = create_unboxed_double_script->Run();
- CHECK(result->ToObject()->HasRealIndexedProperty(2000));
+ CHECK(result->ToObject(isolate)->HasRealIndexedProperty(2000));
Local<Script> key_count_check = v8_compile("key_count;");
result = key_count_check->Run();
CHECK_EQ(v8_num(40013), result);
@@ -6252,11 +6575,9 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(SloppyIndexedPropertyGetter,
- 0,
- 0,
- 0,
- SloppyArgsIndexedPropertyEnumerator);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ SloppyIndexedPropertyGetter, 0, 0, 0,
+ SloppyArgsIndexedPropertyEnumerator));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
Local<Script> create_args_script = v8_compile(
@@ -6278,7 +6599,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
@@ -6300,7 +6622,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
@@ -6324,7 +6647,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6352,7 +6676,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6390,7 +6715,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6414,7 +6740,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6454,7 +6781,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6484,7 +6812,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6515,7 +6844,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -6546,7 +6876,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(IdentityIndexedPropertyGetter);
+ templ->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter));
LocalContext context;
Local<v8::Object> obj = templ->NewInstance();
@@ -7371,14 +7702,175 @@
};
-static void DisposeAndSetFlag(
- const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
- data.GetParameter()->handle.Reset();
+static void SetFlag(const v8::PhantomCallbackData<FlagAndPersistent>& data) {
data.GetParameter()->flag = true;
}
+static void IndependentWeakHandle(bool global_gc, bool interlinked) {
+ v8::Isolate* iso = CcTest::isolate();
+ v8::HandleScope scope(iso);
+ v8::Handle<Context> context = Context::New(iso);
+ Context::Scope context_scope(context);
+
+ FlagAndPersistent object_a, object_b;
+
+ intptr_t big_heap_size;
+
+ {
+ v8::HandleScope handle_scope(iso);
+ Local<Object> a(v8::Object::New(iso));
+ Local<Object> b(v8::Object::New(iso));
+ object_a.handle.Reset(iso, a);
+ object_b.handle.Reset(iso, b);
+ if (interlinked) {
+ a->Set(v8_str("x"), b);
+ b->Set(v8_str("x"), a);
+ }
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
+ // We are relying on this creating a big flag array and reserving the space
+ // up front.
+ v8::Handle<Value> big_array = CompileRun("new Array(50000)");
+ a->Set(v8_str("y"), big_array);
+ big_heap_size = CcTest::heap()->SizeOfObjects();
+ }
+
+ object_a.flag = false;
+ object_b.flag = false;
+ object_a.handle.SetPhantom(&object_a, &SetFlag);
+ object_b.handle.SetPhantom(&object_b, &SetFlag);
+ CHECK(!object_b.handle.IsIndependent());
+ object_a.handle.MarkIndependent();
+ object_b.handle.MarkIndependent();
+ CHECK(object_b.handle.IsIndependent());
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
+ // A single GC should be enough to reclaim the memory, since we are using
+ // phantom handles.
+ CHECK_LT(CcTest::heap()->SizeOfObjects(), big_heap_size - 200000);
+ CHECK(object_a.flag);
+ CHECK(object_b.flag);
+}
+
+
THREADED_TEST(IndependentWeakHandle) {
+ IndependentWeakHandle(false, false);
+ IndependentWeakHandle(false, true);
+ IndependentWeakHandle(true, false);
+ IndependentWeakHandle(true, true);
+}
+
+
+class Trivial {
+ public:
+ explicit Trivial(int x) : x_(x) {}
+
+ int x() { return x_; }
+ void set_x(int x) { x_ = x; }
+
+ private:
+ int x_;
+};
+
+
+class Trivial2 {
+ public:
+ Trivial2(int x, int y) : y_(y), x_(x) {}
+
+ int x() { return x_; }
+ void set_x(int x) { x_ = x; }
+
+ int y() { return y_; }
+ void set_y(int y) { y_ = y; }
+
+ private:
+ int y_;
+ int x_;
+};
+
+
+void CheckInternalFields(
+ const v8::InternalFieldsCallbackData<Trivial, Trivial2>& data) {
+ Trivial* t1 = data.GetInternalField1();
+ Trivial2* t2 = data.GetInternalField2();
+ CHECK_EQ(42, t1->x());
+ CHECK_EQ(103, t2->x());
+ t1->set_x(1729);
+ t2->set_x(33550336);
+}
+
+
+void InternalFieldCallback(bool global_gc) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+ Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
+ Trivial* t1;
+ Trivial2* t2;
+ instance_templ->SetInternalFieldCount(2);
+ {
+ v8::HandleScope scope(isolate);
+ Local<v8::Object> obj = templ->GetFunction()->NewInstance();
+ v8::Persistent<v8::Object> handle(isolate, obj);
+ CHECK_EQ(2, obj->InternalFieldCount());
+ CHECK(obj->GetInternalField(0)->IsUndefined());
+ t1 = new Trivial(42);
+ t2 = new Trivial2(103, 9);
+
+ obj->SetAlignedPointerInInternalField(0, t1);
+ t1 = reinterpret_cast<Trivial*>(obj->GetAlignedPointerFromInternalField(0));
+ CHECK_EQ(42, t1->x());
+
+ obj->SetAlignedPointerInInternalField(1, t2);
+ t2 =
+ reinterpret_cast<Trivial2*>(obj->GetAlignedPointerFromInternalField(1));
+ CHECK_EQ(103, t2->x());
+
+ handle.SetPhantom(CheckInternalFields, 0, 1);
+ if (!global_gc) {
+ handle.MarkIndependent();
+ }
+ }
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(TestHeap::Heap::kNoGCFlags);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
+
+ CHECK_EQ(1729, t1->x());
+ CHECK_EQ(33550336, t2->x());
+
+ delete t1;
+ delete t2;
+}
+
+
+THREADED_TEST(InternalFieldCallback) {
+ InternalFieldCallback(false);
+ InternalFieldCallback(true);
+}
+
+
+static void ResetUseValueAndSetFlag(
+ const v8::WeakCallbackData<v8::Object, FlagAndPersistent>& data) {
+ // Blink will reset the handle, and then use the other handle, so they
+ // can't use the same backing slot.
+ data.GetParameter()->handle.Reset();
+ data.GetValue()->IsBoolean(); // Make sure the handle still works.
+ data.GetParameter()->flag = true;
+}
+
+
+static void ResetWeakHandle(bool global_gc) {
v8::Isolate* iso = CcTest::isolate();
v8::HandleScope scope(iso);
v8::Handle<Context> context = Context::New(iso);
@@ -7388,24 +7880,44 @@
{
v8::HandleScope handle_scope(iso);
- object_a.handle.Reset(iso, v8::Object::New(iso));
- object_b.handle.Reset(iso, v8::Object::New(iso));
+ Local<Object> a(v8::Object::New(iso));
+ Local<Object> b(v8::Object::New(iso));
+ object_a.handle.Reset(iso, a);
+ object_b.handle.Reset(iso, b);
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(
+ TestHeap::Heap::kAbortIncrementalMarkingMask);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
}
object_a.flag = false;
object_b.flag = false;
- object_a.handle.SetWeak(&object_a, &DisposeAndSetFlag);
- object_b.handle.SetWeak(&object_b, &DisposeAndSetFlag);
- CHECK(!object_b.handle.IsIndependent());
- object_a.handle.MarkIndependent();
- object_b.handle.MarkIndependent();
- CHECK(object_b.handle.IsIndependent());
- CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ object_a.handle.SetWeak(&object_a, &ResetUseValueAndSetFlag);
+ object_b.handle.SetWeak(&object_b, &ResetUseValueAndSetFlag);
+ if (!global_gc) {
+ object_a.handle.MarkIndependent();
+ object_b.handle.MarkIndependent();
+ CHECK(object_b.handle.IsIndependent());
+ }
+ if (global_gc) {
+ CcTest::heap()->CollectAllGarbage(
+ TestHeap::Heap::kAbortIncrementalMarkingMask);
+ } else {
+ CcTest::heap()->CollectGarbage(i::NEW_SPACE);
+ }
CHECK(object_a.flag);
CHECK(object_b.flag);
}
+THREADED_TEST(ResetWeakHandle) {
+ ResetWeakHandle(false);
+ ResetWeakHandle(true);
+}
+
+
static void InvokeScavenge() {
CcTest::heap()->CollectGarbage(i::NEW_SPACE);
}
@@ -7533,9 +8045,8 @@
}
-static void NoBlockGetterX(Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>&) {
-}
+static void NoBlockGetterX(Local<Name> name,
+ const v8::PropertyCallbackInfo<v8::Value>&) {}
static void NoBlockGetterI(uint32_t index,
@@ -7543,7 +8054,7 @@
}
-static void PDeleter(Local<String> name,
+static void PDeleter(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
if (!name->Equals(v8_str("foo"))) {
return; // not intercepted
@@ -7567,8 +8078,10 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
- obj->SetNamedPropertyHandler(NoBlockGetterX, NULL, NULL, PDeleter, NULL);
- obj->SetIndexedPropertyHandler(NoBlockGetterI, NULL, NULL, IDeleter, NULL);
+ obj->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX, NULL,
+ NULL, PDeleter, NULL));
+ obj->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ NoBlockGetterI, NULL, NULL, IDeleter, NULL));
LocalContext context;
context->Global()->Set(v8_str("k"), obj->NewInstance());
CompileRun(
@@ -7590,7 +8103,7 @@
}
-static void GetK(Local<String> name,
+static void GetK(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (name->Equals(v8_str("foo")) ||
@@ -7631,8 +8144,10 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
- obj->SetNamedPropertyHandler(GetK, NULL, NULL, NULL, NamedEnum);
- obj->SetIndexedPropertyHandler(IndexedGetK, NULL, NULL, NULL, IndexedEnum);
+ obj->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(GetK, NULL, NULL, NULL, NamedEnum));
+ obj->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ IndexedGetK, NULL, NULL, NULL, IndexedEnum));
LocalContext context;
context->Global()->Set(v8_str("k"), obj->NewInstance());
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
@@ -7724,7 +8239,7 @@
}
-static void PGetter2(Local<String> name,
+static void PGetter2(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
p_getter_count2++;
@@ -7761,7 +8276,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate);
- obj->SetNamedPropertyHandler(PGetter2);
+ obj->SetHandler(v8::NamedPropertyHandlerConfiguration(PGetter2));
p_getter_count2 = 0;
RunHolderTest(obj);
CHECK_EQ(40, p_getter_count2);
@@ -8419,6 +8934,85 @@
}
+static void ThrowV8Exception(const v8::FunctionCallbackInfo<v8::Value>& info) {
+ ApiTestFuzzer::Fuzz();
+ v8::Handle<String> foo = v8_str("foo");
+ v8::Handle<String> message = v8_str("message");
+ v8::Handle<Value> error = v8::Exception::Error(foo);
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message)->Equals(foo));
+ info.GetIsolate()->ThrowException(error);
+ info.GetReturnValue().SetUndefined();
+}
+
+
+THREADED_TEST(ExceptionCreateMessage) {
+ LocalContext context;
+ v8::HandleScope scope(context->GetIsolate());
+ v8::Handle<String> foo_str = v8_str("foo");
+ v8::Handle<String> message_str = v8_str("message");
+
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+ Local<v8::FunctionTemplate> fun =
+ v8::FunctionTemplate::New(context->GetIsolate(), ThrowV8Exception);
+ v8::Local<v8::Object> global = context->Global();
+ global->Set(v8_str("throwV8Exception"), fun->GetFunction());
+
+ TryCatch try_catch;
+ CompileRun(
+ "function f1() {\n"
+ " throwV8Exception();\n"
+ "};\n"
+ "f1();");
+ CHECK(try_catch.HasCaught());
+
+ v8::Handle<v8::Value> error = try_catch.Exception();
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+ v8::Handle<v8::Message> message = v8::Exception::CreateMessage(error);
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(2, message->GetStartColumn());
+
+ v8::Handle<v8::StackTrace> stackTrace = message->GetStackTrace();
+ CHECK(!stackTrace.IsEmpty());
+ CHECK_EQ(2, stackTrace->GetFrameCount());
+
+ stackTrace = v8::Exception::GetStackTrace(error);
+ CHECK(!stackTrace.IsEmpty());
+ CHECK_EQ(2, stackTrace->GetFrameCount());
+
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+
+ // Now check message location when SetCaptureStackTraceForUncaughtExceptions
+ // is false.
+ try_catch.Reset();
+
+ CompileRun(
+ "function f2() {\n"
+ " return throwV8Exception();\n"
+ "};\n"
+ "f2();");
+ CHECK(try_catch.HasCaught());
+
+ error = try_catch.Exception();
+ CHECK(error->IsObject());
+ CHECK(error.As<v8::Object>()->Get(message_str)->Equals(foo_str));
+
+ message = v8::Exception::CreateMessage(error);
+ CHECK(!message.IsEmpty());
+ CHECK_EQ(2, message->GetLineNumber());
+ CHECK_EQ(9, message->GetStartColumn());
+
+ // Should be empty stack trace.
+ stackTrace = message->GetStackTrace();
+ CHECK(stackTrace.IsEmpty());
+ CHECK(v8::Exception::GetStackTrace(error).IsEmpty());
+}
+
+
static void YGetter(Local<String> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
@@ -8532,6 +9126,33 @@
v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener);
}
+
+TEST(ApiUncaughtExceptionInObjectObserve) {
+ v8::internal::FLAG_stack_size = 150;
+ report_count = 0;
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+ v8::V8::AddMessageListener(ApiUncaughtExceptionTestListener);
+ CompileRun(
+ "var obj = {};"
+ "var observe_count = 0;"
+ "function observer1() { ++observe_count; };"
+ "function observer2() { ++observe_count; };"
+ "function observer_throws() { throw new Error(); };"
+ "function stack_overflow() { return (function f(x) { f(x+1); })(0); };"
+ "Object.observe(obj, observer_throws.bind());"
+ "Object.observe(obj, observer1);"
+ "Object.observe(obj, stack_overflow);"
+ "Object.observe(obj, observer2);"
+ "Object.observe(obj, observer_throws.bind());"
+ "obj.foo = 'bar';");
+ CHECK_EQ(3, report_count);
+ ExpectInt32("observe_count", 2);
+ v8::V8::RemoveMessageListeners(ApiUncaughtExceptionTestListener);
+}
+
+
static const char* script_resource_name = "ExceptionInNativeScript.js";
static void ExceptionInNativeScriptTestListener(v8::Handle<v8::Message> message,
v8::Handle<Value>) {
@@ -8603,7 +9224,7 @@
void CEvaluate(const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
- CompileRun(args[0]->ToString());
+ CompileRun(args[0]->ToString(args.GetIsolate()));
}
@@ -8877,11 +9498,11 @@
CHECK(indexed_security_check_with_gc_called);
named_security_check_with_gc_called = false;
- CHECK(CompileRun("obj.foo")->ToString()->Equals(v8_str("1001")));
+ CHECK(CompileRun("obj.foo")->ToString(isolate)->Equals(v8_str("1001")));
CHECK(named_security_check_with_gc_called);
indexed_security_check_with_gc_called = false;
- CHECK(CompileRun("obj[0]")->ToString()->Equals(v8_str("1002")));
+ CHECK(CompileRun("obj[0]")->ToString(isolate)->Equals(v8_str("1002")));
CHECK(indexed_security_check_with_gc_called);
}
@@ -9609,20 +10230,52 @@
LocalContext env;
env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
- v8::TryCatch try_catch;
- CompileRun(
- "function f() { return super.hasOwnProperty; };"
- "var m = f.toMethod(prohibited);"
- "m();");
- CHECK(try_catch.HasCaught());
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { return super.hasOwnProperty; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { return super[42]; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { super.hasOwnProperty = function () {}; };"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "Object.defineProperty(Object.prototype, 'x', { set : function(){}});"
+ "function f() { "
+ " 'use strict';"
+ " super.x = function () {}; "
+ "};"
+ "var m = f.toMethod(prohibited);"
+ "m();");
+ CHECK(try_catch.HasCaught());
+ }
}
static void IndexedPropertyEnumerator(
const v8::PropertyCallbackInfo<v8::Array>& info) {
- v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
+ v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 1);
result->Set(0, v8::Integer::New(info.GetIsolate(), 7));
- result->Set(1, v8::Object::New(info.GetIsolate()));
info.GetReturnValue().Set(result);
}
@@ -9631,7 +10284,7 @@
const v8::PropertyCallbackInfo<v8::Array>& info) {
v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2);
result->Set(0, v8_str("x"));
- result->Set(1, v8::Object::New(info.GetIsolate()));
+ result->Set(1, v8::Symbol::GetIterator(info.GetIsolate()));
info.GetReturnValue().Set(result);
}
@@ -9644,10 +10297,10 @@
obj_template->Set(v8_str("7"), v8::Integer::New(CcTest::isolate(), 7));
obj_template->Set(v8_str("x"), v8::Integer::New(CcTest::isolate(), 42));
- obj_template->SetIndexedPropertyHandler(NULL, NULL, NULL, NULL,
- IndexedPropertyEnumerator);
- obj_template->SetNamedPropertyHandler(NULL, NULL, NULL, NULL,
- NamedPropertyEnumerator);
+ obj_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ NULL, NULL, NULL, NULL, IndexedPropertyEnumerator));
+ obj_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NULL, NULL, NULL, NULL, NamedPropertyEnumerator));
LocalContext context;
v8::Handle<v8::Object> global = context->Global();
@@ -9657,13 +10310,26 @@
CompileRun("Object.getOwnPropertyNames(object)");
CHECK(result->IsArray());
v8::Handle<v8::Array> result_array = v8::Handle<v8::Array>::Cast(result);
- CHECK_EQ(3, result_array->Length());
+ CHECK_EQ(2, result_array->Length());
CHECK(result_array->Get(0)->IsString());
CHECK(result_array->Get(1)->IsString());
- CHECK(result_array->Get(2)->IsString());
CHECK_EQ(v8_str("7"), result_array->Get(0));
- CHECK_EQ(v8_str("[object Object]"), result_array->Get(1));
- CHECK_EQ(v8_str("x"), result_array->Get(2));
+ CHECK_EQ(v8_str("x"), result_array->Get(1));
+
+ result = CompileRun("var ret = []; for (var k in object) ret.push(k); ret");
+ CHECK(result->IsArray());
+ result_array = v8::Handle<v8::Array>::Cast(result);
+ CHECK_EQ(2, result_array->Length());
+ CHECK(result_array->Get(0)->IsString());
+ CHECK(result_array->Get(1)->IsString());
+ CHECK_EQ(v8_str("7"), result_array->Get(0));
+ CHECK_EQ(v8_str("x"), result_array->Get(1));
+
+ result = CompileRun("Object.getOwnPropertySymbols(object)");
+ CHECK(result->IsArray());
+ result_array = v8::Handle<v8::Array>::Cast(result);
+ CHECK_EQ(1, result_array->Length());
+ CHECK_EQ(result_array->Get(0), v8::Symbol::GetIterator(isolate));
}
@@ -9937,15 +10603,13 @@
static void AccessControlNamedGetter(
- Local<String>,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name>, const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(42);
}
static void AccessControlNamedSetter(
- Local<String>,
- Local<Value> value,
+ Local<Name>, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(value);
}
@@ -9984,10 +10648,10 @@
v8::ObjectTemplate::New(isolate);
object_template->SetAccessCheckCallbacks(NamedAccessCounter,
IndexedAccessCounter);
- object_template->SetNamedPropertyHandler(AccessControlNamedGetter,
- AccessControlNamedSetter);
- object_template->SetIndexedPropertyHandler(AccessControlIndexedGetter,
- AccessControlIndexedSetter);
+ object_template->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ AccessControlNamedGetter, AccessControlNamedSetter));
+ object_template->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ AccessControlIndexedGetter, AccessControlIndexedSetter));
Local<v8::Object> object = object_template->NewInstance();
v8::HandleScope scope1(isolate);
@@ -10069,8 +10733,7 @@
static void GlobalObjectInstancePropertiesGet(
- Local<String> key,
- const v8::PropertyCallbackInfo<v8::Value>&) {
+ Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>&) {
ApiTestFuzzer::Fuzz();
}
@@ -10082,8 +10745,8 @@
Local<Value> global_object;
Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
- t->InstanceTemplate()->SetNamedPropertyHandler(
- GlobalObjectInstancePropertiesGet);
+ t->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(GlobalObjectInstancePropertiesGet));
Local<ObjectTemplate> instance_template = t->InstanceTemplate();
instance_template->Set(v8_str("x"), v8_num(42));
instance_template->Set(v8_str("f"),
@@ -10207,9 +10870,8 @@
}
-static void ShadowNamedGet(Local<String> key,
- const v8::PropertyCallbackInfo<v8::Value>&) {
-}
+static void ShadowNamedGet(Local<Name> key,
+ const v8::PropertyCallbackInfo<v8::Value>&) {}
THREADED_TEST(ShadowObject) {
@@ -10221,8 +10883,10 @@
LocalContext context(NULL, global_template);
Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate);
- t->InstanceTemplate()->SetNamedPropertyHandler(ShadowNamedGet);
- t->InstanceTemplate()->SetIndexedPropertyHandler(ShadowIndexedGet);
+ t->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(ShadowNamedGet));
+ t->InstanceTemplate()->SetHandler(
+ v8::IndexedPropertyHandlerConfiguration(ShadowIndexedGet));
Local<ObjectTemplate> proto = t->PrototypeTemplate();
Local<ObjectTemplate> instance = t->InstanceTemplate();
@@ -10709,7 +11373,7 @@
"(function() { var o = new obj('tipli'); return o.a; })()");
CHECK(!try_catch.HasCaught());
CHECK(value->IsString());
- String::Utf8Value string_value1(value->ToString());
+ String::Utf8Value string_value1(value->ToString(isolate));
CHECK_EQ("tipli", *string_value1);
Local<Value> args2[] = { v8_str("tipli") };
@@ -10719,7 +11383,7 @@
value = object2->Get(v8_str("a"));
CHECK(!try_catch.HasCaught());
CHECK(value->IsString());
- String::Utf8Value string_value2(value->ToString());
+ String::Utf8Value string_value2(value->ToString(isolate));
CHECK_EQ("tipli", *string_value2);
// Call the Object's constructor with a Boolean.
@@ -10982,8 +11646,7 @@
// Test that calling eval in a context which has been detached from
-// its global throws an exception. This behavior is consistent with
-// other JavaScript implementations.
+// its global proxy works.
THREADED_TEST(EvalInDetachedGlobal) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
@@ -11011,8 +11674,7 @@
context0->DetachGlobal();
v8::TryCatch catcher;
x_value = CompileRun("fun('x')");
- CHECK(x_value.IsEmpty());
- CHECK(catcher.HasCaught());
+ CHECK_EQ(42, x_value->Int32Value());
context1->Exit();
}
@@ -11330,8 +11992,7 @@
static void InterceptorHasOwnPropertyGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
}
@@ -11342,7 +12003,8 @@
v8::HandleScope scope(isolate);
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
- instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetter);
+ instance_templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetter));
Local<Function> function = fun_templ->GetFunction();
context->Global()->Set(v8_str("constructor"), function);
v8::Handle<Value> value = CompileRun(
@@ -11361,8 +12023,7 @@
static void InterceptorHasOwnPropertyGetterGC(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags);
}
@@ -11374,7 +12035,8 @@
v8::HandleScope scope(isolate);
Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate);
Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate();
- instance_templ->SetNamedPropertyHandler(InterceptorHasOwnPropertyGetterGC);
+ instance_templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetterGC));
Local<Function> function = fun_templ->GetFunction();
context->Global()->Set(v8_str("constructor"), function);
// Let's first make some stuff so we can be sure to get a good GC.
@@ -11398,18 +12060,14 @@
}
-typedef void (*NamedPropertyGetter)(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info);
-
-
-static void CheckInterceptorLoadIC(NamedPropertyGetter getter,
- const char* source,
- int expected) {
+static void CheckInterceptorLoadIC(
+ v8::GenericNamedPropertyGetterCallback getter, const char* source,
+ int expected) {
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(getter, 0, 0, 0, 0, v8_str("data"));
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(getter, 0, 0, 0, 0,
+ v8_str("data")));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(source);
@@ -11418,8 +12076,7 @@
static void InterceptorLoadICGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
v8::Isolate* isolate = CcTest::isolate();
CHECK_EQ(isolate, info.GetIsolate());
@@ -11445,8 +12102,7 @@
// (those cases are special cased to get better performance).
static void InterceptorLoadXICGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
info.GetReturnValue().Set(
v8_str("x")->Equals(name) ?
@@ -11561,8 +12217,7 @@
static int interceptor_load_not_handled_calls = 0;
static void InterceptorLoadNotHandled(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
++interceptor_load_not_handled_calls;
}
@@ -11623,7 +12278,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
templ->SetAccessor(v8_str("y"), Return239Callback);
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
@@ -11653,7 +12309,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ_o->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback);
@@ -11687,7 +12344,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
templ->SetAccessor(v8_str("y"), Return239Callback);
LocalContext context;
@@ -11716,7 +12374,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ_o->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback);
@@ -11745,7 +12404,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ_o->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
@@ -11778,7 +12438,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ_o->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate);
templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis);
@@ -11804,8 +12465,7 @@
static void InterceptorLoadICGetter0(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("x")->Equals(name));
info.GetReturnValue().Set(v8::Integer::New(info.GetIsolate(), 0));
@@ -11820,8 +12480,7 @@
static void InterceptorStoreICSetter(
- Local<String> key,
- Local<Value> value,
+ Local<Name> key, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(v8_str("x")->Equals(key));
CHECK_EQ(42, value->Int32Value());
@@ -11834,9 +12493,9 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorLoadICGetter,
- InterceptorStoreICSetter,
- 0, 0, 0, v8_str("data"));
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0,
+ v8_str("data")));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
CompileRun(
@@ -11850,7 +12509,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -11869,8 +12529,7 @@
v8::Handle<Value> call_ic_function3;
static void InterceptorCallICGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("x")->Equals(name));
info.GetReturnValue().Set(call_ic_function);
@@ -11882,7 +12541,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorCallICGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
call_ic_function =
@@ -11902,7 +12562,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -11917,8 +12577,7 @@
static v8::Handle<Value> call_ic_function4;
static void InterceptorCallICGetter4(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CHECK(v8_str("x")->Equals(name));
info.GetReturnValue().Set(call_ic_function4);
@@ -11932,7 +12591,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorCallICGetter4);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter4));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
call_ic_function4 =
@@ -11953,7 +12613,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -11981,7 +12641,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -11998,8 +12658,7 @@
static v8::Handle<Value> call_ic_function5;
static void InterceptorCallICGetter5(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name))
info.GetReturnValue().Set(call_ic_function5);
@@ -12013,7 +12672,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorCallICGetter5);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter5));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
call_ic_function5 =
@@ -12032,8 +12692,7 @@
static v8::Handle<Value> call_ic_function6;
static void InterceptorCallICGetter6(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name))
info.GetReturnValue().Set(call_ic_function6);
@@ -12047,7 +12706,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorCallICGetter6);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter6));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
call_ic_function6 =
@@ -12078,7 +12738,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -12109,7 +12769,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
v8::Handle<Value> value = CompileRun(
@@ -12135,7 +12795,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+ templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
@@ -12160,8 +12820,7 @@
}
static void InterceptorCallICFastApi(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
CheckReturnValue(info, FUNCTION_ADDR(InterceptorCallICFastApi));
int* call_count =
@@ -12350,9 +13009,9 @@
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12380,9 +13039,9 @@
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12413,9 +13072,9 @@
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12452,9 +13111,9 @@
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12491,9 +13150,9 @@
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12515,7 +13174,7 @@
CHECK(try_catch.HasCaught());
// TODO(verwaest): Adjust message.
CHECK_EQ(v8_str("TypeError: undefined is not a function"),
- try_catch.Exception()->ToString());
+ try_catch.Exception()->ToString(isolate));
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
CHECK_GE(interceptor_call_count, 50);
}
@@ -12534,9 +13193,9 @@
proto_templ->Set(v8_str("method"), method_templ);
fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
- templ->SetNamedPropertyHandler(
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
InterceptorCallICFastApi, NULL, NULL, NULL, NULL,
- v8::External::New(isolate, &interceptor_call_count));
+ v8::External::New(isolate, &interceptor_call_count)));
LocalContext context;
v8::Handle<v8::Function> fun = fun_templ->GetFunction();
GenerateSomeGarbage();
@@ -12557,7 +13216,7 @@
"}");
CHECK(try_catch.HasCaught());
CHECK_EQ(v8_str("TypeError: Illegal invocation"),
- try_catch.Exception()->ToString());
+ try_catch.Exception()->ToString(isolate));
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
CHECK_GE(interceptor_call_count, 50);
}
@@ -12690,7 +13349,7 @@
CHECK(try_catch.HasCaught());
// TODO(verwaest): Adjust message.
CHECK_EQ(v8_str("TypeError: undefined is not a function"),
- try_catch.Exception()->ToString());
+ try_catch.Exception()->ToString(isolate));
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
@@ -12728,7 +13387,7 @@
"}");
CHECK(try_catch.HasCaught());
CHECK_EQ(v8_str("TypeError: Illegal invocation"),
- try_catch.Exception()->ToString());
+ try_catch.Exception()->ToString(isolate));
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
@@ -12736,8 +13395,7 @@
v8::Handle<Value> keyed_call_ic_function;
static void InterceptorKeyedCallICGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name)) {
info.GetReturnValue().Set(keyed_call_ic_function);
@@ -12751,7 +13409,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
CompileRun(
@@ -12776,7 +13434,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorKeyedCallICGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorKeyedCallICGetter));
LocalContext context;
context->Global()->Set(v8_str("proto1"), templ->NewInstance());
keyed_call_ic_function =
@@ -12804,7 +13463,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NoBlockGetterX);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ->NewInstance());
CompileRun(
@@ -12830,7 +13489,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+ templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
@@ -12856,7 +13515,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+ templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("proto"), templ_o->NewInstance());
@@ -12879,7 +13538,7 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate);
- templ_o->SetNamedPropertyHandler(NoBlockGetterX);
+ templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX));
LocalContext context;
context->Global()->Set(v8_str("o"), templ_o->NewInstance());
@@ -12900,8 +13559,7 @@
static int interceptor_call_count = 0;
static void InterceptorICRefErrorGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name) && interceptor_call_count++ < 20) {
info.GetReturnValue().Set(call_ic_function2);
@@ -12916,7 +13574,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorICRefErrorGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorICRefErrorGetter));
LocalContext context(0, templ, v8::Handle<Value>());
call_ic_function2 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
@@ -12944,8 +13603,7 @@
static int interceptor_ic_exception_get_count = 0;
static void InterceptorICExceptionGetter(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (v8_str("x")->Equals(name) && ++interceptor_ic_exception_get_count < 20) {
info.GetReturnValue().Set(call_ic_function3);
@@ -12964,7 +13622,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(InterceptorICExceptionGetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorICExceptionGetter));
LocalContext context(0, templ, v8::Handle<Value>());
call_ic_function3 = v8_compile("function h(x) { return x; }; h")->Run();
v8::Handle<Value> value = CompileRun(
@@ -12992,9 +13651,8 @@
static int interceptor_ic_exception_set_count = 0;
static void InterceptorICExceptionSetter(
- Local<String> key,
- Local<Value> value,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> key, Local<Value> value,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
ApiTestFuzzer::Fuzz();
if (++interceptor_ic_exception_set_count > 20) {
info.GetIsolate()->ThrowException(v8_num(42));
@@ -13009,7 +13667,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(0, InterceptorICExceptionSetter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(0, InterceptorICExceptionSetter));
LocalContext context(0, templ, v8::Handle<Value>());
v8::Handle<Value> value = CompileRun(
"function f() {"
@@ -13028,8 +13687,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(
- static_cast<v8::NamedPropertyGetterCallback>(0));
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ static_cast<v8::GenericNamedPropertyGetterCallback>(0)));
LocalContext context;
templ->Set(CcTest::isolate(), "x", v8_num(42));
v8::Handle<v8::Object> obj = templ->NewInstance();
@@ -13045,8 +13704,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(
- static_cast<v8::IndexedPropertyGetterCallback>(0));
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ static_cast<v8::IndexedPropertyGetterCallback>(0)));
LocalContext context;
templ->Set(CcTest::isolate(), "42", v8_num(42));
v8::Handle<v8::Object> obj = templ->NewInstance();
@@ -13061,7 +13720,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
- templ->InstanceTemplate()->SetNamedPropertyHandler(InterceptorLoadXICGetter);
+ templ->InstanceTemplate()->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter));
LocalContext env;
env->Global()->Set(v8_str("obj"),
templ->GetFunction()->NewInstance());
@@ -13315,7 +13975,7 @@
// Normal ToString call should call replaced Object.prototype.toString
Local<v8::Object> instance = templ->GetFunction()->NewInstance();
- Local<String> value = instance->ToString();
+ Local<String> value = instance->ToString(isolate);
CHECK(value->IsString() && value->Equals(customized_tostring));
// ObjectProtoToString should not call replace toString function.
@@ -13333,9 +13993,127 @@
}
-THREADED_TEST(ObjectGetConstructorName) {
+TEST(ObjectProtoToStringES6) {
+ // TODO(dslomov, caitp): merge into ObjectProtoToString test once shipped.
+ i::FLAG_harmony_tostring = true;
LocalContext context;
- v8::HandleScope scope(context->GetIsolate());
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope scope(isolate);
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate);
+ templ->SetClassName(v8_str("MyClass"));
+
+ Local<String> customized_tostring = v8_str("customized toString");
+
+ // Replace Object.prototype.toString
+ CompileRun(
+ "Object.prototype.toString = function() {"
+ " return 'customized toString';"
+ "}");
+
+ // Normal ToString call should call replaced Object.prototype.toString
+ Local<v8::Object> instance = templ->GetFunction()->NewInstance();
+ Local<String> value = instance->ToString(isolate);
+ CHECK(value->IsString() && value->Equals(customized_tostring));
+
+ // ObjectProtoToString should not call replace toString function.
+ value = instance->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object MyClass]")));
+
+ // Check global
+ value = context->Global()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object global]")));
+
+ // Check ordinary object
+ Local<Value> object = CompileRun("new Object()");
+ value = object.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Object]")));
+
+ // Check that ES6 semantics using @@toStringTag work
+ Local<v8::Symbol> toStringTag = v8::Symbol::GetToStringTag(isolate);
+
+#define TEST_TOSTRINGTAG(type, tag, expected) \
+ do { \
+ object = CompileRun("new " #type "()"); \
+ object.As<v8::Object>()->Set(toStringTag, v8_str(#tag)); \
+ value = object.As<v8::Object>()->ObjectProtoToString(); \
+ CHECK(value->IsString() && \
+ value->Equals(v8_str("[object " #expected "]"))); \
+ } while (0)
+
+ TEST_TOSTRINGTAG(Array, Object, Object);
+ TEST_TOSTRINGTAG(Object, Arguments, ~Arguments);
+ TEST_TOSTRINGTAG(Object, Array, ~Array);
+ TEST_TOSTRINGTAG(Object, Boolean, ~Boolean);
+ TEST_TOSTRINGTAG(Object, Date, ~Date);
+ TEST_TOSTRINGTAG(Object, Error, ~Error);
+ TEST_TOSTRINGTAG(Object, Function, ~Function);
+ TEST_TOSTRINGTAG(Object, Number, ~Number);
+ TEST_TOSTRINGTAG(Object, RegExp, ~RegExp);
+ TEST_TOSTRINGTAG(Object, String, ~String);
+ TEST_TOSTRINGTAG(Object, Foo, Foo);
+
+#undef TEST_TOSTRINGTAG
+
+ // @@toStringTag getter throws
+ Local<Value> obj = v8::Object::New(isolate);
+ obj.As<v8::Object>()->SetAccessor(toStringTag, ThrowingSymbolAccessorGetter);
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+
+ // @@toStringTag getter does not throw
+ obj = v8::Object::New(isolate);
+ obj.As<v8::Object>()->SetAccessor(
+ toStringTag, SymbolAccessorGetterReturnsDefault, 0, v8_str("Test"));
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag value
+ obj = CompileRun("obj = {}; obj[Symbol.toStringTag] = 'Test'; obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag getter throws
+ obj = CompileRun(
+ "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+ " get: function() { throw 'Test'; }"
+ "}); obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ }
+
+ // JS @@toStringTag getter does not throw
+ obj = CompileRun(
+ "obj = {}; Object.defineProperty(obj, Symbol.toStringTag, {"
+ " get: function() { return 'Test'; }"
+ "}); obj");
+ {
+ TryCatch try_catch;
+ value = obj.As<v8::Object>()->ObjectProtoToString();
+ CHECK(value->IsString() && value->Equals(v8_str("[object Test]")));
+ CHECK(!try_catch.HasCaught());
+ }
+}
+
+
+THREADED_TEST(ObjectGetConstructorName) {
+ v8::Isolate* isolate = CcTest::isolate();
+ LocalContext context;
+ v8::HandleScope scope(isolate);
v8_compile("function Parent() {};"
"function Child() {};"
"Child.prototype = new Parent();"
@@ -13345,16 +14123,17 @@
"var x = new outer.inner();")->Run();
Local<v8::Value> p = context->Global()->Get(v8_str("p"));
- CHECK(p->IsObject() && p->ToObject()->GetConstructorName()->Equals(
- v8_str("Parent")));
+ CHECK(p->IsObject() &&
+ p->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Parent")));
Local<v8::Value> c = context->Global()->Get(v8_str("c"));
- CHECK(c->IsObject() && c->ToObject()->GetConstructorName()->Equals(
- v8_str("Child")));
+ CHECK(c->IsObject() &&
+ c->ToObject(isolate)->GetConstructorName()->Equals(v8_str("Child")));
Local<v8::Value> x = context->Global()->Get(v8_str("x"));
- CHECK(x->IsObject() && x->ToObject()->GetConstructorName()->Equals(
- v8_str("outer.inner")));
+ CHECK(x->IsObject() &&
+ x->ToObject(isolate)->GetConstructorName()->Equals(
+ v8_str("outer.inner")));
}
@@ -13902,7 +14681,7 @@
v8::Local<Context> env = Context::New(isolate);
env->Enter();
v8::Handle<Value> value = NestedScope(env);
- v8::Handle<String> str(value->ToString());
+ v8::Handle<String> str(value->ToString(isolate));
CHECK(!str.IsEmpty());
env->Exit();
}
@@ -14744,7 +15523,7 @@
v8::Handle<v8::Array> props = val.As<v8::Object>()->GetPropertyNames();
CHECK_EQ(0, props->Length());
for (uint32_t i = 0; i < props->Length(); i++) {
- printf("p[%d]\n", i);
+ printf("p[%u]\n", i);
}
}
@@ -15291,7 +16070,7 @@
#ifndef V8_INTERPRETED_REGEXP
struct RegExpInterruptionData {
- int loop_count;
+ v8::base::Atomic32 loop_count;
UC16VectorResource* string_resource;
v8::Persistent<v8::String> string;
} regexp_interruption_data;
@@ -15303,9 +16082,10 @@
: Thread(Options("TimeoutThread")), isolate_(isolate) {}
virtual void Run() {
- for (regexp_interruption_data.loop_count = 0;
- regexp_interruption_data.loop_count < 7;
- regexp_interruption_data.loop_count++) {
+ for (v8::base::NoBarrier_Store(®exp_interruption_data.loop_count, 0);
+ v8::base::NoBarrier_Load(®exp_interruption_data.loop_count) < 7;
+ v8::base::NoBarrier_AtomicIncrement(
+ ®exp_interruption_data.loop_count, 1)) {
v8::base::OS::Sleep(50); // Wait a bit before requesting GC.
reinterpret_cast<i::Isolate*>(isolate_)->stack_guard()->RequestGC();
}
@@ -15319,7 +16099,9 @@
void RunBeforeGC(v8::GCType type, v8::GCCallbackFlags flags) {
- if (regexp_interruption_data.loop_count != 2) return;
+ if (v8::base::NoBarrier_Load(®exp_interruption_data.loop_count) != 2) {
+ return;
+ }
v8::HandleScope scope(CcTest::isolate());
v8::Local<v8::String> string = v8::Local<v8::String>::New(
CcTest::isolate(), regexp_interruption_data.string);
@@ -15407,9 +16189,14 @@
force_set_set_count++;
}
+static void ForceSetInterceptGetter(
+ v8::Local<v8::Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
+ CHECK(name->IsString());
+ ForceSetGetter(Local<String>::Cast(name), info);
+}
+
static void ForceSetInterceptSetter(
- v8::Local<v8::String> name,
- v8::Local<v8::Value> value,
+ v8::Local<v8::Name> name, v8::Local<v8::Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
force_set_set_count++;
info.GetReturnValue().SetUndefined();
@@ -15469,7 +16256,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(ForceSetGetter, ForceSetInterceptSetter);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ ForceSetInterceptGetter, ForceSetInterceptSetter));
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
@@ -15537,7 +16325,7 @@
static void ForceDeleteDeleter(
- v8::Local<v8::String> name,
+ v8::Local<v8::Name> name,
const v8::PropertyCallbackInfo<v8::Boolean>& info) {
force_delete_interceptor_count++;
if (pass_on_delete) return;
@@ -15552,7 +16340,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(0, 0, 0, ForceDeleteDeleter);
+ templ->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(0, 0, 0, ForceDeleteDeleter));
LocalContext context(NULL, templ);
v8::Handle<v8::Object> global = context->Global();
@@ -16195,8 +16984,8 @@
}
v8::Handle<v8::ObjectTemplate> templ =
v8::ObjectTemplate::New(context->GetIsolate());
- templ->SetIndexedPropertyHandler(NotHandledIndexedPropertyGetter,
- NotHandledIndexedPropertySetter);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ NotHandledIndexedPropertyGetter, NotHandledIndexedPropertySetter));
v8::Handle<v8::Object> obj = templ->NewInstance();
obj->SetIndexedPropertiesToPixelData(pixel_data, kElementCount);
context->Global()->Set(v8_str("pixels"), obj);
@@ -17335,6 +18124,7 @@
static void StackTraceForUncaughtExceptionListener(
v8::Handle<v8::Message> message,
v8::Handle<Value>) {
+ report_count++;
v8::Handle<v8::StackTrace> stack_trace = message->GetStackTrace();
CHECK_EQ(2, stack_trace->GetFrameCount());
checkStackFrame("origin", "foo", 2, 3, false, false,
@@ -17365,6 +18155,38 @@
Function::Cast(*trouble)->Call(global, 0, NULL);
v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+ CHECK_EQ(1, report_count);
+}
+
+
+TEST(GetStackTraceForUncaughtExceptionFromSimpleStackTrace) {
+ report_count = 0;
+ LocalContext env;
+ v8::HandleScope scope(env->GetIsolate());
+
+ // Create an Error object first.
+ CompileRunWithOrigin(
+ "function foo() {\n"
+ "e=new Error('err');\n"
+ "};\n"
+ "function bar() {\n"
+ " foo();\n"
+ "};\n"
+ "var e;",
+ "origin");
+ v8::Local<v8::Object> global = env->Global();
+ Local<Value> trouble = global->Get(v8_str("bar"));
+ CHECK(trouble->IsFunction());
+ Function::Cast(*trouble)->Call(global, 0, NULL);
+
+ // Enable capturing detailed stack trace late, and throw the exception.
+ // The detailed stack trace should be extracted from the simple stack.
+ v8::V8::AddMessageListener(StackTraceForUncaughtExceptionListener);
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true);
+ CompileRunWithOrigin("throw e", "origin");
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+ v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener);
+ CHECK_EQ(1, report_count);
}
@@ -17519,6 +18341,343 @@
}
+v8::PromiseRejectEvent reject_event = v8::kPromiseRejectWithNoHandler;
+int promise_reject_counter = 0;
+int promise_revoke_counter = 0;
+int promise_reject_line_number = -1;
+int promise_reject_frame_count = -1;
+
+void PromiseRejectCallback(v8::PromiseRejectMessage message) {
+ if (message.GetEvent() == v8::kPromiseRejectWithNoHandler) {
+ promise_reject_counter++;
+ CcTest::global()->Set(v8_str("rejected"), message.GetPromise());
+ CcTest::global()->Set(v8_str("value"), message.GetValue());
+ v8::Handle<v8::StackTrace> stack_trace =
+ v8::Exception::CreateMessage(message.GetValue())->GetStackTrace();
+ if (!stack_trace.IsEmpty()) {
+ promise_reject_frame_count = stack_trace->GetFrameCount();
+ if (promise_reject_frame_count > 0) {
+ CHECK(stack_trace->GetFrame(0)->GetScriptName()->Equals(v8_str("pro")));
+ promise_reject_line_number = stack_trace->GetFrame(0)->GetLineNumber();
+ } else {
+ promise_reject_line_number = -1;
+ }
+ }
+ } else {
+ promise_revoke_counter++;
+ CcTest::global()->Set(v8_str("revoked"), message.GetPromise());
+ CHECK(message.GetValue().IsEmpty());
+ }
+}
+
+
+v8::Handle<v8::Promise> GetPromise(const char* name) {
+ return v8::Handle<v8::Promise>::Cast(CcTest::global()->Get(v8_str(name)));
+}
+
+
+v8::Handle<v8::Value> RejectValue() {
+ return CcTest::global()->Get(v8_str("value"));
+}
+
+
+void ResetPromiseStates() {
+ promise_reject_counter = 0;
+ promise_revoke_counter = 0;
+ promise_reject_line_number = -1;
+ promise_reject_frame_count = -1;
+ CcTest::global()->Set(v8_str("rejected"), v8_str(""));
+ CcTest::global()->Set(v8_str("value"), v8_str(""));
+ CcTest::global()->Set(v8_str("revoked"), v8_str(""));
+}
+
+
+TEST(PromiseRejectCallback) {
+ LocalContext env;
+ v8::Isolate* isolate = env->GetIsolate();
+ v8::HandleScope scope(isolate);
+
+ isolate->SetPromiseRejectCallback(PromiseRejectCallback);
+
+ ResetPromiseStates();
+
+ // Create promise p0.
+ CompileRun(
+ "var reject; \n"
+ "var p0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n");
+ CHECK(!GetPromise("p0")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add resolve handler (and default reject handler) to p0.
+ CompileRun("var p1 = p0.then(function(){});");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject p0.
+ CompileRun("reject('ppp');");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(v8::kPromiseRejectWithNoHandler, reject_event);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("p1")));
+ CHECK(RejectValue()->Equals(v8_str("ppp")));
+
+ // Reject p0 again. Callback is not triggered again.
+ CompileRun("reject();");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(!GetPromise("p1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add resolve handler to p1.
+ CompileRun("var p2 = p1.then(function(){});");
+ CHECK(GetPromise("p0")->HasHandler());
+ CHECK(GetPromise("p1")->HasHandler());
+ CHECK(!GetPromise("p2")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("p2")));
+ CHECK(RejectValue()->Equals(v8_str("ppp")));
+ CHECK(GetPromise("revoked")->Equals(GetPromise("p1")));
+
+ ResetPromiseStates();
+
+ // Create promise q0.
+ CompileRun(
+ "var q0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n");
+ CHECK(!GetPromise("q0")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add reject handler to q0.
+ CompileRun("var q1 = q0.catch(function() {});");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject q0.
+ CompileRun("reject('qq')");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Add a new reject handler, which rejects by returning Promise.reject().
+ // The returned promise q_ triggers a reject callback at first, only to
+ // revoke it when returning it causes q2 to be rejected.
+ CompileRun(
+ "var q_;"
+ "var q2 = q0.catch( \n"
+ " function() { \n"
+ " q_ = Promise.reject('qqq'); \n"
+ " return q_; \n"
+ " } \n"
+ "); \n");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(!GetPromise("q1")->HasHandler());
+ CHECK(!GetPromise("q2")->HasHandler());
+ CHECK(GetPromise("q_")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("q2")));
+ CHECK(GetPromise("revoked")->Equals(GetPromise("q_")));
+ CHECK(RejectValue()->Equals(v8_str("qqq")));
+
+ // Add a reject handler to the resolved q1, which rejects by throwing.
+ CompileRun(
+ "var q3 = q1.then( \n"
+ " function() { \n"
+ " throw 'qqqq'; \n"
+ " } \n"
+ "); \n");
+ CHECK(GetPromise("q0")->HasHandler());
+ CHECK(GetPromise("q1")->HasHandler());
+ CHECK(!GetPromise("q2")->HasHandler());
+ CHECK(!GetPromise("q3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("q3")));
+ CHECK(RejectValue()->Equals(v8_str("qqqq")));
+
+ ResetPromiseStates();
+
+ // Create promise r0, which has three handlers, two of which handle rejects.
+ CompileRun(
+ "var r0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n"
+ "var r1 = r0.catch(function() {}); \n"
+ "var r2 = r0.then(function() {}); \n"
+ "var r3 = r0.then(function() {}, \n"
+ " function() {}); \n");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(!GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject r0.
+ CompileRun("reject('rrr')");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(!GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK(GetPromise("rejected")->Equals(GetPromise("r2")));
+ CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+ // Add reject handler to r2.
+ CompileRun("var r4 = r2.catch(function() {});");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK(!GetPromise("r4")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK(GetPromise("revoked")->Equals(GetPromise("r2")));
+ CHECK(RejectValue()->Equals(v8_str("rrr")));
+
+ // Add reject handlers to r4.
+ CompileRun("var r5 = r4.then(function() {}, function() {});");
+ CHECK(GetPromise("r0")->HasHandler());
+ CHECK(!GetPromise("r1")->HasHandler());
+ CHECK(GetPromise("r2")->HasHandler());
+ CHECK(!GetPromise("r3")->HasHandler());
+ CHECK(GetPromise("r4")->HasHandler());
+ CHECK(!GetPromise("r5")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+
+ ResetPromiseStates();
+
+ // Create promise s0, which has three handlers, none of which handle rejects.
+ CompileRun(
+ "var s0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reject = rej; \n"
+ " } \n"
+ "); \n"
+ "var s1 = s0.then(function() {}); \n"
+ "var s2 = s0.then(function() {}); \n"
+ "var s3 = s0.then(function() {}); \n");
+ CHECK(GetPromise("s0")->HasHandler());
+ CHECK(!GetPromise("s1")->HasHandler());
+ CHECK(!GetPromise("s2")->HasHandler());
+ CHECK(!GetPromise("s3")->HasHandler());
+ CHECK_EQ(0, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+
+ // Reject s0.
+ CompileRun("reject('sss')");
+ CHECK(GetPromise("s0")->HasHandler());
+ CHECK(!GetPromise("s1")->HasHandler());
+ CHECK(!GetPromise("s2")->HasHandler());
+ CHECK(!GetPromise("s3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK(RejectValue()->Equals(v8_str("sss")));
+
+ // Test stack frames.
+ V8::SetCaptureStackTraceForUncaughtExceptions(true);
+
+ ResetPromiseStates();
+
+ // Create promise t0, which is rejected in the constructor with an error.
+ CompileRunWithOrigin(
+ "var t0 = new Promise( \n"
+ " function(res, rej) { \n"
+ " reference_error; \n"
+ " } \n"
+ "); \n",
+ "pro", 0, 0);
+ CHECK(!GetPromise("t0")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(2, promise_reject_frame_count);
+ CHECK_EQ(3, promise_reject_line_number);
+
+ ResetPromiseStates();
+
+ // Create promise u0 and chain u1 to it, which is rejected via throw.
+ CompileRunWithOrigin(
+ "var u0 = Promise.resolve(); \n"
+ "var u1 = u0.then( \n"
+ " function() { \n"
+ " (function() { \n"
+ " throw new Error(); \n"
+ " })(); \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("u0")->HasHandler());
+ CHECK(!GetPromise("u1")->HasHandler());
+ CHECK_EQ(1, promise_reject_counter);
+ CHECK_EQ(0, promise_revoke_counter);
+ CHECK_EQ(2, promise_reject_frame_count);
+ CHECK_EQ(5, promise_reject_line_number);
+
+ // Throw in u3, which handles u1's rejection.
+ CompileRunWithOrigin(
+ "function f() { \n"
+ " return (function() { \n"
+ " return new Error(); \n"
+ " })(); \n"
+ "} \n"
+ "var u2 = Promise.reject(f()); \n"
+ "var u3 = u1.catch( \n"
+ " function() { \n"
+ " return u2; \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("u0")->HasHandler());
+ CHECK(GetPromise("u1")->HasHandler());
+ CHECK(GetPromise("u2")->HasHandler());
+ CHECK(!GetPromise("u3")->HasHandler());
+ CHECK_EQ(3, promise_reject_counter);
+ CHECK_EQ(2, promise_revoke_counter);
+ CHECK_EQ(3, promise_reject_frame_count);
+ CHECK_EQ(3, promise_reject_line_number);
+
+ ResetPromiseStates();
+
+ // Create promise rejected promise v0, which is incorrectly handled by v1
+ // via chaining cycle.
+ CompileRunWithOrigin(
+ "var v0 = Promise.reject(); \n"
+ "var v1 = v0.catch( \n"
+ " function() { \n"
+ " return v1; \n"
+ " } \n"
+ " ); \n",
+ "pro", 0, 0);
+ CHECK(GetPromise("v0")->HasHandler());
+ CHECK(!GetPromise("v1")->HasHandler());
+ CHECK_EQ(2, promise_reject_counter);
+ CHECK_EQ(1, promise_revoke_counter);
+ CHECK_EQ(0, promise_reject_frame_count);
+ CHECK_EQ(-1, promise_reject_line_number);
+}
+
+
void AnalyzeStackOfEvalWithSourceURL(
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
@@ -17835,40 +18994,6 @@
}
-TEST(Regress2107) {
- const intptr_t MB = 1024 * 1024;
- const int kIdlePauseInMs = 1000;
- LocalContext env;
- v8::Isolate* isolate = env->GetIsolate();
- v8::HandleScope scope(env->GetIsolate());
- intptr_t initial_size = CcTest::heap()->SizeOfObjects();
- // Send idle notification to start a round of incremental GCs.
- env->GetIsolate()->IdleNotification(kIdlePauseInMs);
- // Emulate 7 page reloads.
- for (int i = 0; i < 7; i++) {
- {
- v8::HandleScope inner_scope(env->GetIsolate());
- v8::Local<v8::Context> ctx = v8::Context::New(isolate);
- ctx->Enter();
- CreateGarbageInOldSpace();
- ctx->Exit();
- }
- env->GetIsolate()->ContextDisposedNotification();
- env->GetIsolate()->IdleNotification(kIdlePauseInMs);
- }
- // Create garbage and check that idle notification still collects it.
- CreateGarbageInOldSpace();
- intptr_t size_with_garbage = CcTest::heap()->SizeOfObjects();
- CHECK_GT(size_with_garbage, initial_size + MB);
- bool finished = false;
- for (int i = 0; i < 200 && !finished; i++) {
- finished = env->GetIsolate()->IdleNotification(kIdlePauseInMs);
- }
- intptr_t final_size = CcTest::heap()->SizeOfObjects();
- CHECK_LT(final_size, initial_size + 1);
-}
-
-
TEST(Regress2333) {
LocalContext env;
for (int i = 0; i < 3; i++) {
@@ -17998,10 +19123,11 @@
TEST(ExternalizeOldSpaceTwoByteCons) {
+ v8::Isolate* isolate = CcTest::isolate();
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(isolate);
v8::Local<v8::String> cons =
- CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate);
CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
CcTest::heap()->CollectAllAvailableGarbage();
CHECK(CcTest::heap()->old_pointer_space()->Contains(
@@ -18020,10 +19146,11 @@
TEST(ExternalizeOldSpaceOneByteCons) {
+ v8::Isolate* isolate = CcTest::isolate();
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(isolate);
v8::Local<v8::String> cons =
- CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString();
+ CompileRun("'Romeo Montague ' + 'Juliet Capulet'")->ToString(isolate);
CHECK(v8::Utils::OpenHandle(*cons)->IsConsString());
CcTest::heap()->CollectAllAvailableGarbage();
CHECK(CcTest::heap()->old_pointer_space()->Contains(
@@ -18042,8 +19169,9 @@
TEST(VisitExternalStrings) {
+ v8::Isolate* isolate = CcTest::isolate();
LocalContext env;
- v8::HandleScope scope(env->GetIsolate());
+ v8::HandleScope scope(isolate);
const char* string = "Some string";
uint16_t* two_byte_string = AsciiToTwoByteString(string);
TestResource* resource[4];
@@ -18113,7 +19241,7 @@
const char* s = "One string to test them all";
TestOneByteResource* inscription =
new TestOneByteResource(i::StrDup(s), &destroyed);
- v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+ v8::Local<v8::String> ring = CompileRun("ring")->ToString(isolate);
CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
ring->MakeExternal(inscription);
// Ring is still alive. Orcs are roaming freely across our lands.
@@ -18128,6 +19256,9 @@
TEST(ExternalInternalizedStringCollectedAtGC) {
+ // TODO(mvstanton): vector ics need weak support.
+ if (i::FLAG_vector_ics) return;
+
int destroyed = 0;
{ LocalContext env;
v8::HandleScope handle_scope(env->GetIsolate());
@@ -18135,7 +19266,7 @@
const char* s = "One string to test them all";
TestOneByteResource* inscription =
new TestOneByteResource(i::StrDup(s), &destroyed);
- v8::Local<v8::String> ring = CompileRun("ring")->ToString();
+ v8::Local<v8::String> ring = CompileRun("ring").As<v8::String>();
CHECK(v8::Utils::OpenHandle(*ring)->IsInternalizedString());
ring->MakeExternal(inscription);
// Ring is still alive. Orcs are roaming freely across our lands.
@@ -18274,7 +19405,7 @@
const v8::FunctionCallbackInfo<v8::Value>& args) {
v8::HandleScope scope(args.GetIsolate());
v8::TryCatch tc;
- v8::Handle<v8::String> str(args[0]->ToString());
+ v8::Handle<v8::String> str(args[0]->ToString(args.GetIsolate()));
USE(str);
if (tc.HasCaught())
tc.ReThrow();
@@ -18625,7 +19756,7 @@
}
-void FooGetInterceptor(Local<String> name,
+void FooGetInterceptor(Local<Name> name,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
@@ -18634,8 +19765,7 @@
}
-void FooSetInterceptor(Local<String> name,
- Local<Value> value,
+void FooSetInterceptor(Local<Name> name, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
CHECK(v8::Utils::OpenHandle(*info.This())->IsJSObject());
CHECK(v8::Utils::OpenHandle(*info.Holder())->IsJSObject());
@@ -18681,15 +19811,13 @@
static void NamedPropertyGetterWhichReturns42(
- Local<String> name,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(v8_num(42));
}
static void NamedPropertySetterWhichSetsYOnThisTo23(
- Local<String> name,
- Local<Value> value,
+ Local<Name> name, Local<Value> value,
const v8::PropertyCallbackInfo<v8::Value>& info) {
if (name->Equals(v8_str("x"))) {
Local<Object>::Cast(info.This())->Set(v8_str("y"), v8_num(23));
@@ -18701,8 +19829,9 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(NamedPropertyGetterWhichReturns42,
- NamedPropertySetterWhichSetsYOnThisTo23);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ NamedPropertyGetterWhichReturns42,
+ NamedPropertySetterWhichSetsYOnThisTo23));
LocalContext context;
context->Global()->Set(v8_str("P"), templ->NewInstance());
CompileRun("function C1() {"
@@ -19860,7 +20989,7 @@
CHECK_EQ(42, object.WrapperClassId());
Visitor42 visitor(&object);
- v8::V8::VisitHandlesWithClassIds(&visitor);
+ v8::V8::VisitHandlesWithClassIds(isolate, &visitor);
CHECK_EQ(1, visitor.counter_);
object.Reset();
@@ -19994,8 +21123,8 @@
}
-static void Getter(v8::Local<v8::String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info ) {
+static void Getter(v8::Local<v8::Name> property,
+ const v8::PropertyCallbackInfo<v8::Value>& info) {
info.GetReturnValue().Set(v8_str("42!"));
}
@@ -20014,7 +21143,8 @@
v8::Context::Scope context_scope(context.local());
v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(isolate);
- tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator);
+ tmpl->SetHandler(v8::NamedPropertyHandlerConfiguration(Getter, NULL, NULL,
+ NULL, Enumerator));
context->Global()->Set(v8_str("o"), tmpl->NewInstance());
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun(
"var result = []; for (var k in o) result.push(k); result"));
@@ -20159,8 +21289,7 @@
void HasOwnPropertyNamedPropertyGetter(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {
if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(v8_str("yes"));
}
@@ -20172,15 +21301,13 @@
void HasOwnPropertyNamedPropertyQuery(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
if (property->Equals(v8_str("foo"))) info.GetReturnValue().Set(1);
}
void HasOwnPropertyNamedPropertyQuery2(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Integer>& info) {
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) {
if (property->Equals(v8_str("bar"))) info.GetReturnValue().Set(1);
}
@@ -20209,7 +21336,7 @@
"Bar.prototype = new Foo();"
"new Bar();");
CHECK(value->IsObject());
- Handle<Object> object = value->ToObject();
+ Handle<Object> object = value->ToObject(isolate);
CHECK(object->Has(v8_str("foo")));
CHECK(!object->HasOwnProperty(v8_str("foo")));
CHECK(object->HasOwnProperty(v8_str("bar")));
@@ -20219,7 +21346,8 @@
}
{ // Check named getter interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ HasOwnPropertyNamedPropertyGetter));
Handle<Object> instance = templ->NewInstance();
CHECK(!instance->HasOwnProperty(v8_str("42")));
CHECK(instance->HasOwnProperty(v8_str("foo")));
@@ -20227,7 +21355,8 @@
}
{ // Check indexed getter interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(HasOwnPropertyIndexedPropertyGetter);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ HasOwnPropertyIndexedPropertyGetter));
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("43")));
@@ -20235,14 +21364,16 @@
}
{ // Check named query interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(0, 0, HasOwnPropertyNamedPropertyQuery);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ 0, 0, HasOwnPropertyNamedPropertyQuery));
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("foo")));
CHECK(!instance->HasOwnProperty(v8_str("bar")));
}
{ // Check indexed query interceptors.
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(0, 0, HasOwnPropertyIndexedPropertyQuery);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ 0, 0, HasOwnPropertyIndexedPropertyQuery));
Handle<Object> instance = templ->NewInstance();
CHECK(instance->HasOwnProperty(v8_str("42")));
CHECK(!instance->HasOwnProperty(v8_str("41")));
@@ -20256,9 +21387,9 @@
}
{ // Check that query wins on disagreement.
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetNamedPropertyHandler(HasOwnPropertyNamedPropertyGetter,
- 0,
- HasOwnPropertyNamedPropertyQuery2);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(
+ HasOwnPropertyNamedPropertyGetter, 0,
+ HasOwnPropertyNamedPropertyQuery2));
Handle<Object> instance = templ->NewInstance();
CHECK(!instance->HasOwnProperty(v8_str("foo")));
CHECK(instance->HasOwnProperty(v8_str("bar")));
@@ -20270,9 +21401,8 @@
v8::Isolate* isolate = CcTest::isolate();
v8::HandleScope scope(isolate);
Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate);
- templ->SetIndexedPropertyHandler(NULL,
- NULL,
- HasOwnPropertyIndexedPropertyQuery);
+ templ->SetHandler(v8::IndexedPropertyHandlerConfiguration(
+ NULL, NULL, HasOwnPropertyIndexedPropertyQuery));
LocalContext context;
context->Global()->Set(v8_str("obj"), templ->NewInstance());
CompileRun("var s = new String('foobar'); obj.__proto__ = s;");
@@ -20417,29 +21547,40 @@
}
+static int CountLiveMapsInMapCache(i::Context* context) {
+ i::FixedArray* map_cache = i::FixedArray::cast(context->map_cache());
+ int length = map_cache->length();
+ int count = 0;
+ for (int i = 0; i < length; i++) {
+ i::Object* value = map_cache->get(i);
+ if (value->IsWeakCell() && !i::WeakCell::cast(value)->cleared()) count++;
+ }
+ return count;
+}
+
+
THREADED_TEST(Regress1516) {
LocalContext context;
v8::HandleScope scope(context->GetIsolate());
+ // Object with 20 properties is not a common case, so it should be removed
+ // from the cache after GC.
{ v8::HandleScope temp_scope(context->GetIsolate());
- CompileRun("({'a': 0})");
+ CompileRun(
+ "({"
+ "'a00': 0, 'a01': 0, 'a02': 0, 'a03': 0, 'a04': 0, "
+ "'a05': 0, 'a06': 0, 'a07': 0, 'a08': 0, 'a09': 0, "
+ "'a10': 0, 'a11': 0, 'a12': 0, 'a13': 0, 'a14': 0, "
+ "'a15': 0, 'a16': 0, 'a17': 0, 'a18': 0, 'a19': 0, "
+ "})");
}
- int elements;
- { i::MapCache* map_cache =
- i::MapCache::cast(CcTest::i_isolate()->context()->map_cache());
- elements = map_cache->NumberOfElements();
- CHECK_LE(1, elements);
- }
+ int elements = CountLiveMapsInMapCache(CcTest::i_isolate()->context());
+ CHECK_LE(1, elements);
- CcTest::heap()->CollectAllGarbage(
- i::Heap::kAbortIncrementalMarkingMask);
- { i::Object* raw_map_cache = CcTest::i_isolate()->context()->map_cache();
- if (raw_map_cache != CcTest::heap()->undefined_value()) {
- i::MapCache* map_cache = i::MapCache::cast(raw_map_cache);
- CHECK_GT(elements, map_cache->NumberOfElements());
- }
- }
+ CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+
+ CHECK_GT(elements, CountLiveMapsInMapCache(CcTest::i_isolate()->context()));
}
@@ -20448,12 +21589,11 @@
v8::AccessType type,
Local<Value> data) {
// Only block read access to __proto__.
- if (type == v8::ACCESS_GET &&
- name->IsString() &&
- name->ToString()->Length() == 9 &&
- name->ToString()->Utf8Length() == 9) {
+ if (type == v8::ACCESS_GET && name->IsString() &&
+ name.As<v8::String>()->Length() == 9 &&
+ name.As<v8::String>()->Utf8Length() == 9) {
char buffer[10];
- CHECK_EQ(10, name->ToString()->WriteUtf8(buffer));
+ CHECK_EQ(10, name.As<v8::String>()->WriteUtf8(buffer));
return strncmp(buffer, "__proto__", 9) != 0;
}
@@ -20500,8 +21640,7 @@
context->Global();
// Global object, the prototype of proxy_object. No security checks.
- Local<Object> global_object =
- proxy_object->GetPrototype()->ToObject();
+ Local<Object> global_object = proxy_object->GetPrototype()->ToObject(isolate);
// Hidden prototype without security check.
Local<Object> hidden_prototype =
@@ -20545,7 +21684,7 @@
Local<Value> result5 = CompileRun("Object.getPrototypeOf(hidden)");
CHECK(result5->Equals(
- object_with_hidden->GetPrototype()->ToObject()->GetPrototype()));
+ object_with_hidden->GetPrototype()->ToObject(isolate)->GetPrototype()));
Local<Value> result6 = CompileRun("Object.getPrototypeOf(phidden)");
CHECK(result6.IsEmpty());
@@ -20581,8 +21720,8 @@
const char* code) {
Local<Value> result = CompileRun(code);
CHECK(result->IsObject());
- CHECK(expected_receiver->Equals(result->ToObject()->Get(1)));
- CHECK(expected_result->Equals(result->ToObject()->Get(0)));
+ CHECK(expected_receiver->Equals(result.As<v8::Object>()->Get(1)));
+ CHECK(expected_result->Equals(result.As<v8::Object>()->Get(0)));
}
@@ -20970,8 +22109,8 @@
Handle<Object> exec_state = event_details.GetExecutionState();
Handle<Value> break_id = exec_state->Get(v8_str("break_id"));
CompileRun("function f(id) { new FrameDetails(id, 0); }");
- Handle<Function> fun = Handle<Function>::Cast(
- CcTest::global()->Get(v8_str("f"))->ToObject());
+ Handle<Function> fun =
+ Handle<Function>::Cast(CcTest::global()->Get(v8_str("f")));
fun->Call(CcTest::global(), 1, &break_id);
}
@@ -20995,7 +22134,7 @@
}
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
static int probes_counter = 0;
static int misses_counter = 0;
static int updates_counter = 0;
@@ -21029,7 +22168,7 @@
static void StubCacheHelper(bool primary) {
-#ifdef DEBUG
+#ifdef ENABLE_DISASSEMBLER
i::FLAG_native_code_counters = true;
if (primary) {
i::FLAG_test_primary_stub_cache = true;
@@ -21376,7 +22515,8 @@
LocalContext context;
Local<ObjectTemplate> templ = ObjectTemplate::New(context->GetIsolate());
if (interceptor) {
- templ->SetNamedPropertyHandler(FooGetInterceptor, FooSetInterceptor);
+ templ->SetHandler(v8::NamedPropertyHandlerConfiguration(FooGetInterceptor,
+ FooSetInterceptor));
} else {
templ->SetAccessor(v8_str("foo"),
GetterWhichReturns42,
@@ -21782,7 +22922,8 @@
void HasOwnPropertyCallback(const v8::FunctionCallbackInfo<v8::Value>& args) {
- args[0]->ToObject()->HasOwnProperty(args[1]->ToString());
+ args[0]->ToObject(args.GetIsolate())->HasOwnProperty(
+ args[1]->ToString(args.GetIsolate()));
}
@@ -21998,8 +23139,6 @@
TestBody();
- isolate_->ClearInterrupt();
-
// Verify we arrived here because interruptor was called
// not due to a bug causing us to exit the loop too early.
CHECK(!should_continue());
@@ -22149,7 +23288,8 @@
proto->Set(v8_str("shouldContinue"), Function::New(
isolate_, ShouldContinueCallback, v8::External::New(isolate_, this)));
v8::Local<v8::ObjectTemplate> instance_template = t->InstanceTemplate();
- instance_template->SetNamedPropertyHandler(EmptyInterceptor);
+ instance_template->SetHandler(
+ v8::NamedPropertyHandlerConfiguration(EmptyInterceptor));
env_->Global()->Set(v8_str("Klass"), t->GetFunction());
@@ -22158,9 +23298,7 @@
private:
static void EmptyInterceptor(
- Local<String> property,
- const v8::PropertyCallbackInfo<v8::Value>& info) {
- }
+ Local<Name> property, const v8::PropertyCallbackInfo<v8::Value>& info) {}
};
@@ -22249,10 +23387,9 @@
}
-class ClearInterruptFromAnotherThread
- : public RequestInterruptTestBase {
+class RequestMultipleInterrupts : public RequestInterruptTestBase {
public:
- ClearInterruptFromAnotherThread() : i_thread(this), sem2_(0) { }
+ RequestMultipleInterrupts() : i_thread(this), counter_(0) {}
virtual void StartInterruptThread() {
i_thread.Start();
@@ -22269,39 +23406,33 @@
private:
class InterruptThread : public v8::base::Thread {
public:
- explicit InterruptThread(ClearInterruptFromAnotherThread* test)
+ enum { NUM_INTERRUPTS = 10 };
+ explicit InterruptThread(RequestMultipleInterrupts* test)
: Thread(Options("RequestInterruptTest")), test_(test) {}
virtual void Run() {
test_->sem_.Wait();
- test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
- test_->sem_.Wait();
- test_->isolate_->ClearInterrupt();
- test_->sem2_.Signal();
+ for (int i = 0; i < NUM_INTERRUPTS; i++) {
+ test_->isolate_->RequestInterrupt(&OnInterrupt, test_);
+ }
}
static void OnInterrupt(v8::Isolate* isolate, void* data) {
- ClearInterruptFromAnotherThread* test =
- reinterpret_cast<ClearInterruptFromAnotherThread*>(data);
- test->sem_.Signal();
- bool success = test->sem2_.WaitFor(v8::base::TimeDelta::FromSeconds(2));
- // Crash instead of timeout to make this failure more prominent.
- CHECK(success);
- test->should_continue_ = false;
+ RequestMultipleInterrupts* test =
+ reinterpret_cast<RequestMultipleInterrupts*>(data);
+ test->should_continue_ = ++test->counter_ < NUM_INTERRUPTS;
}
private:
- ClearInterruptFromAnotherThread* test_;
+ RequestMultipleInterrupts* test_;
};
InterruptThread i_thread;
- v8::base::Semaphore sem2_;
+ int counter_;
};
-TEST(ClearInterruptFromAnotherThread) {
- ClearInterruptFromAnotherThread().RunTest();
-}
+TEST(RequestMultipleInterrupts) { RequestMultipleInterrupts().RunTest(); }
static Local<Value> function_new_expected_env;
@@ -22606,6 +23737,7 @@
Handle<v8::Promise::Resolver> rr = v8::Promise::Resolver::New(isolate);
Handle<v8::Promise> p = pr->GetPromise();
Handle<v8::Promise> r = rr->GetPromise();
+ CHECK_EQ(isolate, p->GetIsolate());
// IsPromise predicate.
CHECK(p->IsPromise());
@@ -22867,10 +23999,8 @@
CHECK_EQ(13, line_number);
}
-
-void SourceURLHelper(const char* source, const char* expected_source_url,
- const char* expected_source_mapping_url) {
- Local<Script> script = v8_compile(source);
+void CheckMagicComments(Handle<Script> script, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
if (expected_source_url != NULL) {
v8::String::Utf8Value url(script->GetUnboundScript()->GetSourceURL());
CHECK_EQ(expected_source_url, *url);
@@ -22886,6 +24016,12 @@
}
}
+void SourceURLHelper(const char* source, const char* expected_source_url,
+ const char* expected_source_mapping_url) {
+ Local<Script> script = v8_compile(source);
+ CheckMagicComments(script, expected_source_url, expected_source_mapping_url);
+}
+
TEST(ScriptSourceURLAndSourceMappingURL) {
LocalContext env;
@@ -23077,7 +24213,9 @@
void RunStreamingTest(const char** chunks,
v8::ScriptCompiler::StreamedSource::Encoding encoding =
v8::ScriptCompiler::StreamedSource::ONE_BYTE,
- bool expected_success = true) {
+ bool expected_success = true,
+ const char* expected_source_url = NULL,
+ const char* expected_source_mapping_url = NULL) {
LocalContext env;
v8::Isolate* isolate = env->GetIsolate();
v8::HandleScope scope(isolate);
@@ -23106,6 +24244,8 @@
v8::Handle<Value> result(script->Run());
// All scripts are supposed to return the fixed value 13 when ran.
CHECK_EQ(13, result->Int32Value());
+ CheckMagicComments(script, expected_source_url,
+ expected_source_mapping_url);
} else {
CHECK(script.IsEmpty());
CHECK(try_catch.HasCaught());
@@ -23170,14 +24310,14 @@
TEST(StreamingUtf8Script) {
- // We'd want to write \uc481 instead of \xeb\x91\x80, but Windows compilers
+ // We'd want to write \uc481 instead of \xec\x92\x81, but Windows compilers
// don't like it.
const char* chunk1 =
"function foo() {\n"
" // This function will contain an UTF-8 character which is not in\n"
" // ASCII.\n"
- " var foob\xeb\x91\x80r = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " var foob\xec\x92\x81r = 13;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
const char* chunks[] = {chunk1, "foo(); ", NULL};
RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
@@ -23188,7 +24328,7 @@
// A sanity check to prove that the approach of splitting UTF-8
// characters is correct. Here is an UTF-8 character which will take three
// bytes.
- const char* reference = "\xeb\x91\x80";
+ const char* reference = "\xec\x92\x81";
CHECK(3u == strlen(reference)); // NOLINT - no CHECK_EQ for unsigned.
char chunk1[] =
@@ -23198,7 +24338,7 @@
" var foob";
char chunk2[] =
"XXXr = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
for (int i = 0; i < 3; ++i) {
chunk2[i] = reference[i];
@@ -23211,7 +24351,7 @@
TEST(StreamingUtf8ScriptWithSplitCharacters) {
// Stream data where a multi-byte UTF-8 character is split between two data
// chunks.
- const char* reference = "\xeb\x91\x80";
+ const char* reference = "\xec\x92\x81";
char chunk1[] =
"function foo() {\n"
" // This function will contain an UTF-8 character which is not in\n"
@@ -23219,7 +24359,7 @@
" var foobX";
char chunk2[] =
"XXr = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
chunk1[strlen(chunk1) - 1] = reference[0];
chunk2[0] = reference[1];
@@ -23235,7 +24375,7 @@
// Case 1: a chunk contains only bytes for a split character (and no other
// data). This kind of a chunk would be exceptionally small, but we should
// still decode it correctly.
- const char* reference = "\xeb\x91\x80";
+ const char* reference = "\xec\x92\x81";
// The small chunk is at the beginning of the split character
{
char chunk1[] =
@@ -23246,7 +24386,7 @@
char chunk2[] = "XX";
char chunk3[] =
"Xr = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
chunk2[0] = reference[0];
chunk2[1] = reference[1];
@@ -23264,7 +24404,7 @@
char chunk2[] = "XX";
char chunk3[] =
"r = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
chunk1[strlen(chunk1) - 1] = reference[0];
chunk2[0] = reference[1];
@@ -23276,8 +24416,8 @@
// decoded correctly and not just ignored.
{
char chunk1[] =
- "var foob\xeb\x91\x80 = 13;\n"
- "foob\xeb\x91\x80";
+ "var foob\xec\x92\x81 = 13;\n"
+ "foob\xec\x92\x81";
const char* chunks[] = {chunk1, NULL};
RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
}
@@ -23288,7 +24428,7 @@
// Test cases where a UTF-8 character is split over several chunks. Those
// cases are not supported (the embedder should give the data in big enough
// chunks), but we shouldn't crash, just produce a parse error.
- const char* reference = "\xeb\x91\x80";
+ const char* reference = "\xec\x92\x81";
char chunk1[] =
"function foo() {\n"
" // This function will contain an UTF-8 character which is not in\n"
@@ -23297,7 +24437,7 @@
char chunk2[] = "X";
char chunk3[] =
"Xr = 13;\n"
- " return foob\xeb\x91\x80r;\n"
+ " return foob\xec\x92\x81r;\n"
"}\n";
chunk1[strlen(chunk1) - 1] = reference[0];
chunk2[0] = reference[1];
@@ -23332,6 +24472,7 @@
const v8::ScriptCompiler::CachedData* cached_data = source.GetCachedData();
CHECK(cached_data != NULL);
CHECK(cached_data->data != NULL);
+ CHECK(!cached_data->rejected);
CHECK_GT(cached_data->length, 0);
}
@@ -23339,7 +24480,7 @@
TEST(StreamingScriptWithInvalidUtf8) {
// Regression test for a crash: test that invalid UTF-8 bytes in the end of a
// chunk don't produce a crash.
- const char* reference = "\xeb\x91\x80\x80\x80";
+ const char* reference = "\xec\x92\x81\x80\x80";
char chunk1[] =
"function foo() {\n"
" // This function will contain an UTF-8 character which is not in\n"
@@ -23347,10 +24488,274 @@
" var foobXXXXX"; // Too many bytes which look like incomplete chars!
char chunk2[] =
"r = 13;\n"
- " return foob\xeb\x91\x80\x80\x80r;\n"
+ " return foob\xec\x92\x81\x80\x80r;\n"
"}\n";
for (int i = 0; i < 5; ++i) chunk1[strlen(chunk1) - 5 + i] = reference[i];
const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, false);
}
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit) {
+ // Regression test: Stream data where there are several multi-byte UTF-8
+ // characters in a sequence and one of them is split between two data chunks.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foob\xec\x92\x81X";
+ char chunk2[] =
+ "XXr = 13;\n"
+ " return foob\xec\x92\x81\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+TEST(StreamingUtf8ScriptWithMultipleMultibyteCharactersSomeSplit2) {
+ // Another regression test, similar to the previous one. The difference is
+ // that the split character is not the last one in the sequence.
+ const char* reference = "\xec\x92\x81";
+ char chunk1[] =
+ "function foo() {\n"
+ " // This function will contain an UTF-8 character which is not in\n"
+ " // ASCII.\n"
+ " var foobX";
+ char chunk2[] =
+ "XX\xec\x92\x81r = 13;\n"
+ " return foob\xec\x92\x81\xec\x92\x81r;\n"
+ "}\n";
+ chunk1[strlen(chunk1) - 1] = reference[0];
+ chunk2[0] = reference[1];
+ chunk2[1] = reference[2];
+ const char* chunks[] = {chunk1, chunk2, "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8);
+}
+
+
+void TestInvalidCacheData(v8::ScriptCompiler::CompileOptions option) {
+ const char* garbage = "garbage garbage garbage garbage garbage garbage";
+ const uint8_t* data = reinterpret_cast<const uint8_t*>(garbage);
+ int length = 16;
+ v8::ScriptCompiler::CachedData* cached_data =
+ new v8::ScriptCompiler::CachedData(data, length);
+ DCHECK(!cached_data->rejected);
+ v8::ScriptOrigin origin(v8_str("origin"));
+ v8::ScriptCompiler::Source source(v8_str("42"), origin, cached_data);
+ v8::Handle<v8::Script> script =
+ v8::ScriptCompiler::Compile(CcTest::isolate(), &source, option);
+ CHECK(cached_data->rejected);
+ CHECK_EQ(42, script->Run()->Int32Value());
+}
+
+
+TEST(InvalidCacheData) {
+ v8::V8::Initialize();
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext context;
+ TestInvalidCacheData(v8::ScriptCompiler::kConsumeParserCache);
+ TestInvalidCacheData(v8::ScriptCompiler::kConsumeCodeCache);
+}
+
+
+TEST(ParserCacheRejectedGracefully) {
+ i::FLAG_min_preparse_length = 0;
+ v8::V8::Initialize();
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext context;
+ // Produce valid cached data.
+ v8::ScriptOrigin origin(v8_str("origin"));
+ v8::Local<v8::String> source_str = v8_str("function foo() {}");
+ v8::ScriptCompiler::Source source(source_str, origin);
+ v8::Handle<v8::Script> script = v8::ScriptCompiler::Compile(
+ CcTest::isolate(), &source, v8::ScriptCompiler::kProduceParserCache);
+ CHECK(!script.IsEmpty());
+ const v8::ScriptCompiler::CachedData* original_cached_data =
+ source.GetCachedData();
+ CHECK(original_cached_data != NULL);
+ CHECK(original_cached_data->data != NULL);
+ CHECK(!original_cached_data->rejected);
+ CHECK_GT(original_cached_data->length, 0);
+ // Recompiling the same script with it won't reject the data.
+ {
+ v8::ScriptCompiler::Source source_with_cached_data(
+ source_str, origin,
+ new v8::ScriptCompiler::CachedData(original_cached_data->data,
+ original_cached_data->length));
+ v8::Handle<v8::Script> script =
+ v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data,
+ v8::ScriptCompiler::kConsumeParserCache);
+ CHECK(!script.IsEmpty());
+ const v8::ScriptCompiler::CachedData* new_cached_data =
+ source_with_cached_data.GetCachedData();
+ CHECK(new_cached_data != NULL);
+ CHECK(!new_cached_data->rejected);
+ }
+ // Compile an incompatible script with the cached data. The new script doesn't
+ // have the same starting position for the function as the old one, so the old
+ // cached data will be incompatible with it and will be rejected.
+ {
+ v8::Local<v8::String> incompatible_source_str =
+ v8_str(" function foo() {}");
+ v8::ScriptCompiler::Source source_with_cached_data(
+ incompatible_source_str, origin,
+ new v8::ScriptCompiler::CachedData(original_cached_data->data,
+ original_cached_data->length));
+ v8::Handle<v8::Script> script =
+ v8::ScriptCompiler::Compile(CcTest::isolate(), &source_with_cached_data,
+ v8::ScriptCompiler::kConsumeParserCache);
+ CHECK(!script.IsEmpty());
+ const v8::ScriptCompiler::CachedData* new_cached_data =
+ source_with_cached_data.GetCachedData();
+ CHECK(new_cached_data != NULL);
+ CHECK(new_cached_data->rejected);
+ }
+}
+
+
+TEST(StringConcatOverflow) {
+ v8::V8::Initialize();
+ v8::HandleScope scope(CcTest::isolate());
+ RandomLengthOneByteResource* r =
+ new RandomLengthOneByteResource(i::String::kMaxLength);
+ v8::Local<v8::String> str = v8::String::NewExternal(CcTest::isolate(), r);
+ CHECK(!str.IsEmpty());
+ v8::TryCatch try_catch;
+ v8::Local<v8::String> result = v8::String::Concat(str, str);
+ CHECK(result.IsEmpty());
+ CHECK(!try_catch.HasCaught());
+}
+
+
+TEST(TurboAsmDisablesNeuter) {
+ v8::V8::Initialize();
+ v8::HandleScope scope(CcTest::isolate());
+ LocalContext context;
+#if V8_TURBOFAN_TARGET
+ bool should_be_neuterable = !i::FLAG_turbo_asm;
+#else
+ bool should_be_neuterable = true;
+#endif
+ const char* load =
+ "function Module(stdlib, foreign, heap) {"
+ " 'use asm';"
+ " var MEM32 = new stdlib.Int32Array(heap);"
+ " function load() { return MEM32[0]; }"
+ " return { load: load };"
+ "}"
+ "var buffer = new ArrayBuffer(4);"
+ "Module(this, {}, buffer).load();"
+ "buffer";
+
+ v8::Local<v8::ArrayBuffer> result = CompileRun(load).As<v8::ArrayBuffer>();
+ CHECK_EQ(should_be_neuterable, result->IsNeuterable());
+
+ const char* store =
+ "function Module(stdlib, foreign, heap) {"
+ " 'use asm';"
+ " var MEM32 = new stdlib.Int32Array(heap);"
+ " function store() { MEM32[0] = 0; }"
+ " return { store: store };"
+ "}"
+ "var buffer = new ArrayBuffer(4);"
+ "Module(this, {}, buffer).store();"
+ "buffer";
+
+ result = CompileRun(store).As<v8::ArrayBuffer>();
+ CHECK_EQ(should_be_neuterable, result->IsNeuterable());
+}
+
+
+TEST(GetPrototypeAccessControl) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ v8::Handle<v8::ObjectTemplate> obj_template =
+ v8::ObjectTemplate::New(isolate);
+ obj_template->SetAccessCheckCallbacks(BlockEverythingNamed,
+ BlockEverythingIndexed);
+
+ env->Global()->Set(v8_str("prohibited"), obj_template->NewInstance());
+
+ {
+ v8::TryCatch try_catch;
+ CompileRun(
+ "function f() { %_GetPrototype(prohibited); }"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f();");
+ CHECK(try_catch.HasCaught());
+ }
+}
+
+
+TEST(GetPrototypeHidden) {
+ i::FLAG_allow_natives_syntax = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ Handle<FunctionTemplate> t = FunctionTemplate::New(isolate);
+ t->SetHiddenPrototype(true);
+ Handle<Object> proto = t->GetFunction()->NewInstance();
+ Handle<Object> object = Object::New(isolate);
+ Handle<Object> proto2 = Object::New(isolate);
+ object->SetPrototype(proto);
+ proto->SetPrototype(proto2);
+
+ env->Global()->Set(v8_str("object"), object);
+ env->Global()->Set(v8_str("proto"), proto);
+ env->Global()->Set(v8_str("proto2"), proto2);
+
+ v8::Handle<v8::Value> result = CompileRun("%_GetPrototype(object)");
+ CHECK(result->Equals(proto2));
+
+ result = CompileRun(
+ "function f() { return %_GetPrototype(object); }"
+ "%OptimizeFunctionOnNextCall(f);"
+ "f()");
+ CHECK(result->Equals(proto2));
+}
+
+
+TEST(ClassPrototypeCreationContext) {
+ i::FLAG_harmony_classes = true;
+ v8::Isolate* isolate = CcTest::isolate();
+ v8::HandleScope handle_scope(isolate);
+ LocalContext env;
+
+ Handle<Object> result = Handle<Object>::Cast(
+ CompileRun("'use strict'; class Example { }; Example.prototype"));
+ CHECK(env.local() == result->CreationContext());
+}
+
+
+TEST(SimpleStreamingScriptWithSourceURL) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f", "oo();\n",
+ "//# sourceURL=bar2.js\n", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+ "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSplitSourceURL) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; } f",
+ "oo();\n//# sourceURL=b", "ar2.js\n", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true,
+ "bar2.js");
+}
+
+
+TEST(StreamingScriptWithSourceMappingURLInTheMiddle) {
+ const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#",
+ " sourceMappingURL=bar2.js\n", "foo();", NULL};
+ RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL,
+ "bar2.js");
+}