Index: test/cctest/test-api.cc |
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc |
index e27d6ad57f8f843ffb9d7c4774fb60b4aa8ec469..742ccd886319245739c9ee4c39ff1262b7a360fc 100644 |
--- a/test/cctest/test-api.cc |
+++ b/test/cctest/test-api.cc |
@@ -30,7 +30,7 @@ |
#include <map> |
#include <string> |
-#include "src/v8.h" |
+#include "test/cctest/test-api.h" |
#if V8_OS_POSIX |
#include <unistd.h> // NOLINT |
@@ -41,9 +41,7 @@ |
#include "src/arguments.h" |
#include "src/base/platform/platform.h" |
#include "src/compilation-cache.h" |
-#include "src/cpu-profiler.h" |
#include "src/execution.h" |
-#include "src/isolate.h" |
#include "src/objects.h" |
#include "src/parser.h" |
#include "src/smart-pointers.h" |
@@ -51,7 +49,6 @@ |
#include "src/unicode-inl.h" |
#include "src/utils.h" |
#include "src/vm-state.h" |
-#include "test/cctest/cctest.h" |
static const bool kLogThreading = false; |
@@ -893,32 +890,6 @@ THREADED_TEST(GlobalProperties) { |
} |
-template<typename T> |
-static void CheckReturnValue(const T& t, i::Address callback) { |
- v8::ReturnValue<v8::Value> rv = t.GetReturnValue(); |
- i::Object** o = *reinterpret_cast<i::Object***>(&rv); |
- CHECK_EQ(CcTest::isolate(), t.GetIsolate()); |
- CHECK_EQ(t.GetIsolate(), rv.GetIsolate()); |
- CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); |
- // Verify reset |
- bool is_runtime = (*o)->IsTheHole(); |
- rv.Set(true); |
- CHECK(!(*o)->IsTheHole() && !(*o)->IsUndefined()); |
- rv.Set(v8::Handle<v8::Object>()); |
- CHECK((*o)->IsTheHole() || (*o)->IsUndefined()); |
- CHECK_EQ(is_runtime, (*o)->IsTheHole()); |
- |
- i::Isolate* isolate = reinterpret_cast<i::Isolate*>(t.GetIsolate()); |
- // 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(v8::EXTERNAL, isolate->current_vm_state()); |
- CHECK(isolate->external_callback_scope()); |
- CHECK_EQ(callback, isolate->external_callback_scope()->callback()); |
- } |
-} |
- |
- |
static void handle_callback_impl(const v8::FunctionCallbackInfo<Value>& info, |
i::Address callback) { |
ApiTestFuzzer::Fuzz(); |
@@ -1908,18 +1879,6 @@ THREADED_TEST(DescriptorInheritance) { |
} |
-int echo_named_call_count; |
- |
- |
-static void EchoNamedProperty(Local<Name> name, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CHECK(v8_str("data")->Equals(info.Data())); |
- echo_named_call_count++; |
- info.GetReturnValue().Set(name); |
-} |
- |
- |
// Helper functions for Interceptor/Accessor interaction tests |
void SimpleAccessorGetter(Local<String> name, |
@@ -1967,213 +1926,6 @@ static void ThrowingSymbolAccessorGetter( |
} |
-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_"; |
- int i; |
- for (i = 0; name_str[i] && prefix[i]; ++i) { |
- if (name_str[i] != prefix[i]) return; |
- } |
- Handle<Object> self = Handle<Object>::Cast(info.This()); |
- info.GetReturnValue().Set(self->GetHiddenValue(v8_str(name_str + i))); |
-} |
- |
- |
-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); |
- char* name_str = *utf8; |
- char prefix[] = "accessor_"; |
- int i; |
- for (i = 0; name_str[i] && prefix[i]; ++i) { |
- if (name_str[i] != prefix[i]) break; |
- } |
- if (!prefix[i]) return; |
- |
- if (value->IsInt32() && value->Int32Value() < 10000) { |
- Handle<Object> self = Handle<Object>::Cast(info.This()); |
- self->SetHiddenValue(name, value); |
- info.GetReturnValue().Set(value); |
- } |
-} |
- |
-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, |
- v8::AccessorSetterCallback setter) { |
- templ->PrototypeTemplate()->SetAccessor(name, getter, setter); |
-} |
- |
-void AddInterceptor(Handle<FunctionTemplate> templ, |
- v8::NamedPropertyGetterCallback getter, |
- v8::NamedPropertySetterCallback setter) { |
- templ->InstanceTemplate()->SetNamedPropertyHandler(getter, setter); |
-} |
- |
- |
-void AddAccessor(Handle<FunctionTemplate> templ, |
- Handle<Name> name, |
- v8::AccessorNameGetterCallback getter, |
- v8::AccessorNameSetterCallback setter) { |
- 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()); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
- child->Inherit(parent); |
- AddAccessor(parent, v8_str("age"), |
- SimpleAccessorGetter, SimpleAccessorSetter); |
- AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "child.age = 10;"); |
- ExpectBoolean("child.hasOwnProperty('age')", false); |
- ExpectInt32("child.age", 10); |
- ExpectInt32("child.accessor_age", 10); |
-} |
- |
- |
-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); |
@@ -2194,469 +1946,6 @@ THREADED_TEST(ExecutableAccessorIsPreservedOnAttributeChange) { |
} |
-THREADED_TEST(EmptyInterceptorBreakTransitions) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Constructor"), templ->GetFunction()); |
- CompileRun("var o1 = new Constructor;" |
- "o1.a = 1;" // Ensure a and x share the descriptor array. |
- "Object.defineProperty(o1, 'x', {value: 10});"); |
- CompileRun("var o2 = new Constructor;" |
- "o2.a = 1;" |
- "Object.defineProperty(o2, 'x', {value: 10});"); |
-} |
- |
- |
-THREADED_TEST(EmptyInterceptorDoesNotShadowJSAccessors) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
- child->Inherit(parent); |
- AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "var parent = child.__proto__;" |
- "Object.defineProperty(parent, 'age', " |
- " {get: function(){ return this.accessor_age; }, " |
- " set: function(v){ this.accessor_age = v; }, " |
- " enumerable: true, configurable: true});" |
- "child.age = 10;"); |
- ExpectBoolean("child.hasOwnProperty('age')", false); |
- ExpectInt32("child.age", 10); |
- ExpectInt32("child.accessor_age", 10); |
-} |
- |
- |
-THREADED_TEST(EmptyInterceptorDoesNotShadowApiAccessors) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
- auto returns_42 = FunctionTemplate::New(isolate, Returns42); |
- parent->PrototypeTemplate()->SetAccessorProperty(v8_str("age"), returns_42); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
- child->Inherit(parent); |
- AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun( |
- "var child = new Child;" |
- "var parent = child.__proto__;"); |
- ExpectBoolean("child.hasOwnProperty('age')", false); |
- ExpectInt32("child.age", 42); |
- // Check interceptor followup. |
- ExpectInt32( |
- "var result;" |
- "for (var i = 0; i < 4; ++i) {" |
- " result = child.age;" |
- "}" |
- "result", |
- 42); |
-} |
- |
- |
-THREADED_TEST(EmptyInterceptorDoesNotAffectJSProperties) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(isolate); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(isolate); |
- child->Inherit(parent); |
- AddInterceptor(child, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "var parent = child.__proto__;" |
- "parent.name = 'Alice';"); |
- ExpectBoolean("child.hasOwnProperty('name')", false); |
- ExpectString("child.name", "Alice"); |
- CompileRun("child.name = 'Bob';"); |
- ExpectString("child.name", "Bob"); |
- ExpectBoolean("child.hasOwnProperty('name')", true); |
- ExpectString("parent.name", "Alice"); |
-} |
- |
- |
-THREADED_TEST(SwitchFromInterceptorToAccessor) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddAccessor(templ, v8_str("age"), |
- SimpleAccessorGetter, SimpleAccessorSetter); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "function setAge(i){ obj.age = i; };" |
- "for(var i = 0; i <= 10000; i++) setAge(i);"); |
- // All i < 10000 go to the interceptor. |
- ExpectInt32("obj.interceptor_age", 9999); |
- // The last i goes to the accessor. |
- ExpectInt32("obj.accessor_age", 10000); |
-} |
- |
- |
-THREADED_TEST(SwitchFromAccessorToInterceptor) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddAccessor(templ, v8_str("age"), |
- SimpleAccessorGetter, SimpleAccessorSetter); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "function setAge(i){ obj.age = i; };" |
- "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
- // All i >= 10000 go to the accessor. |
- ExpectInt32("obj.accessor_age", 10000); |
- // The last i goes to the interceptor. |
- ExpectInt32("obj.interceptor_age", 9999); |
-} |
- |
- |
-THREADED_TEST(SwitchFromInterceptorToAccessorWithInheritance) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
- child->Inherit(parent); |
- AddAccessor(parent, v8_str("age"), |
- SimpleAccessorGetter, SimpleAccessorSetter); |
- AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "function setAge(i){ child.age = i; };" |
- "for(var i = 0; i <= 10000; i++) setAge(i);"); |
- // All i < 10000 go to the interceptor. |
- ExpectInt32("child.interceptor_age", 9999); |
- // The last i goes to the accessor. |
- ExpectInt32("child.accessor_age", 10000); |
-} |
- |
- |
-THREADED_TEST(SwitchFromAccessorToInterceptorWithInheritance) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
- child->Inherit(parent); |
- AddAccessor(parent, v8_str("age"), |
- SimpleAccessorGetter, SimpleAccessorSetter); |
- AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "function setAge(i){ child.age = i; };" |
- "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
- // All i >= 10000 go to the accessor. |
- ExpectInt32("child.accessor_age", 10000); |
- // The last i goes to the interceptor. |
- ExpectInt32("child.interceptor_age", 9999); |
-} |
- |
- |
-THREADED_TEST(SwitchFromInterceptorToJSAccessor) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "function setter(i) { this.accessor_age = i; };" |
- "function getter() { return this.accessor_age; };" |
- "function setAge(i) { obj.age = i; };" |
- "Object.defineProperty(obj, 'age', { get:getter, set:setter });" |
- "for(var i = 0; i <= 10000; i++) setAge(i);"); |
- // All i < 10000 go to the interceptor. |
- ExpectInt32("obj.interceptor_age", 9999); |
- // The last i goes to the JavaScript accessor. |
- ExpectInt32("obj.accessor_age", 10000); |
- // The installed JavaScript getter is still intact. |
- // This last part is a regression test for issue 1651 and relies on the fact |
- // that both interceptor and accessor are being installed on the same object. |
- ExpectInt32("obj.age", 10000); |
- ExpectBoolean("obj.hasOwnProperty('age')", true); |
- ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); |
-} |
- |
- |
-THREADED_TEST(SwitchFromJSAccessorToInterceptor) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "function setter(i) { this.accessor_age = i; };" |
- "function getter() { return this.accessor_age; };" |
- "function setAge(i) { obj.age = i; };" |
- "Object.defineProperty(obj, 'age', { get:getter, set:setter });" |
- "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
- // All i >= 10000 go to the accessor. |
- ExpectInt32("obj.accessor_age", 10000); |
- // The last i goes to the interceptor. |
- ExpectInt32("obj.interceptor_age", 9999); |
- // The installed JavaScript getter is still intact. |
- // This last part is a regression test for issue 1651 and relies on the fact |
- // that both interceptor and accessor are being installed on the same object. |
- ExpectInt32("obj.age", 10000); |
- ExpectBoolean("obj.hasOwnProperty('age')", true); |
- ExpectUndefined("Object.getOwnPropertyDescriptor(obj, 'age').value"); |
-} |
- |
- |
-THREADED_TEST(SwitchFromInterceptorToProperty) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
- child->Inherit(parent); |
- AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "function setAge(i){ child.age = i; };" |
- "for(var i = 0; i <= 10000; i++) setAge(i);"); |
- // All i < 10000 go to the interceptor. |
- ExpectInt32("child.interceptor_age", 9999); |
- // The last i goes to child's own property. |
- ExpectInt32("child.age", 10000); |
-} |
- |
- |
-THREADED_TEST(SwitchFromPropertyToInterceptor) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> parent = FunctionTemplate::New(CcTest::isolate()); |
- Handle<FunctionTemplate> child = FunctionTemplate::New(CcTest::isolate()); |
- child->Inherit(parent); |
- AddInterceptor(child, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Child"), child->GetFunction()); |
- CompileRun("var child = new Child;" |
- "function setAge(i){ child.age = i; };" |
- "for(var i = 20000; i >= 9999; i--) setAge(i);"); |
- // All i >= 10000 go to child's own property. |
- ExpectInt32("child.age", 10000); |
- // The last i goes to the interceptor. |
- ExpectInt32("child.interceptor_age", 9999); |
-} |
- |
- |
-THREADED_TEST(NamedPropertyHandlerGetter) { |
- echo_named_call_count = 0; |
- v8::HandleScope scope(CcTest::isolate()); |
- v8::Handle<v8::FunctionTemplate> templ = |
- v8::FunctionTemplate::New(CcTest::isolate()); |
- templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
- EchoNamedProperty, 0, 0, 0, 0, v8_str("data"))); |
- LocalContext env; |
- env->Global()->Set(v8_str("obj"), |
- templ->GetFunction()->NewInstance()); |
- CHECK_EQ(echo_named_call_count, 0); |
- v8_compile("obj.x")->Run(); |
- CHECK_EQ(echo_named_call_count, 1); |
- const char* code = "var str = 'oddle'; obj[str] + obj.poddle;"; |
- v8::Handle<Value> str = CompileRun(code); |
- String::Utf8Value value(str); |
- CHECK_EQ(0, strcmp(*value, "oddlepoddle")); |
- // Check default behavior |
- CHECK_EQ(10, v8_compile("obj.flob = 10;")->Run()->Int32Value()); |
- CHECK(v8_compile("'myProperty' in obj")->Run()->BooleanValue()); |
- CHECK(v8_compile("delete obj.myProperty")->Run()->BooleanValue()); |
-} |
- |
- |
-int echo_indexed_call_count = 0; |
- |
- |
-static void EchoIndexedProperty( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CHECK(v8_num(637)->Equals(info.Data())); |
- echo_indexed_call_count++; |
- info.GetReturnValue().Set(v8_num(index)); |
-} |
- |
- |
-THREADED_TEST(IndexedPropertyHandlerGetter) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
- templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
- EchoIndexedProperty, 0, 0, 0, 0, v8_num(637))); |
- LocalContext env; |
- env->Global()->Set(v8_str("obj"), |
- templ->GetFunction()->NewInstance()); |
- Local<Script> script = v8_compile("obj[900]"); |
- CHECK_EQ(script->Run()->Int32Value(), 900); |
-} |
- |
- |
-v8::Handle<v8::Object> bottom; |
- |
-static void CheckThisIndexedPropertyHandler( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyHandler)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
-static void CheckThisNamedPropertyHandler( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyHandler)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
-void CheckThisIndexedPropertySetter( |
- uint32_t index, |
- Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertySetter)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisNamedPropertySetter( |
- Local<Name> property, Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertySetter)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
-void CheckThisIndexedPropertyQuery( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Integer>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyQuery)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisNamedPropertyQuery( |
- Local<Name> property, const v8::PropertyCallbackInfo<v8::Integer>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyQuery)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisIndexedPropertyDeleter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyDeleter)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisNamedPropertyDeleter( |
- Local<Name> property, const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyDeleter)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisIndexedPropertyEnumerator( |
- const v8::PropertyCallbackInfo<v8::Array>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisIndexedPropertyEnumerator)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-void CheckThisNamedPropertyEnumerator( |
- const v8::PropertyCallbackInfo<v8::Array>& info) { |
- CheckReturnValue(info, FUNCTION_ADDR(CheckThisNamedPropertyEnumerator)); |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.This()->Equals(bottom)); |
-} |
- |
- |
-THREADED_PROFILED_TEST(PropertyHandlerInPrototype) { |
- LocalContext env; |
- v8::Isolate* isolate = env->GetIsolate(); |
- v8::HandleScope scope(isolate); |
- |
- // Set up a prototype chain with three interceptors. |
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
- templ->InstanceTemplate()->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
- CheckThisIndexedPropertyHandler, CheckThisIndexedPropertySetter, |
- CheckThisIndexedPropertyQuery, CheckThisIndexedPropertyDeleter, |
- CheckThisIndexedPropertyEnumerator)); |
- |
- templ->InstanceTemplate()->SetHandler(v8::NamedPropertyHandlerConfiguration( |
- CheckThisNamedPropertyHandler, CheckThisNamedPropertySetter, |
- CheckThisNamedPropertyQuery, CheckThisNamedPropertyDeleter, |
- CheckThisNamedPropertyEnumerator)); |
- |
- bottom = templ->GetFunction()->NewInstance(); |
- Local<v8::Object> top = templ->GetFunction()->NewInstance(); |
- Local<v8::Object> middle = templ->GetFunction()->NewInstance(); |
- |
- bottom->SetPrototype(middle); |
- middle->SetPrototype(top); |
- env->Global()->Set(v8_str("obj"), bottom); |
- |
- // Indexed and named get. |
- CompileRun("obj[0]"); |
- CompileRun("obj.x"); |
- |
- // Indexed and named set. |
- CompileRun("obj[1] = 42"); |
- CompileRun("obj.y = 42"); |
- |
- // Indexed and named query. |
- CompileRun("0 in obj"); |
- CompileRun("'x' in obj"); |
- |
- // Indexed and named deleter. |
- CompileRun("delete obj[0]"); |
- CompileRun("delete obj.x"); |
- |
- // Enumerators. |
- CompileRun("for (var p in obj) ;"); |
-} |
- |
- |
-static void PrePropertyHandlerGet( |
- Local<Name> key, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (v8_str("pre")->Equals(key)) { |
- info.GetReturnValue().Set(v8_str("PrePropertyHandler: pre")); |
- } |
-} |
- |
- |
-static void PrePropertyHandlerQuery( |
- Local<Name> key, const v8::PropertyCallbackInfo<v8::Integer>& info) { |
- if (v8_str("pre")->Equals(key)) { |
- info.GetReturnValue().Set(static_cast<int32_t>(v8::None)); |
- } |
-} |
- |
- |
-THREADED_TEST(PrePropertyHandler) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
- 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"); |
- CHECK(v8_str("PrePropertyHandler: pre")->Equals(result_pre)); |
- v8::Handle<Value> result_on = CompileRun("on"); |
- CHECK(v8_str("Object: on")->Equals(result_on)); |
- v8::Handle<Value> result_post = CompileRun("post"); |
- CHECK(result_post.IsEmpty()); |
-} |
- |
- |
THREADED_TEST(UndefinedIsNotEnumerable) { |
LocalContext env; |
v8::HandleScope scope(env->GetIsolate()); |
@@ -2743,11 +2032,11 @@ THREADED_TEST(CallbackExceptionRegression) { |
ThrowingPropertyHandlerGet, ThrowingPropertyHandlerSet)); |
LocalContext env; |
env->Global()->Set(v8_str("obj"), obj->NewInstance()); |
- v8::Handle<Value> otto = CompileRun( |
- "try { with (obj) { otto; } } catch (e) { e; }"); |
+ v8::Handle<Value> otto = |
+ CompileRun("try { with (obj) { otto; } } catch (e) { e; }"); |
CHECK(v8_str("otto")->Equals(otto)); |
- v8::Handle<Value> netto = CompileRun( |
- "try { with (obj) { netto = 4; } } catch (e) { e; }"); |
+ v8::Handle<Value> netto = |
+ CompileRun("try { with (obj) { netto = 4; } } catch (e) { e; }"); |
CHECK(v8_str("netto")->Equals(netto)); |
} |
@@ -2843,8 +2132,7 @@ THREADED_TEST(InternalFieldsAlignedPointers) { |
} |
-static void CheckAlignedPointerInEmbedderData(LocalContext* env, |
- int index, |
+static void CheckAlignedPointerInEmbedderData(LocalContext* env, int index, |
void* value) { |
CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1)); |
(*env)->SetAlignedPointerInEmbedderData(index, value); |
@@ -2885,8 +2173,7 @@ THREADED_TEST(EmbedderDataAlignedPointers) { |
} |
-static void CheckEmbedderData(LocalContext* env, |
- int index, |
+static void CheckEmbedderData(LocalContext* env, int index, |
v8::Handle<Value> data) { |
(*env)->SetEmbedderData(index, data); |
CHECK((*env)->GetEmbedderData(index)->StrictEquals(data)); |
@@ -2899,10 +2186,9 @@ THREADED_TEST(EmbedderData) { |
v8::HandleScope scope(isolate); |
CheckEmbedderData( |
- &env, 3, |
- v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); |
- CheckEmbedderData(&env, 2, v8::String::NewFromUtf8(isolate, |
- "over the lazy dog.")); |
+ &env, 3, v8::String::NewFromUtf8(isolate, "The quick brown fox jumps")); |
+ CheckEmbedderData(&env, 2, |
+ v8::String::NewFromUtf8(isolate, "over the lazy dog.")); |
CheckEmbedderData(&env, 1, v8::Number::New(isolate, 1.2345)); |
CheckEmbedderData(&env, 0, v8::Boolean::New(isolate, true)); |
} |
@@ -3036,10 +2322,8 @@ THREADED_TEST(SymbolProperties) { |
v8::Local<v8::Object> obj = v8::Object::New(isolate); |
v8::Local<v8::Symbol> sym1 = v8::Symbol::New(isolate); |
- v8::Local<v8::Symbol> sym2 = |
- v8::Symbol::New(isolate, v8_str("my-symbol")); |
- v8::Local<v8::Symbol> sym3 = |
- v8::Symbol::New(isolate, v8_str("sym3")); |
+ v8::Local<v8::Symbol> sym2 = v8::Symbol::New(isolate, v8_str("my-symbol")); |
+ v8::Local<v8::Symbol> sym3 = v8::Symbol::New(isolate, v8_str("sym3")); |
CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
@@ -3099,8 +2383,8 @@ THREADED_TEST(SymbolProperties) { |
CHECK(obj->Get(sym3)->IsUndefined()); |
CHECK(obj->Set(sym3, v8::Integer::New(isolate, 42))); |
CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
- CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( |
- v8::Integer::New(isolate, 42))); |
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
+ ->Equals(v8::Integer::New(isolate, 42))); |
// Add another property and delete it afterwards to force the object in |
// slow case. |
@@ -3121,8 +2405,8 @@ THREADED_TEST(SymbolProperties) { |
CHECK(obj->Has(v8::String::NewFromUtf8(isolate, "accessor_sym3"))); |
CHECK_EQ(2002, obj->Get(sym1)->Int32Value()); |
CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
- CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( |
- v8::Integer::New(isolate, 42))); |
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
+ ->Equals(v8::Integer::New(isolate, 42))); |
CHECK_EQ(2u, obj->GetOwnPropertyNames()->Length()); |
// Symbol properties are inherited. |
@@ -3131,8 +2415,8 @@ THREADED_TEST(SymbolProperties) { |
CHECK(child->Has(sym1)); |
CHECK_EQ(2002, child->Get(sym1)->Int32Value()); |
CHECK(obj->Get(sym3)->Equals(v8::Integer::New(isolate, 42))); |
- CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3"))->Equals( |
- v8::Integer::New(isolate, 42))); |
+ CHECK(obj->Get(v8::String::NewFromUtf8(isolate, "accessor_sym3")) |
+ ->Equals(v8::Integer::New(isolate, 42))); |
CHECK_EQ(0u, child->GetOwnPropertyNames()->Length()); |
} |
@@ -3282,12 +2566,12 @@ THREADED_TEST(GlobalPrivates) { |
class ScopedArrayBufferContents { |
public: |
- explicit ScopedArrayBufferContents( |
- const v8::ArrayBuffer::Contents& contents) |
- : contents_(contents) {} |
+ explicit ScopedArrayBufferContents(const v8::ArrayBuffer::Contents& contents) |
+ : contents_(contents) {} |
~ScopedArrayBufferContents() { free(contents_.Data()); } |
void* Data() const { return contents_.Data(); } |
size_t ByteLength() const { return contents_.ByteLength(); } |
+ |
private: |
const v8::ArrayBuffer::Contents contents_; |
}; |
@@ -3323,10 +2607,11 @@ THREADED_TEST(ArrayBuffer_ApiInternalToExternal) { |
v8::Handle<v8::Value> result = CompileRun("ab.byteLength"); |
CHECK_EQ(1024, result->Int32Value()); |
- result = CompileRun("var u8 = new Uint8Array(ab);" |
- "u8[0] = 0xFF;" |
- "u8[1] = 0xAA;" |
- "u8.length"); |
+ result = CompileRun( |
+ "var u8 = new Uint8Array(ab);" |
+ "u8[0] = 0xFF;" |
+ "u8[1] = 0xAA;" |
+ "u8.length"); |
CHECK_EQ(1024, result->Int32Value()); |
CHECK_EQ(0xFF, data[0]); |
CHECK_EQ(0xAA, data[1]); |
@@ -3343,11 +2628,11 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { |
v8::HandleScope handle_scope(isolate); |
- v8::Local<v8::Value> result = |
- CompileRun("var ab1 = new ArrayBuffer(2);" |
- "var u8_a = new Uint8Array(ab1);" |
- "u8_a[0] = 0xAA;" |
- "u8_a[1] = 0xFF; u8_a.buffer"); |
+ v8::Local<v8::Value> result = CompileRun( |
+ "var ab1 = new ArrayBuffer(2);" |
+ "var u8_a = new Uint8Array(ab1);" |
+ "u8_a[0] = 0xAA;" |
+ "u8_a[1] = 0xFF; u8_a.buffer"); |
Local<v8::ArrayBuffer> ab1 = Local<v8::ArrayBuffer>::Cast(result); |
CheckInternalFieldsAreZero(ab1); |
CHECK_EQ(2, static_cast<int>(ab1->ByteLength())); |
@@ -3361,9 +2646,10 @@ THREADED_TEST(ArrayBuffer_JSInternalToExternal) { |
CHECK_EQ(0xAA, result->Int32Value()); |
result = CompileRun("u8_a[1]"); |
CHECK_EQ(0xFF, result->Int32Value()); |
- result = CompileRun("var u8_b = new Uint8Array(ab1);" |
- "u8_b[0] = 0xBB;" |
- "u8_a[0]"); |
+ result = CompileRun( |
+ "var u8_b = new Uint8Array(ab1);" |
+ "u8_b[0] = 0xBB;" |
+ "u8_a[0]"); |
CHECK_EQ(0xBB, result->Int32Value()); |
result = CompileRun("u8_b[1]"); |
CHECK_EQ(0xFF, result->Int32Value()); |
@@ -3397,10 +2683,11 @@ THREADED_TEST(ArrayBuffer_External) { |
v8::Handle<v8::Value> result = CompileRun("ab3.byteLength"); |
CHECK_EQ(100, result->Int32Value()); |
- result = CompileRun("var u8_b = new Uint8Array(ab3);" |
- "u8_b[0] = 0xBB;" |
- "u8_b[1] = 0xCC;" |
- "u8_b.length"); |
+ result = CompileRun( |
+ "var u8_b = new Uint8Array(ab3);" |
+ "u8_b[0] = 0xBB;" |
+ "u8_b[1] = 0xCC;" |
+ "u8_b.length"); |
CHECK_EQ(100, result->Int32Value()); |
CHECK_EQ(0xBB, my_data[0]); |
CHECK_EQ(0xCC, my_data[1]); |
@@ -3445,19 +2732,18 @@ static void CheckIsNeutered(v8::Handle<v8::TypedArray> ta) { |
static void CheckIsTypedArrayVarNeutered(const char* name) { |
i::ScopedVector<char> source(1024); |
i::SNPrintF(source, |
- "%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0", |
- name, name, name); |
+ "%s.byteLength == 0 && %s.byteOffset == 0 && %s.length == 0", |
+ name, name, name); |
CHECK(CompileRun(source.start())->IsTrue()); |
v8::Handle<v8::TypedArray> ta = |
- v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); |
+ v8::Handle<v8::TypedArray>::Cast(CompileRun(name)); |
CheckIsNeutered(ta); |
} |
template <typename TypedArray, int kElementSize> |
static Handle<TypedArray> CreateAndCheck(Handle<v8::ArrayBuffer> ab, |
- int byteOffset, |
- int length) { |
+ int byteOffset, int length) { |
v8::Handle<TypedArray> ta = TypedArray::New(ab, byteOffset, length); |
CheckInternalFieldsAreZero<v8::ArrayBufferView>(ta); |
CHECK_EQ(byteOffset, static_cast<int>(ta->ByteOffset())); |
@@ -3475,26 +2761,26 @@ THREADED_TEST(ArrayBuffer_NeuteringApi) { |
v8::Handle<v8::ArrayBuffer> buffer = v8::ArrayBuffer::New(isolate, 1024); |
v8::Handle<v8::Uint8Array> u8a = |
- CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); |
+ CreateAndCheck<v8::Uint8Array, 1>(buffer, 1, 1023); |
v8::Handle<v8::Uint8ClampedArray> u8c = |
- CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023); |
+ CreateAndCheck<v8::Uint8ClampedArray, 1>(buffer, 1, 1023); |
v8::Handle<v8::Int8Array> i8a = |
- CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023); |
+ CreateAndCheck<v8::Int8Array, 1>(buffer, 1, 1023); |
v8::Handle<v8::Uint16Array> u16a = |
- CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511); |
+ CreateAndCheck<v8::Uint16Array, 2>(buffer, 2, 511); |
v8::Handle<v8::Int16Array> i16a = |
- CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511); |
+ CreateAndCheck<v8::Int16Array, 2>(buffer, 2, 511); |
v8::Handle<v8::Uint32Array> u32a = |
- CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); |
+ CreateAndCheck<v8::Uint32Array, 4>(buffer, 4, 255); |
v8::Handle<v8::Int32Array> i32a = |
- CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); |
+ CreateAndCheck<v8::Int32Array, 4>(buffer, 4, 255); |
v8::Handle<v8::Float32Array> f32a = |
- CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); |
+ CreateAndCheck<v8::Float32Array, 4>(buffer, 4, 255); |
v8::Handle<v8::Float64Array> f64a = |
- CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); |
+ CreateAndCheck<v8::Float64Array, 8>(buffer, 8, 127); |
v8::Handle<v8::DataView> dv = v8::DataView::New(buffer, 1, 1023); |
CheckInternalFieldsAreZero<v8::ArrayBufferView>(dv); |
@@ -3539,7 +2825,7 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) { |
Local<v8::ArrayBuffer>::Cast(CompileRun("ab")); |
v8::Handle<v8::DataView> dv = |
- v8::Handle<v8::DataView>::Cast(CompileRun("dv")); |
+ v8::Handle<v8::DataView>::Cast(CompileRun("dv")); |
ScopedArrayBufferContents contents(ab->Externalize()); |
ab->Neuter(); |
@@ -3561,7 +2847,6 @@ THREADED_TEST(ArrayBuffer_NeuteringScript) { |
} |
- |
THREADED_TEST(HiddenProperties) { |
LocalContext env; |
v8::Isolate* isolate = env->GetIsolate(); |
@@ -3643,35 +2928,6 @@ THREADED_TEST(Regress97784) { |
} |
-static bool interceptor_for_hidden_properties_called; |
-static void InterceptorForHiddenProperties( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- interceptor_for_hidden_properties_called = true; |
-} |
- |
- |
-THREADED_TEST(HiddenPropertiesWithInterceptors) { |
- LocalContext context; |
- v8::Isolate* isolate = context->GetIsolate(); |
- v8::HandleScope scope(isolate); |
- |
- interceptor_for_hidden_properties_called = false; |
- |
- v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
- |
- // 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->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))); |
- CHECK_EQ(2302, obj->GetHiddenValue(key)->Int32Value()); |
- CHECK(!interceptor_for_hidden_properties_called); |
-} |
- |
- |
THREADED_TEST(External) { |
v8::HandleScope scope(CcTest::isolate()); |
int x = 3; |
@@ -3780,15 +3036,15 @@ THREADED_TEST(ResettingGlobalHandleToEmpty) { |
} |
-template<class T> |
+template <class T> |
static v8::UniquePersistent<T> PassUnique(v8::UniquePersistent<T> unique) { |
return unique.Pass(); |
} |
-template<class T> |
+template <class T> |
static v8::UniquePersistent<T> ReturnUnique(v8::Isolate* isolate, |
- const v8::Persistent<T> & global) { |
+ const v8::Persistent<T>& global) { |
v8::UniquePersistent<String> unique(isolate, global); |
return unique.Pass(); |
} |
@@ -3847,18 +3103,17 @@ THREADED_TEST(UniquePersistent) { |
} |
-template<typename K, typename V> |
+template <typename K, typename V> |
class WeakStdMapTraits : public v8::StdMapTraits<K, V> { |
public: |
- typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V> > |
- MapType; |
+ typedef typename v8::PersistentValueMap<K, V, WeakStdMapTraits<K, V>> MapType; |
static const v8::PersistentContainerCallbackType kCallbackType = v8::kWeak; |
struct WeakCallbackDataType { |
MapType* map; |
K key; |
}; |
- static WeakCallbackDataType* WeakCallbackParameter( |
- MapType* map, const K& key, Local<V> value) { |
+ static WeakCallbackDataType* WeakCallbackParameter(MapType* map, const K& key, |
+ Local<V> value) { |
WeakCallbackDataType* data = new WeakCallbackDataType; |
data->map = map; |
data->key = key; |
@@ -3872,15 +3127,13 @@ class WeakStdMapTraits : public v8::StdMapTraits<K, V> { |
const v8::WeakCallbackData<V, WeakCallbackDataType>& data) { |
return data.GetParameter()->key; |
} |
- static void DisposeCallbackData(WeakCallbackDataType* data) { |
- delete data; |
- } |
+ static void DisposeCallbackData(WeakCallbackDataType* data) { delete data; } |
static void Dispose(v8::Isolate* isolate, v8::UniquePersistent<V> value, |
- K key) { } |
+ K key) {} |
}; |
-template<typename Map> |
+template <typename Map> |
static void TestPersistentValueMap() { |
LocalContext env; |
v8::Isolate* isolate = env->GetIsolate(); |
@@ -3914,8 +3167,8 @@ static void TestPersistentValueMap() { |
{ |
typename Map::PersistentValueReference ref; |
Local<v8::Object> expected2 = v8::Object::New(isolate); |
- removed = map.Set(8, |
- v8::UniquePersistent<v8::Object>(isolate, expected2), &ref); |
+ removed = map.Set(8, v8::UniquePersistent<v8::Object>(isolate, expected2), |
+ &ref); |
CHECK_EQ(1, static_cast<int>(map.Size())); |
CHECK(expected == removed); |
CHECK(expected2->Equals(ref.NewLocal(isolate))); |
@@ -3923,8 +3176,9 @@ static void TestPersistentValueMap() { |
} |
CHECK_EQ(initial_handle_count + 1, global_handles->global_handles_count()); |
if (map.IsWeak()) { |
- reinterpret_cast<v8::internal::Isolate*>(isolate)->heap()-> |
- CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
+ reinterpret_cast<v8::internal::Isolate*>(isolate) |
+ ->heap() |
+ ->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
} else { |
map.Clear(); |
} |
@@ -3935,11 +3189,12 @@ static void TestPersistentValueMap() { |
TEST(PersistentValueMap) { |
// Default case, w/o weak callbacks: |
- TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object> >(); |
+ TestPersistentValueMap<v8::StdPersistentValueMap<int, v8::Object>>(); |
// Custom traits with weak callbacks: |
typedef v8::PersistentValueMap<int, v8::Object, |
- WeakStdMapTraits<int, v8::Object> > WeakPersistentValueMap; |
+ WeakStdMapTraits<int, v8::Object>> |
+ WeakPersistentValueMap; |
TestPersistentValueMap<WeakPersistentValueMap>(); |
} |
@@ -4048,17 +3303,18 @@ THREADED_TEST(LocalHandle) { |
class WeakCallCounter { |
public: |
- explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) { } |
+ explicit WeakCallCounter(int id) : id_(id), number_of_weak_calls_(0) {} |
int id() { return id_; } |
void increment() { number_of_weak_calls_++; } |
int NumberOfWeakCalls() { return number_of_weak_calls_; } |
+ |
private: |
int id_; |
int number_of_weak_calls_; |
}; |
-template<typename T> |
+template <typename T> |
struct WeakCallCounterAndPersistent { |
explicit WeakCallCounterAndPersistent(WeakCallCounter* counter) |
: counter(counter) {} |
@@ -4069,14 +3325,14 @@ struct WeakCallCounterAndPersistent { |
template <typename T> |
static void WeakPointerCallback( |
- const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T> >& data) { |
+ const v8::WeakCallbackData<T, WeakCallCounterAndPersistent<T>>& data) { |
CHECK_EQ(1234, data.GetParameter()->counter->id()); |
data.GetParameter()->counter->increment(); |
data.GetParameter()->handle.Reset(); |
} |
-template<typename T> |
+template <typename T> |
static UniqueId MakeUniqueId(const Persistent<T>& p) { |
return UniqueId(reinterpret_cast<uintptr_t>(*v8::Utils::OpenPersistent(p))); |
} |
@@ -4119,10 +3375,10 @@ THREADED_TEST(ApiObjectGroups) { |
// Connect group 1 and 2, make a cycle. |
{ |
HandleScope scope(iso); |
- CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>())-> |
- Set(0, Local<Value>::New(iso, g2s2.handle))); |
- CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>())-> |
- Set(0, Local<Value>::New(iso, g1s1.handle))); |
+ CHECK(Local<Object>::New(iso, g1s2.handle.As<Object>()) |
+ ->Set(0, Local<Value>::New(iso, g2s2.handle))); |
+ CHECK(Local<Object>::New(iso, g2s1.handle.As<Object>()) |
+ ->Set(0, Local<Value>::New(iso, g1s1.handle))); |
} |
{ |
@@ -4136,8 +3392,8 @@ THREADED_TEST(ApiObjectGroups) { |
iso->SetReferenceFromGroup(id2, g2c1.handle); |
} |
// Do a single full GC, ensure incremental marking is stopped. |
- v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
- iso)->heap(); |
+ v8::internal::Heap* heap = |
+ reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
// All object should be alive. |
@@ -4230,8 +3486,8 @@ THREADED_TEST(ApiObjectGroupsForSubtypes) { |
iso->SetReferenceFromGroup(id2, g2c1.handle); |
} |
// Do a single full GC, ensure incremental marking is stopped. |
- v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
- iso)->heap(); |
+ v8::internal::Heap* heap = |
+ reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
// All object should be alive. |
@@ -4342,8 +3598,8 @@ THREADED_TEST(ApiObjectGroupsCycle) { |
iso->SetReferenceFromGroup(id4, g1s1.handle); |
} |
// Do a single full GC |
- v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
- iso)->heap(); |
+ v8::internal::Heap* heap = |
+ reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
heap->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
// All object should be alive. |
@@ -4394,9 +3650,9 @@ THREADED_TEST(WeakRootsSurviveTwoRoundsOfGC) { |
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)); |
+ 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); |
@@ -4472,20 +3728,20 @@ TEST(ApiObjectGroupsCycleForScavenger) { |
g3s2.handle.MarkPartiallyDependent(); |
iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); |
iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); |
- Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
+ Local<Object>::New(iso, g1s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); |
iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); |
- Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
+ Local<Object>::New(iso, g2s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); |
iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); |
- Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
+ Local<Object>::New(iso, g3s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
} |
- v8::internal::Heap* heap = reinterpret_cast<v8::internal::Isolate*>( |
- iso)->heap(); |
+ v8::internal::Heap* heap = |
+ reinterpret_cast<v8::internal::Isolate*>(iso)->heap(); |
heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
// All objects should be alive. |
@@ -4506,16 +3762,16 @@ TEST(ApiObjectGroupsCycleForScavenger) { |
g3s2.handle.MarkPartiallyDependent(); |
iso->SetObjectGroupId(g1s1.handle, UniqueId(1)); |
iso->SetObjectGroupId(g1s2.handle, UniqueId(1)); |
- Local<Object>::New(iso, g1s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
+ Local<Object>::New(iso, g1s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g2s1.handle)); |
iso->SetObjectGroupId(g2s1.handle, UniqueId(2)); |
iso->SetObjectGroupId(g2s2.handle, UniqueId(2)); |
- Local<Object>::New(iso, g2s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
+ Local<Object>::New(iso, g2s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g3s1.handle)); |
iso->SetObjectGroupId(g3s1.handle, UniqueId(3)); |
iso->SetObjectGroupId(g3s2.handle, UniqueId(3)); |
- Local<Object>::New(iso, g3s1.handle.As<Object>())->Set( |
- v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
+ Local<Object>::New(iso, g3s1.handle.As<Object>()) |
+ ->Set(v8_str("x"), Local<Value>::New(iso, g1s1.handle)); |
} |
heap->CollectAllGarbage(i::Heap::kNoGCFlags); |
@@ -4543,11 +3799,14 @@ TEST(TryCatchCustomException) { |
v8::Isolate* isolate = env->GetIsolate(); |
v8::HandleScope scope(isolate); |
v8::TryCatch try_catch; |
- CompileRun("function CustomError() { this.a = 'b'; }" |
- "(function f() { throw new CustomError(); })();"); |
+ CompileRun( |
+ "function CustomError() { this.a = 'b'; }" |
+ "(function f() { throw new CustomError(); })();"); |
CHECK(try_catch.HasCaught()); |
- CHECK(try_catch.Exception()->ToObject(isolate)->Get(v8_str("a"))->Equals( |
- v8_str("b"))); |
+ CHECK(try_catch.Exception() |
+ ->ToObject(isolate) |
+ ->Get(v8_str("a")) |
+ ->Equals(v8_str("b"))); |
} |
@@ -4618,8 +3877,8 @@ TEST(MessageHandler2) { |
v8::V8::AddMessageListener(check_message_2); |
LocalContext context; |
v8::Local<v8::Value> error = v8::Exception::Error(v8_str("custom error")); |
- v8::Object::Cast(*error)->SetHiddenValue(v8_str("hidden key"), |
- v8_str("hidden value")); |
+ v8::Object::Cast(*error) |
+ ->SetHiddenValue(v8_str("hidden key"), v8_str("hidden value")); |
context->Global()->Set(v8_str("error"), error); |
CompileRun("throw error;"); |
CHECK(message_received); |
@@ -4649,8 +3908,8 @@ TEST(MessageHandler3) { |
v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
v8::Integer::New(isolate, 2), v8::True(isolate), |
Handle<v8::Integer>(), v8::True(isolate)); |
- v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), |
- &origin); |
+ v8::Handle<v8::Script> script = |
+ Script::Compile(v8_str("throw 'error'"), &origin); |
script->Run(); |
CHECK(message_received); |
// clear out the message listener |
@@ -4674,12 +3933,10 @@ TEST(MessageHandler4) { |
v8::V8::AddMessageListener(check_message_4); |
LocalContext context; |
v8::ScriptOrigin origin = |
- v8::ScriptOrigin(v8_str("6.75"), |
- v8::Integer::New(isolate, 1), |
- v8::Integer::New(isolate, 2), |
- v8::False(isolate)); |
- v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), |
- &origin); |
+ v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
+ v8::Integer::New(isolate, 2), v8::False(isolate)); |
+ v8::Handle<v8::Script> script = |
+ Script::Compile(v8_str("throw 'error'"), &origin); |
script->Run(); |
CHECK(message_received); |
// clear out the message listener |
@@ -4688,7 +3945,7 @@ TEST(MessageHandler4) { |
static void check_message_5a(v8::Handle<v8::Message> message, |
- v8::Handle<Value> data) { |
+ v8::Handle<Value> data) { |
CHECK(message->IsSharedCrossOrigin()); |
CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
message_received = true; |
@@ -4696,7 +3953,7 @@ static void check_message_5a(v8::Handle<v8::Message> message, |
static void check_message_5b(v8::Handle<v8::Message> message, |
- v8::Handle<Value> data) { |
+ v8::Handle<Value> data) { |
CHECK(!message->IsSharedCrossOrigin()); |
CHECK_EQ(6.75, message->GetScriptOrigin().ResourceName()->NumberValue()); |
message_received = true; |
@@ -4711,12 +3968,10 @@ TEST(MessageHandler5) { |
v8::V8::AddMessageListener(check_message_5a); |
LocalContext context; |
v8::ScriptOrigin origin = |
- v8::ScriptOrigin(v8_str("6.75"), |
- v8::Integer::New(isolate, 1), |
- v8::Integer::New(isolate, 2), |
- v8::True(isolate)); |
- v8::Handle<v8::Script> script = Script::Compile(v8_str("throw 'error'"), |
- &origin); |
+ v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
+ v8::Integer::New(isolate, 2), v8::True(isolate)); |
+ v8::Handle<v8::Script> script = |
+ Script::Compile(v8_str("throw 'error'"), &origin); |
script->Run(); |
CHECK(message_received); |
// clear out the message listener |
@@ -4724,13 +3979,9 @@ TEST(MessageHandler5) { |
message_received = false; |
v8::V8::AddMessageListener(check_message_5b); |
- origin = |
- v8::ScriptOrigin(v8_str("6.75"), |
- v8::Integer::New(isolate, 1), |
- v8::Integer::New(isolate, 2), |
- v8::False(isolate)); |
- script = Script::Compile(v8_str("throw 'error'"), |
- &origin); |
+ origin = v8::ScriptOrigin(v8_str("6.75"), v8::Integer::New(isolate, 1), |
+ v8::Integer::New(isolate, 2), v8::False(isolate)); |
+ script = Script::Compile(v8_str("throw 'error'"), &origin); |
script->Run(); |
CHECK(message_received); |
// clear out the message listener |
@@ -4916,8 +4167,7 @@ void HandleF(const v8::FunctionCallbackInfo<v8::Value>& args) { |
v8::EscapableHandleScope scope(args.GetIsolate()); |
ApiTestFuzzer::Fuzz(); |
Local<v8::Array> result = v8::Array::New(args.GetIsolate(), args.Length()); |
- for (int i = 0; i < args.Length(); i++) |
- result->Set(i, args[i]); |
+ for (int i = 0; i < args.Length(); i++) result->Set(i, args[i]); |
args.GetReturnValue().Set(scope.Escape(result)); |
} |
@@ -4966,20 +4216,20 @@ THREADED_TEST(FunctionCall) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope scope(isolate); |
CompileRun( |
- "function Foo() {" |
- " var result = [];" |
- " for (var i = 0; i < arguments.length; i++) {" |
- " result.push(arguments[i]);" |
- " }" |
- " return result;" |
- "}" |
- "function ReturnThisSloppy() {" |
- " return this;" |
- "}" |
- "function ReturnThisStrict() {" |
- " 'use strict';" |
- " return this;" |
- "}"); |
+ "function Foo() {" |
+ " var result = [];" |
+ " for (var i = 0; i < arguments.length; i++) {" |
+ " result.push(arguments[i]);" |
+ " }" |
+ " return result;" |
+ "}" |
+ "function ReturnThisSloppy() {" |
+ " return this;" |
+ "}" |
+ "function ReturnThisStrict() {" |
+ " 'use strict';" |
+ " return this;" |
+ "}"); |
Local<Function> Foo = |
Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); |
Local<Function> ReturnThisSloppy = |
@@ -4991,31 +4241,26 @@ THREADED_TEST(FunctionCall) { |
Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->Call(Foo, 0, args0)); |
CHECK_EQ(0u, a0->Length()); |
- v8::Handle<Value> args1[] = { v8_num(1.1) }; |
+ v8::Handle<Value> args1[] = {v8_num(1.1)}; |
Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->Call(Foo, 1, args1)); |
CHECK_EQ(1u, a1->Length()); |
CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
- v8::Handle<Value> args2[] = { v8_num(2.2), |
- v8_num(3.3) }; |
+ v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; |
Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->Call(Foo, 2, args2)); |
CHECK_EQ(2u, a2->Length()); |
CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
- v8::Handle<Value> args3[] = { v8_num(4.4), |
- v8_num(5.5), |
- v8_num(6.6) }; |
+ v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; |
Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->Call(Foo, 3, args3)); |
CHECK_EQ(3u, a3->Length()); |
CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
- v8::Handle<Value> args4[] = { v8_num(7.7), |
- v8_num(8.8), |
- v8_num(9.9), |
- v8_num(10.11) }; |
+ v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), |
+ v8_num(10.11)}; |
Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->Call(Foo, 4, args4)); |
CHECK_EQ(4u, a4->Length()); |
CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
@@ -5055,13 +4300,13 @@ THREADED_TEST(ConstructCall) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope scope(isolate); |
CompileRun( |
- "function Foo() {" |
- " var result = [];" |
- " for (var i = 0; i < arguments.length; i++) {" |
- " result.push(arguments[i]);" |
- " }" |
- " return result;" |
- "}"); |
+ "function Foo() {" |
+ " var result = [];" |
+ " for (var i = 0; i < arguments.length; i++) {" |
+ " result.push(arguments[i]);" |
+ " }" |
+ " return result;" |
+ "}"); |
Local<Function> Foo = |
Local<Function>::Cast(context->Global()->Get(v8_str("Foo"))); |
@@ -5069,31 +4314,26 @@ THREADED_TEST(ConstructCall) { |
Local<v8::Array> a0 = Local<v8::Array>::Cast(Foo->NewInstance(0, args0)); |
CHECK_EQ(0u, a0->Length()); |
- v8::Handle<Value> args1[] = { v8_num(1.1) }; |
+ v8::Handle<Value> args1[] = {v8_num(1.1)}; |
Local<v8::Array> a1 = Local<v8::Array>::Cast(Foo->NewInstance(1, args1)); |
CHECK_EQ(1u, a1->Length()); |
CHECK_EQ(1.1, a1->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
- v8::Handle<Value> args2[] = { v8_num(2.2), |
- v8_num(3.3) }; |
+ v8::Handle<Value> args2[] = {v8_num(2.2), v8_num(3.3)}; |
Local<v8::Array> a2 = Local<v8::Array>::Cast(Foo->NewInstance(2, args2)); |
CHECK_EQ(2u, a2->Length()); |
CHECK_EQ(2.2, a2->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
CHECK_EQ(3.3, a2->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
- v8::Handle<Value> args3[] = { v8_num(4.4), |
- v8_num(5.5), |
- v8_num(6.6) }; |
+ v8::Handle<Value> args3[] = {v8_num(4.4), v8_num(5.5), v8_num(6.6)}; |
Local<v8::Array> a3 = Local<v8::Array>::Cast(Foo->NewInstance(3, args3)); |
CHECK_EQ(3u, a3->Length()); |
CHECK_EQ(4.4, a3->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
CHECK_EQ(5.5, a3->Get(v8::Integer::New(isolate, 1))->NumberValue()); |
CHECK_EQ(6.6, a3->Get(v8::Integer::New(isolate, 2))->NumberValue()); |
- v8::Handle<Value> args4[] = { v8_num(7.7), |
- v8_num(8.8), |
- v8_num(9.9), |
- v8_num(10.11) }; |
+ v8::Handle<Value> args4[] = {v8_num(7.7), v8_num(8.8), v8_num(9.9), |
+ v8_num(10.11)}; |
Local<v8::Array> a4 = Local<v8::Array>::Cast(Foo->NewInstance(4, args4)); |
CHECK_EQ(4u, a4->Length()); |
CHECK_EQ(7.7, a4->Get(v8::Integer::New(isolate, 0))->NumberValue()); |
@@ -5217,9 +4457,9 @@ THREADED_TEST(ConversionException) { |
v8::Isolate* isolate = env->GetIsolate(); |
v8::HandleScope scope(isolate); |
CompileRun( |
- "function TestClass() { };" |
- "TestClass.prototype.toString = function () { throw 'uncle?'; };" |
- "var obj = new TestClass();"); |
+ "function TestClass() { };" |
+ "TestClass.prototype.toString = function () { throw 'uncle?'; };" |
+ "var obj = new TestClass();"); |
Local<Value> obj = env->Global()->Get(v8_str("obj")); |
v8::TryCatch try_catch(isolate); |
@@ -5294,12 +4534,12 @@ THREADED_TEST(APICatch) { |
v8::FunctionTemplate::New(isolate, ThrowFromC)); |
LocalContext context(0, templ); |
CompileRun( |
- "var thrown = false;" |
- "try {" |
- " ThrowFromC();" |
- "} catch (e) {" |
- " thrown = true;" |
- "}"); |
+ "var thrown = false;" |
+ "try {" |
+ " ThrowFromC();" |
+ "} catch (e) {" |
+ " thrown = true;" |
+ "}"); |
Local<Value> thrown = context->Global()->Get(v8_str("thrown")); |
CHECK(thrown->BooleanValue()); |
} |
@@ -5329,23 +4569,22 @@ TEST(TryCatchInTryFinally) { |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope scope(isolate); |
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->Set(v8_str("CCatcher"), |
- v8::FunctionTemplate::New(isolate, CCatcher)); |
+ templ->Set(v8_str("CCatcher"), v8::FunctionTemplate::New(isolate, CCatcher)); |
LocalContext context(0, templ); |
- Local<Value> result = CompileRun("try {" |
- " try {" |
- " CCatcher('throw 7;');" |
- " } finally {" |
- " }" |
- "} catch (e) {" |
- "}"); |
+ Local<Value> result = CompileRun( |
+ "try {" |
+ " try {" |
+ " CCatcher('throw 7;');" |
+ " } finally {" |
+ " }" |
+ "} catch (e) {" |
+ "}"); |
CHECK(result->IsTrue()); |
} |
-static void check_reference_error_message( |
- v8::Handle<v8::Message> message, |
- v8::Handle<v8::Value> data) { |
+static void check_reference_error_message(v8::Handle<v8::Message> message, |
+ v8::Handle<v8::Value> data) { |
const char* reference_error = "Uncaught ReferenceError: asdf is not defined"; |
CHECK(message->Get()->Equals(v8_str(reference_error))); |
} |
@@ -5368,17 +4607,19 @@ TEST(APIThrowMessageOverwrittenToString) { |
templ->Set(v8_str("fail"), v8::FunctionTemplate::New(isolate, Fail)); |
LocalContext context(NULL, templ); |
CompileRun("asdf;"); |
- CompileRun("var limit = {};" |
- "limit.valueOf = fail;" |
- "Error.stackTraceLimit = limit;"); |
+ CompileRun( |
+ "var limit = {};" |
+ "limit.valueOf = fail;" |
+ "Error.stackTraceLimit = limit;"); |
CompileRun("asdf"); |
CompileRun("Array.prototype.pop = fail;"); |
CompileRun("Object.prototype.hasOwnProperty = fail;"); |
CompileRun("Object.prototype.toString = function f() { return 'Yikes'; }"); |
CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }"); |
CompileRun("String.prototype.toString = function f() { return 'Yikes'; }"); |
- CompileRun("ReferenceError.prototype.toString =" |
- " function() { return 'Whoops' }"); |
+ CompileRun( |
+ "ReferenceError.prototype.toString =" |
+ " function() { return 'Whoops' }"); |
CompileRun("asdf;"); |
CompileRun("ReferenceError.prototype.constructor.name = void 0;"); |
CompileRun("asdf;"); |
@@ -5390,18 +4631,18 @@ TEST(APIThrowMessageOverwrittenToString) { |
CompileRun("asdf;"); |
v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }"); |
CHECK(string->Equals(v8_str("Whoops"))); |
- CompileRun("ReferenceError.prototype.constructor = new Object();" |
- "ReferenceError.prototype.constructor.name = 1;" |
- "Number.prototype.toString = function() { return 'Whoops'; };" |
- "ReferenceError.prototype.toString = Object.prototype.toString;"); |
+ CompileRun( |
+ "ReferenceError.prototype.constructor = new Object();" |
+ "ReferenceError.prototype.constructor.name = 1;" |
+ "Number.prototype.toString = function() { return 'Whoops'; };" |
+ "ReferenceError.prototype.toString = Object.prototype.toString;"); |
CompileRun("asdf;"); |
v8::V8::RemoveMessageListeners(check_reference_error_message); |
} |
-static void check_custom_error_tostring( |
- v8::Handle<v8::Message> message, |
- v8::Handle<v8::Value> data) { |
+static void check_custom_error_tostring(v8::Handle<v8::Message> message, |
+ v8::Handle<v8::Value> data) { |
const char* uncaught_error = "Uncaught MyError toString"; |
CHECK(message->Get()->Equals(v8_str(uncaught_error))); |
} |
@@ -5412,22 +4653,21 @@ TEST(CustomErrorToString) { |
v8::HandleScope scope(context->GetIsolate()); |
v8::V8::AddMessageListener(check_custom_error_tostring); |
CompileRun( |
- "function MyError(name, message) { " |
- " this.name = name; " |
- " this.message = message; " |
- "} " |
- "MyError.prototype = Object.create(Error.prototype); " |
- "MyError.prototype.toString = function() { " |
- " return 'MyError toString'; " |
- "}; " |
- "throw new MyError('my name', 'my message'); "); |
+ "function MyError(name, message) { " |
+ " this.name = name; " |
+ " this.message = message; " |
+ "} " |
+ "MyError.prototype = Object.create(Error.prototype); " |
+ "MyError.prototype.toString = function() { " |
+ " return 'MyError toString'; " |
+ "}; " |
+ "throw new MyError('my name', 'my message'); "); |
v8::V8::RemoveMessageListeners(check_custom_error_tostring); |
} |
-static void check_custom_error_message( |
- v8::Handle<v8::Message> message, |
- v8::Handle<v8::Value> data) { |
+static void check_custom_error_message(v8::Handle<v8::Message> message, |
+ v8::Handle<v8::Value> data) { |
const char* uncaught_error = "Uncaught MyError: my message"; |
printf("%s\n", *v8::String::Utf8Value(message->Get())); |
CHECK(message->Get()->Equals(v8_str(uncaught_error))); |
@@ -5441,37 +4681,37 @@ TEST(CustomErrorMessage) { |
// Handlebars. |
CompileRun( |
- "function MyError(msg) { " |
- " this.name = 'MyError'; " |
- " this.message = msg; " |
- "} " |
- "MyError.prototype = new Error(); " |
- "throw new MyError('my message'); "); |
+ "function MyError(msg) { " |
+ " this.name = 'MyError'; " |
+ " this.message = msg; " |
+ "} " |
+ "MyError.prototype = new Error(); " |
+ "throw new MyError('my message'); "); |
// Closure. |
CompileRun( |
- "function MyError(msg) { " |
- " this.name = 'MyError'; " |
- " this.message = msg; " |
- "} " |
- "inherits = function(childCtor, parentCtor) { " |
- " function tempCtor() {}; " |
- " tempCtor.prototype = parentCtor.prototype; " |
- " childCtor.superClass_ = parentCtor.prototype; " |
- " childCtor.prototype = new tempCtor(); " |
- " childCtor.prototype.constructor = childCtor; " |
- "}; " |
- "inherits(MyError, Error); " |
- "throw new MyError('my message'); "); |
+ "function MyError(msg) { " |
+ " this.name = 'MyError'; " |
+ " this.message = msg; " |
+ "} " |
+ "inherits = function(childCtor, parentCtor) { " |
+ " function tempCtor() {}; " |
+ " tempCtor.prototype = parentCtor.prototype; " |
+ " childCtor.superClass_ = parentCtor.prototype; " |
+ " childCtor.prototype = new tempCtor(); " |
+ " childCtor.prototype.constructor = childCtor; " |
+ "}; " |
+ "inherits(MyError, Error); " |
+ "throw new MyError('my message'); "); |
// Object.create. |
CompileRun( |
- "function MyError(msg) { " |
- " this.name = 'MyError'; " |
- " this.message = msg; " |
- "} " |
- "MyError.prototype = Object.create(Error.prototype); " |
- "throw new MyError('my message'); "); |
+ "function MyError(msg) { " |
+ " this.name = 'MyError'; " |
+ " this.message = msg; " |
+ "} " |
+ "MyError.prototype = Object.create(Error.prototype); " |
+ "throw new MyError('my message'); "); |
v8::V8::RemoveMessageListeners(check_custom_error_message); |
} |
@@ -5550,7 +4790,6 @@ THREADED_TEST(ExternalScriptException) { |
} |
- |
void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { |
ApiTestFuzzer::Fuzz(); |
CHECK_EQ(4, args.Length()); |
@@ -5560,13 +4799,9 @@ void CThrowCountDown(const v8::FunctionCallbackInfo<v8::Value>& args) { |
args.GetIsolate()->ThrowException(v8_str("FromC")); |
return; |
} else { |
- Local<v8::Object> global = |
- args.GetIsolate()->GetCurrentContext()->Global(); |
+ Local<v8::Object> global = args.GetIsolate()->GetCurrentContext()->Global(); |
Local<Value> fun = global->Get(v8_str("JSThrowCountDown")); |
- v8::Handle<Value> argv[] = { v8_num(count - 1), |
- args[1], |
- args[2], |
- args[3] }; |
+ v8::Handle<Value> argv[] = {v8_num(count - 1), args[1], args[2], args[3]}; |
if (count % cInterval == 0) { |
v8::TryCatch try_catch; |
Local<Value> result = fun.As<Function>()->Call(global, 4, argv); |
@@ -5606,13 +4841,14 @@ THREADED_TEST(EvalInTryFinally) { |
LocalContext context; |
v8::HandleScope scope(context->GetIsolate()); |
v8::TryCatch try_catch; |
- CompileRun("(function() {" |
- " try {" |
- " eval('asldkf (*&^&*^');" |
- " } finally {" |
- " return;" |
- " }" |
- "})()"); |
+ CompileRun( |
+ "(function() {" |
+ " try {" |
+ " eval('asldkf (*&^&*^');" |
+ " } finally {" |
+ " return;" |
+ " }" |
+ "})()"); |
CHECK(!try_catch.HasCaught()); |
} |
@@ -5646,23 +4882,23 @@ TEST(ExceptionOrder) { |
v8::FunctionTemplate::New(isolate, CThrowCountDown)); |
LocalContext context(0, templ); |
CompileRun( |
- "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" |
- " if (count == 0) throw 'FromJS';" |
- " if (count % jsInterval == 0) {" |
- " try {" |
- " var value = CThrowCountDown(count - 1," |
- " jsInterval," |
- " cInterval," |
- " expected);" |
- " check(false, count, expected);" |
- " return value;" |
- " } catch (e) {" |
- " check(true, count, expected);" |
- " }" |
- " } else {" |
- " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" |
- " }" |
- "}"); |
+ "function JSThrowCountDown(count, jsInterval, cInterval, expected) {" |
+ " if (count == 0) throw 'FromJS';" |
+ " if (count % jsInterval == 0) {" |
+ " try {" |
+ " var value = CThrowCountDown(count - 1," |
+ " jsInterval," |
+ " cInterval," |
+ " expected);" |
+ " check(false, count, expected);" |
+ " return value;" |
+ " } catch (e) {" |
+ " check(true, count, expected);" |
+ " }" |
+ " } else {" |
+ " return CThrowCountDown(count - 1, jsInterval, cInterval, expected);" |
+ " }" |
+ "}"); |
Local<Function> fun = |
Local<Function>::Cast(context->Global()->Get(v8_str("JSThrowCountDown"))); |
@@ -5670,27 +4906,27 @@ TEST(ExceptionOrder) { |
// count jsInterval cInterval expected |
// *JS[4] *C[3] @JS[2] C[1] JS[0] |
- v8::Handle<Value> a0[argc] = { v8_num(4), v8_num(2), v8_num(3), v8_num(2) }; |
+ v8::Handle<Value> a0[argc] = {v8_num(4), v8_num(2), v8_num(3), v8_num(2)}; |
fun->Call(fun, argc, a0); |
// JS[5] *C[4] JS[3] @C[2] JS[1] C[0] |
- v8::Handle<Value> a1[argc] = { v8_num(5), v8_num(6), v8_num(1), v8_num(2) }; |
+ v8::Handle<Value> a1[argc] = {v8_num(5), v8_num(6), v8_num(1), v8_num(2)}; |
fun->Call(fun, argc, a1); |
// JS[6] @C[5] JS[4] C[3] JS[2] C[1] JS[0] |
- v8::Handle<Value> a2[argc] = { v8_num(6), v8_num(7), v8_num(5), v8_num(5) }; |
+ v8::Handle<Value> a2[argc] = {v8_num(6), v8_num(7), v8_num(5), v8_num(5)}; |
fun->Call(fun, argc, a2); |
// @JS[6] C[5] JS[4] C[3] JS[2] C[1] JS[0] |
- v8::Handle<Value> a3[argc] = { v8_num(6), v8_num(6), v8_num(7), v8_num(6) }; |
+ v8::Handle<Value> a3[argc] = {v8_num(6), v8_num(6), v8_num(7), v8_num(6)}; |
fun->Call(fun, argc, a3); |
// JS[6] *C[5] @JS[4] C[3] JS[2] C[1] JS[0] |
- v8::Handle<Value> a4[argc] = { v8_num(6), v8_num(4), v8_num(5), v8_num(4) }; |
+ v8::Handle<Value> a4[argc] = {v8_num(6), v8_num(4), v8_num(5), v8_num(4)}; |
fun->Call(fun, argc, a4); |
// JS[6] C[5] *JS[4] @C[3] JS[2] C[1] JS[0] |
- v8::Handle<Value> a5[argc] = { v8_num(6), v8_num(4), v8_num(3), v8_num(3) }; |
+ v8::Handle<Value> a5[argc] = {v8_num(6), v8_num(4), v8_num(3), v8_num(3)}; |
fun->Call(fun, argc, a5); |
} |
@@ -5709,15 +4945,15 @@ THREADED_TEST(ThrowValues) { |
templ->Set(v8_str("Throw"), v8::FunctionTemplate::New(isolate, ThrowValue)); |
LocalContext context(0, templ); |
v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( |
- "function Run(obj) {" |
- " try {" |
- " Throw(obj);" |
- " } catch (e) {" |
- " return e;" |
- " }" |
- " return 'no exception';" |
- "}" |
- "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); |
+ "function Run(obj) {" |
+ " try {" |
+ " Throw(obj);" |
+ " } catch (e) {" |
+ " return e;" |
+ " }" |
+ " return 'no exception';" |
+ "}" |
+ "[Run('str'), Run(1), Run(0), Run(null), Run(void 0)];")); |
CHECK_EQ(5u, result->Length()); |
CHECK(result->Get(v8::Integer::New(isolate, 0))->IsString()); |
CHECK(result->Get(v8::Integer::New(isolate, 1))->IsNumber()); |
@@ -5844,8 +5080,8 @@ void TryCatchMixedNestingCheck(v8::TryCatch* try_catch) { |
Handle<Message> message = try_catch->Message(); |
Handle<Value> resource = message->GetScriptOrigin().ResourceName(); |
CHECK_EQ(0, strcmp(*v8::String::Utf8Value(resource), "inner")); |
- CHECK_EQ(0, strcmp(*v8::String::Utf8Value(message->Get()), |
- "Uncaught Error: a")); |
+ CHECK_EQ(0, |
+ strcmp(*v8::String::Utf8Value(message->Get()), "Uncaught Error: a")); |
CHECK_EQ(1, message->GetLineNumber()); |
CHECK_EQ(6, message->GetStartColumn()); |
} |
@@ -5975,8 +5211,7 @@ THREADED_TEST(MultiRun) { |
LocalContext context; |
v8::HandleScope scope(context->GetIsolate()); |
Local<Script> script = v8_compile("x"); |
- for (int i = 0; i < 10; i++) |
- script->Run(); |
+ for (int i = 0; i < 10; i++) script->Run(); |
} |
@@ -6121,14 +5356,14 @@ THREADED_TEST(DefineAPIAccessorOnObject) { |
CHECK(CompileRun("obj1.x")->IsUndefined()); |
CHECK(CompileRun("obj2.x")->IsUndefined()); |
- CHECK(GetGlobalProperty(&context, "obj1")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
ExpectString("obj1.x", "x"); |
CHECK(CompileRun("obj2.x")->IsUndefined()); |
- CHECK(GetGlobalProperty(&context, "obj2")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
ExpectString("obj1.x", "x"); |
ExpectString("obj2.x", "x"); |
@@ -6136,14 +5371,16 @@ THREADED_TEST(DefineAPIAccessorOnObject) { |
ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
- CompileRun("Object.defineProperty(obj1, 'x'," |
- "{ get: function() { return 'y'; }, configurable: true })"); |
+ CompileRun( |
+ "Object.defineProperty(obj1, 'x'," |
+ "{ get: function() { return 'y'; }, configurable: true })"); |
ExpectString("obj1.x", "y"); |
ExpectString("obj2.x", "x"); |
- CompileRun("Object.defineProperty(obj2, 'x'," |
- "{ get: function() { return 'y'; }, configurable: true })"); |
+ CompileRun( |
+ "Object.defineProperty(obj2, 'x'," |
+ "{ get: function() { return 'y'; }, configurable: true })"); |
ExpectString("obj1.x", "y"); |
ExpectString("obj2.x", "y"); |
@@ -6151,10 +5388,10 @@ THREADED_TEST(DefineAPIAccessorOnObject) { |
ExpectTrue("Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
- CHECK(GetGlobalProperty(&context, "obj1")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
- CHECK(GetGlobalProperty(&context, "obj2")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
ExpectString("obj1.x", "x"); |
ExpectString("obj2.x", "x"); |
@@ -6163,10 +5400,12 @@ THREADED_TEST(DefineAPIAccessorOnObject) { |
ExpectTrue("Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
// Define getters/setters, but now make them not configurable. |
- CompileRun("Object.defineProperty(obj1, 'x'," |
- "{ get: function() { return 'z'; }, configurable: false })"); |
- CompileRun("Object.defineProperty(obj2, 'x'," |
- "{ get: function() { return 'z'; }, configurable: false })"); |
+ CompileRun( |
+ "Object.defineProperty(obj1, 'x'," |
+ "{ get: function() { return 'z'; }, configurable: false })"); |
+ CompileRun( |
+ "Object.defineProperty(obj2, 'x'," |
+ "{ get: function() { return 'z'; }, configurable: false })"); |
ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
@@ -6174,10 +5413,10 @@ THREADED_TEST(DefineAPIAccessorOnObject) { |
ExpectString("obj1.x", "z"); |
ExpectString("obj2.x", "z"); |
- CHECK(!GetGlobalProperty(&context, "obj1")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
- CHECK(!GetGlobalProperty(&context, "obj2")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(!GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(!GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
ExpectString("obj1.x", "z"); |
ExpectString("obj2.x", "z"); |
@@ -6193,14 +5432,12 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { |
context->Global()->Set(v8_str("obj1"), templ->NewInstance()); |
CompileRun("var obj2 = {};"); |
- CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor( |
- v8_str("x"), |
- GetXValue, NULL, |
- v8_str("donut"), v8::DEFAULT, v8::DontDelete)); |
- CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor( |
- v8_str("x"), |
- GetXValue, NULL, |
- v8_str("donut"), v8::DEFAULT, v8::DontDelete)); |
+ CHECK(GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), |
+ v8::DEFAULT, v8::DontDelete)); |
+ CHECK(GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"), |
+ v8::DEFAULT, v8::DontDelete)); |
ExpectString("obj1.x", "x"); |
ExpectString("obj2.x", "x"); |
@@ -6208,14 +5445,15 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { |
ExpectTrue("!Object.getOwnPropertyDescriptor(obj1, 'x').configurable"); |
ExpectTrue("!Object.getOwnPropertyDescriptor(obj2, 'x').configurable"); |
- CHECK(!GetGlobalProperty(&context, "obj1")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
- CHECK(!GetGlobalProperty(&context, "obj2")-> |
- SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(!GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
+ CHECK(!GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("x"), GetXValue, NULL, v8_str("donut"))); |
{ |
v8::TryCatch try_catch; |
- CompileRun("Object.defineProperty(obj1, 'x'," |
+ CompileRun( |
+ "Object.defineProperty(obj1, 'x'," |
"{get: function() { return 'func'; }})"); |
CHECK(try_catch.HasCaught()); |
String::Utf8Value exception_value(try_catch.Exception()); |
@@ -6224,7 +5462,8 @@ THREADED_TEST(DontDeleteAPIAccessorsCannotBeOverriden) { |
} |
{ |
v8::TryCatch try_catch; |
- CompileRun("Object.defineProperty(obj2, 'x'," |
+ CompileRun( |
+ "Object.defineProperty(obj2, 'x'," |
"{get: function() { return 'func'; }})"); |
CHECK(try_catch.HasCaught()); |
String::Utf8Value exception_value(try_catch.Exception()); |
@@ -6252,14 +5491,10 @@ THREADED_TEST(ElementAPIAccessor) { |
context->Global()->Set(v8_str("obj1"), templ->NewInstance()); |
CompileRun("var obj2 = {};"); |
- CHECK(GetGlobalProperty(&context, "obj1")->SetAccessor( |
- v8_str("239"), |
- Get239Value, NULL, |
- v8_str("donut"))); |
- CHECK(GetGlobalProperty(&context, "obj2")->SetAccessor( |
- v8_str("239"), |
- Get239Value, NULL, |
- v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj1") |
+ ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); |
+ CHECK(GetGlobalProperty(&context, "obj2") |
+ ->SetAccessor(v8_str("239"), Get239Value, NULL, v8_str("donut"))); |
ExpectString("obj1[239]", "239"); |
ExpectString("obj2[239]", "239"); |
@@ -6271,8 +5506,7 @@ THREADED_TEST(ElementAPIAccessor) { |
v8::Persistent<Value> xValue; |
-static void SetXValue(Local<String> name, |
- Local<Value> value, |
+static void SetXValue(Local<String> name, Local<Value> value, |
const v8::PropertyCallbackInfo<void>& info) { |
CHECK(value->Equals(v8_num(4))); |
CHECK(info.Data()->Equals(v8_str("donut"))); |
@@ -6320,10 +5554,8 @@ THREADED_TEST(NoAccessors) { |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope scope(isolate); |
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetAccessor(v8_str("x"), |
- static_cast<v8::AccessorGetterCallback>(NULL), |
- NULL, |
- v8_str("donut")); |
+ templ->SetAccessor(v8_str("x"), static_cast<v8::AccessorGetterCallback>(NULL), |
+ NULL, v8_str("donut")); |
LocalContext context; |
context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
Local<Script> script = v8_compile("obj.x = 4; obj.x"); |
@@ -6333,1374 +5565,760 @@ THREADED_TEST(NoAccessors) { |
} |
-static void XPropertyGetter(Local<Name> property, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CHECK(info.Data()->IsUndefined()); |
- info.GetReturnValue().Set(property); |
-} |
- |
- |
-THREADED_TEST(NamedInterceptorPropertyRead) { |
+THREADED_TEST(MultiContexts) { |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); |
- LocalContext context; |
- context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
- Local<Script> script = v8_compile("obj.x"); |
- for (int i = 0; i < 10; i++) { |
- Local<Value> result = script->Run(); |
- CHECK(result->Equals(v8_str("x"))); |
- } |
-} |
- |
+ v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
+ templ->Set(v8_str("dummy"), |
+ v8::FunctionTemplate::New(isolate, DummyCallHandler)); |
-THREADED_TEST(NamedInterceptorDictionaryIC) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(XPropertyGetter)); |
- LocalContext context; |
- // Create an object with a named interceptor. |
- context->Global()->Set(v8_str("interceptor_obj"), templ->NewInstance()); |
- Local<Script> script = v8_compile("interceptor_obj.x"); |
- for (int i = 0; i < 10; i++) { |
- Local<Value> result = script->Run(); |
- CHECK(result->Equals(v8_str("x"))); |
- } |
- // Create a slow case object and a function accessing a property in |
- // that slow case object (with dictionary probing in generated |
- // code). Then force object with a named interceptor into slow-case, |
- // pass it to the function, and check that the interceptor is called |
- // instead of accessing the local property. |
- Local<Value> result = |
- CompileRun("function get_x(o) { return o.x; };" |
- "var obj = { x : 42, y : 0 };" |
- "delete obj.y;" |
- "for (var i = 0; i < 10; i++) get_x(obj);" |
- "interceptor_obj.x = 42;" |
- "interceptor_obj.y = 10;" |
- "delete interceptor_obj.y;" |
- "get_x(interceptor_obj)"); |
- CHECK(result->Equals(v8_str("x"))); |
-} |
- |
- |
-THREADED_TEST(NamedInterceptorDictionaryICMultipleContext) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Local<Context> context1 = Context::New(isolate); |
+ Local<String> password = v8_str("Password"); |
- context1->Enter(); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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); |
- |
- // Force the object into the slow case. |
- CompileRun("interceptor_obj.y = 0;" |
- "delete interceptor_obj.y;"); |
- context1->Exit(); |
+ // Create an environment |
+ LocalContext context0(0, templ); |
+ context0->SetSecurityToken(password); |
+ v8::Handle<v8::Object> global0 = context0->Global(); |
+ global0->Set(v8_str("custom"), v8_num(1234)); |
+ CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); |
- { |
- // Introduce the object into a different context. |
- // Repeat named loads to exercise ICs. |
- LocalContext context2; |
- context2->Global()->Set(v8_str("interceptor_obj"), object); |
- Local<Value> result = |
- CompileRun("function get_x(o) { return o.x; }" |
- "interceptor_obj.x = 42;" |
- "for (var i=0; i != 10; i++) {" |
- " get_x(interceptor_obj);" |
- "}" |
- "get_x(interceptor_obj)"); |
- // Check that the interceptor was actually invoked. |
- CHECK(result->Equals(v8_str("x"))); |
- } |
+ // Create an independent environment |
+ LocalContext context1(0, templ); |
+ context1->SetSecurityToken(password); |
+ v8::Handle<v8::Object> global1 = context1->Global(); |
+ global1->Set(v8_str("custom"), v8_num(1234)); |
+ CHECK(!global0->Equals(global1)); |
+ CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); |
+ CHECK_EQ(1234, global1->Get(v8_str("custom"))->Int32Value()); |
- // Return to the original context and force some object to the slow case |
- // to cause the NormalizedMapCache to verify. |
- context1->Enter(); |
- CompileRun("var obj = { x : 0 }; delete obj.x;"); |
- context1->Exit(); |
+ // Now create a new context with the old global |
+ LocalContext context2(0, templ, global1); |
+ context2->SetSecurityToken(password); |
+ v8::Handle<v8::Object> global2 = context2->Global(); |
+ CHECK(global1->Equals(global2)); |
+ CHECK_EQ(0, global1->Get(v8_str("custom"))->Int32Value()); |
+ CHECK_EQ(0, global2->Get(v8_str("custom"))->Int32Value()); |
} |
-static void SetXOnPrototypeGetter( |
- 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"), |
- v8::Integer::New(info.GetIsolate(), 23)); |
-} |
- |
+THREADED_TEST(FunctionPrototypeAcrossContexts) { |
+ // Make sure that functions created by cloning boilerplates cannot |
+ // communicate through their __proto__ field. |
-// This is a regression test for http://crbug.com/20104. Map |
-// transitions should not interfere with post interceptor lookup. |
-THREADED_TEST(NamedInterceptorMapTransitionRead) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<v8::FunctionTemplate> function_template = |
- v8::FunctionTemplate::New(isolate); |
- Local<v8::ObjectTemplate> instance_template |
- = function_template->InstanceTemplate(); |
- 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. |
- CompileRun("var o = new F(); o.x = 23;"); |
- // Create an instance of F and invoke the getter. The result should be 23. |
- Local<Value> result = CompileRun("o = new F(); o.x"); |
- CHECK_EQ(result->Int32Value(), 23); |
-} |
+ v8::HandleScope scope(CcTest::isolate()); |
+ LocalContext env0; |
+ v8::Handle<v8::Object> global0 = env0->Global(); |
+ v8::Handle<v8::Object> object0 = |
+ global0->Get(v8_str("Object")).As<v8::Object>(); |
+ v8::Handle<v8::Object> tostring0 = |
+ object0->Get(v8_str("toString")).As<v8::Object>(); |
+ v8::Handle<v8::Object> proto0 = |
+ tostring0->Get(v8_str("__proto__")).As<v8::Object>(); |
+ proto0->Set(v8_str("custom"), v8_num(1234)); |
-static void IndexedPropertyGetter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index == 37) { |
- info.GetReturnValue().Set(v8_num(625)); |
- } |
+ LocalContext env1; |
+ v8::Handle<v8::Object> global1 = env1->Global(); |
+ v8::Handle<v8::Object> object1 = |
+ global1->Get(v8_str("Object")).As<v8::Object>(); |
+ v8::Handle<v8::Object> tostring1 = |
+ object1->Get(v8_str("toString")).As<v8::Object>(); |
+ v8::Handle<v8::Object> proto1 = |
+ tostring1->Get(v8_str("__proto__")).As<v8::Object>(); |
+ CHECK(!proto1->Has(v8_str("custom"))); |
} |
-static void IndexedPropertySetter( |
- uint32_t index, |
- Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index == 39) { |
- info.GetReturnValue().Set(value); |
- } |
-} |
+THREADED_TEST(Regress892105) { |
+ // Make sure that object and array literals created by cloning |
+ // boilerplates cannot communicate through their __proto__ |
+ // field. This is rather difficult to check, but we try to add stuff |
+ // to Object.prototype and Array.prototype and create a new |
+ // environment. This should succeed. |
+ v8::HandleScope scope(CcTest::isolate()); |
-THREADED_TEST(IndexedInterceptorWithIndexedAccessor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::IndexedPropertyHandlerConfiguration( |
- IndexedPropertyGetter, IndexedPropertySetter)); |
- LocalContext context; |
- context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
- Local<Script> getter_script = v8_compile( |
- "obj.__defineGetter__(\"3\", function(){return 5;});obj[3];"); |
- Local<Script> setter_script = v8_compile( |
- "obj.__defineSetter__(\"17\", function(val){this.foo = val;});" |
- "obj[17] = 23;" |
- "obj.foo;"); |
- Local<Script> interceptor_setter_script = v8_compile( |
- "obj.__defineSetter__(\"39\", function(val){this.foo = \"hit\";});" |
- "obj[39] = 47;" |
- "obj.foo;"); // This setter should not run, due to the interceptor. |
- Local<Script> interceptor_getter_script = v8_compile( |
- "obj[37];"); |
- Local<Value> result = getter_script->Run(); |
- CHECK(v8_num(5)->Equals(result)); |
- result = setter_script->Run(); |
- CHECK(v8_num(23)->Equals(result)); |
- result = interceptor_setter_script->Run(); |
- CHECK(v8_num(23)->Equals(result)); |
- result = interceptor_getter_script->Run(); |
- CHECK(v8_num(625)->Equals(result)); |
-} |
- |
- |
-static void UnboxedDoubleIndexedPropertyGetter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index < 25) { |
- info.GetReturnValue().Set(v8_num(index)); |
- } |
-} |
+ Local<String> source = v8_str( |
+ "Object.prototype.obj = 1234;" |
+ "Array.prototype.arr = 4567;" |
+ "8901"); |
+ LocalContext env0; |
+ Local<Script> script0 = v8_compile(source); |
+ CHECK_EQ(8901.0, script0->Run()->NumberValue()); |
-static void UnboxedDoubleIndexedPropertySetter( |
- uint32_t index, |
- Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index < 25) { |
- info.GetReturnValue().Set(v8_num(index)); |
- } |
+ LocalContext env1; |
+ Local<Script> script1 = v8_compile(source); |
+ CHECK_EQ(8901.0, script1->Run()->NumberValue()); |
} |
-void UnboxedDoubleIndexedPropertyEnumerator( |
- const v8::PropertyCallbackInfo<v8::Array>& info) { |
- // Force the list of returned keys to be stored in a FastDoubleArray. |
- Local<Script> indexed_property_names_script = v8_compile( |
- "keys = new Array(); keys[125000] = 1;" |
- "for(i = 0; i < 80000; i++) { keys[i] = i; };" |
- "keys.length = 25; keys;"); |
- Local<Value> result = indexed_property_names_script->Run(); |
- info.GetReturnValue().Set(Local<v8::Array>::Cast(result)); |
-} |
+THREADED_TEST(UndetectableObject) { |
+ LocalContext env; |
+ v8::HandleScope scope(env->GetIsolate()); |
+ Local<v8::FunctionTemplate> desc = |
+ v8::FunctionTemplate::New(env->GetIsolate()); |
+ desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
-// Make sure that the the interceptor code in the runtime properly handles |
-// merging property name lists for double-array-backed arrays. |
-THREADED_TEST(IndexedInterceptorUnboxedDoubleWithIndexedAccessor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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. |
- Local<Script> create_unboxed_double_script = v8_compile( |
- "obj[125000] = 1; for(i = 0; i < 80000; i+=2) { obj[i] = i; } " |
- "key_count = 0; " |
- "for (x in obj) {key_count++;};" |
- "obj;"); |
- Local<Value> result = create_unboxed_double_script->Run(); |
- CHECK(result->ToObject(isolate)->HasRealIndexedProperty(2000)); |
- Local<Script> key_count_check = v8_compile("key_count;"); |
- result = key_count_check->Run(); |
- CHECK(v8_num(40013)->Equals(result)); |
-} |
- |
- |
-void SloppyArgsIndexedPropertyEnumerator( |
- const v8::PropertyCallbackInfo<v8::Array>& info) { |
- // Force the list of returned keys to be stored in a Arguments object. |
- Local<Script> indexed_property_names_script = v8_compile( |
- "function f(w,x) {" |
- " return arguments;" |
- "}" |
- "keys = f(0, 1, 2, 3);" |
- "keys;"); |
- Local<Object> result = |
- Local<Object>::Cast(indexed_property_names_script->Run()); |
- // Have to populate the handle manually, as it's not Cast-able. |
- i::Handle<i::JSObject> o = |
- v8::Utils::OpenHandle<Object, i::JSObject>(result); |
- i::Handle<i::JSArray> array(reinterpret_cast<i::JSArray*>(*o)); |
- info.GetReturnValue().Set(v8::Utils::ToLocal(array)); |
-} |
+ Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8_str("undetectable"), obj); |
+ ExpectString("undetectable.toString()", "[object Object]"); |
+ ExpectString("typeof undetectable", "undefined"); |
+ ExpectString("typeof(undetectable)", "undefined"); |
+ ExpectBoolean("typeof undetectable == 'undefined'", true); |
+ ExpectBoolean("typeof undetectable == 'object'", false); |
+ ExpectBoolean("if (undetectable) { true; } else { false; }", false); |
+ ExpectBoolean("!undetectable", true); |
-static void SloppyIndexedPropertyGetter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index < 4) { |
- info.GetReturnValue().Set(v8_num(index)); |
- } |
-} |
+ ExpectObject("true&&undetectable", obj); |
+ ExpectBoolean("false&&undetectable", false); |
+ ExpectBoolean("true||undetectable", true); |
+ ExpectObject("false||undetectable", obj); |
+ ExpectObject("undetectable&&true", obj); |
+ ExpectObject("undetectable&&false", obj); |
+ ExpectBoolean("undetectable||true", true); |
+ ExpectBoolean("undetectable||false", false); |
-// Make sure that the the interceptor code in the runtime properly handles |
-// merging property name lists for non-string arguments arrays. |
-THREADED_TEST(IndexedInterceptorSloppyArgsWithIndexedAccessor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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( |
- "var key_count = 0;" |
- "for (x in obj) {key_count++;} key_count;"); |
- Local<Value> result = create_args_script->Run(); |
- CHECK(v8_num(4)->Equals(result)); |
-} |
+ ExpectBoolean("undetectable==null", true); |
+ ExpectBoolean("null==undetectable", true); |
+ ExpectBoolean("undetectable==undefined", true); |
+ ExpectBoolean("undefined==undetectable", true); |
+ ExpectBoolean("undetectable==undetectable", true); |
-static void IdentityIndexedPropertyGetter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- info.GetReturnValue().Set(index); |
+ ExpectBoolean("undetectable===null", false); |
+ ExpectBoolean("null===undetectable", false); |
+ ExpectBoolean("undetectable===undefined", false); |
+ ExpectBoolean("undefined===undetectable", false); |
+ ExpectBoolean("undetectable===undetectable", true); |
} |
-THREADED_TEST(IndexedInterceptorWithGetOwnPropertyDescriptor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
+THREADED_TEST(VoidLiteral) { |
+ LocalContext env; |
+ v8::Isolate* isolate = env->GetIsolate(); |
v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
- // Check fast object case. |
- const char* fast_case_code = |
- "Object.getOwnPropertyDescriptor(obj, 0).value.toString()"; |
- ExpectString(fast_case_code, "0"); |
- |
- // Check slow case. |
- const char* slow_case_code = |
- "obj.x = 1; delete obj.x;" |
- "Object.getOwnPropertyDescriptor(obj, 1).value.toString()"; |
- ExpectString(slow_case_code, "1"); |
-} |
+ Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
+ desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
+ Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8_str("undetectable"), obj); |
-THREADED_TEST(IndexedInterceptorWithNoSetter) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+ ExpectBoolean("undefined == void 0", true); |
+ ExpectBoolean("undetectable == void 0", true); |
+ ExpectBoolean("null == void 0", true); |
+ ExpectBoolean("undefined === void 0", true); |
+ ExpectBoolean("undetectable === void 0", false); |
+ ExpectBoolean("null === void 0", false); |
- LocalContext context; |
- context->Global()->Set(v8_str("obj"), templ->NewInstance()); |
+ ExpectBoolean("void 0 == undefined", true); |
+ ExpectBoolean("void 0 == undetectable", true); |
+ ExpectBoolean("void 0 == null", true); |
+ ExpectBoolean("void 0 === undefined", true); |
+ ExpectBoolean("void 0 === undetectable", false); |
+ ExpectBoolean("void 0 === null", false); |
- const char* code = |
- "try {" |
- " obj[0] = 239;" |
- " for (var i = 0; i < 100; i++) {" |
- " var v = obj[0];" |
- " if (v != 0) throw 'Wrong value ' + v + ' at iteration ' + i;" |
+ ExpectString( |
+ "(function() {" |
+ " try {" |
+ " return x === void 0;" |
+ " } catch(e) {" |
+ " return e.toString();" |
" }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+ "})()", |
+ "ReferenceError: x is not defined"); |
+ ExpectString( |
+ "(function() {" |
+ " try {" |
+ " return void 0 === x;" |
+ " } catch(e) {" |
+ " return e.toString();" |
+ " }" |
+ "})()", |
+ "ReferenceError: x is not defined"); |
} |
-THREADED_TEST(IndexedInterceptorWithAccessorCheck) { |
- v8::Isolate* isolate = CcTest::isolate(); |
+THREADED_TEST(ExtensibleOnUndetectable) { |
+ LocalContext env; |
+ v8::Isolate* isolate = env->GetIsolate(); |
v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- obj->TurnOnAccessCheck(); |
- context->Global()->Set(v8_str("obj"), obj); |
+ Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
+ desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
- const char* code = |
- "var result = 'PASSED';" |
- "for (var i = 0; i < 100; i++) {" |
- " try {" |
- " var v = obj[0];" |
- " result = 'Wrong value ' + v + ' at iteration ' + i;" |
- " break;" |
- " } catch (e) {" |
- " /* pass */" |
- " }" |
- "}" |
- "result"; |
- ExpectString(code, "PASSED"); |
-} |
+ Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
+ env->Global()->Set(v8_str("undetectable"), obj); |
+ Local<String> source = v8_str( |
+ "undetectable.x = 42;" |
+ "undetectable.x"); |
-THREADED_TEST(IndexedInterceptorWithAccessorCheckSwitchedOn) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+ Local<Script> script = v8_compile(source); |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
+ CHECK(v8::Integer::New(isolate, 42)->Equals(script->Run())); |
- const char* code = |
- "var result = 'PASSED';" |
- "for (var i = 0; i < 100; i++) {" |
- " var expected = i;" |
- " if (i == 5) {" |
- " %EnableAccessChecks(obj);" |
- " }" |
- " try {" |
- " var v = obj[i];" |
- " if (i == 5) {" |
- " result = 'Should not have reached this!';" |
- " break;" |
- " } else if (v != expected) {" |
- " result = 'Wrong value ' + v + ' at iteration ' + i;" |
- " break;" |
- " }" |
- " } catch (e) {" |
- " if (i != 5) {" |
- " result = e;" |
- " }" |
- " }" |
- " if (i == 5) %DisableAccessChecks(obj);" |
- "}" |
- "result"; |
- ExpectString(code, "PASSED"); |
+ ExpectBoolean("Object.isExtensible(undetectable)", true); |
+ |
+ source = v8_str("Object.preventExtensions(undetectable);"); |
+ script = v8_compile(source); |
+ script->Run(); |
+ ExpectBoolean("Object.isExtensible(undetectable)", false); |
+ |
+ source = v8_str("undetectable.y = 2000;"); |
+ script = v8_compile(source); |
+ script->Run(); |
+ ExpectBoolean("undetectable.y == undefined", true); |
} |
-THREADED_TEST(IndexedInterceptorWithDifferentIndices) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+THREADED_TEST(UndetectableString) { |
+ LocalContext env; |
+ v8::HandleScope scope(env->GetIsolate()); |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
+ Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", |
+ String::kUndetectableString); |
+ env->Global()->Set(v8_str("undetectable"), obj); |
- const char* code = |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var v = obj[i];" |
- " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
-} |
+ ExpectString("undetectable", "foo"); |
+ ExpectString("typeof undetectable", "undefined"); |
+ ExpectString("typeof(undetectable)", "undefined"); |
+ ExpectBoolean("typeof undetectable == 'undefined'", true); |
+ ExpectBoolean("typeof undetectable == 'string'", false); |
+ ExpectBoolean("if (undetectable) { true; } else { false; }", false); |
+ ExpectBoolean("!undetectable", true); |
+ ExpectObject("true&&undetectable", obj); |
+ ExpectBoolean("false&&undetectable", false); |
+ ExpectBoolean("true||undetectable", true); |
+ ExpectObject("false||undetectable", obj); |
-THREADED_TEST(IndexedInterceptorWithNegativeIndices) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+ ExpectObject("undetectable&&true", obj); |
+ ExpectObject("undetectable&&false", obj); |
+ ExpectBoolean("undetectable||true", true); |
+ ExpectBoolean("undetectable||false", false); |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
+ ExpectBoolean("undetectable==null", true); |
+ ExpectBoolean("null==undetectable", true); |
+ ExpectBoolean("undetectable==undefined", true); |
+ ExpectBoolean("undefined==undetectable", true); |
+ ExpectBoolean("undetectable==undetectable", true); |
- const char* code = |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var expected = i;" |
- " var key = i;" |
- " if (i == 25) {" |
- " key = -1;" |
- " expected = undefined;" |
- " }" |
- " if (i == 50) {" |
- " /* probe minimal Smi number on 32-bit platforms */" |
- " key = -(1 << 30);" |
- " expected = undefined;" |
- " }" |
- " if (i == 75) {" |
- " /* probe minimal Smi number on 64-bit platforms */" |
- " key = 1 << 31;" |
- " expected = undefined;" |
- " }" |
- " var v = obj[key];" |
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+ |
+ ExpectBoolean("undetectable===null", false); |
+ ExpectBoolean("null===undetectable", false); |
+ ExpectBoolean("undetectable===undefined", false); |
+ ExpectBoolean("undefined===undetectable", false); |
+ ExpectBoolean("undetectable===undetectable", true); |
} |
-THREADED_TEST(IndexedInterceptorWithNotSmiLookup) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+TEST(UndetectableOptimized) { |
+ i::FLAG_allow_natives_syntax = true; |
+ LocalContext env; |
+ v8::HandleScope scope(env->GetIsolate()); |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
+ Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", |
+ String::kUndetectableString); |
+ env->Global()->Set(v8_str("undetectable"), obj); |
+ env->Global()->Set(v8_str("detectable"), v8_str("bar")); |
- const char* code = |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var expected = i;" |
- " var key = i;" |
- " if (i == 50) {" |
- " key = 'foobar';" |
- " expected = undefined;" |
- " }" |
- " var v = obj[key];" |
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+ ExpectString( |
+ "function testBranch() {" |
+ " if (!%_IsUndetectableObject(undetectable)) throw 1;" |
+ " if (%_IsUndetectableObject(detectable)) throw 2;" |
+ "}\n" |
+ "function testBool() {" |
+ " var b1 = !%_IsUndetectableObject(undetectable);" |
+ " var b2 = %_IsUndetectableObject(detectable);" |
+ " if (b1) throw 3;" |
+ " if (b2) throw 4;" |
+ " return b1 == b2;" |
+ "}\n" |
+ "%OptimizeFunctionOnNextCall(testBranch);" |
+ "%OptimizeFunctionOnNextCall(testBool);" |
+ "for (var i = 0; i < 10; i++) {" |
+ " testBranch();" |
+ " testBool();" |
+ "}\n" |
+ "\"PASS\"", |
+ "PASS"); |
} |
-THREADED_TEST(IndexedInterceptorGoingMegamorphic) { |
+// The point of this test is type checking. We run it only so compilers |
+// don't complain about an unused function. |
+TEST(PersistentHandles) { |
+ LocalContext env; |
v8::Isolate* isolate = CcTest::isolate(); |
v8::HandleScope scope(isolate); |
+ Local<String> str = v8_str("foo"); |
+ v8::Persistent<String> p_str(isolate, str); |
+ p_str.Reset(); |
+ Local<Script> scr = v8_compile(""); |
+ v8::Persistent<Script> p_scr(isolate, scr); |
+ p_scr.Reset(); |
Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+ v8::Persistent<ObjectTemplate> p_templ(isolate, templ); |
+ p_templ.Reset(); |
+} |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
- const char* code = |
- "var original = obj;" |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var expected = i;" |
- " if (i == 50) {" |
- " obj = {50: 'foobar'};" |
- " expected = 'foobar';" |
- " }" |
- " var v = obj[i];" |
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " if (i == 50) obj = original;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+static void HandleLogDelegator( |
+ const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ ApiTestFuzzer::Fuzz(); |
} |
-THREADED_TEST(IndexedInterceptorReceiverTurningSmi) { |
+THREADED_TEST(GlobalObjectTemplate) { |
v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
- |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
- |
- const char* code = |
- "var original = obj;" |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var expected = i;" |
- " if (i == 5) {" |
- " obj = 239;" |
- " expected = undefined;" |
- " }" |
- " var v = obj[i];" |
- " if (v != expected) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " if (i == 5) obj = original;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+ v8::HandleScope handle_scope(isolate); |
+ Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); |
+ global_template->Set(v8_str("JSNI_Log"), |
+ v8::FunctionTemplate::New(isolate, HandleLogDelegator)); |
+ v8::Local<Context> context = Context::New(isolate, 0, global_template); |
+ Context::Scope context_scope(context); |
+ CompileRun("JSNI_Log('LOG')"); |
} |
-THREADED_TEST(IndexedInterceptorOnProto) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::IndexedPropertyHandlerConfiguration(IdentityIndexedPropertyGetter)); |
+static const char* kSimpleExtensionSource = |
+ "function Foo() {" |
+ " return 4;" |
+ "}"; |
- LocalContext context; |
- Local<v8::Object> obj = templ->NewInstance(); |
- context->Global()->Set(v8_str("obj"), obj); |
- const char* code = |
- "var o = {__proto__: obj};" |
- "try {" |
- " for (var i = 0; i < 100; i++) {" |
- " var v = o[i];" |
- " if (v != i) throw 'Wrong value ' + v + ' at iteration ' + i;" |
- " }" |
- " 'PASSED'" |
- "} catch(e) {" |
- " e" |
- "}"; |
- ExpectString(code, "PASSED"); |
+TEST(SimpleExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); |
+ const char* extension_names[] = {"simpletest"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("Foo()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
} |
-THREADED_TEST(MultiContexts) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->Set(v8_str("dummy"), v8::FunctionTemplate::New(isolate, |
- DummyCallHandler)); |
- |
- Local<String> password = v8_str("Password"); |
- |
- // Create an environment |
- LocalContext context0(0, templ); |
- context0->SetSecurityToken(password); |
- v8::Handle<v8::Object> global0 = context0->Global(); |
- global0->Set(v8_str("custom"), v8_num(1234)); |
- CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); |
+static const char* kStackTraceFromExtensionSource = |
+ "function foo() {" |
+ " throw new Error();" |
+ "}" |
+ "function bar() {" |
+ " foo();" |
+ "}"; |
- // Create an independent environment |
- LocalContext context1(0, templ); |
- context1->SetSecurityToken(password); |
- v8::Handle<v8::Object> global1 = context1->Global(); |
- global1->Set(v8_str("custom"), v8_num(1234)); |
- CHECK(!global0->Equals(global1)); |
- CHECK_EQ(1234, global0->Get(v8_str("custom"))->Int32Value()); |
- CHECK_EQ(1234, global1->Get(v8_str("custom"))->Int32Value()); |
- // Now create a new context with the old global |
- LocalContext context2(0, templ, global1); |
- context2->SetSecurityToken(password); |
- v8::Handle<v8::Object> global2 = context2->Global(); |
- CHECK(global1->Equals(global2)); |
- CHECK_EQ(0, global1->Get(v8_str("custom"))->Int32Value()); |
- CHECK_EQ(0, global2->Get(v8_str("custom"))->Int32Value()); |
+TEST(StackTraceInExtension) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension( |
+ new Extension("stacktracetest", kStackTraceFromExtensionSource)); |
+ const char* extension_names[] = {"stacktracetest"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ CompileRun( |
+ "function user() { bar(); }" |
+ "var error;" |
+ "try{ user(); } catch (e) { error = e; }"); |
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value()); |
+ CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value()); |
+ CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value()); |
} |
-THREADED_TEST(FunctionPrototypeAcrossContexts) { |
- // Make sure that functions created by cloning boilerplates cannot |
- // communicate through their __proto__ field. |
- |
- v8::HandleScope scope(CcTest::isolate()); |
- |
- LocalContext env0; |
- v8::Handle<v8::Object> global0 = |
- env0->Global(); |
- v8::Handle<v8::Object> object0 = |
- global0->Get(v8_str("Object")).As<v8::Object>(); |
- v8::Handle<v8::Object> tostring0 = |
- object0->Get(v8_str("toString")).As<v8::Object>(); |
- v8::Handle<v8::Object> proto0 = |
- tostring0->Get(v8_str("__proto__")).As<v8::Object>(); |
- proto0->Set(v8_str("custom"), v8_num(1234)); |
- |
- LocalContext env1; |
- v8::Handle<v8::Object> global1 = |
- env1->Global(); |
- v8::Handle<v8::Object> object1 = |
- global1->Get(v8_str("Object")).As<v8::Object>(); |
- v8::Handle<v8::Object> tostring1 = |
- object1->Get(v8_str("toString")).As<v8::Object>(); |
- v8::Handle<v8::Object> proto1 = |
- tostring1->Get(v8_str("__proto__")).As<v8::Object>(); |
- CHECK(!proto1->Has(v8_str("custom"))); |
+TEST(NullExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension(new Extension("nulltest", NULL)); |
+ const char* extension_names[] = {"nulltest"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("1+3"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
} |
-THREADED_TEST(Regress892105) { |
- // Make sure that object and array literals created by cloning |
- // boilerplates cannot communicate through their __proto__ |
- // field. This is rather difficult to check, but we try to add stuff |
- // to Object.prototype and Array.prototype and create a new |
- // environment. This should succeed. |
+static const char* kEmbeddedExtensionSource = |
+ "function Ret54321(){return 54321;}~~@@$" |
+ "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; |
+static const int kEmbeddedExtensionSourceValidLen = 34; |
- v8::HandleScope scope(CcTest::isolate()); |
- Local<String> source = v8_str("Object.prototype.obj = 1234;" |
- "Array.prototype.arr = 4567;" |
- "8901"); |
+TEST(ExtensionMissingSourceLength) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension( |
+ new Extension("srclentest_fail", kEmbeddedExtensionSource)); |
+ const char* extension_names[] = {"srclentest_fail"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ CHECK(0 == *context); |
+} |
- LocalContext env0; |
- Local<Script> script0 = v8_compile(source); |
- CHECK_EQ(8901.0, script0->Run()->NumberValue()); |
- LocalContext env1; |
- Local<Script> script1 = v8_compile(source); |
- CHECK_EQ(8901.0, script1->Run()->NumberValue()); |
+TEST(ExtensionWithSourceLength) { |
+ for (int source_len = kEmbeddedExtensionSourceValidLen - 1; |
+ source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ i::ScopedVector<char> extension_name(32); |
+ i::SNPrintF(extension_name, "ext #%d", source_len); |
+ v8::RegisterExtension(new Extension( |
+ extension_name.start(), kEmbeddedExtensionSource, 0, 0, source_len)); |
+ const char* extension_names[1] = {extension_name.start()}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ if (source_len == kEmbeddedExtensionSourceValidLen) { |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("Ret54321()"); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 54321)->Equals(result)); |
+ } else { |
+ // Anything but exactly the right length should fail to compile. |
+ CHECK(0 == *context); |
+ } |
+ } |
} |
-THREADED_TEST(UndetectableObject) { |
- LocalContext env; |
- v8::HandleScope scope(env->GetIsolate()); |
+static const char* kEvalExtensionSource1 = |
+ "function UseEval1() {" |
+ " var x = 42;" |
+ " return eval('x');" |
+ "}"; |
- Local<v8::FunctionTemplate> desc = |
- v8::FunctionTemplate::New(env->GetIsolate()); |
- desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
- Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
- env->Global()->Set(v8_str("undetectable"), obj); |
+static const char* kEvalExtensionSource2 = |
+ "(function() {" |
+ " var x = 42;" |
+ " function e() {" |
+ " return eval('x');" |
+ " }" |
+ " this.UseEval2 = e;" |
+ "})()"; |
- ExpectString("undetectable.toString()", "[object Object]"); |
- ExpectString("typeof undetectable", "undefined"); |
- ExpectString("typeof(undetectable)", "undefined"); |
- ExpectBoolean("typeof undetectable == 'undefined'", true); |
- ExpectBoolean("typeof undetectable == 'object'", false); |
- ExpectBoolean("if (undetectable) { true; } else { false; }", false); |
- ExpectBoolean("!undetectable", true); |
- ExpectObject("true&&undetectable", obj); |
- ExpectBoolean("false&&undetectable", false); |
- ExpectBoolean("true||undetectable", true); |
- ExpectObject("false||undetectable", obj); |
+TEST(UseEvalFromExtension) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); |
+ v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); |
+ const char* extension_names[] = {"evaltest1", "evaltest2"}; |
+ v8::ExtensionConfiguration extensions(2, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("UseEval1()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
+ result = CompileRun("UseEval2()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
+} |
- ExpectObject("undetectable&&true", obj); |
- ExpectObject("undetectable&&false", obj); |
- ExpectBoolean("undetectable||true", true); |
- ExpectBoolean("undetectable||false", false); |
- ExpectBoolean("undetectable==null", true); |
- ExpectBoolean("null==undetectable", true); |
- ExpectBoolean("undetectable==undefined", true); |
- ExpectBoolean("undefined==undetectable", true); |
- ExpectBoolean("undetectable==undetectable", true); |
+static const char* kWithExtensionSource1 = |
+ "function UseWith1() {" |
+ " var x = 42;" |
+ " with({x:87}) { return x; }" |
+ "}"; |
- ExpectBoolean("undetectable===null", false); |
- ExpectBoolean("null===undetectable", false); |
- ExpectBoolean("undetectable===undefined", false); |
- ExpectBoolean("undefined===undetectable", false); |
- ExpectBoolean("undetectable===undetectable", true); |
-} |
+static const char* kWithExtensionSource2 = |
+ "(function() {" |
+ " var x = 42;" |
+ " function e() {" |
+ " with ({x:87}) { return x; }" |
+ " }" |
+ " this.UseWith2 = e;" |
+ "})()"; |
-THREADED_TEST(VoidLiteral) { |
- LocalContext env; |
- v8::Isolate* isolate = env->GetIsolate(); |
- v8::HandleScope scope(isolate); |
+TEST(UseWithFromExtension) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); |
+ v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); |
+ const char* extension_names[] = {"withtest1", "withtest2"}; |
+ v8::ExtensionConfiguration extensions(2, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("UseWith1()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
+ result = CompileRun("UseWith2()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
+} |
- Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
- desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
- Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
- env->Global()->Set(v8_str("undetectable"), obj); |
+TEST(AutoExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ Extension* extension = new Extension("autotest", kSimpleExtensionSource); |
+ extension->set_auto_enable(true); |
+ v8::RegisterExtension(extension); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate()); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("Foo()"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
+} |
- ExpectBoolean("undefined == void 0", true); |
- ExpectBoolean("undetectable == void 0", true); |
- ExpectBoolean("null == void 0", true); |
- ExpectBoolean("undefined === void 0", true); |
- ExpectBoolean("undetectable === void 0", false); |
- ExpectBoolean("null === void 0", false); |
- ExpectBoolean("void 0 == undefined", true); |
- ExpectBoolean("void 0 == undetectable", true); |
- ExpectBoolean("void 0 == null", true); |
- ExpectBoolean("void 0 === undefined", true); |
- ExpectBoolean("void 0 === undetectable", false); |
- ExpectBoolean("void 0 === null", false); |
+static const char* kSyntaxErrorInExtensionSource = "["; |
- ExpectString("(function() {" |
- " try {" |
- " return x === void 0;" |
- " } catch(e) {" |
- " return e.toString();" |
- " }" |
- "})()", |
- "ReferenceError: x is not defined"); |
- ExpectString("(function() {" |
- " try {" |
- " return void 0 === x;" |
- " } catch(e) {" |
- " return e.toString();" |
- " }" |
- "})()", |
- "ReferenceError: x is not defined"); |
-} |
+// Test that a syntax error in an extension does not cause a fatal |
+// error but results in an empty context. |
+TEST(SyntaxErrorExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension( |
+ new Extension("syntaxerror", kSyntaxErrorInExtensionSource)); |
+ const char* extension_names[] = {"syntaxerror"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ CHECK(context.IsEmpty()); |
+} |
-THREADED_TEST(ExtensibleOnUndetectable) { |
- LocalContext env; |
- v8::Isolate* isolate = env->GetIsolate(); |
- v8::HandleScope scope(isolate); |
- Local<v8::FunctionTemplate> desc = v8::FunctionTemplate::New(isolate); |
- desc->InstanceTemplate()->MarkAsUndetectable(); // undetectable |
+static const char* kExceptionInExtensionSource = "throw 42"; |
- Local<v8::Object> obj = desc->GetFunction()->NewInstance(); |
- env->Global()->Set(v8_str("undetectable"), obj); |
- Local<String> source = v8_str("undetectable.x = 42;" |
- "undetectable.x"); |
+// Test that an exception when installing an extension does not cause |
+// a fatal error but results in an empty context. |
+TEST(ExceptionExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension( |
+ new Extension("exception", kExceptionInExtensionSource)); |
+ const char* extension_names[] = {"exception"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ CHECK(context.IsEmpty()); |
+} |
- Local<Script> script = v8_compile(source); |
- CHECK(v8::Integer::New(isolate, 42)->Equals(script->Run())); |
+static const char* kNativeCallInExtensionSource = |
+ "function call_runtime_last_index_of(x) {" |
+ " return %StringLastIndexOf(x, 'bob', 10);" |
+ "}"; |
- ExpectBoolean("Object.isExtensible(undetectable)", true); |
- source = v8_str("Object.preventExtensions(undetectable);"); |
- script = v8_compile(source); |
- script->Run(); |
- ExpectBoolean("Object.isExtensible(undetectable)", false); |
+static const char* kNativeCallTest = |
+ "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; |
- source = v8_str("undetectable.y = 2000;"); |
- script = v8_compile(source); |
- script->Run(); |
- ExpectBoolean("undetectable.y == undefined", true); |
+// Test that a native runtime calls are supported in extensions. |
+TEST(NativeCallInExtensions) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::RegisterExtension( |
+ new Extension("nativecall", kNativeCallInExtensionSource)); |
+ const char* extension_names[] = {"nativecall"}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun(kNativeCallTest); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 3))); |
} |
+class NativeFunctionExtension : public Extension { |
+ public: |
+ NativeFunctionExtension(const char* name, const char* source, |
+ v8::FunctionCallback fun = &Echo) |
+ : Extension(name, source), function_(fun) {} |
-THREADED_TEST(UndetectableString) { |
- LocalContext env; |
- v8::HandleScope scope(env->GetIsolate()); |
- |
- Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", |
- String::kUndetectableString); |
- env->Global()->Set(v8_str("undetectable"), obj); |
- |
- ExpectString("undetectable", "foo"); |
- ExpectString("typeof undetectable", "undefined"); |
- ExpectString("typeof(undetectable)", "undefined"); |
- ExpectBoolean("typeof undetectable == 'undefined'", true); |
- ExpectBoolean("typeof undetectable == 'string'", false); |
- ExpectBoolean("if (undetectable) { true; } else { false; }", false); |
- ExpectBoolean("!undetectable", true); |
- |
- ExpectObject("true&&undetectable", obj); |
- ExpectBoolean("false&&undetectable", false); |
- ExpectBoolean("true||undetectable", true); |
- ExpectObject("false||undetectable", obj); |
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
+ v8::Isolate* isolate, v8::Handle<v8::String> name) { |
+ return v8::FunctionTemplate::New(isolate, function_); |
+ } |
- ExpectObject("undetectable&&true", obj); |
- ExpectObject("undetectable&&false", obj); |
- ExpectBoolean("undetectable||true", true); |
- ExpectBoolean("undetectable||false", false); |
+ static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); |
+ } |
- ExpectBoolean("undetectable==null", true); |
- ExpectBoolean("null==undetectable", true); |
- ExpectBoolean("undetectable==undefined", true); |
- ExpectBoolean("undefined==undetectable", true); |
- ExpectBoolean("undetectable==undetectable", true); |
+ private: |
+ v8::FunctionCallback function_; |
+}; |
- ExpectBoolean("undetectable===null", false); |
- ExpectBoolean("null===undetectable", false); |
- ExpectBoolean("undetectable===undefined", false); |
- ExpectBoolean("undefined===undetectable", false); |
- ExpectBoolean("undetectable===undetectable", true); |
+TEST(NativeFunctionDeclaration) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ const char* name = "nativedecl"; |
+ v8::RegisterExtension( |
+ new NativeFunctionExtension(name, "native function foo();")); |
+ const char* extension_names[] = {name}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ Context::Scope lock(context); |
+ v8::Handle<Value> result = CompileRun("foo(42);"); |
+ CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
} |
-TEST(UndetectableOptimized) { |
- i::FLAG_allow_natives_syntax = true; |
- LocalContext env; |
- v8::HandleScope scope(env->GetIsolate()); |
- |
- Local<String> obj = String::NewFromUtf8(env->GetIsolate(), "foo", |
- String::kUndetectableString); |
- env->Global()->Set(v8_str("undetectable"), obj); |
- env->Global()->Set(v8_str("detectable"), v8_str("bar")); |
- |
- ExpectString( |
- "function testBranch() {" |
- " if (!%_IsUndetectableObject(undetectable)) throw 1;" |
- " if (%_IsUndetectableObject(detectable)) throw 2;" |
- "}\n" |
- "function testBool() {" |
- " var b1 = !%_IsUndetectableObject(undetectable);" |
- " var b2 = %_IsUndetectableObject(detectable);" |
- " if (b1) throw 3;" |
- " if (b2) throw 4;" |
- " return b1 == b2;" |
- "}\n" |
- "%OptimizeFunctionOnNextCall(testBranch);" |
- "%OptimizeFunctionOnNextCall(testBool);" |
- "for (var i = 0; i < 10; i++) {" |
- " testBranch();" |
- " testBool();" |
- "}\n" |
- "\"PASS\"", |
- "PASS"); |
+TEST(NativeFunctionDeclarationError) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ const char* name = "nativedeclerr"; |
+ // Syntax error in extension code. |
+ v8::RegisterExtension( |
+ new NativeFunctionExtension(name, "native\nfunction foo();")); |
+ const char* extension_names[] = {name}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ CHECK(context.IsEmpty()); |
} |
-// The point of this test is type checking. We run it only so compilers |
-// don't complain about an unused function. |
-TEST(PersistentHandles) { |
- LocalContext env; |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- Local<String> str = v8_str("foo"); |
- v8::Persistent<String> p_str(isolate, str); |
- p_str.Reset(); |
- Local<Script> scr = v8_compile(""); |
- v8::Persistent<Script> p_scr(isolate, scr); |
- p_scr.Reset(); |
- Local<ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- v8::Persistent<ObjectTemplate> p_templ(isolate, templ); |
- p_templ.Reset(); |
+TEST(NativeFunctionDeclarationErrorEscape) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ const char* name = "nativedeclerresc"; |
+ // Syntax error in extension code - escape code in "native" means that |
+ // it's not treated as a keyword. |
+ v8::RegisterExtension( |
+ new NativeFunctionExtension(name, "nativ\\u0065 function foo();")); |
+ const char* extension_names[] = {name}; |
+ v8::ExtensionConfiguration extensions(1, extension_names); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &extensions); |
+ CHECK(context.IsEmpty()); |
} |
-static void HandleLogDelegator( |
- const v8::FunctionCallbackInfo<v8::Value>& args) { |
- ApiTestFuzzer::Fuzz(); |
+static void CheckDependencies(const char* name, const char* expected) { |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ v8::ExtensionConfiguration config(1, &name); |
+ LocalContext context(&config); |
+ CHECK(String::NewFromUtf8(CcTest::isolate(), expected) |
+ ->Equals(context->Global()->Get(v8_str("loaded")))); |
} |
-THREADED_TEST(GlobalObjectTemplate) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope handle_scope(isolate); |
- Local<ObjectTemplate> global_template = ObjectTemplate::New(isolate); |
- global_template->Set(v8_str("JSNI_Log"), |
- v8::FunctionTemplate::New(isolate, HandleLogDelegator)); |
- v8::Local<Context> context = Context::New(isolate, 0, global_template); |
- Context::Scope context_scope(context); |
- CompileRun("JSNI_Log('LOG')"); |
+/* |
+ * Configuration: |
+ * |
+ * /-- B <--\ |
+ * A <- -- D <-- E |
+ * \-- C <--/ |
+ */ |
+THREADED_TEST(ExtensionDependency) { |
+ static const char* kEDeps[] = {"D"}; |
+ v8::RegisterExtension(new Extension("E", "this.loaded += 'E';", 1, kEDeps)); |
+ static const char* kDDeps[] = {"B", "C"}; |
+ v8::RegisterExtension(new Extension("D", "this.loaded += 'D';", 2, kDDeps)); |
+ static const char* kBCDeps[] = {"A"}; |
+ v8::RegisterExtension(new Extension("B", "this.loaded += 'B';", 1, kBCDeps)); |
+ v8::RegisterExtension(new Extension("C", "this.loaded += 'C';", 1, kBCDeps)); |
+ v8::RegisterExtension(new Extension("A", "this.loaded += 'A';")); |
+ CheckDependencies("A", "undefinedA"); |
+ CheckDependencies("B", "undefinedAB"); |
+ CheckDependencies("C", "undefinedAC"); |
+ CheckDependencies("D", "undefinedABCD"); |
+ CheckDependencies("E", "undefinedABCDE"); |
+ v8::HandleScope handle_scope(CcTest::isolate()); |
+ static const char* exts[2] = {"C", "E"}; |
+ v8::ExtensionConfiguration config(2, exts); |
+ LocalContext context(&config); |
+ CHECK(v8_str("undefinedACBDE") |
+ ->Equals(context->Global()->Get(v8_str("loaded")))); |
} |
-static const char* kSimpleExtensionSource = |
- "function Foo() {" |
- " return 4;" |
- "}"; |
+static const char* kExtensionTestScript = |
+ "native function A();" |
+ "native function B();" |
+ "native function C();" |
+ "function Foo(i) {" |
+ " if (i == 0) return A();" |
+ " if (i == 1) return B();" |
+ " if (i == 2) return C();" |
+ "}"; |
-TEST(SimpleExtensions) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("simpletest", kSimpleExtensionSource)); |
- const char* extension_names[] = { "simpletest" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("Foo()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
+static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { |
+ ApiTestFuzzer::Fuzz(); |
+ if (args.IsConstructCall()) { |
+ args.This()->Set(v8_str("data"), args.Data()); |
+ args.GetReturnValue().SetNull(); |
+ return; |
+ } |
+ args.GetReturnValue().Set(args.Data()); |
} |
-static const char* kStackTraceFromExtensionSource = |
- "function foo() {" |
- " throw new Error();" |
- "}" |
- "function bar() {" |
- " foo();" |
- "}"; |
+class FunctionExtension : public Extension { |
+ public: |
+ FunctionExtension() : Extension("functiontest", kExtensionTestScript) {} |
+ virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
+ v8::Isolate* isolate, v8::Handle<String> name); |
+}; |
-TEST(StackTraceInExtension) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("stacktracetest", |
- kStackTraceFromExtensionSource)); |
- const char* extension_names[] = { "stacktracetest" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- CompileRun("function user() { bar(); }" |
- "var error;" |
- "try{ user(); } catch (e) { error = e; }"); |
- CHECK_EQ(-1, CompileRun("error.stack.indexOf('foo')")->Int32Value()); |
- CHECK_EQ(-1, CompileRun("error.stack.indexOf('bar')")->Int32Value()); |
- CHECK_NE(-1, CompileRun("error.stack.indexOf('user')")->Int32Value()); |
+static int lookup_count = 0; |
+v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( |
+ v8::Isolate* isolate, v8::Handle<String> name) { |
+ lookup_count++; |
+ if (name->Equals(v8_str("A"))) { |
+ return v8::FunctionTemplate::New(isolate, CallFun, |
+ v8::Integer::New(isolate, 8)); |
+ } else if (name->Equals(v8_str("B"))) { |
+ return v8::FunctionTemplate::New(isolate, CallFun, |
+ v8::Integer::New(isolate, 7)); |
+ } else if (name->Equals(v8_str("C"))) { |
+ return v8::FunctionTemplate::New(isolate, CallFun, |
+ v8::Integer::New(isolate, 6)); |
+ } else { |
+ return v8::Handle<v8::FunctionTemplate>(); |
+ } |
} |
-TEST(NullExtensions) { |
+THREADED_TEST(FunctionLookup) { |
+ v8::RegisterExtension(new FunctionExtension()); |
v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("nulltest", NULL)); |
- const char* extension_names[] = { "nulltest" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("1+3"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
+ static const char* exts[1] = {"functiontest"}; |
+ v8::ExtensionConfiguration config(1, exts); |
+ LocalContext context(&config); |
+ CHECK_EQ(3, lookup_count); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 8)->Equals(CompileRun("Foo(0)"))); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 7)->Equals(CompileRun("Foo(1)"))); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 6)->Equals(CompileRun("Foo(2)"))); |
} |
-static const char* kEmbeddedExtensionSource = |
- "function Ret54321(){return 54321;}~~@@$" |
- "$%% THIS IS A SERIES OF NON-NULL-TERMINATED STRINGS."; |
-static const int kEmbeddedExtensionSourceValidLen = 34; |
- |
- |
-TEST(ExtensionMissingSourceLength) { |
+THREADED_TEST(NativeFunctionConstructCall) { |
+ v8::RegisterExtension(new FunctionExtension()); |
v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("srclentest_fail", |
- kEmbeddedExtensionSource)); |
- const char* extension_names[] = { "srclentest_fail" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- CHECK(0 == *context); |
+ static const char* exts[1] = {"functiontest"}; |
+ v8::ExtensionConfiguration config(1, exts); |
+ LocalContext context(&config); |
+ for (int i = 0; i < 10; i++) { |
+ // Run a few times to ensure that allocation of objects doesn't |
+ // change behavior of a constructor function. |
+ CHECK(v8::Integer::New(CcTest::isolate(), 8) |
+ ->Equals(CompileRun("(new A()).data"))); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 7) |
+ ->Equals(CompileRun("(new B()).data"))); |
+ CHECK(v8::Integer::New(CcTest::isolate(), 6) |
+ ->Equals(CompileRun("(new C()).data"))); |
+ } |
} |
-TEST(ExtensionWithSourceLength) { |
- for (int source_len = kEmbeddedExtensionSourceValidLen - 1; |
- source_len <= kEmbeddedExtensionSourceValidLen + 1; ++source_len) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- i::ScopedVector<char> extension_name(32); |
- i::SNPrintF(extension_name, "ext #%d", source_len); |
- v8::RegisterExtension(new Extension(extension_name.start(), |
- kEmbeddedExtensionSource, 0, 0, |
- source_len)); |
- const char* extension_names[1] = { extension_name.start() }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- if (source_len == kEmbeddedExtensionSourceValidLen) { |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("Ret54321()"); |
- CHECK(v8::Integer::New(CcTest::isolate(), 54321)->Equals(result)); |
- } else { |
- // Anything but exactly the right length should fail to compile. |
- CHECK(0 == *context); |
- } |
+static const char* last_location; |
+static const char* last_message; |
+void StoringErrorCallback(const char* location, const char* message) { |
+ if (last_location == NULL) { |
+ last_location = location; |
+ last_message = message; |
} |
} |
-static const char* kEvalExtensionSource1 = |
- "function UseEval1() {" |
- " var x = 42;" |
- " return eval('x');" |
- "}"; |
- |
- |
-static const char* kEvalExtensionSource2 = |
- "(function() {" |
- " var x = 42;" |
- " function e() {" |
- " return eval('x');" |
- " }" |
- " this.UseEval2 = e;" |
- "})()"; |
- |
- |
-TEST(UseEvalFromExtension) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("evaltest1", kEvalExtensionSource1)); |
- v8::RegisterExtension(new Extension("evaltest2", kEvalExtensionSource2)); |
- const char* extension_names[] = { "evaltest1", "evaltest2" }; |
- v8::ExtensionConfiguration extensions(2, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("UseEval1()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
- result = CompileRun("UseEval2()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
-} |
- |
- |
-static const char* kWithExtensionSource1 = |
- "function UseWith1() {" |
- " var x = 42;" |
- " with({x:87}) { return x; }" |
- "}"; |
- |
- |
- |
-static const char* kWithExtensionSource2 = |
- "(function() {" |
- " var x = 42;" |
- " function e() {" |
- " with ({x:87}) { return x; }" |
- " }" |
- " this.UseWith2 = e;" |
- "})()"; |
- |
- |
-TEST(UseWithFromExtension) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("withtest1", kWithExtensionSource1)); |
- v8::RegisterExtension(new Extension("withtest2", kWithExtensionSource2)); |
- const char* extension_names[] = { "withtest1", "withtest2" }; |
- v8::ExtensionConfiguration extensions(2, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("UseWith1()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
- result = CompileRun("UseWith2()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 87))); |
-} |
- |
- |
-TEST(AutoExtensions) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- Extension* extension = new Extension("autotest", kSimpleExtensionSource); |
- extension->set_auto_enable(true); |
- v8::RegisterExtension(extension); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate()); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("Foo()"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 4))); |
-} |
- |
- |
-static const char* kSyntaxErrorInExtensionSource = |
- "["; |
- |
- |
-// Test that a syntax error in an extension does not cause a fatal |
-// error but results in an empty context. |
-TEST(SyntaxErrorExtensions) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("syntaxerror", |
- kSyntaxErrorInExtensionSource)); |
- const char* extension_names[] = { "syntaxerror" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- CHECK(context.IsEmpty()); |
-} |
- |
- |
-static const char* kExceptionInExtensionSource = |
- "throw 42"; |
- |
- |
-// Test that an exception when installing an extension does not cause |
-// a fatal error but results in an empty context. |
-TEST(ExceptionExtensions) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("exception", |
- kExceptionInExtensionSource)); |
- const char* extension_names[] = { "exception" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- CHECK(context.IsEmpty()); |
-} |
- |
- |
-static const char* kNativeCallInExtensionSource = |
- "function call_runtime_last_index_of(x) {" |
- " return %StringLastIndexOf(x, 'bob', 10);" |
- "}"; |
- |
- |
-static const char* kNativeCallTest = |
- "call_runtime_last_index_of('bobbobboellebobboellebobbob');"; |
- |
-// Test that a native runtime calls are supported in extensions. |
-TEST(NativeCallInExtensions) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::RegisterExtension(new Extension("nativecall", |
- kNativeCallInExtensionSource)); |
- const char* extension_names[] = { "nativecall" }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun(kNativeCallTest); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 3))); |
-} |
- |
- |
-class NativeFunctionExtension : public Extension { |
- public: |
- NativeFunctionExtension(const char* name, |
- const char* source, |
- v8::FunctionCallback fun = &Echo) |
- : Extension(name, source), |
- function_(fun) { } |
- |
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
- v8::Isolate* isolate, |
- v8::Handle<v8::String> name) { |
- return v8::FunctionTemplate::New(isolate, function_); |
- } |
- |
- static void Echo(const v8::FunctionCallbackInfo<v8::Value>& args) { |
- if (args.Length() >= 1) args.GetReturnValue().Set(args[0]); |
- } |
- private: |
- v8::FunctionCallback function_; |
-}; |
- |
- |
-TEST(NativeFunctionDeclaration) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- const char* name = "nativedecl"; |
- v8::RegisterExtension(new NativeFunctionExtension(name, |
- "native function foo();")); |
- const char* extension_names[] = { name }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- Context::Scope lock(context); |
- v8::Handle<Value> result = CompileRun("foo(42);"); |
- CHECK(result->Equals(v8::Integer::New(CcTest::isolate(), 42))); |
-} |
- |
- |
-TEST(NativeFunctionDeclarationError) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- const char* name = "nativedeclerr"; |
- // Syntax error in extension code. |
- v8::RegisterExtension(new NativeFunctionExtension(name, |
- "native\nfunction foo();")); |
- const char* extension_names[] = { name }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- CHECK(context.IsEmpty()); |
-} |
- |
- |
-TEST(NativeFunctionDeclarationErrorEscape) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- const char* name = "nativedeclerresc"; |
- // Syntax error in extension code - escape code in "native" means that |
- // it's not treated as a keyword. |
- v8::RegisterExtension(new NativeFunctionExtension( |
- name, |
- "nativ\\u0065 function foo();")); |
- const char* extension_names[] = { name }; |
- v8::ExtensionConfiguration extensions(1, extension_names); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &extensions); |
- CHECK(context.IsEmpty()); |
-} |
- |
- |
-static void CheckDependencies(const char* name, const char* expected) { |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- v8::ExtensionConfiguration config(1, &name); |
- LocalContext context(&config); |
- CHECK(String::NewFromUtf8(CcTest::isolate(), expected) |
- ->Equals(context->Global()->Get(v8_str("loaded")))); |
-} |
- |
- |
-/* |
- * Configuration: |
- * |
- * /-- B <--\ |
- * A <- -- D <-- E |
- * \-- C <--/ |
- */ |
-THREADED_TEST(ExtensionDependency) { |
- static const char* kEDeps[] = { "D" }; |
- v8::RegisterExtension(new Extension("E", "this.loaded += 'E';", 1, kEDeps)); |
- static const char* kDDeps[] = { "B", "C" }; |
- v8::RegisterExtension(new Extension("D", "this.loaded += 'D';", 2, kDDeps)); |
- static const char* kBCDeps[] = { "A" }; |
- v8::RegisterExtension(new Extension("B", "this.loaded += 'B';", 1, kBCDeps)); |
- v8::RegisterExtension(new Extension("C", "this.loaded += 'C';", 1, kBCDeps)); |
- v8::RegisterExtension(new Extension("A", "this.loaded += 'A';")); |
- CheckDependencies("A", "undefinedA"); |
- CheckDependencies("B", "undefinedAB"); |
- CheckDependencies("C", "undefinedAC"); |
- CheckDependencies("D", "undefinedABCD"); |
- CheckDependencies("E", "undefinedABCDE"); |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- static const char* exts[2] = { "C", "E" }; |
- v8::ExtensionConfiguration config(2, exts); |
- LocalContext context(&config); |
- CHECK(v8_str("undefinedACBDE") |
- ->Equals(context->Global()->Get(v8_str("loaded")))); |
-} |
- |
- |
-static const char* kExtensionTestScript = |
- "native function A();" |
- "native function B();" |
- "native function C();" |
- "function Foo(i) {" |
- " if (i == 0) return A();" |
- " if (i == 1) return B();" |
- " if (i == 2) return C();" |
- "}"; |
- |
- |
-static void CallFun(const v8::FunctionCallbackInfo<v8::Value>& args) { |
- ApiTestFuzzer::Fuzz(); |
- if (args.IsConstructCall()) { |
- args.This()->Set(v8_str("data"), args.Data()); |
- args.GetReturnValue().SetNull(); |
- return; |
- } |
- args.GetReturnValue().Set(args.Data()); |
-} |
- |
- |
-class FunctionExtension : public Extension { |
- public: |
- FunctionExtension() : Extension("functiontest", kExtensionTestScript) { } |
- virtual v8::Handle<v8::FunctionTemplate> GetNativeFunctionTemplate( |
- v8::Isolate* isolate, |
- v8::Handle<String> name); |
-}; |
- |
- |
-static int lookup_count = 0; |
-v8::Handle<v8::FunctionTemplate> FunctionExtension::GetNativeFunctionTemplate( |
- v8::Isolate* isolate, v8::Handle<String> name) { |
- lookup_count++; |
- if (name->Equals(v8_str("A"))) { |
- return v8::FunctionTemplate::New( |
- isolate, CallFun, v8::Integer::New(isolate, 8)); |
- } else if (name->Equals(v8_str("B"))) { |
- return v8::FunctionTemplate::New( |
- isolate, CallFun, v8::Integer::New(isolate, 7)); |
- } else if (name->Equals(v8_str("C"))) { |
- return v8::FunctionTemplate::New( |
- isolate, CallFun, v8::Integer::New(isolate, 6)); |
- } else { |
- return v8::Handle<v8::FunctionTemplate>(); |
- } |
-} |
- |
- |
-THREADED_TEST(FunctionLookup) { |
- v8::RegisterExtension(new FunctionExtension()); |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- static const char* exts[1] = { "functiontest" }; |
- v8::ExtensionConfiguration config(1, exts); |
- LocalContext context(&config); |
- CHECK_EQ(3, lookup_count); |
- CHECK(v8::Integer::New(CcTest::isolate(), 8)->Equals(CompileRun("Foo(0)"))); |
- CHECK(v8::Integer::New(CcTest::isolate(), 7)->Equals(CompileRun("Foo(1)"))); |
- CHECK(v8::Integer::New(CcTest::isolate(), 6)->Equals(CompileRun("Foo(2)"))); |
-} |
- |
- |
-THREADED_TEST(NativeFunctionConstructCall) { |
- v8::RegisterExtension(new FunctionExtension()); |
- v8::HandleScope handle_scope(CcTest::isolate()); |
- static const char* exts[1] = { "functiontest" }; |
- v8::ExtensionConfiguration config(1, exts); |
- LocalContext context(&config); |
- for (int i = 0; i < 10; i++) { |
- // Run a few times to ensure that allocation of objects doesn't |
- // change behavior of a constructor function. |
- CHECK(v8::Integer::New(CcTest::isolate(), 8) |
- ->Equals(CompileRun("(new A()).data"))); |
- CHECK(v8::Integer::New(CcTest::isolate(), 7) |
- ->Equals(CompileRun("(new B()).data"))); |
- CHECK(v8::Integer::New(CcTest::isolate(), 6) |
- ->Equals(CompileRun("(new C()).data"))); |
- } |
-} |
- |
- |
-static const char* last_location; |
-static const char* last_message; |
-void StoringErrorCallback(const char* location, const char* message) { |
- if (last_location == NULL) { |
- last_location = location; |
- last_message = message; |
- } |
-} |
- |
- |
-// ErrorReporting creates a circular extensions configuration and |
-// tests that the fatal error handler gets called. This renders V8 |
-// unusable and therefore this test cannot be run in parallel. |
-TEST(ErrorReporting) { |
- v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
- static const char* aDeps[] = { "B" }; |
- v8::RegisterExtension(new Extension("A", "", 1, aDeps)); |
- static const char* bDeps[] = { "A" }; |
- v8::RegisterExtension(new Extension("B", "", 1, bDeps)); |
- last_location = NULL; |
- v8::ExtensionConfiguration config(1, bDeps); |
- v8::Handle<Context> context = |
- Context::New(CcTest::isolate(), &config); |
- CHECK(context.IsEmpty()); |
- CHECK(last_location); |
-} |
+// ErrorReporting creates a circular extensions configuration and |
+// tests that the fatal error handler gets called. This renders V8 |
+// unusable and therefore this test cannot be run in parallel. |
+TEST(ErrorReporting) { |
+ v8::V8::SetFatalErrorHandler(StoringErrorCallback); |
+ static const char* aDeps[] = {"B"}; |
+ v8::RegisterExtension(new Extension("A", "", 1, aDeps)); |
+ static const char* bDeps[] = {"A"}; |
+ v8::RegisterExtension(new Extension("B", "", 1, bDeps)); |
+ last_location = NULL; |
+ v8::ExtensionConfiguration config(1, bDeps); |
+ v8::Handle<Context> context = Context::New(CcTest::isolate(), &config); |
+ CHECK(context.IsEmpty()); |
+ CHECK(last_location); |
+} |
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message, |
@@ -7947,9 +6565,7 @@ THREADED_TEST(ResetWeakHandle) { |
} |
-static void InvokeScavenge() { |
- CcTest::heap()->CollectGarbage(i::NEW_SPACE); |
-} |
+static void InvokeScavenge() { CcTest::heap()->CollectGarbage(i::NEW_SPACE); } |
static void InvokeMarkSweep() { |
@@ -8074,166 +6690,8 @@ THREADED_TEST(Arguments) { |
} |
-static void NoBlockGetterX(Local<Name> name, |
- const v8::PropertyCallbackInfo<v8::Value>&) {} |
- |
- |
-static void NoBlockGetterI(uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>&) { |
-} |
- |
- |
-static void PDeleter(Local<Name> name, |
- const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
- if (!name->Equals(v8_str("foo"))) { |
- return; // not intercepted |
- } |
- |
- info.GetReturnValue().Set(false); // intercepted, don't delete the property |
-} |
- |
- |
-static void IDeleter(uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Boolean>& info) { |
- if (index != 2) { |
- return; // not intercepted |
- } |
- |
- info.GetReturnValue().Set(false); // intercepted, don't delete the property |
-} |
- |
- |
-THREADED_TEST(Deleter) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); |
- 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( |
- "k.foo = 'foo';" |
- "k.bar = 'bar';" |
- "k[2] = 2;" |
- "k[4] = 4;"); |
- CHECK(v8_compile("delete k.foo")->Run()->IsFalse()); |
- CHECK(v8_compile("delete k.bar")->Run()->IsTrue()); |
- |
- CHECK(v8_compile("k.foo")->Run()->Equals(v8_str("foo"))); |
- CHECK(v8_compile("k.bar")->Run()->IsUndefined()); |
- |
- CHECK(v8_compile("delete k[2]")->Run()->IsFalse()); |
- CHECK(v8_compile("delete k[4]")->Run()->IsTrue()); |
- |
- CHECK(v8_compile("k[2]")->Run()->Equals(v8_num(2))); |
- CHECK(v8_compile("k[4]")->Run()->IsUndefined()); |
-} |
- |
- |
-static void GetK(Local<Name> name, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (name->Equals(v8_str("foo")) || |
- name->Equals(v8_str("bar")) || |
- name->Equals(v8_str("baz"))) { |
- info.GetReturnValue().SetUndefined(); |
- } |
-} |
- |
- |
-static void IndexedGetK(uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (index == 0 || index == 1) info.GetReturnValue().SetUndefined(); |
-} |
- |
- |
-static void NamedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { |
- ApiTestFuzzer::Fuzz(); |
- v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 3); |
- result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("foo")); |
- result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("bar")); |
- result->Set(v8::Integer::New(info.GetIsolate(), 2), v8_str("baz")); |
- info.GetReturnValue().Set(result); |
-} |
- |
- |
-static void IndexedEnum(const v8::PropertyCallbackInfo<v8::Array>& info) { |
- ApiTestFuzzer::Fuzz(); |
- v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 2); |
- result->Set(v8::Integer::New(info.GetIsolate(), 0), v8_str("0")); |
- result->Set(v8::Integer::New(info.GetIsolate(), 1), v8_str("1")); |
- info.GetReturnValue().Set(result); |
-} |
- |
- |
-THREADED_TEST(Enumerators) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> obj = ObjectTemplate::New(isolate); |
- 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( |
- "k[10] = 0;" |
- "k.a = 0;" |
- "k[5] = 0;" |
- "k.b = 0;" |
- "k[4294967295] = 0;" |
- "k.c = 0;" |
- "k[4294967296] = 0;" |
- "k.d = 0;" |
- "k[140000] = 0;" |
- "k.e = 0;" |
- "k[30000000000] = 0;" |
- "k.f = 0;" |
- "var result = [];" |
- "for (var prop in k) {" |
- " result.push(prop);" |
- "}" |
- "result")); |
- // Check that we get all the property names returned including the |
- // ones from the enumerators in the right order: indexed properties |
- // in numerical order, indexed interceptor properties, named |
- // properties in insertion order, named interceptor properties. |
- // This order is not mandated by the spec, so this test is just |
- // documenting our behavior. |
- CHECK_EQ(17u, result->Length()); |
- // Indexed properties in numerical order. |
- CHECK(v8_str("5")->Equals(result->Get(v8::Integer::New(isolate, 0)))); |
- CHECK(v8_str("10")->Equals(result->Get(v8::Integer::New(isolate, 1)))); |
- CHECK(v8_str("140000")->Equals(result->Get(v8::Integer::New(isolate, 2)))); |
- CHECK( |
- v8_str("4294967295")->Equals(result->Get(v8::Integer::New(isolate, 3)))); |
- // Indexed interceptor properties in the order they are returned |
- // from the enumerator interceptor. |
- CHECK(v8_str("0")->Equals(result->Get(v8::Integer::New(isolate, 4)))); |
- CHECK(v8_str("1")->Equals(result->Get(v8::Integer::New(isolate, 5)))); |
- // Named properties in insertion order. |
- CHECK(v8_str("a")->Equals(result->Get(v8::Integer::New(isolate, 6)))); |
- CHECK(v8_str("b")->Equals(result->Get(v8::Integer::New(isolate, 7)))); |
- CHECK(v8_str("c")->Equals(result->Get(v8::Integer::New(isolate, 8)))); |
- CHECK( |
- v8_str("4294967296")->Equals(result->Get(v8::Integer::New(isolate, 9)))); |
- CHECK(v8_str("d")->Equals(result->Get(v8::Integer::New(isolate, 10)))); |
- CHECK(v8_str("e")->Equals(result->Get(v8::Integer::New(isolate, 11)))); |
- CHECK(v8_str("30000000000") |
- ->Equals(result->Get(v8::Integer::New(isolate, 12)))); |
- CHECK(v8_str("f")->Equals(result->Get(v8::Integer::New(isolate, 13)))); |
- // Named interceptor properties. |
- CHECK(v8_str("foo")->Equals(result->Get(v8::Integer::New(isolate, 14)))); |
- CHECK(v8_str("bar")->Equals(result->Get(v8::Integer::New(isolate, 15)))); |
- CHECK(v8_str("baz")->Equals(result->Get(v8::Integer::New(isolate, 16)))); |
-} |
- |
- |
-int p_getter_count; |
-int p_getter_count2; |
+static int p_getter_count; |
+static int p_getter_count2; |
static void PGetter(Local<String> name, |
@@ -10304,67 +8762,6 @@ TEST(SuperAccessControl) { |
} |
-static void IndexedPropertyEnumerator( |
- const v8::PropertyCallbackInfo<v8::Array>& info) { |
- v8::Handle<v8::Array> result = v8::Array::New(info.GetIsolate(), 1); |
- result->Set(0, v8::Integer::New(info.GetIsolate(), 7)); |
- info.GetReturnValue().Set(result); |
-} |
- |
- |
-static void NamedPropertyEnumerator( |
- 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::Symbol::GetIterator(info.GetIsolate())); |
- info.GetReturnValue().Set(result); |
-} |
- |
- |
-THREADED_TEST(GetOwnPropertyNamesWithInterceptor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope handle_scope(isolate); |
- v8::Handle<v8::ObjectTemplate> obj_template = |
- v8::ObjectTemplate::New(isolate); |
- |
- 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->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(); |
- global->Set(v8_str("object"), obj_template->NewInstance()); |
- |
- v8::Handle<v8::Value> result = |
- CompileRun("Object.getOwnPropertyNames(object)"); |
- CHECK(result->IsArray()); |
- v8::Handle<v8::Array> result_array = v8::Handle<v8::Array>::Cast(result); |
- CHECK_EQ(2u, result_array->Length()); |
- CHECK(result_array->Get(0)->IsString()); |
- CHECK(result_array->Get(1)->IsString()); |
- CHECK(v8_str("7")->Equals(result_array->Get(0))); |
- CHECK(v8_str("x")->Equals(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(2u, result_array->Length()); |
- CHECK(result_array->Get(0)->IsString()); |
- CHECK(result_array->Get(1)->IsString()); |
- CHECK(v8_str("7")->Equals(result_array->Get(0))); |
- CHECK(v8_str("x")->Equals(result_array->Get(1))); |
- |
- result = CompileRun("Object.getOwnPropertySymbols(object)"); |
- CHECK(result->IsArray()); |
- result_array = v8::Handle<v8::Array>::Cast(result); |
- CHECK_EQ(1u, result_array->Length()); |
- CHECK(result_array->Get(0)->Equals(v8::Symbol::GetIterator(isolate))); |
-} |
- |
- |
static void ConstTenGetter(Local<String> name, |
const v8::PropertyCallbackInfo<v8::Value>& info) { |
info.GetReturnValue().Set(v8_num(10)); |
@@ -10634,104 +9031,7 @@ THREADED_TEST(AccessControlFlatten) { |
} |
-static void AccessControlNamedGetter( |
- Local<Name>, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- info.GetReturnValue().Set(42); |
-} |
- |
- |
-static void AccessControlNamedSetter( |
- Local<Name>, Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- info.GetReturnValue().Set(value); |
-} |
- |
- |
-static void AccessControlIndexedGetter( |
- uint32_t index, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- info.GetReturnValue().Set(v8_num(42)); |
-} |
- |
- |
-static void AccessControlIndexedSetter( |
- uint32_t, |
- Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- info.GetReturnValue().Set(value); |
-} |
- |
- |
-THREADED_TEST(AccessControlInterceptorIC) { |
- named_access_count = 0; |
- indexed_access_count = 0; |
- |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope handle_scope(isolate); |
- |
- // Create an environment. |
- v8::Local<Context> context0 = Context::New(isolate); |
- context0->Enter(); |
- |
- // Create an object that requires access-check functions to be |
- // called for cross-domain access. The object also has interceptors |
- // interceptor. |
- v8::Handle<v8::ObjectTemplate> object_template = |
- v8::ObjectTemplate::New(isolate); |
- object_template->SetAccessCheckCallbacks(NamedAccessCounter, |
- IndexedAccessCounter); |
- 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); |
- |
- // Create another environment. |
- v8::Local<Context> context1 = Context::New(isolate); |
- context1->Enter(); |
- |
- // Make easy access to the object from the other environment. |
- v8::Handle<v8::Object> global1 = context1->Global(); |
- global1->Set(v8_str("obj"), object); |
- |
- v8::Handle<Value> value; |
- |
- // Check that the named access-control function is called every time |
- // eventhough there is an interceptor on the object. |
- value = v8_compile("for (var i = 0; i < 10; i++) obj.x = 1;")->Run(); |
- value = v8_compile("for (var i = 0; i < 10; i++) obj.x;" |
- "obj.x")->Run(); |
- CHECK(value->IsNumber()); |
- CHECK_EQ(42, value->Int32Value()); |
- CHECK_EQ(21, named_access_count); |
- |
- value = v8_compile("var p = 'x';")->Run(); |
- value = v8_compile("for (var i = 0; i < 10; i++) obj[p] = 1;")->Run(); |
- value = v8_compile("for (var i = 0; i < 10; i++) obj[p];" |
- "obj[p]")->Run(); |
- CHECK(value->IsNumber()); |
- CHECK_EQ(42, value->Int32Value()); |
- CHECK_EQ(42, named_access_count); |
- |
- // Check that the indexed access-control function is called every |
- // time eventhough there is an interceptor on the object. |
- value = v8_compile("for (var i = 0; i < 10; i++) obj[0] = 1;")->Run(); |
- value = v8_compile("for (var i = 0; i < 10; i++) obj[0];" |
- "obj[0]")->Run(); |
- CHECK(value->IsNumber()); |
- CHECK_EQ(42, value->Int32Value()); |
- CHECK_EQ(21, indexed_access_count); |
- |
- context1->Exit(); |
- context0->Exit(); |
-} |
- |
- |
-THREADED_TEST(Version) { |
- v8::V8::GetVersion(); |
-} |
+THREADED_TEST(Version) { v8::V8::GetVersion(); } |
static void InstanceFunctionCallback( |
@@ -11309,11 +9609,11 @@ THREADED_TEST(GetterSetterExceptions) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope handle_scope(isolate); |
CompileRun( |
- "function Foo() { };" |
- "function Throw() { throw 5; };" |
- "var x = { };" |
- "x.__defineSetter__('set', Throw);" |
- "x.__defineGetter__('get', Throw);"); |
+ "function Foo() { };" |
+ "function Throw() { throw 5; };" |
+ "var x = { };" |
+ "x.__defineSetter__('set', Throw);" |
+ "x.__defineGetter__('get', Throw);"); |
Local<v8::Object> x = |
Local<v8::Object>::Cast(context->Global()->Get(v8_str("x"))); |
v8::TryCatch try_catch; |
@@ -11377,7 +9677,8 @@ THREADED_TEST(ConstructorForObject) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope handle_scope(isolate); |
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
+ { |
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
instance_template->SetCallAsFunctionHandler(ConstructorCallback); |
Local<Object> instance = instance_template->NewInstance(); |
context->Global()->Set(v8_str("obj"), instance); |
@@ -11391,7 +9692,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK(value->IsInt32()); |
CHECK_EQ(28, value->Int32Value()); |
- Local<Value> args1[] = { v8_num(28) }; |
+ Local<Value> args1[] = {v8_num(28)}; |
Local<Value> value_obj1 = instance->CallAsConstructor(1, args1); |
CHECK(value_obj1->IsObject()); |
Local<Object> object1 = Local<Object>::Cast(value_obj1); |
@@ -11401,14 +9702,14 @@ THREADED_TEST(ConstructorForObject) { |
CHECK_EQ(28, value->Int32Value()); |
// Call the Object's constructor with a String. |
- value = CompileRun( |
- "(function() { var o = new obj('tipli'); return o.a; })()"); |
+ value = |
+ CompileRun("(function() { var o = new obj('tipli'); return o.a; })()"); |
CHECK(!try_catch.HasCaught()); |
CHECK(value->IsString()); |
String::Utf8Value string_value1(value->ToString(isolate)); |
CHECK_EQ(0, strcmp("tipli", *string_value1)); |
- Local<Value> args2[] = { v8_str("tipli") }; |
+ Local<Value> args2[] = {v8_str("tipli")}; |
Local<Value> value_obj2 = instance->CallAsConstructor(1, args2); |
CHECK(value_obj2->IsObject()); |
Local<Object> object2 = Local<Object>::Cast(value_obj2); |
@@ -11424,7 +9725,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK(value->IsBoolean()); |
CHECK_EQ(true, value->BooleanValue()); |
- Handle<Value> args3[] = { v8::True(isolate) }; |
+ Handle<Value> args3[] = {v8::True(isolate)}; |
Local<Value> value_obj3 = instance->CallAsConstructor(1, args3); |
CHECK(value_obj3->IsObject()); |
Local<Object> object3 = Local<Object>::Cast(value_obj3); |
@@ -11434,7 +9735,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK_EQ(true, value->BooleanValue()); |
// Call the Object's constructor with undefined. |
- Handle<Value> args4[] = { v8::Undefined(isolate) }; |
+ Handle<Value> args4[] = {v8::Undefined(isolate)}; |
Local<Value> value_obj4 = instance->CallAsConstructor(1, args4); |
CHECK(value_obj4->IsObject()); |
Local<Object> object4 = Local<Object>::Cast(value_obj4); |
@@ -11443,7 +9744,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK(value->IsUndefined()); |
// Call the Object's constructor with null. |
- Handle<Value> args5[] = { v8::Null(isolate) }; |
+ Handle<Value> args5[] = {v8::Null(isolate)}; |
Local<Value> value_obj5 = instance->CallAsConstructor(1, args5); |
CHECK(value_obj5->IsObject()); |
Local<Object> object5 = Local<Object>::Cast(value_obj5); |
@@ -11453,7 +9754,8 @@ THREADED_TEST(ConstructorForObject) { |
} |
// Check exception handling when there is no constructor set for the Object. |
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
+ { |
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
Local<Object> instance = instance_template->NewInstance(); |
context->Global()->Set(v8_str("obj2"), instance); |
v8::TryCatch try_catch; |
@@ -11466,7 +9768,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK_EQ(0, strcmp("TypeError: obj2 is not a function", *exception_value1)); |
try_catch.Reset(); |
- Local<Value> args[] = { v8_num(29) }; |
+ Local<Value> args[] = {v8_num(29)}; |
value = instance->CallAsConstructor(1, args); |
CHECK(try_catch.HasCaught()); |
String::Utf8Value exception_value2(try_catch.Exception()); |
@@ -11476,7 +9778,8 @@ THREADED_TEST(ConstructorForObject) { |
} |
// Check the case when constructor throws exception. |
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
+ { |
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
instance_template->SetCallAsFunctionHandler(ThrowValue); |
Local<Object> instance = instance_template->NewInstance(); |
context->Global()->Set(v8_str("obj3"), instance); |
@@ -11490,7 +9793,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK_EQ(0, strcmp("22", *exception_value1)); |
try_catch.Reset(); |
- Local<Value> args[] = { v8_num(23) }; |
+ Local<Value> args[] = {v8_num(23)}; |
value = instance->CallAsConstructor(1, args); |
CHECK(try_catch.HasCaught()); |
String::Utf8Value exception_value2(try_catch.Exception()); |
@@ -11499,7 +9802,8 @@ THREADED_TEST(ConstructorForObject) { |
} |
// Check whether constructor returns with an object or non-object. |
- { Local<FunctionTemplate> function_template = |
+ { |
+ Local<FunctionTemplate> function_template = |
FunctionTemplate::New(isolate, FakeConstructorCallback); |
Local<Function> function = function_template->GetFunction(); |
Local<Object> instance1 = function; |
@@ -11515,7 +9819,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK(!try_catch.HasCaught()); |
CHECK(value->IsObject()); |
- Local<Value> args1[] = { v8_num(28) }; |
+ Local<Value> args1[] = {v8_num(28)}; |
value = instance1->CallAsConstructor(1, args1); |
CHECK(!try_catch.HasCaught()); |
CHECK(value->IsObject()); |
@@ -11533,7 +9837,7 @@ THREADED_TEST(ConstructorForObject) { |
CHECK(!try_catch.HasCaught()); |
CHECK(!value->IsObject()); |
- Local<Value> args2[] = { v8_num(28) }; |
+ Local<Value> args2[] = {v8_num(28)}; |
value = instance2->CallAsConstructor(1, args2); |
CHECK(!try_catch.HasCaught()); |
CHECK(!value->IsObject()); |
@@ -11550,19 +9854,19 @@ THREADED_TEST(FunctionDescriptorException) { |
Local<Function> cons = templ->GetFunction(); |
context->Global()->Set(v8_str("Fun"), cons); |
Local<Value> value = CompileRun( |
- "function test() {" |
- " try {" |
- " (new Fun()).blah()" |
- " } catch (e) {" |
- " var str = String(e);" |
- // " if (str.indexOf('TypeError') == -1) return 1;" |
- // " if (str.indexOf('[object Fun]') != -1) return 2;" |
- // " if (str.indexOf('#<Fun>') == -1) return 3;" |
- " return 0;" |
- " }" |
- " return 4;" |
- "}" |
- "test();"); |
+ "function test() {" |
+ " try {" |
+ " (new Fun()).blah()" |
+ " } catch (e) {" |
+ " var str = String(e);" |
+ // " if (str.indexOf('TypeError') == -1) return 1;" |
+ // " if (str.indexOf('[object Fun]') != -1) return 2;" |
+ // " if (str.indexOf('#<Fun>') == -1) return 3;" |
+ " return 0;" |
+ " }" |
+ " return 4;" |
+ "}" |
+ "test();"); |
CHECK_EQ(0, value->Int32Value()); |
} |
@@ -11689,12 +9993,12 @@ THREADED_TEST(EvalInDetachedGlobal) { |
// Set up function in context0 that uses eval from context0. |
context0->Enter(); |
- v8::Handle<v8::Value> fun = |
- CompileRun("var x = 42;" |
- "(function() {" |
- " var e = eval;" |
- " return function(s) { return e(s); }" |
- "})()"); |
+ v8::Handle<v8::Value> fun = CompileRun( |
+ "var x = 42;" |
+ "(function() {" |
+ " var e = eval;" |
+ " return function(s) { return e(s); }" |
+ "})()"); |
context0->Exit(); |
// Put the function into context1 and call it before and after |
@@ -11757,7 +10061,8 @@ THREADED_TEST(CallAsFunction) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope scope(isolate); |
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
+ { |
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
instance_template->SetCallAsFunctionHandler(call_as_function); |
Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
@@ -11779,8 +10084,9 @@ THREADED_TEST(CallAsFunction) { |
CHECK(!try_catch.HasCaught()); |
CHECK_EQ(45, value->Int32Value()); |
- value = CompileRun("obj.call = Function.prototype.call;" |
- "obj.call(null, 87)"); |
+ value = CompileRun( |
+ "obj.call = Function.prototype.call;" |
+ "obj.call(null, 87)"); |
CHECK(!try_catch.HasCaught()); |
CHECK_EQ(87, value->Int32Value()); |
@@ -11804,13 +10110,14 @@ THREADED_TEST(CallAsFunction) { |
// Check that the call-as-function handler can be called through |
// the API. |
- v8::Handle<Value> args[] = { v8_num(28) }; |
+ v8::Handle<Value> args[] = {v8_num(28)}; |
value = instance->CallAsFunction(instance, 1, args); |
CHECK(!try_catch.HasCaught()); |
CHECK_EQ(28, value->Int32Value()); |
} |
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
+ { |
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
Local<ObjectTemplate> instance_template(t->InstanceTemplate()); |
USE(instance_template); |
Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
@@ -11830,7 +10137,7 @@ THREADED_TEST(CallAsFunction) { |
// Call an object without call-as-function handler through the API |
value = CompileRun("obj2(28)"); |
- v8::Handle<Value> args[] = { v8_num(28) }; |
+ v8::Handle<Value> args[] = {v8_num(28)}; |
value = instance->CallAsFunction(instance, 1, args); |
CHECK(value.IsEmpty()); |
CHECK(try_catch.HasCaught()); |
@@ -11840,7 +10147,8 @@ THREADED_TEST(CallAsFunction) { |
try_catch.Reset(); |
} |
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
+ { |
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
instance_template->SetCallAsFunctionHandler(ThrowValue); |
Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
@@ -11856,7 +10164,7 @@ THREADED_TEST(CallAsFunction) { |
CHECK_EQ(0, strcmp("22", *exception_value1)); |
try_catch.Reset(); |
- v8::Handle<Value> args[] = { v8_num(23) }; |
+ v8::Handle<Value> args[] = {v8_num(23)}; |
value = instance->CallAsFunction(instance, 1, args); |
CHECK(try_catch.HasCaught()); |
String::Utf8Value exception_value2(try_catch.Exception()); |
@@ -11864,7 +10172,8 @@ THREADED_TEST(CallAsFunction) { |
try_catch.Reset(); |
} |
- { Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
+ { |
+ Local<v8::FunctionTemplate> t = v8::FunctionTemplate::New(isolate); |
Local<ObjectTemplate> instance_template = t->InstanceTemplate(); |
instance_template->SetCallAsFunctionHandler(ReturnThis); |
Local<v8::Object> instance = t->GetFunction()->NewInstance(); |
@@ -11872,34 +10181,29 @@ THREADED_TEST(CallAsFunction) { |
Local<v8::Value> a1 = |
instance->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
CHECK(a1->StrictEquals(instance)); |
- Local<v8::Value> a2 = |
- instance->CallAsFunction(v8::Null(isolate), 0, NULL); |
+ Local<v8::Value> a2 = instance->CallAsFunction(v8::Null(isolate), 0, NULL); |
CHECK(a2->StrictEquals(instance)); |
- Local<v8::Value> a3 = |
- instance->CallAsFunction(v8_num(42), 0, NULL); |
+ Local<v8::Value> a3 = instance->CallAsFunction(v8_num(42), 0, NULL); |
CHECK(a3->StrictEquals(instance)); |
- Local<v8::Value> a4 = |
- instance->CallAsFunction(v8_str("hello"), 0, NULL); |
+ Local<v8::Value> a4 = instance->CallAsFunction(v8_str("hello"), 0, NULL); |
CHECK(a4->StrictEquals(instance)); |
- Local<v8::Value> a5 = |
- instance->CallAsFunction(v8::True(isolate), 0, NULL); |
+ Local<v8::Value> a5 = instance->CallAsFunction(v8::True(isolate), 0, NULL); |
CHECK(a5->StrictEquals(instance)); |
} |
- { CompileRun( |
- "function ReturnThisSloppy() {" |
- " return this;" |
- "}" |
- "function ReturnThisStrict() {" |
- " 'use strict';" |
- " return this;" |
- "}"); |
- Local<Function> ReturnThisSloppy = |
- Local<Function>::Cast( |
- context->Global()->Get(v8_str("ReturnThisSloppy"))); |
- Local<Function> ReturnThisStrict = |
- Local<Function>::Cast( |
- context->Global()->Get(v8_str("ReturnThisStrict"))); |
+ { |
+ CompileRun( |
+ "function ReturnThisSloppy() {" |
+ " return this;" |
+ "}" |
+ "function ReturnThisStrict() {" |
+ " 'use strict';" |
+ " return this;" |
+ "}"); |
+ Local<Function> ReturnThisSloppy = Local<Function>::Cast( |
+ context->Global()->Get(v8_str("ReturnThisSloppy"))); |
+ Local<Function> ReturnThisStrict = Local<Function>::Cast( |
+ context->Global()->Get(v8_str("ReturnThisStrict"))); |
Local<v8::Value> a1 = |
ReturnThisSloppy->CallAsFunction(v8::Undefined(isolate), 0, NULL); |
@@ -11907,8 +10211,7 @@ THREADED_TEST(CallAsFunction) { |
Local<v8::Value> a2 = |
ReturnThisSloppy->CallAsFunction(v8::Null(isolate), 0, NULL); |
CHECK(a2->StrictEquals(context->Global())); |
- Local<v8::Value> a3 = |
- ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); |
+ Local<v8::Value> a3 = ReturnThisSloppy->CallAsFunction(v8_num(42), 0, NULL); |
CHECK(a3->IsNumberObject()); |
CHECK_EQ(42.0, a3.As<v8::NumberObject>()->ValueOf()); |
Local<v8::Value> a4 = |
@@ -11926,8 +10229,7 @@ THREADED_TEST(CallAsFunction) { |
Local<v8::Value> a7 = |
ReturnThisStrict->CallAsFunction(v8::Null(isolate), 0, NULL); |
CHECK(a7->IsNull()); |
- Local<v8::Value> a8 = |
- ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); |
+ Local<v8::Value> a8 = ReturnThisStrict->CallAsFunction(v8_num(42), 0, NULL); |
CHECK(a8->StrictEquals(v8_num(42))); |
Local<v8::Value> a9 = |
ReturnThisStrict->CallAsFunction(v8_str("hello"), 0, NULL); |
@@ -11945,7 +10247,8 @@ THREADED_TEST(CallableObject) { |
v8::Isolate* isolate = context->GetIsolate(); |
v8::HandleScope scope(isolate); |
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
+ { |
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
instance_template->SetCallAsFunctionHandler(call_as_function); |
Local<Object> instance = instance_template->NewInstance(); |
v8::TryCatch try_catch; |
@@ -11954,7 +10257,8 @@ THREADED_TEST(CallableObject) { |
CHECK(!try_catch.HasCaught()); |
} |
- { Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
+ { |
+ Local<ObjectTemplate> instance_template = ObjectTemplate::New(isolate); |
Local<Object> instance = instance_template->NewInstance(); |
v8::TryCatch try_catch; |
@@ -11962,896 +10266,70 @@ THREADED_TEST(CallableObject) { |
CHECK(!try_catch.HasCaught()); |
} |
- { Local<FunctionTemplate> function_template = |
- FunctionTemplate::New(isolate, call_as_function); |
- Local<Function> function = function_template->GetFunction(); |
- Local<Object> instance = function; |
- v8::TryCatch try_catch; |
- |
- CHECK(instance->IsCallable()); |
- CHECK(!try_catch.HasCaught()); |
- } |
- |
- { Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); |
- Local<Function> function = function_template->GetFunction(); |
- Local<Object> instance = function; |
- v8::TryCatch try_catch; |
- |
- CHECK(instance->IsCallable()); |
- CHECK(!try_catch.HasCaught()); |
- } |
-} |
- |
- |
-static int Recurse(v8::Isolate* isolate, int depth, int iterations) { |
- v8::HandleScope scope(isolate); |
- if (depth == 0) return v8::HandleScope::NumberOfHandles(isolate); |
- for (int i = 0; i < iterations; i++) { |
- Local<v8::Number> n(v8::Integer::New(isolate, 42)); |
- } |
- return Recurse(isolate, depth - 1, iterations); |
-} |
- |
- |
-THREADED_TEST(HandleIteration) { |
- static const int kIterations = 500; |
- static const int kNesting = 200; |
- LocalContext context; |
- v8::Isolate* isolate = context->GetIsolate(); |
- v8::HandleScope scope0(isolate); |
- CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
- { |
- v8::HandleScope scope1(isolate); |
- CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
- for (int i = 0; i < kIterations; i++) { |
- Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); |
- CHECK_EQ(i + 1, v8::HandleScope::NumberOfHandles(isolate)); |
- } |
- |
- CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); |
- { |
- v8::HandleScope scope2(CcTest::isolate()); |
- for (int j = 0; j < kIterations; j++) { |
- Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); |
- CHECK_EQ(j + 1 + kIterations, |
- v8::HandleScope::NumberOfHandles(isolate)); |
- } |
- } |
- CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); |
- } |
- CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
- CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations)); |
-} |
- |
- |
-static void InterceptorHasOwnPropertyGetter( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
-} |
- |
- |
-THREADED_TEST(InterceptorHasOwnProperty) { |
- LocalContext context; |
- v8::Isolate* isolate = context->GetIsolate(); |
- v8::HandleScope scope(isolate); |
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); |
- Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
- instance_templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorHasOwnPropertyGetter)); |
- Local<Function> function = fun_templ->GetFunction(); |
- context->Global()->Set(v8_str("constructor"), function); |
- v8::Handle<Value> value = CompileRun( |
- "var o = new constructor();" |
- "o.hasOwnProperty('ostehaps');"); |
- CHECK_EQ(false, value->BooleanValue()); |
- value = CompileRun( |
- "o.ostehaps = 42;" |
- "o.hasOwnProperty('ostehaps');"); |
- CHECK_EQ(true, value->BooleanValue()); |
- value = CompileRun( |
- "var p = new constructor();" |
- "p.hasOwnProperty('ostehaps');"); |
- CHECK_EQ(false, value->BooleanValue()); |
-} |
- |
- |
-static void InterceptorHasOwnPropertyGetterGC( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
-} |
- |
- |
-THREADED_TEST(InterceptorHasOwnPropertyCausingGC) { |
- LocalContext context; |
- v8::Isolate* isolate = context->GetIsolate(); |
- v8::HandleScope scope(isolate); |
- Local<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(isolate); |
- Local<v8::ObjectTemplate> instance_templ = fun_templ->InstanceTemplate(); |
- 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. |
- CompileRun( |
- "function makestr(size) {" |
- " switch (size) {" |
- " case 1: return 'f';" |
- " case 2: return 'fo';" |
- " case 3: return 'foo';" |
- " }" |
- " return makestr(size >> 1) + makestr((size + 1) >> 1);" |
- "}" |
- "var x = makestr(12345);" |
- "x = makestr(31415);" |
- "x = makestr(23456);"); |
- v8::Handle<Value> value = CompileRun( |
- "var o = new constructor();" |
- "o.__proto__ = new String(x);" |
- "o.hasOwnProperty('ostehaps');"); |
- CHECK_EQ(false, value->BooleanValue()); |
-} |
- |
- |
-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->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); |
- CHECK_EQ(expected, value->Int32Value()); |
-} |
- |
- |
-static void InterceptorLoadICGetter( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- v8::Isolate* isolate = CcTest::isolate(); |
- CHECK_EQ(isolate, info.GetIsolate()); |
- CHECK(v8_str("data")->Equals(info.Data())); |
- CHECK(v8_str("x")->Equals(name)); |
- info.GetReturnValue().Set(v8::Integer::New(isolate, 42)); |
-} |
- |
- |
-// This test should hit the load IC for the interceptor case. |
-THREADED_TEST(InterceptorLoadIC) { |
- CheckInterceptorLoadIC(InterceptorLoadICGetter, |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.x;" |
- "}", |
- 42); |
-} |
- |
- |
-// Below go several tests which verify that JITing for various |
-// configurations of interceptor and explicit fields works fine |
-// (those cases are special cased to get better performance). |
- |
-static void InterceptorLoadXICGetter( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- info.GetReturnValue().Set( |
- v8_str("x")->Equals(name) ? |
- v8::Handle<v8::Value>(v8::Integer::New(info.GetIsolate(), 42)) : |
- v8::Handle<v8::Value>()); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithFieldOnHolder) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "var result = 0;" |
- "o.y = 239;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.y;" |
- "}", |
- 239); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithSubstitutedProto) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "var result = 0;" |
- "o.__proto__ = { 'y': 239 };" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.y + o.x;" |
- "}", |
- 239 + 42); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithPropertyOnProto) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "var result = 0;" |
- "o.__proto__.y = 239;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.y + o.x;" |
- "}", |
- 239 + 42); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICUndefined) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = (o.y == undefined) ? 239 : 42;" |
- "}", |
- 239); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithOverride) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "fst = new Object(); fst.__proto__ = o;" |
- "snd = new Object(); snd.__proto__ = fst;" |
- "var result1 = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result1 = snd.x;" |
- "}" |
- "fst.x = 239;" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = snd.x;" |
- "}" |
- "result + result1", |
- 239 + 42); |
-} |
- |
- |
-// Test the case when we stored field into |
-// a stub, but interceptor produced value on its own. |
-THREADED_TEST(InterceptorLoadICFieldNotNeeded) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "proto = new Object();" |
- "o.__proto__ = proto;" |
- "proto.x = 239;" |
- "for (var i = 0; i < 1000; i++) {" |
- " o.x;" |
- // Now it should be ICed and keep a reference to x defined on proto |
- "}" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result += o.x;" |
- "}" |
- "result;", |
- 42 * 1000); |
-} |
- |
- |
-// Test the case when we stored field into |
-// a stub, but it got invalidated later on. |
-THREADED_TEST(InterceptorLoadICInvalidatedField) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "proto1 = new Object();" |
- "proto2 = new Object();" |
- "o.__proto__ = proto1;" |
- "proto1.__proto__ = proto2;" |
- "proto2.y = 239;" |
- "for (var i = 0; i < 1000; i++) {" |
- " o.y;" |
- // Now it should be ICed and keep a reference to y defined on proto2 |
- "}" |
- "proto1.y = 42;" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result += o.y;" |
- "}" |
- "result;", |
- 42 * 1000); |
-} |
- |
- |
-static int interceptor_load_not_handled_calls = 0; |
-static void InterceptorLoadNotHandled( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ++interceptor_load_not_handled_calls; |
-} |
- |
- |
-// Test how post-interceptor lookups are done in the non-cacheable |
-// case: the interceptor should not be invoked during this lookup. |
-THREADED_TEST(InterceptorLoadICPostInterceptor) { |
- interceptor_load_not_handled_calls = 0; |
- CheckInterceptorLoadIC(InterceptorLoadNotHandled, |
- "receiver = new Object();" |
- "receiver.__proto__ = o;" |
- "proto = new Object();" |
- "/* Make proto a slow-case object. */" |
- "for (var i = 0; i < 1000; i++) {" |
- " proto[\"xxxxxxxx\" + i] = [];" |
- "}" |
- "proto.x = 17;" |
- "o.__proto__ = proto;" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result += receiver.x;" |
- "}" |
- "result;", |
- 17 * 1000); |
- CHECK_EQ(1000, interceptor_load_not_handled_calls); |
-} |
- |
- |
-// Test the case when we stored field into |
-// a stub, but it got invalidated later on due to override on |
-// global object which is between interceptor and fields' holders. |
-THREADED_TEST(InterceptorLoadICInvalidatedFieldViaGlobal) { |
- CheckInterceptorLoadIC(InterceptorLoadXICGetter, |
- "o.__proto__ = this;" // set a global to be a proto of o. |
- "this.__proto__.y = 239;" |
- "for (var i = 0; i < 10; i++) {" |
- " if (o.y != 239) throw 'oops: ' + o.y;" |
- // Now it should be ICed and keep a reference to y defined on field_holder. |
- "}" |
- "this.y = 42;" // Assign on a global. |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " result += o.y;" |
- "}" |
- "result;", |
- 42 * 10); |
-} |
- |
- |
-static void SetOnThis(Local<String> name, |
- Local<Value> value, |
- const v8::PropertyCallbackInfo<void>& info) { |
- Local<Object>::Cast(info.This())->ForceSet(name, value); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithCallbackOnHolder) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- templ->SetAccessor(v8_str("y"), Return239Callback); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- |
- // Check the case when receiver and interceptor's holder |
- // are the same objects. |
- v8::Handle<Value> value = CompileRun( |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = o.y;" |
- "}"); |
- CHECK_EQ(239, value->Int32Value()); |
- |
- // Check the case when interceptor's holder is in proto chain |
- // of receiver. |
- value = CompileRun( |
- "r = { __proto__: o };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = r.y;" |
- "}"); |
- CHECK_EQ(239, value->Int32Value()); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICWithCallbackOnProto) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); |
- templ_p->SetAccessor(v8_str("y"), Return239Callback); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- context->Global()->Set(v8_str("p"), templ_p->NewInstance()); |
- |
- // Check the case when receiver and interceptor's holder |
- // are the same objects. |
- v8::Handle<Value> value = CompileRun( |
- "o.__proto__ = p;" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = o.x + o.y;" |
- "}"); |
- CHECK_EQ(239 + 42, value->Int32Value()); |
- |
- // Check the case when interceptor's holder is in proto chain |
- // of receiver. |
- value = CompileRun( |
- "r = { __proto__: o };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = r.x + r.y;" |
- "}"); |
- CHECK_EQ(239 + 42, value->Int32Value()); |
-} |
- |
- |
-THREADED_TEST(InterceptorLoadICForCallbackWithOverride) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- templ->SetAccessor(v8_str("y"), Return239Callback); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- |
- v8::Handle<Value> value = CompileRun( |
- "fst = new Object(); fst.__proto__ = o;" |
- "snd = new Object(); snd.__proto__ = fst;" |
- "var result1 = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result1 = snd.x;" |
- "}" |
- "fst.x = 239;" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = snd.x;" |
- "}" |
- "result + result1"); |
- CHECK_EQ(239 + 42, value->Int32Value()); |
-} |
- |
- |
-// Test the case when we stored callback into |
-// a stub, but interceptor produced value on its own. |
-THREADED_TEST(InterceptorLoadICCallbackNotNeeded) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); |
- templ_p->SetAccessor(v8_str("y"), Return239Callback); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- context->Global()->Set(v8_str("p"), templ_p->NewInstance()); |
- |
- v8::Handle<Value> value = CompileRun( |
- "o.__proto__ = p;" |
- "for (var i = 0; i < 7; i++) {" |
- " o.x;" |
- // Now it should be ICed and keep a reference to x defined on p |
- "}" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result += o.x;" |
- "}" |
- "result"); |
- CHECK_EQ(42 * 7, value->Int32Value()); |
-} |
- |
- |
-// Test the case when we stored callback into |
-// a stub, but it got invalidated later on. |
-THREADED_TEST(InterceptorLoadICInvalidatedCallback) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); |
- templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- context->Global()->Set(v8_str("p"), templ_p->NewInstance()); |
- |
- v8::Handle<Value> value = CompileRun( |
- "inbetween = new Object();" |
- "o.__proto__ = inbetween;" |
- "inbetween.__proto__ = p;" |
- "for (var i = 0; i < 10; i++) {" |
- " o.y;" |
- // Now it should be ICed and keep a reference to y defined on p |
- "}" |
- "inbetween.y = 42;" |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " result += o.y;" |
- "}" |
- "result"); |
- CHECK_EQ(42 * 10, value->Int32Value()); |
-} |
- |
- |
-// Test the case when we stored callback into |
-// a stub, but it got invalidated later on due to override on |
-// global object which is between interceptor and callbacks' holders. |
-THREADED_TEST(InterceptorLoadICInvalidatedCallbackViaGlobal) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- v8::Handle<v8::ObjectTemplate> templ_p = ObjectTemplate::New(isolate); |
- templ_p->SetAccessor(v8_str("y"), Return239Callback, SetOnThis); |
- |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- context->Global()->Set(v8_str("p"), templ_p->NewInstance()); |
- |
- v8::Handle<Value> value = CompileRun( |
- "o.__proto__ = this;" |
- "this.__proto__ = p;" |
- "for (var i = 0; i < 10; i++) {" |
- " if (o.y != 239) throw 'oops: ' + o.y;" |
- // Now it should be ICed and keep a reference to y defined on p |
- "}" |
- "this.y = 42;" |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " result += o.y;" |
- "}" |
- "result"); |
- CHECK_EQ(42 * 10, value->Int32Value()); |
-} |
- |
- |
-static void InterceptorLoadICGetter0( |
- 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)); |
-} |
- |
- |
-THREADED_TEST(InterceptorReturningZero) { |
- CheckInterceptorLoadIC(InterceptorLoadICGetter0, |
- "o.x == undefined ? 1 : 0", |
- 0); |
-} |
- |
- |
-static void InterceptorStoreICSetter( |
- Local<Name> key, Local<Value> value, |
- const v8::PropertyCallbackInfo<v8::Value>& info) { |
- CHECK(v8_str("x")->Equals(key)); |
- CHECK_EQ(42, value->Int32Value()); |
- info.GetReturnValue().Set(value); |
-} |
- |
- |
-// This test should hit the store IC for the interceptor case. |
-THREADED_TEST(InterceptorStoreIC) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration( |
- InterceptorLoadICGetter, InterceptorStoreICSetter, 0, 0, 0, |
- v8_str("data"))); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- CompileRun( |
- "for (var i = 0; i < 1000; i++) {" |
- " o.x = 42;" |
- "}"); |
-} |
- |
- |
-THREADED_TEST(InterceptorStoreICWithNoSetter) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "for (var i = 0; i < 1000; i++) {" |
- " o.y = 239;" |
- "}" |
- "42 + o.y"); |
- CHECK_EQ(239 + 42, value->Int32Value()); |
-} |
- |
- |
- |
- |
-v8::Handle<Value> call_ic_function; |
-v8::Handle<Value> call_ic_function2; |
-v8::Handle<Value> call_ic_function3; |
- |
-static void InterceptorCallICGetter( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CHECK(v8_str("x")->Equals(name)); |
- info.GetReturnValue().Set(call_ic_function); |
-} |
- |
- |
-// This test should hit the call IC for the interceptor case. |
-THREADED_TEST(InterceptorCallIC) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- call_ic_function = |
- v8_compile("function f(x) { return x + 1; }; f")->Run(); |
- v8::Handle<Value> value = CompileRun( |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.x(41);" |
- "}"); |
- CHECK_EQ(42, value->Int32Value()); |
-} |
- |
- |
-// This test checks that if interceptor doesn't provide |
-// a value, we can fetch regular value. |
-THREADED_TEST(InterceptorCallICSeesOthers) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "o.x = function f(x) { return x + 1; };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result = o.x(41);" |
- "}"); |
- CHECK_EQ(42, value->Int32Value()); |
-} |
- |
- |
-static v8::Handle<Value> call_ic_function4; |
-static void InterceptorCallICGetter4( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- CHECK(v8_str("x")->Equals(name)); |
- info.GetReturnValue().Set(call_ic_function4); |
-} |
- |
- |
-// This test checks that if interceptor provides a function, |
-// even if we cached shadowed variant, interceptor's function |
-// is invoked |
-THREADED_TEST(InterceptorCallICCacheableNotNeeded) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter4)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- call_ic_function4 = |
- v8_compile("function f(x) { return x - 1; }; f")->Run(); |
- v8::Handle<Value> value = CompileRun( |
- "Object.getPrototypeOf(o).x = function(x) { return x + 1; };" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.x(42);" |
- "}"); |
- CHECK_EQ(41, value->Int32Value()); |
-} |
- |
- |
-// Test the case when we stored cacheable lookup into |
-// a stub, but it got invalidated later on |
-THREADED_TEST(InterceptorCallICInvalidatedCacheable) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "proto1 = new Object();" |
- "proto2 = new Object();" |
- "o.__proto__ = proto1;" |
- "proto1.__proto__ = proto2;" |
- "proto2.y = function(x) { return x + 1; };" |
- // Invoke it many times to compile a stub |
- "for (var i = 0; i < 7; i++) {" |
- " o.y(42);" |
- "}" |
- "proto1.y = function(x) { return x - 1; };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result += o.y(42);" |
- "}"); |
- CHECK_EQ(41 * 7, value->Int32Value()); |
-} |
- |
- |
-// This test checks that if interceptor doesn't provide a function, |
-// cached constant function is used |
-THREADED_TEST(InterceptorCallICConstantFunctionUsed) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "o.x = inc;" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.x(42);" |
- "}"); |
- CHECK_EQ(43, value->Int32Value()); |
-} |
- |
- |
-static v8::Handle<Value> call_ic_function5; |
-static void InterceptorCallICGetter5( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (v8_str("x")->Equals(name)) |
- info.GetReturnValue().Set(call_ic_function5); |
-} |
- |
+ { |
+ Local<FunctionTemplate> function_template = |
+ FunctionTemplate::New(isolate, call_as_function); |
+ Local<Function> function = function_template->GetFunction(); |
+ Local<Object> instance = function; |
+ v8::TryCatch try_catch; |
-// This test checks that if interceptor provides a function, |
-// even if we cached constant function, interceptor's function |
-// is invoked |
-THREADED_TEST(InterceptorCallICConstantFunctionNotNeeded) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter5)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- call_ic_function5 = |
- v8_compile("function f(x) { return x - 1; }; f")->Run(); |
- v8::Handle<Value> value = CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "o.x = inc;" |
- "var result = 0;" |
- "for (var i = 0; i < 1000; i++) {" |
- " result = o.x(42);" |
- "}"); |
- CHECK_EQ(41, value->Int32Value()); |
-} |
- |
- |
-static v8::Handle<Value> call_ic_function6; |
-static void InterceptorCallICGetter6( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (v8_str("x")->Equals(name)) |
- info.GetReturnValue().Set(call_ic_function6); |
-} |
+ CHECK(instance->IsCallable()); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
+ { |
+ Local<FunctionTemplate> function_template = FunctionTemplate::New(isolate); |
+ Local<Function> function = function_template->GetFunction(); |
+ Local<Object> instance = function; |
+ v8::TryCatch try_catch; |
-// Same test as above, except the code is wrapped in a function |
-// to test the optimized compiler. |
-THREADED_TEST(InterceptorCallICConstantFunctionNotNeededWrapped) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorCallICGetter6)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- call_ic_function6 = |
- v8_compile("function f(x) { return x - 1; }; f")->Run(); |
- v8::Handle<Value> value = CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "o.x = inc;" |
- "function test() {" |
- " var result = 0;" |
- " for (var i = 0; i < 1000; i++) {" |
- " result = o.x(42);" |
- " }" |
- " return result;" |
- "};" |
- "test();" |
- "test();" |
- "test();" |
- "%OptimizeFunctionOnNextCall(test);" |
- "test()"); |
- CHECK_EQ(41, value->Int32Value()); |
+ CHECK(instance->IsCallable()); |
+ CHECK(!try_catch.HasCaught()); |
+ } |
} |
-// Test the case when we stored constant function into |
-// a stub, but it got invalidated later on |
-THREADED_TEST(InterceptorCallICInvalidatedConstantFunction) { |
- v8::Isolate* isolate = CcTest::isolate(); |
+static int Recurse(v8::Isolate* isolate, int depth, int iterations) { |
v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "proto1 = new Object();" |
- "proto2 = new Object();" |
- "o.__proto__ = proto1;" |
- "proto1.__proto__ = proto2;" |
- "proto2.y = inc;" |
- // Invoke it many times to compile a stub |
- "for (var i = 0; i < 7; i++) {" |
- " o.y(42);" |
- "}" |
- "proto1.y = function(x) { return x - 1; };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result += o.y(42);" |
- "}"); |
- CHECK_EQ(41 * 7, value->Int32Value()); |
+ if (depth == 0) return v8::HandleScope::NumberOfHandles(isolate); |
+ for (int i = 0; i < iterations; i++) { |
+ Local<v8::Number> n(v8::Integer::New(isolate, 42)); |
+ } |
+ return Recurse(isolate, depth - 1, iterations); |
} |
-// Test the case when we stored constant function into |
-// a stub, but it got invalidated later on due to override on |
-// global object which is between interceptor and constant function' holders. |
-THREADED_TEST(InterceptorCallICInvalidatedConstantFunctionViaGlobal) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
+THREADED_TEST(HandleIteration) { |
+ static const int kIterations = 500; |
+ static const int kNesting = 200; |
LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- v8::Handle<Value> value = CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "o.__proto__ = this;" |
- "this.__proto__.y = inc;" |
- // Invoke it many times to compile a stub |
- "for (var i = 0; i < 7; i++) {" |
- " if (o.y(42) != 43) throw 'oops: ' + o.y(42);" |
- "}" |
- "this.y = function(x) { return x - 1; };" |
- "var result = 0;" |
- "for (var i = 0; i < 7; i++) {" |
- " result += o.y(42);" |
- "}"); |
- CHECK_EQ(41 * 7, value->Int32Value()); |
-} |
- |
- |
-// Test the case when actual function to call sits on global object. |
-THREADED_TEST(InterceptorCallICCachedFromGlobal) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
+ v8::Isolate* isolate = context->GetIsolate(); |
+ v8::HandleScope scope0(isolate); |
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
+ { |
+ v8::HandleScope scope1(isolate); |
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
+ for (int i = 0; i < kIterations; i++) { |
+ Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); |
+ CHECK_EQ(i + 1, v8::HandleScope::NumberOfHandles(isolate)); |
+ } |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- |
- v8::Handle<Value> value = CompileRun( |
- "try {" |
- " o.__proto__ = this;" |
- " for (var i = 0; i < 10; i++) {" |
- " var v = o.parseFloat('239');" |
- " if (v != 239) throw v;" |
- // Now it should be ICed and keep a reference to parseFloat. |
- " }" |
- " var result = 0;" |
- " for (var i = 0; i < 10; i++) {" |
- " result += o.parseFloat('239');" |
- " }" |
- " result" |
- "} catch(e) {" |
- " e" |
- "};"); |
- CHECK_EQ(239 * 10, value->Int32Value()); |
+ CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); |
+ { |
+ v8::HandleScope scope2(CcTest::isolate()); |
+ for (int j = 0; j < kIterations; j++) { |
+ Local<v8::Number> n(v8::Integer::New(CcTest::isolate(), 42)); |
+ CHECK_EQ(j + 1 + kIterations, |
+ v8::HandleScope::NumberOfHandles(isolate)); |
+ } |
+ } |
+ CHECK_EQ(kIterations, v8::HandleScope::NumberOfHandles(isolate)); |
+ } |
+ CHECK_EQ(0, v8::HandleScope::NumberOfHandles(isolate)); |
+ CHECK_EQ(kNesting * kIterations, Recurse(isolate, kNesting, kIterations)); |
} |
+ |
static void InterceptorCallICFastApi( |
Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
ApiTestFuzzer::Fuzz(); |
@@ -12963,14 +10441,18 @@ THREADED_TEST(CallICFastApi_DirectCall_Throw) { |
} |
+static int p_getter_count_3; |
+ |
+ |
static Handle<Value> DoDirectGetter() { |
- if (++p_getter_count % 3 == 0) { |
+ if (++p_getter_count_3 % 3 == 0) { |
CcTest::heap()->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask); |
GenerateSomeGarbage(); |
} |
return v8_str("Direct Getter Result"); |
} |
+ |
static void DirectGetterCallback( |
Local<String> name, |
const v8::PropertyCallbackInfo<v8::Value>& info) { |
@@ -12987,7 +10469,7 @@ static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { |
v8::Handle<v8::ObjectTemplate> obj = v8::ObjectTemplate::New(isolate); |
obj->SetAccessor(v8_str("p1"), accessor); |
context->Global()->Set(v8_str("o1"), obj->NewInstance()); |
- p_getter_count = 0; |
+ p_getter_count_3 = 0; |
v8::Handle<v8::Value> result = CompileRun( |
"function f() {" |
" for (var i = 0; i < 30; i++) o1.p1;" |
@@ -12995,7 +10477,7 @@ static void LoadICFastApi_DirectCall_GCMoveStub(Accessor accessor) { |
"}" |
"f();"); |
CHECK(v8_str("Direct Getter Result")->Equals(result)); |
- CHECK_EQ(31, p_getter_count); |
+ CHECK_EQ(31, p_getter_count_3); |
} |
@@ -13425,344 +10907,6 @@ THREADED_PROFILED_TEST(CallICFastApi_SimpleSignature_TypeError) { |
} |
-v8::Handle<Value> keyed_call_ic_function; |
- |
-static void InterceptorKeyedCallICGetter( |
- Local<Name> name, const v8::PropertyCallbackInfo<v8::Value>& info) { |
- ApiTestFuzzer::Fuzz(); |
- if (v8_str("x")->Equals(name)) { |
- info.GetReturnValue().Set(keyed_call_ic_function); |
- } |
-} |
- |
- |
-// Test the case when we stored cacheable lookup into |
-// a stub, but the function name changed (to another cacheable function). |
-THREADED_TEST(InterceptorKeyedCallICKeyChange1) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- CompileRun( |
- "proto = new Object();" |
- "proto.y = function(x) { return x + 1; };" |
- "proto.z = function(x) { return x - 1; };" |
- "o.__proto__ = proto;" |
- "var result = 0;" |
- "var method = 'y';" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) { method = 'z'; };" |
- " result += o[method](41);" |
- "}"); |
- CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); |
-} |
- |
- |
-// Test the case when we stored cacheable lookup into |
-// a stub, but the function name changed (and the new function is present |
-// both before and after the interceptor in the prototype chain). |
-THREADED_TEST(InterceptorKeyedCallICKeyChange2) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorKeyedCallICGetter)); |
- LocalContext context; |
- context->Global()->Set(v8_str("proto1"), templ->NewInstance()); |
- keyed_call_ic_function = |
- v8_compile("function f(x) { return x - 1; }; f")->Run(); |
- CompileRun( |
- "o = new Object();" |
- "proto2 = new Object();" |
- "o.y = function(x) { return x + 1; };" |
- "proto2.y = function(x) { return x + 2; };" |
- "o.__proto__ = proto1;" |
- "proto1.__proto__ = proto2;" |
- "var result = 0;" |
- "var method = 'x';" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) { method = 'y'; };" |
- " result += o[method](41);" |
- "}"); |
- CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); |
-} |
- |
- |
-// Same as InterceptorKeyedCallICKeyChange1 only the cacheable function sit |
-// on the global object. |
-THREADED_TEST(InterceptorKeyedCallICKeyChangeOnGlobal) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ->NewInstance()); |
- CompileRun( |
- "function inc(x) { return x + 1; };" |
- "inc(1);" |
- "function dec(x) { return x - 1; };" |
- "dec(1);" |
- "o.__proto__ = this;" |
- "this.__proto__.x = inc;" |
- "this.__proto__.y = dec;" |
- "var result = 0;" |
- "var method = 'x';" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) { method = 'y'; };" |
- " result += o[method](41);" |
- "}"); |
- CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); |
-} |
- |
- |
-// Test the case when actual function to call sits on global object. |
-THREADED_TEST(InterceptorKeyedCallICFromGlobal) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- |
- CompileRun( |
- "function len(x) { return x.length; };" |
- "o.__proto__ = this;" |
- "var m = 'parseFloat';" |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) {" |
- " m = 'len';" |
- " saved_result = result;" |
- " };" |
- " result = o[m]('239');" |
- "}"); |
- CHECK_EQ(3, context->Global()->Get(v8_str("result"))->Int32Value()); |
- CHECK_EQ(239, context->Global()->Get(v8_str("saved_result"))->Int32Value()); |
-} |
- |
- |
-// Test the map transition before the interceptor. |
-THREADED_TEST(InterceptorKeyedCallICMapChangeBefore) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("proto"), templ_o->NewInstance()); |
- |
- CompileRun( |
- "var o = new Object();" |
- "o.__proto__ = proto;" |
- "o.method = function(x) { return x + 1; };" |
- "var m = 'method';" |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) { o.method = function(x) { return x - 1; }; };" |
- " result += o[m](41);" |
- "}"); |
- CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); |
-} |
- |
- |
-// Test the map transition after the interceptor. |
-THREADED_TEST(InterceptorKeyedCallICMapChangeAfter) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ_o = ObjectTemplate::New(isolate); |
- templ_o->SetHandler(v8::NamedPropertyHandlerConfiguration(NoBlockGetterX)); |
- LocalContext context; |
- context->Global()->Set(v8_str("o"), templ_o->NewInstance()); |
- |
- CompileRun( |
- "var proto = new Object();" |
- "o.__proto__ = proto;" |
- "proto.method = function(x) { return x + 1; };" |
- "var m = 'method';" |
- "var result = 0;" |
- "for (var i = 0; i < 10; i++) {" |
- " if (i == 5) { proto.method = function(x) { return x - 1; }; };" |
- " result += o[m](41);" |
- "}"); |
- CHECK_EQ(42*5 + 40*5, context->Global()->Get(v8_str("result"))->Int32Value()); |
-} |
- |
- |
-static int interceptor_call_count = 0; |
- |
-static void InterceptorICRefErrorGetter( |
- 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); |
- } |
-} |
- |
- |
-// This test should hit load and call ICs for the interceptor case. |
-// Once in a while, the interceptor will reply that a property was not |
-// found in which case we should get a reference error. |
-THREADED_TEST(InterceptorICReferenceErrors) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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( |
- "function f() {" |
- " for (var i = 0; i < 1000; i++) {" |
- " try { x; } catch(e) { return true; }" |
- " }" |
- " return false;" |
- "};" |
- "f();"); |
- CHECK_EQ(true, value->BooleanValue()); |
- interceptor_call_count = 0; |
- value = CompileRun( |
- "function g() {" |
- " for (var i = 0; i < 1000; i++) {" |
- " try { x(42); } catch(e) { return true; }" |
- " }" |
- " return false;" |
- "};" |
- "g();"); |
- CHECK_EQ(true, value->BooleanValue()); |
-} |
- |
- |
-static int interceptor_ic_exception_get_count = 0; |
- |
-static void InterceptorICExceptionGetter( |
- 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); |
- } |
- if (interceptor_ic_exception_get_count == 20) { |
- info.GetIsolate()->ThrowException(v8_num(42)); |
- return; |
- } |
-} |
- |
- |
-// Test interceptor load/call IC where the interceptor throws an |
-// exception once in a while. |
-THREADED_TEST(InterceptorICGetterExceptions) { |
- interceptor_ic_exception_get_count = 0; |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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( |
- "function f() {" |
- " for (var i = 0; i < 100; i++) {" |
- " try { x; } catch(e) { return true; }" |
- " }" |
- " return false;" |
- "};" |
- "f();"); |
- CHECK_EQ(true, value->BooleanValue()); |
- interceptor_ic_exception_get_count = 0; |
- value = CompileRun( |
- "function f() {" |
- " for (var i = 0; i < 100; i++) {" |
- " try { x(42); } catch(e) { return true; }" |
- " }" |
- " return false;" |
- "};" |
- "f();"); |
- CHECK_EQ(true, value->BooleanValue()); |
-} |
- |
- |
-static int interceptor_ic_exception_set_count = 0; |
- |
-static void InterceptorICExceptionSetter( |
- 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)); |
- } |
-} |
- |
- |
-// Test interceptor store IC where the interceptor throws an exception |
-// once in a while. |
-THREADED_TEST(InterceptorICSetterExceptions) { |
- interceptor_ic_exception_set_count = 0; |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- templ->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(0, InterceptorICExceptionSetter)); |
- LocalContext context(0, templ, v8::Handle<Value>()); |
- v8::Handle<Value> value = CompileRun( |
- "function f() {" |
- " for (var i = 0; i < 100; i++) {" |
- " try { x = 42; } catch(e) { return true; }" |
- " }" |
- " return false;" |
- "};" |
- "f();"); |
- CHECK_EQ(true, value->BooleanValue()); |
-} |
- |
- |
-// Test that we ignore null interceptors. |
-THREADED_TEST(NullNamedInterceptor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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(); |
- context->Global()->Set(v8_str("obj"), obj); |
- v8::Handle<Value> value = CompileRun("obj.x"); |
- CHECK(value->IsInt32()); |
- CHECK_EQ(42, value->Int32Value()); |
-} |
- |
- |
-// Test that we ignore null interceptors. |
-THREADED_TEST(NullIndexedInterceptor) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::ObjectTemplate> templ = ObjectTemplate::New(isolate); |
- 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(); |
- context->Global()->Set(v8_str("obj"), obj); |
- v8::Handle<Value> value = CompileRun("obj[42]"); |
- CHECK(value->IsInt32()); |
- CHECK_EQ(42, value->Int32Value()); |
-} |
- |
- |
-THREADED_TEST(NamedPropertyHandlerGetterAttributes) { |
- v8::Isolate* isolate = CcTest::isolate(); |
- v8::HandleScope scope(isolate); |
- v8::Handle<v8::FunctionTemplate> templ = v8::FunctionTemplate::New(isolate); |
- templ->InstanceTemplate()->SetHandler( |
- v8::NamedPropertyHandlerConfiguration(InterceptorLoadXICGetter)); |
- LocalContext env; |
- env->Global()->Set(v8_str("obj"), |
- templ->GetFunction()->NewInstance()); |
- ExpectTrue("obj.x === 42"); |
- ExpectTrue("!obj.propertyIsEnumerable('x')"); |
-} |
- |
- |
static void ThrowingGetter(Local<String> name, |
const v8::PropertyCallbackInfo<v8::Value>& info) { |
ApiTestFuzzer::Fuzz(); |
@@ -21631,30 +18775,6 @@ THREADED_TEST(Regress93759) { |
} |
-THREADED_TEST(Regress125988) { |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> intercept = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(intercept, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Intercept"), intercept->GetFunction()); |
- CompileRun("var a = new Object();" |
- "var b = new Intercept();" |
- "var c = new Object();" |
- "c.__proto__ = b;" |
- "b.__proto__ = a;" |
- "a.x = 23;" |
- "for (var i = 0; i < 3; i++) c.x;"); |
- ExpectBoolean("c.hasOwnProperty('x')", false); |
- ExpectInt32("c.x", 23); |
- CompileRun("a.y = 42;" |
- "for (var i = 0; i < 3; i++) c.x;"); |
- ExpectBoolean("c.hasOwnProperty('x')", false); |
- ExpectInt32("c.x", 23); |
- ExpectBoolean("c.hasOwnProperty('y')", false); |
- ExpectInt32("c.y", 42); |
-} |
- |
- |
static void TestReceiver(Local<Value> expected_result, |
Local<Value> expected_receiver, |
const char* code) { |
@@ -22342,6 +19462,15 @@ THREADED_TEST(InstanceCheckOnInstanceAccessor) { |
} |
+static void EmptyInterceptorGetter( |
+ Local<String> name, const v8::PropertyCallbackInfo<v8::Value>& info) {} |
+ |
+ |
+static void EmptyInterceptorSetter( |
+ Local<String> name, Local<Value> value, |
+ const v8::PropertyCallbackInfo<v8::Value>& info) {} |
+ |
+ |
THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { |
v8::internal::FLAG_allow_natives_syntax = true; |
LocalContext context; |
@@ -22349,7 +19478,8 @@ THREADED_TEST(InstanceCheckOnInstanceAccessorWithInterceptor) { |
Local<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); |
Local<ObjectTemplate> inst = templ->InstanceTemplate(); |
- AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
+ templ->InstanceTemplate()->SetNamedPropertyHandler(EmptyInterceptorGetter, |
+ EmptyInterceptorSetter); |
inst->SetAccessor(v8_str("foo"), |
InstanceCheckedGetter, InstanceCheckedSetter, |
Handle<Value>(), |
@@ -22624,16 +19754,6 @@ THREADED_TEST(Regress137496) { |
} |
-THREADED_TEST(Regress149912) { |
- LocalContext context; |
- v8::HandleScope scope(context->GetIsolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); |
- AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- context->Global()->Set(v8_str("Bug"), templ->GetFunction()); |
- CompileRun("Number.prototype.__proto__ = new Bug; var x = 0; x.foo();"); |
-} |
- |
- |
THREADED_TEST(Regress157124) { |
LocalContext context; |
v8::Isolate* isolate = context->GetIsolate(); |
@@ -22951,111 +20071,6 @@ TEST(AccessCheckThrows) { |
} |
-THREADED_TEST(Regress256330) { |
- i::FLAG_allow_natives_syntax = true; |
- LocalContext context; |
- v8::HandleScope scope(context->GetIsolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(context->GetIsolate()); |
- AddInterceptor(templ, EmptyInterceptorGetter, EmptyInterceptorSetter); |
- context->Global()->Set(v8_str("Bug"), templ->GetFunction()); |
- CompileRun("\"use strict\"; var o = new Bug;" |
- "function f(o) { o.x = 10; };" |
- "f(o); f(o); f(o);" |
- "%OptimizeFunctionOnNextCall(f);" |
- "f(o);"); |
- ExpectBoolean("%GetOptimizationStatus(f) != 2", true); |
-} |
- |
- |
-THREADED_TEST(CrankshaftInterceptorSetter) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- // Initialize fields to avoid transitions later. |
- "obj.age = 0;" |
- "obj.accessor_age = 42;" |
- "function setter(i) { this.accessor_age = i; };" |
- "function getter() { return this.accessor_age; };" |
- "function setAge(i) { obj.age = i; };" |
- "Object.defineProperty(obj, 'age', { get:getter, set:setter });" |
- "setAge(1);" |
- "setAge(2);" |
- "setAge(3);" |
- "%OptimizeFunctionOnNextCall(setAge);" |
- "setAge(4);"); |
- // All stores went through the interceptor. |
- ExpectInt32("obj.interceptor_age", 4); |
- ExpectInt32("obj.accessor_age", 42); |
-} |
- |
- |
-THREADED_TEST(CrankshaftInterceptorGetter) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- // Initialize fields to avoid transitions later. |
- "obj.age = 1;" |
- "obj.accessor_age = 42;" |
- "function getter() { return this.accessor_age; };" |
- "function getAge() { return obj.interceptor_age; };" |
- "Object.defineProperty(obj, 'interceptor_age', { get:getter });" |
- "getAge();" |
- "getAge();" |
- "getAge();" |
- "%OptimizeFunctionOnNextCall(getAge);"); |
- // Access through interceptor. |
- ExpectInt32("getAge()", 1); |
-} |
- |
- |
-THREADED_TEST(CrankshaftInterceptorFieldRead) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "obj.__proto__.interceptor_age = 42;" |
- "obj.age = 100;" |
- "function getAge() { return obj.interceptor_age; };"); |
- ExpectInt32("getAge();", 100); |
- ExpectInt32("getAge();", 100); |
- ExpectInt32("getAge();", 100); |
- CompileRun("%OptimizeFunctionOnNextCall(getAge);"); |
- // Access through interceptor. |
- ExpectInt32("getAge();", 100); |
-} |
- |
- |
-THREADED_TEST(CrankshaftInterceptorFieldWrite) { |
- i::FLAG_allow_natives_syntax = true; |
- v8::HandleScope scope(CcTest::isolate()); |
- Handle<FunctionTemplate> templ = FunctionTemplate::New(CcTest::isolate()); |
- AddInterceptor(templ, InterceptorGetter, InterceptorSetter); |
- LocalContext env; |
- env->Global()->Set(v8_str("Obj"), templ->GetFunction()); |
- CompileRun("var obj = new Obj;" |
- "obj.age = 100000;" |
- "function setAge(i) { obj.age = i };" |
- "setAge(100);" |
- "setAge(101);" |
- "setAge(102);" |
- "%OptimizeFunctionOnNextCall(setAge);" |
- "setAge(103);"); |
- ExpectInt32("obj.age", 100000); |
- ExpectInt32("obj.interceptor_age", 103); |
-} |
- |
- |
class RequestInterruptTestBase { |
public: |
RequestInterruptTestBase() |