summaryrefslogtreecommitdiff
path: root/deps/v8/test/cctest/test-api.cc
diff options
context:
space:
mode:
authorFedor Indutny <fedor.indutny@gmail.com>2013-01-01 12:28:07 +0400
committerFedor Indutny <fedor.indutny@gmail.com>2013-01-01 16:07:02 +0400
commit7b4d95a976f1b76e6dcefb6ca91dff738c80ab7a (patch)
tree1eb943733a2e660fc0183778fd441443e06196e2 /deps/v8/test/cctest/test-api.cc
parent9e32c2ef3ede29ba0ae2086bdf658f6cd44182df (diff)
downloadnode-new-7b4d95a976f1b76e6dcefb6ca91dff738c80ab7a.tar.gz
deps: update v8 to 3.15.11
Diffstat (limited to 'deps/v8/test/cctest/test-api.cc')
-rw-r--r--deps/v8/test/cctest/test-api.cc708
1 files changed, 652 insertions, 56 deletions
diff --git a/deps/v8/test/cctest/test-api.cc b/deps/v8/test/cctest/test-api.cc
index 1e12652c0a..0a5583bb94 100644
--- a/deps/v8/test/cctest/test-api.cc
+++ b/deps/v8/test/cctest/test-api.cc
@@ -25,6 +25,9 @@
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// We want to test our deprecated API entries, too.
+#define V8_DISABLE_DEPRECATIONS 1
+
#include <limits.h>
#ifndef WIN32
@@ -404,6 +407,10 @@ THREADED_TEST(ScriptUsingStringResource) {
CHECK(source->IsExternal());
CHECK_EQ(resource,
static_cast<TestResource*>(source->GetExternalStringResource()));
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::TWO_BYTE_ENCODING, encoding);
HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
CHECK_EQ(0, dispose_count);
}
@@ -419,9 +426,16 @@ THREADED_TEST(ScriptUsingAsciiStringResource) {
{
v8::HandleScope scope;
LocalContext env;
- Local<String> source =
- String::NewExternal(new TestAsciiResource(i::StrDup(c_source),
- &dispose_count));
+ TestAsciiResource* resource = new TestAsciiResource(i::StrDup(c_source),
+ &dispose_count);
+ Local<String> source = String::NewExternal(resource);
+ CHECK(source->IsExternalAscii());
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalAsciiStringResource());
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(static_cast<const String::ExternalStringResourceBase*>(resource),
+ source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
Local<Script> script = Script::Compile(source);
Local<Value> value = script->Run();
CHECK(value->IsNumber());
@@ -445,6 +459,11 @@ THREADED_TEST(ScriptMakingExternalString) {
// Trigger GCs so that the newly allocated string moves to old gen.
HEAP->CollectGarbage(i::NEW_SPACE); // in survivor space now
HEAP->CollectGarbage(i::NEW_SPACE); // in old gen now
+ CHECK_EQ(source->IsExternal(), false);
+ CHECK_EQ(source->IsExternalAscii(), false);
+ String::Encoding encoding = String::UNKNOWN_ENCODING;
+ CHECK_EQ(NULL, source->GetExternalStringResourceBase(&encoding));
+ CHECK_EQ(String::ASCII_ENCODING, encoding);
bool success = source->MakeExternal(new TestResource(two_byte_source,
&dispose_count));
CHECK(success);
@@ -607,6 +626,8 @@ THREADED_TEST(UsingExternalAsciiString) {
THREADED_TEST(ScavengeExternalString) {
+ i::FLAG_stress_compaction = false;
+ i::FLAG_gc_global = false;
int dispose_count = 0;
bool in_new_space = false;
{
@@ -627,6 +648,8 @@ THREADED_TEST(ScavengeExternalString) {
THREADED_TEST(ScavengeExternalAsciiString) {
+ i::FLAG_stress_compaction = false;
+ i::FLAG_gc_global = false;
int dispose_count = 0;
bool in_new_space = false;
{
@@ -953,22 +976,33 @@ THREADED_TEST(FindInstanceInPrototypeChain) {
THREADED_TEST(TinyInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
int32_t value = 239;
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigSmiInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
int32_t value = i::Smi::kMaxValue;
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
+
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
@@ -976,6 +1010,8 @@ THREADED_TEST(BigSmiInteger) {
THREADED_TEST(BigInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
// We cannot add one to a Smi::kMaxValue without wrapping.
if (i::kSmiValueSize < 32) {
// The casts allow this to compile, even if Smi::kMaxValue is 2^31-1.
@@ -984,8 +1020,12 @@ THREADED_TEST(BigInteger) {
static_cast<int32_t>(static_cast<uint32_t>(i::Smi::kMaxValue) + 1);
CHECK(value > i::Smi::kMaxValue);
CHECK(!i::Smi::IsValid(value));
+
Local<v8::Integer> value_obj = v8::Integer::New(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::New(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
}
@@ -993,42 +1033,66 @@ THREADED_TEST(BigInteger) {
THREADED_TEST(TinyUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = 239;
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedSmiInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue);
CHECK(i::Smi::IsValid(value));
CHECK(!i::Smi::IsValid(value + 1));
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(BigUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t value = static_cast<uint32_t>(i::Smi::kMaxValue) + 1;
CHECK(value > static_cast<uint32_t>(i::Smi::kMaxValue));
CHECK(!i::Smi::IsValid(value));
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
THREADED_TEST(OutOfSignedRangeUnsignedInteger) {
v8::HandleScope scope;
LocalContext env;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+
uint32_t INT32_MAX_AS_UINT = (1U << 31) - 1;
uint32_t value = INT32_MAX_AS_UINT + 1;
CHECK(value > INT32_MAX_AS_UINT); // No overflow.
+
Local<v8::Integer> value_obj = v8::Integer::NewFromUnsigned(value);
CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
+
+ value_obj = v8::Integer::NewFromUnsigned(value, isolate);
+ CHECK_EQ(static_cast<int64_t>(value), value_obj->Value());
}
@@ -1999,6 +2063,99 @@ THREADED_TEST(InternalFieldsNativePointersAndExternal) {
}
+static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj,
+ void* value) {
+ CHECK_EQ(0, static_cast<int>(reinterpret_cast<uintptr_t>(value) & 0x1));
+ obj->SetPointerInInternalField(0, value);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CHECK_EQ(value, obj->GetPointerFromInternalField(0));
+}
+
+
+THREADED_TEST(InternalFieldsAlignedPointers) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ Local<v8::FunctionTemplate> templ = v8::FunctionTemplate::New();
+ Local<v8::ObjectTemplate> instance_templ = templ->InstanceTemplate();
+ instance_templ->SetInternalFieldCount(1);
+ Local<v8::Object> obj = templ->GetFunction()->NewInstance();
+ CHECK_EQ(1, obj->InternalFieldCount());
+
+ CheckAlignedPointerInInternalField(obj, NULL);
+
+ int* heap_allocated = new int[100];
+ CheckAlignedPointerInInternalField(obj, heap_allocated);
+ delete[] heap_allocated;
+
+ int stack_allocated[100];
+ CheckAlignedPointerInInternalField(obj, stack_allocated);
+
+ void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1));
+ CheckAlignedPointerInInternalField(obj, huge);
+}
+
+
+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);
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ CHECK_EQ(value, (*env)->GetAlignedPointerFromEmbedderData(index));
+}
+
+
+static void* AlignedTestPointer(int i) {
+ return reinterpret_cast<void*>(i * 1234);
+}
+
+
+THREADED_TEST(EmbedderDataAlignedPointers) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CheckAlignedPointerInEmbedderData(&env, 0, NULL);
+
+ int* heap_allocated = new int[100];
+ CheckAlignedPointerInEmbedderData(&env, 1, heap_allocated);
+ delete[] heap_allocated;
+
+ int stack_allocated[100];
+ CheckAlignedPointerInEmbedderData(&env, 2, stack_allocated);
+
+ void* huge = reinterpret_cast<void*>(~static_cast<uintptr_t>(1));
+ CheckAlignedPointerInEmbedderData(&env, 3, huge);
+
+ // Test growing of the embedder data's backing store.
+ for (int i = 0; i < 100; i++) {
+ env->SetAlignedPointerInEmbedderData(i, AlignedTestPointer(i));
+ }
+ HEAP->CollectAllGarbage(i::Heap::kNoGCFlags);
+ for (int i = 0; i < 100; i++) {
+ CHECK_EQ(AlignedTestPointer(i), env->GetAlignedPointerFromEmbedderData(i));
+ }
+}
+
+
+static void CheckEmbedderData(LocalContext* env,
+ int index,
+ v8::Handle<Value> data) {
+ (*env)->SetEmbedderData(index, data);
+ CHECK((*env)->GetEmbedderData(index)->StrictEquals(data));
+}
+
+THREADED_TEST(EmbedderData) {
+ v8::HandleScope scope;
+ LocalContext env;
+
+ CheckEmbedderData(&env, 3, v8::String::New("The quick brown fox jumps"));
+ CheckEmbedderData(&env, 2, v8::String::New("over the lazy dog."));
+ CheckEmbedderData(&env, 1, v8::Number::New(1.2345));
+ CheckEmbedderData(&env, 0, v8::Boolean::New(true));
+}
+
+
THREADED_TEST(IdentityHash) {
v8::HandleScope scope;
LocalContext env;
@@ -2192,6 +2349,24 @@ THREADED_TEST(GlobalHandle) {
}
CHECK_EQ(global->Length(), 3);
global.Dispose();
+
+ {
+ v8::HandleScope scope;
+ Local<String> str = v8_str("str");
+ global = v8::Persistent<String>::New(str);
+ }
+ CHECK_EQ(global->Length(), 3);
+ global.Dispose(v8::Isolate::GetCurrent());
+}
+
+
+THREADED_TEST(LocalHandle) {
+ v8::HandleScope scope;
+ v8::Local<String> local = v8::Local<String>::New(v8_str("str"));
+ CHECK_EQ(local->Length(), 3);
+
+ local = v8::Local<String>::New(v8::Isolate::GetCurrent(), v8_str("str"));
+ CHECK_EQ(local->Length(), 3);
}
@@ -2312,23 +2487,41 @@ THREADED_TEST(ApiObjectGroupsCycle) {
Persistent<Object> g2s2;
Persistent<Object> g3s1;
Persistent<Object> g3s2;
+ Persistent<Object> g4s1;
+ Persistent<Object> g4s2;
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
{
HandleScope scope;
g1s1 = Persistent<Object>::New(Object::New());
g1s2 = Persistent<Object>::New(Object::New());
g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ CHECK(g1s1.IsWeak());
+ CHECK(g1s2.IsWeak());
g2s1 = Persistent<Object>::New(Object::New());
g2s2 = Persistent<Object>::New(Object::New());
g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ CHECK(g2s1.IsWeak());
+ CHECK(g2s2.IsWeak());
g3s1 = Persistent<Object>::New(Object::New());
g3s2 = Persistent<Object>::New(Object::New());
g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ CHECK(g3s1.IsWeak());
+ CHECK(g3s2.IsWeak());
+
+ g4s1 = Persistent<Object>::New(Object::New());
+ g4s2 = Persistent<Object>::New(Object::New());
+ g4s1.MakeWeak(isolate,
+ reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g4s2.MakeWeak(isolate,
+ reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ CHECK(g4s1.IsWeak(isolate));
+ CHECK(g4s2.IsWeak(isolate));
}
Persistent<Object> root = Persistent<Object>::New(g1s1); // make a root.
@@ -2342,13 +2535,17 @@ THREADED_TEST(ApiObjectGroupsCycle) {
Persistent<Value> g2_objects[] = { g2s1, g2s2 };
Persistent<Value> g2_children[] = { g3s1 };
Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- Persistent<Value> g3_children[] = { g1s1 };
+ Persistent<Value> g3_children[] = { g4s1 };
+ Persistent<Value> g4_objects[] = { g4s1, g4s2 };
+ Persistent<Value> g4_children[] = { g1s1 };
V8::AddObjectGroup(g1_objects, 2);
V8::AddImplicitReferences(g1s1, g1_children, 1);
V8::AddObjectGroup(g2_objects, 2);
V8::AddImplicitReferences(g2s1, g2_children, 1);
V8::AddObjectGroup(g3_objects, 2);
V8::AddImplicitReferences(g3s1, g3_children, 1);
+ V8::AddObjectGroup(isolate, g4_objects, 2);
+ V8::AddImplicitReferences(g4s1, g4_children, 1);
}
// Do a single full GC
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
@@ -2366,17 +2563,117 @@ THREADED_TEST(ApiObjectGroupsCycle) {
Persistent<Value> g2_objects[] = { g2s1, g2s2 };
Persistent<Value> g2_children[] = { g3s1 };
Persistent<Value> g3_objects[] = { g3s1, g3s2 };
- Persistent<Value> g3_children[] = { g1s1 };
+ Persistent<Value> g3_children[] = { g4s1 };
+ Persistent<Value> g4_objects[] = { g4s1, g4s2 };
+ Persistent<Value> g4_children[] = { g1s1 };
V8::AddObjectGroup(g1_objects, 2);
V8::AddImplicitReferences(g1s1, g1_children, 1);
V8::AddObjectGroup(g2_objects, 2);
V8::AddImplicitReferences(g2s1, g2_children, 1);
V8::AddObjectGroup(g3_objects, 2);
V8::AddImplicitReferences(g3s1, g3_children, 1);
+ V8::AddObjectGroup(g4_objects, 2);
+ V8::AddImplicitReferences(g4s1, g4_children, 1);
}
HEAP->CollectAllGarbage(i::Heap::kAbortIncrementalMarkingMask);
+ // All objects should be gone. 9 global handles in total.
+ CHECK_EQ(9, counter.NumberOfWeakCalls());
+}
+
+
+// TODO(mstarzinger): This should be a THREADED_TEST but causes failures
+// on the buildbots, so was made non-threaded for the time being.
+TEST(ApiObjectGroupsCycleForScavenger) {
+ i::FLAG_stress_compaction = false;
+ i::FLAG_gc_global = false;
+ HandleScope scope;
+ LocalContext env;
+
+ WeakCallCounter counter(1234);
+
+ Persistent<Object> g1s1;
+ Persistent<Object> g1s2;
+ Persistent<Object> g2s1;
+ Persistent<Object> g2s2;
+ Persistent<Object> g3s1;
+ Persistent<Object> g3s2;
+
+ {
+ HandleScope scope;
+ g1s1 = Persistent<Object>::New(Object::New());
+ g1s2 = Persistent<Object>::New(Object::New());
+ g1s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g1s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+
+ g2s1 = Persistent<Object>::New(Object::New());
+ g2s2 = Persistent<Object>::New(Object::New());
+ g2s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g2s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+
+ g3s1 = Persistent<Object>::New(Object::New());
+ g3s2 = Persistent<Object>::New(Object::New());
+ g3s1.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ g3s2.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ }
+
+ // Make a root.
+ Persistent<Object> root = Persistent<Object>::New(g1s1);
+ root.MarkPartiallyDependent();
+
+ // Connect groups. We're building the following cycle:
+ // G1: { g1s1, g2s1 }, g1s1 implicitly references g2s1, ditto for other
+ // groups.
+ {
+ g1s1.MarkPartiallyDependent();
+ g1s2.MarkPartiallyDependent();
+ g2s1.MarkPartiallyDependent();
+ g2s2.MarkPartiallyDependent();
+ g3s1.MarkPartiallyDependent();
+ g3s2.MarkPartiallyDependent();
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g3_objects[] = { g3s1, g3s2 };
+ V8::AddObjectGroup(g1_objects, 2);
+ g1s1->Set(v8_str("x"), g2s1);
+ V8::AddObjectGroup(g2_objects, 2);
+ g2s1->Set(v8_str("x"), g3s1);
+ V8::AddObjectGroup(g3_objects, 2);
+ g3s1->Set(v8_str("x"), g1s1);
+ }
+
+ HEAP->CollectGarbage(i::NEW_SPACE);
+
+ // All objects should be alive.
+ CHECK_EQ(0, counter.NumberOfWeakCalls());
+
+ // Weaken the root.
+ root.MakeWeak(reinterpret_cast<void*>(&counter), &WeakPointerCallback);
+ root.MarkPartiallyDependent();
+
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
+ // Groups are deleted, rebuild groups.
+ {
+ g1s1.MarkPartiallyDependent(isolate);
+ g1s2.MarkPartiallyDependent(isolate);
+ g2s1.MarkPartiallyDependent(isolate);
+ g2s2.MarkPartiallyDependent(isolate);
+ g3s1.MarkPartiallyDependent(isolate);
+ g3s2.MarkPartiallyDependent(isolate);
+ Persistent<Value> g1_objects[] = { g1s1, g1s2 };
+ Persistent<Value> g2_objects[] = { g2s1, g2s2 };
+ Persistent<Value> g3_objects[] = { g3s1, g3s2 };
+ V8::AddObjectGroup(g1_objects, 2);
+ g1s1->Set(v8_str("x"), g2s1);
+ V8::AddObjectGroup(g2_objects, 2);
+ g2s1->Set(v8_str("x"), g3s1);
+ V8::AddObjectGroup(g3_objects, 2);
+ g3s1->Set(v8_str("x"), g1s1);
+ }
+
+ HEAP->CollectGarbage(i::NEW_SPACE);
+
// All objects should be gone. 7 global handles in total.
CHECK_EQ(7, counter.NumberOfWeakCalls());
}
@@ -2395,23 +2692,34 @@ THREADED_TEST(ScriptException) {
}
+TEST(TryCatchCustomException) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::TryCatch try_catch;
+ CompileRun("function CustomError() { this.a = 'b'; }"
+ "(function f() { throw new CustomError(); })();");
+ CHECK(try_catch.HasCaught());
+ CHECK(try_catch.Exception()->ToObject()->
+ Get(v8_str("a"))->Equals(v8_str("b")));
+}
+
+
bool message_received;
-static void check_message(v8::Handle<v8::Message> message,
- v8::Handle<Value> data) {
- CHECK_EQ(5.76, data->NumberValue());
+static void check_message_0(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
CHECK_EQ(6.75, message->GetScriptResourceName()->NumberValue());
CHECK_EQ(7.56, message->GetScriptData()->NumberValue());
message_received = true;
}
-THREADED_TEST(MessageHandlerData) {
+THREADED_TEST(MessageHandler0) {
message_received = false;
v8::HandleScope scope;
CHECK(!message_received);
- v8::V8::AddMessageListener(check_message, v8_num(5.76));
+ v8::V8::AddMessageListener(check_message_0);
LocalContext context;
v8::ScriptOrigin origin =
v8::ScriptOrigin(v8_str("6.75"));
@@ -2421,7 +2729,56 @@ THREADED_TEST(MessageHandlerData) {
script->Run();
CHECK(message_received);
// clear out the message listener
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(check_message_0);
+}
+
+
+static void check_message_1(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ CHECK(data->IsNumber());
+ CHECK_EQ(1337, data->Int32Value());
+ message_received = true;
+}
+
+
+TEST(MessageHandler1) {
+ message_received = false;
+ v8::HandleScope scope;
+ CHECK(!message_received);
+ v8::V8::AddMessageListener(check_message_1);
+ LocalContext context;
+ CompileRun("throw 1337;");
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_1);
+}
+
+
+static void check_message_2(v8::Handle<v8::Message> message,
+ v8::Handle<Value> data) {
+ LocalContext context;
+ CHECK(data->IsObject());
+ v8::Local<v8::Value> hidden_property =
+ v8::Object::Cast(*data)->GetHiddenValue(v8_str("hidden key"));
+ CHECK(v8_str("hidden value")->Equals(hidden_property));
+ message_received = true;
+}
+
+
+TEST(MessageHandler2) {
+ message_received = false;
+ v8::HandleScope scope;
+ CHECK(!message_received);
+ 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"));
+ context->Global()->Set(v8_str("error"), error);
+ CompileRun("throw error;");
+ CHECK(message_received);
+ // clear out the message listener
+ v8::V8::RemoveMessageListeners(check_message_2);
}
@@ -3062,7 +3419,7 @@ TEST(APIThrowMessageOverwrittenToString) {
"Number.prototype.toString = function() { return 'Whoops'; };"
"ReferenceError.prototype.toString = Object.prototype.toString;");
CompileRun("asdf;");
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(check_reference_error_message);
}
@@ -3109,7 +3466,7 @@ TEST(APIThrowMessage) {
LocalContext context(0, templ);
CompileRun("ThrowFromC();");
CHECK(message_received);
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(receive_message);
}
@@ -3127,7 +3484,7 @@ TEST(APIThrowMessageAndVerboseTryCatch) {
CHECK(try_catch.HasCaught());
CHECK(result.IsEmpty());
CHECK(message_received);
- v8::V8::RemoveMessageListeners(check_message);
+ v8::V8::RemoveMessageListeners(receive_message);
}
@@ -3399,6 +3756,30 @@ THREADED_TEST(TryCatchAndFinally) {
}
+static void TryCatchNestedHelper(int depth) {
+ if (depth > 0) {
+ v8::TryCatch try_catch;
+ try_catch.SetVerbose(true);
+ TryCatchNestedHelper(depth - 1);
+ CHECK(try_catch.HasCaught());
+ try_catch.ReThrow();
+ } else {
+ v8::ThrowException(v8_str("back"));
+ }
+}
+
+
+TEST(TryCatchNested) {
+ v8::V8::Initialize();
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::TryCatch try_catch;
+ TryCatchNestedHelper(5);
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(0, strcmp(*v8::String::Utf8Value(try_catch.Exception()), "back"));
+}
+
+
THREADED_TEST(Equality) {
v8::HandleScope scope;
LocalContext context;
@@ -5092,7 +5473,6 @@ TEST(RegexpOutOfMemory) {
static void MissingScriptInfoMessageListener(v8::Handle<v8::Message> message,
v8::Handle<Value> data) {
- CHECK_EQ(v8::Undefined(), data);
CHECK(message->GetScriptResourceName()->IsUndefined());
CHECK_EQ(v8::Undefined(), message->GetScriptResourceName());
message->GetLineNumber();
@@ -5204,18 +5584,28 @@ THREADED_TEST(IndependentWeakHandle) {
v8::Persistent<Context> context = Context::New();
Context::Scope context_scope(context);
- v8::Persistent<v8::Object> object_a;
+ v8::Persistent<v8::Object> object_a, object_b;
{
v8::HandleScope handle_scope;
object_a = v8::Persistent<v8::Object>::New(v8::Object::New());
+ object_b = v8::Persistent<v8::Object>::New(v8::Object::New());
}
+ v8::Isolate* isolate = v8::Isolate::GetCurrent();
bool object_a_disposed = false;
+ bool object_b_disposed = false;
object_a.MakeWeak(&object_a_disposed, &DisposeAndSetFlag);
+ object_b.MakeWeak(&object_b_disposed, &DisposeAndSetFlag);
+ CHECK(!object_a.IsIndependent());
+ CHECK(!object_b.IsIndependent(isolate));
object_a.MarkIndependent();
+ object_b.MarkIndependent(isolate);
+ CHECK(object_a.IsIndependent());
+ CHECK(object_b.IsIndependent(isolate));
HEAP->PerformScavenge();
CHECK(object_a_disposed);
+ CHECK(object_b_disposed);
}
@@ -7739,12 +8129,8 @@ THREADED_TEST(ShadowObject) {
Local<ObjectTemplate> proto = t->PrototypeTemplate();
Local<ObjectTemplate> instance = t->InstanceTemplate();
- // Only allow calls of f on instances of t.
- Local<v8::Signature> signature = v8::Signature::New(t);
proto->Set(v8_str("f"),
- v8::FunctionTemplate::New(ShadowFunctionCallback,
- Local<Value>(),
- signature));
+ v8::FunctionTemplate::New(ShadowFunctionCallback, Local<Value>()));
proto->Set(v8_str("x"), v8_num(12));
instance->SetAccessor(v8_str("y"), ShadowYGetter, ShadowYSetter);
@@ -9609,6 +9995,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
@@ -9639,6 +10026,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss1) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
@@ -9675,6 +10063,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss2) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
@@ -9711,6 +10100,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_Miss3) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
@@ -9750,6 +10140,7 @@ THREADED_TEST(InterceptorCallICFastApi_SimpleSignature_TypeError) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ = fun_templ->InstanceTemplate();
templ->SetNamedPropertyHandler(InterceptorCallICFastApi,
NULL, NULL, NULL, NULL,
@@ -9812,6 +10203,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
CHECK(!templ.IsEmpty());
LocalContext context;
@@ -9839,6 +10231,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss1) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
CHECK(!templ.IsEmpty());
LocalContext context;
@@ -9871,6 +10264,7 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss2) {
v8::Signature::New(fun_templ));
v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
CHECK(!templ.IsEmpty());
LocalContext context;
@@ -9897,6 +10291,42 @@ THREADED_TEST(CallICFastApi_SimpleSignature_Miss2) {
CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
}
+THREADED_TEST(CallICFastApi_SimpleSignature_TypeError) {
+ v8::HandleScope scope;
+ v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New();
+ v8::Handle<v8::FunctionTemplate> method_templ =
+ v8::FunctionTemplate::New(FastApiCallback_SimpleSignature,
+ v8_str("method_data"),
+ v8::Signature::New(fun_templ));
+ v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate();
+ proto_templ->Set(v8_str("method"), method_templ);
+ fun_templ->SetHiddenPrototype(true);
+ v8::Handle<v8::ObjectTemplate> templ(fun_templ->InstanceTemplate());
+ CHECK(!templ.IsEmpty());
+ LocalContext context;
+ v8::Handle<v8::Function> fun = fun_templ->GetFunction();
+ GenerateSomeGarbage();
+ context->Global()->Set(v8_str("o"), fun->NewInstance());
+ v8::TryCatch try_catch;
+ CompileRun(
+ "o.foo = 17;"
+ "var receiver = {};"
+ "receiver.__proto__ = o;"
+ "var result = 0;"
+ "var saved_result = 0;"
+ "for (var i = 0; i < 100; i++) {"
+ " result = receiver.method(41);"
+ " if (i == 50) {"
+ " saved_result = result;"
+ " receiver = Object.create(receiver);"
+ " }"
+ "}");
+ CHECK(try_catch.HasCaught());
+ CHECK_EQ(v8_str("TypeError: Illegal invocation"),
+ try_catch.Exception()->ToString());
+ CHECK_EQ(42, context->Global()->Get(v8_str("saved_result"))->Int32Value());
+}
+
v8::Handle<Value> keyed_call_ic_function;
@@ -10824,18 +11254,21 @@ TEST(DontLeakGlobalObjects) {
{ v8::HandleScope scope;
LocalContext context;
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
LocalContext context;
v8_compile("Date")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
LocalContext context;
v8_compile("/aaa/")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
{ v8::HandleScope scope;
@@ -10844,6 +11277,7 @@ TEST(DontLeakGlobalObjects) {
LocalContext context(&extensions);
v8_compile("gc();")->Run();
}
+ v8::V8::ContextDisposedNotification();
CheckSurvivingGlobalObjectsCount(0);
}
}
@@ -11044,6 +11478,7 @@ static void RunLoopInNewEnv() {
TEST(SetFunctionEntryHook) {
i::FLAG_allow_natives_syntax = true;
+ i::FLAG_use_inlining = false;
// Test setting and resetting the entry hook.
// Nulling it should always succeed.
@@ -11176,10 +11611,6 @@ static void event_handler(const v8::JitCodeEvent* event) {
}
-// Implemented in the test-alloc.cc test suite.
-void SimulateFullSpace(i::PagedSpace* space);
-
-
static bool MatchPointers(void* key1, void* key2) {
return key1 == key2;
}
@@ -12301,7 +12732,7 @@ static void MorphAString(i::String* string,
AsciiVectorResource* ascii_resource,
UC16VectorResource* uc16_resource) {
CHECK(i::StringShape(string).IsExternal());
- if (string->IsAsciiRepresentation()) {
+ if (string->IsOneByteRepresentation()) {
// Check old map is not symbol or long.
CHECK(string->map() == HEAP->external_ascii_string_map());
// Morph external string to be TwoByte string.
@@ -14436,6 +14867,89 @@ TEST(SourceURLInStackTrace) {
}
+v8::Handle<Value> AnalyzeStackOfInlineScriptWithSourceURL(
+ const v8::Arguments& args) {
+ v8::HandleScope scope;
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ CHECK_EQ(4, stackTrace->GetFrameCount());
+ v8::Handle<v8::String> url = v8_str("url");
+ for (int i = 0; i < 3; i++) {
+ v8::Handle<v8::String> name =
+ stackTrace->GetFrame(i)->GetScriptNameOrSourceURL();
+ CHECK(!name.IsEmpty());
+ CHECK_EQ(url, name);
+ }
+ return v8::Undefined();
+}
+
+
+TEST(InlineScriptWithSourceURLInStackTrace) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("AnalyzeStackOfInlineScriptWithSourceURL"),
+ v8::FunctionTemplate::New(
+ AnalyzeStackOfInlineScriptWithSourceURL));
+ LocalContext context(0, templ);
+
+ const char *source =
+ "function outer() {\n"
+ "function bar() {\n"
+ " AnalyzeStackOfInlineScriptWithSourceURL();\n"
+ "}\n"
+ "function foo() {\n"
+ "\n"
+ " bar();\n"
+ "}\n"
+ "foo();\n"
+ "}\n"
+ "outer()\n"
+ "//@ sourceURL=source_url";
+ CHECK(CompileRunWithOrigin(source, "url", 0, 1)->IsUndefined());
+}
+
+
+v8::Handle<Value> AnalyzeStackOfDynamicScriptWithSourceURL(
+ const v8::Arguments& args) {
+ v8::HandleScope scope;
+ v8::Handle<v8::StackTrace> stackTrace =
+ v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed);
+ CHECK_EQ(4, stackTrace->GetFrameCount());
+ v8::Handle<v8::String> url = v8_str("source_url");
+ for (int i = 0; i < 3; i++) {
+ v8::Handle<v8::String> name =
+ stackTrace->GetFrame(i)->GetScriptNameOrSourceURL();
+ CHECK(!name.IsEmpty());
+ CHECK_EQ(url, name);
+ }
+ return v8::Undefined();
+}
+
+
+TEST(DynamicWithSourceURLInStackTrace) {
+ v8::HandleScope scope;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("AnalyzeStackOfDynamicScriptWithSourceURL"),
+ v8::FunctionTemplate::New(
+ AnalyzeStackOfDynamicScriptWithSourceURL));
+ LocalContext context(0, templ);
+
+ const char *source =
+ "function outer() {\n"
+ "function bar() {\n"
+ " AnalyzeStackOfDynamicScriptWithSourceURL();\n"
+ "}\n"
+ "function foo() {\n"
+ "\n"
+ " bar();\n"
+ "}\n"
+ "foo();\n"
+ "}\n"
+ "outer()\n"
+ "//@ sourceURL=source_url";
+ CHECK(CompileRunWithOrigin(source, "url", 0, 0)->IsUndefined());
+}
+
static void CreateGarbageInOldSpace() {
v8::HandleScope scope;
i::AlwaysAllocateScope always_allocate;
@@ -14623,11 +15137,12 @@ THREADED_TEST(GetHeapStatistics) {
class VisitorImpl : public v8::ExternalResourceVisitor {
public:
- VisitorImpl(TestResource* r1, TestResource* r2)
- : resource1_(r1),
- resource2_(r2),
- found_resource1_(false),
- found_resource2_(false) {}
+ explicit VisitorImpl(TestResource** resource) {
+ for (int i = 0; i < 4; i++) {
+ resource_[i] = resource[i];
+ found_resource_[i] = false;
+ }
+ }
virtual ~VisitorImpl() {}
virtual void VisitExternalString(v8::Handle<v8::String> string) {
if (!string->IsExternal()) {
@@ -14637,25 +15152,22 @@ class VisitorImpl : public v8::ExternalResourceVisitor {
v8::String::ExternalStringResource* resource =
string->GetExternalStringResource();
CHECK(resource);
- if (resource1_ == resource) {
- CHECK(!found_resource1_);
- found_resource1_ = true;
- }
- if (resource2_ == resource) {
- CHECK(!found_resource2_);
- found_resource2_ = true;
+ for (int i = 0; i < 4; i++) {
+ if (resource_[i] == resource) {
+ CHECK(!found_resource_[i]);
+ found_resource_[i] = true;
+ }
}
}
void CheckVisitedResources() {
- CHECK(found_resource1_);
- CHECK(found_resource2_);
+ for (int i = 0; i < 4; i++) {
+ CHECK(found_resource_[i]);
+ }
}
private:
- v8::String::ExternalStringResource* resource1_;
- v8::String::ExternalStringResource* resource2_;
- bool found_resource1_;
- bool found_resource2_;
+ v8::String::ExternalStringResource* resource_[4];
+ bool found_resource_[4];
};
TEST(VisitExternalStrings) {
@@ -14663,16 +15175,33 @@ TEST(VisitExternalStrings) {
LocalContext env;
const char* string = "Some string";
uint16_t* two_byte_string = AsciiToTwoByteString(string);
- TestResource* resource1 = new TestResource(two_byte_string);
- v8::Local<v8::String> string1 = v8::String::NewExternal(resource1);
- TestResource* resource2 = new TestResource(two_byte_string);
- v8::Local<v8::String> string2 = v8::String::NewExternal(resource2);
-
- // We need to add usages for string1 and string2 to avoid warnings in GCC 4.7
+ TestResource* resource[4];
+ resource[0] = new TestResource(two_byte_string);
+ v8::Local<v8::String> string0 = v8::String::NewExternal(resource[0]);
+ resource[1] = new TestResource(two_byte_string);
+ v8::Local<v8::String> string1 = v8::String::NewExternal(resource[1]);
+
+ // Externalized symbol.
+ resource[2] = new TestResource(two_byte_string);
+ v8::Local<v8::String> string2 = v8::String::NewSymbol(string);
+ CHECK(string2->MakeExternal(resource[2]));
+
+ // Symbolized External.
+ resource[3] = new TestResource(AsciiToTwoByteString("Some other string"));
+ v8::Local<v8::String> string3 = v8::String::NewExternal(resource[3]);
+ HEAP->CollectAllAvailableGarbage(); // Tenure string.
+ // Turn into a symbol.
+ i::Handle<i::String> string3_i = v8::Utils::OpenHandle(*string3);
+ CHECK(!HEAP->LookupSymbol(*string3_i)->IsFailure());
+ CHECK(string3_i->IsSymbol());
+
+ // We need to add usages for string* to avoid warnings in GCC 4.7
+ CHECK(string0->IsExternal());
CHECK(string1->IsExternal());
CHECK(string2->IsExternal());
+ CHECK(string3->IsExternal());
- VisitorImpl visitor(resource1, resource2);
+ VisitorImpl visitor(resource);
v8::V8::VisitExternalResources(&visitor);
visitor.CheckVisitedResources();
}
@@ -14907,6 +15436,7 @@ TEST(Regress528) {
context->Exit();
}
context.Dispose();
+ v8::V8::ContextDisposedNotification();
for (gc_count = 1; gc_count < 10; gc_count++) {
other_context->Enter();
CompileRun(source_exception);
@@ -15361,13 +15891,13 @@ THREADED_TEST(TwoByteStringInAsciiCons) {
CHECK(result->IsString());
i::Handle<i::String> string = v8::Utils::OpenHandle(String::Cast(*result));
int length = string->length();
- CHECK(string->IsAsciiRepresentation());
+ CHECK(string->IsOneByteRepresentation());
FlattenString(string);
i::Handle<i::String> flat_string = FlattenGetString(string);
- CHECK(string->IsAsciiRepresentation());
- CHECK(flat_string->IsAsciiRepresentation());
+ CHECK(string->IsOneByteRepresentation());
+ CHECK(flat_string->IsOneByteRepresentation());
// Create external resource.
uint16_t* uc16_buffer = new uint16_t[length + 1];
@@ -15386,7 +15916,7 @@ THREADED_TEST(TwoByteStringInAsciiCons) {
// ASCII characters). This is a valid sequence of steps, and it can happen
// in real pages.
- CHECK(string->IsAsciiRepresentation());
+ CHECK(string->IsOneByteRepresentation());
i::ConsString* cons = i::ConsString::cast(*string);
CHECK_EQ(0, cons->second()->length());
CHECK(cons->first()->IsTwoByteRepresentation());
@@ -16073,6 +16603,45 @@ TEST(DontDeleteCellLoadICAPI) {
}
+class Visitor42 : public v8::PersistentHandleVisitor {
+ public:
+ explicit Visitor42(v8::Persistent<v8::Object> object)
+ : counter_(0), object_(object) { }
+
+ virtual void VisitPersistentHandle(Persistent<Value> value,
+ uint16_t class_id) {
+ if (class_id == 42) {
+ CHECK(value->IsObject());
+ v8::Persistent<v8::Object> visited =
+ v8::Persistent<v8::Object>::Cast(value);
+ CHECK_EQ(42, visited.WrapperClassId());
+ CHECK_EQ(object_, visited);
+ ++counter_;
+ }
+ }
+
+ int counter_;
+ v8::Persistent<v8::Object> object_;
+};
+
+
+TEST(PersistentHandleVisitor) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Persistent<v8::Object> object =
+ v8::Persistent<v8::Object>::New(v8::Object::New());
+ CHECK_EQ(0, object.WrapperClassId());
+ object.SetWrapperClassId(42);
+ CHECK_EQ(42, object.WrapperClassId());
+
+ Visitor42 visitor(object);
+ v8::V8::VisitHandlesWithClassIds(&visitor);
+ CHECK_EQ(1, visitor.counter_);
+
+ object.Dispose();
+}
+
+
TEST(RegExp) {
v8::HandleScope scope;
LocalContext context;
@@ -16508,6 +17077,24 @@ THREADED_TEST(AllowCodeGenFromStrings) {
}
+TEST(SetErrorMessageForCodeGenFromStrings) {
+ v8::HandleScope scope;
+ LocalContext context;
+ TryCatch try_catch;
+
+ Handle<String> message = v8_str("Message") ;
+ Handle<String> expected_message = v8_str("Uncaught EvalError: Message");
+ V8::SetAllowCodeGenerationFromStringsCallback(&CodeGenerationDisallowed);
+ context->AllowCodeGenerationFromStrings(false);
+ context->SetErrorMessageForCodeGenerationFromStrings(message);
+ Handle<Value> result = CompileRun("eval('42')");
+ CHECK(result.IsEmpty());
+ CHECK(try_catch.HasCaught());
+ Handle<String> actual_message = try_catch.Message()->Get();
+ CHECK(expected_message->Equals(actual_message));
+}
+
+
static v8::Handle<Value> NonObjectThis(const v8::Arguments& args) {
return v8::Undefined();
}
@@ -17445,6 +18032,16 @@ THREADED_TEST(Regress149912) {
}
+THREADED_TEST(Regress157124) {
+ v8::HandleScope scope;
+ LocalContext context;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ Local<Object> obj = templ->NewInstance();
+ obj->GetIdentityHash();
+ obj->DeleteHiddenValue(v8_str("Bug"));
+}
+
+
#ifndef WIN32
class ThreadInterruptTest {
public:
@@ -17496,7 +18093,6 @@ class ThreadInterruptTest {
private:
ThreadInterruptTest* test_;
- struct sigaction sa_;
};
i::Semaphore* sem_;