Update V8 to r6768 as required by WebKit r78450
Change-Id: Ib8868ff7147a76547a8d1d85f257ebe8546a3d3f
diff --git a/test/cctest/test-api.cc b/test/cctest/test-api.cc
index 6a2f328..b92185f 100644
--- a/test/cctest/test-api.cc
+++ b/test/cctest/test-api.cc
@@ -874,6 +874,10 @@
TestExternalPointerWrapping();
#if defined(V8_HOST_ARCH_X64)
+ // Check a value with a leading 1 bit in x64 Smi encoding.
+ expected_ptr = reinterpret_cast<void*>(0x400000000);
+ TestExternalPointerWrapping();
+
expected_ptr = reinterpret_cast<void*>(0xdeadbeefdeadbeef);
TestExternalPointerWrapping();
@@ -1645,6 +1649,23 @@
CHECK_NE(hash, hash3);
int hash4 = obj->GetIdentityHash();
CHECK_EQ(hash, hash4);
+
+ // Check identity hashes behaviour in the presence of JS accessors.
+ // Put a getter for 'v8::IdentityHash' on the Object's prototype:
+ {
+ CompileRun("Object.prototype['v8::IdentityHash'] = 42;\n");
+ Local<v8::Object> o1 = v8::Object::New();
+ Local<v8::Object> o2 = v8::Object::New();
+ CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash());
+ }
+ {
+ CompileRun(
+ "function cnst() { return 42; };\n"
+ "Object.prototype.__defineGetter__('v8::IdentityHash', cnst);\n");
+ Local<v8::Object> o1 = v8::Object::New();
+ Local<v8::Object> o2 = v8::Object::New();
+ CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash());
+ }
}
@@ -2365,18 +2386,50 @@
}
-// Test that overwritten toString methods are not invoked on uncaught
-// exception formatting. However, they are invoked when performing
-// normal error string conversions.
+static v8::Handle<Value> Fail(const v8::Arguments& args) {
+ ApiTestFuzzer::Fuzz();
+ CHECK(false);
+ return v8::Undefined();
+}
+
+
+// Test that overwritten methods are not invoked on uncaught exception
+// formatting. However, they are invoked when performing normal error
+// string conversions.
TEST(APIThrowMessageOverwrittenToString) {
v8::HandleScope scope;
v8::V8::AddMessageListener(check_reference_error_message);
- LocalContext context;
+ Local<ObjectTemplate> templ = ObjectTemplate::New();
+ templ->Set(v8_str("fail"), v8::FunctionTemplate::New(Fail));
+ LocalContext context(NULL, templ);
+ CompileRun("asdf;");
+ 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("asdf;");
+ CompileRun("ReferenceError.prototype.constructor.name = void 0;");
+ CompileRun("asdf;");
+ CompileRun("ReferenceError.prototype.constructor = void 0;");
+ CompileRun("asdf;");
+ CompileRun("ReferenceError.prototype.__proto__ = new Object();");
+ CompileRun("asdf;");
+ CompileRun("ReferenceError.prototype = new Object();");
+ 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("asdf;");
v8::V8::RemoveMessageListeners(check_message);
}
@@ -5273,11 +5326,13 @@
}
+static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false };
static bool NamedAccessBlocker(Local<v8::Object> global,
Local<Value> name,
v8::AccessType type,
Local<Value> data) {
- return Context::GetCurrent()->Global()->Equals(global);
+ return Context::GetCurrent()->Global()->Equals(global) ||
+ allowed_access_type[type];
}
@@ -5285,7 +5340,8 @@
uint32_t key,
v8::AccessType type,
Local<Value> data) {
- return Context::GetCurrent()->Global()->Equals(global);
+ return Context::GetCurrent()->Global()->Equals(global) ||
+ allowed_access_type[type];
}
@@ -5317,7 +5373,7 @@
}
-THREADED_TEST(AccessControl) {
+TEST(AccessControl) {
v8::HandleScope handle_scope;
v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New();
@@ -5343,6 +5399,27 @@
v8::Handle<v8::Object> global0 = context0->Global();
+ // Define a property with JS getter and setter.
+ CompileRun(
+ "function getter() { return 'getter'; };\n"
+ "function setter() { return 'setter'; }\n"
+ "Object.defineProperty(this, 'js_accessor_p', {get:getter, set:setter})");
+
+ Local<Value> getter = global0->Get(v8_str("getter"));
+ Local<Value> setter = global0->Get(v8_str("setter"));
+
+ // And define normal element.
+ global0->Set(239, v8_str("239"));
+
+ // Define an element with JS getter and setter.
+ CompileRun(
+ "function el_getter() { return 'el_getter'; };\n"
+ "function el_setter() { return 'el_setter'; };\n"
+ "Object.defineProperty(this, '42', {get: el_getter, set: el_setter});");
+
+ Local<Value> el_getter = global0->Get(v8_str("el_getter"));
+ Local<Value> el_setter = global0->Get(v8_str("el_setter"));
+
v8::HandleScope scope1;
v8::Persistent<Context> context1 = Context::New();
@@ -5351,40 +5428,187 @@
v8::Handle<v8::Object> global1 = context1->Global();
global1->Set(v8_str("other"), global0);
+ // Access blocked property.
+ CompileRun("other.blocked_prop = 1");
+
+ ExpectUndefined("other.blocked_prop");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'blocked_prop')");
+ ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')");
+
+ // Enable ACCESS_HAS
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ ExpectUndefined("other.blocked_prop");
+ // ... and now we can get the descriptor...
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'blocked_prop').value");
+ // ... and enumerate the property.
+ ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')");
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Access blocked element.
+ CompileRun("other[239] = 1");
+
+ ExpectUndefined("other[239]");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')");
+ ExpectFalse("propertyIsEnumerable.call(other, '239')");
+
+ // Enable ACCESS_HAS
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ ExpectUndefined("other[239]");
+ // ... and now we can get the descriptor...
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value");
+ // ... and enumerate the property.
+ ExpectTrue("propertyIsEnumerable.call(other, '239')");
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Access a property with JS accessor.
+ CompileRun("other.js_accessor_p = 2");
+
+ ExpectUndefined("other.js_accessor_p");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')");
+
+ // Enable ACCESS_HAS.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ ExpectUndefined("other.js_accessor_p");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS and ACCESS_GET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_GET] = true;
+
+ ExpectString("other.js_accessor_p", "getter");
+ ExpectObject(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
+
+ allowed_access_type[v8::ACCESS_GET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS and ACCESS_SET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_SET] = true;
+
+ ExpectUndefined("other.js_accessor_p");
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get");
+ ExpectObject(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
+
+ allowed_access_type[v8::ACCESS_SET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_GET] = true;
+ allowed_access_type[v8::ACCESS_SET] = true;
+
+ ExpectString("other.js_accessor_p", "getter");
+ ExpectObject(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter);
+ ExpectObject(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter);
+ ExpectUndefined(
+ "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value");
+
+ allowed_access_type[v8::ACCESS_SET] = false;
+ allowed_access_type[v8::ACCESS_GET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Access an element with JS accessor.
+ CompileRun("other[42] = 2");
+
+ ExpectUndefined("other[42]");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')");
+
+ // Enable ACCESS_HAS.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ ExpectUndefined("other[42]");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS and ACCESS_GET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_GET] = true;
+
+ ExpectString("other[42]", "el_getter");
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
+
+ allowed_access_type[v8::ACCESS_GET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS and ACCESS_SET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_SET] = true;
+
+ ExpectUndefined("other[42]");
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get");
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
+
+ allowed_access_type[v8::ACCESS_SET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
+ // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET.
+ allowed_access_type[v8::ACCESS_HAS] = true;
+ allowed_access_type[v8::ACCESS_GET] = true;
+ allowed_access_type[v8::ACCESS_SET] = true;
+
+ ExpectString("other[42]", "el_getter");
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter);
+ ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter);
+ ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value");
+
+ allowed_access_type[v8::ACCESS_SET] = false;
+ allowed_access_type[v8::ACCESS_GET] = false;
+ allowed_access_type[v8::ACCESS_HAS] = false;
+
v8::Handle<Value> value;
- // Access blocked property
- value = v8_compile("other.blocked_prop = 1")->Run();
- value = v8_compile("other.blocked_prop")->Run();
- CHECK(value->IsUndefined());
-
- value = v8_compile("propertyIsEnumerable.call(other, 'blocked_prop')")->Run();
- CHECK(value->IsFalse());
-
// Access accessible property
- value = v8_compile("other.accessible_prop = 3")->Run();
+ value = CompileRun("other.accessible_prop = 3");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
CHECK_EQ(3, g_echo_value);
- value = v8_compile("other.accessible_prop")->Run();
+ value = CompileRun("other.accessible_prop");
CHECK(value->IsNumber());
CHECK_EQ(3, value->Int32Value());
- value =
- v8_compile("propertyIsEnumerable.call(other, 'accessible_prop')")->Run();
+ value = CompileRun(
+ "Object.getOwnPropertyDescriptor(other, 'accessible_prop').value");
+ CHECK(value->IsNumber());
+ CHECK_EQ(3, value->Int32Value());
+
+ value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')");
CHECK(value->IsTrue());
// Enumeration doesn't enumerate accessors from inaccessible objects in
// the prototype chain even if the accessors are in themselves accessible.
- Local<Value> result =
+ value =
CompileRun("(function(){var obj = {'__proto__':other};"
"for (var p in obj)"
" if (p == 'accessible_prop' || p == 'blocked_prop') {"
" return false;"
" }"
"return true;})()");
- CHECK(result->IsTrue());
+ CHECK(value->IsTrue());
context1->Exit();
context0->Exit();
@@ -6229,7 +6453,7 @@
" var str = String(e);"
" if (str.indexOf('TypeError') == -1) return 1;"
" if (str.indexOf('[object Fun]') != -1) return 2;"
- " if (str.indexOf('#<a Fun>') == -1) return 3;"
+ " if (str.indexOf('#<Fun>') == -1) return 3;"
" return 0;"
" }"
" return 4;"
@@ -7318,6 +7542,61 @@
"garbage = undefined;");
}
+v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) {
+ static int count = 0;
+ if (count++ % 3 == 0) {
+ v8::V8::LowMemoryNotification(); // This should move the stub
+ GenerateSomeGarbage(); // This should ensure the old stub memory is flushed
+ }
+ return v8::Handle<v8::Value>();
+}
+
+
+THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New();
+ nativeobject_templ->Set("callback",
+ v8::FunctionTemplate::New(DirectApiCallback));
+ v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance();
+ context->Global()->Set(v8_str("nativeobject"), nativeobject_obj);
+ // call the api function multiple times to ensure direct call stub creation.
+ CompileRun(
+ "function f() {"
+ " for (var i = 1; i <= 30; i++) {"
+ " nativeobject.callback();"
+ " }"
+ "}"
+ "f();");
+}
+
+
+v8::Handle<v8::Value> ThrowingDirectApiCallback(const v8::Arguments& args) {
+ return v8::ThrowException(v8_str("g"));
+}
+
+
+THREADED_TEST(CallICFastApi_DirectCall_Throw) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New();
+ nativeobject_templ->Set("callback",
+ v8::FunctionTemplate::New(ThrowingDirectApiCallback));
+ v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance();
+ context->Global()->Set(v8_str("nativeobject"), nativeobject_obj);
+ // call the api function multiple times to ensure direct call stub creation.
+ v8::Handle<Value> result = CompileRun(
+ "var result = '';"
+ "function f() {"
+ " for (var i = 1; i <= 5; i++) {"
+ " try { nativeobject.callback(); } catch (e) { result += e; }"
+ " }"
+ "}"
+ "f(); result;");
+ CHECK_EQ(v8_str("ggggg"), result);
+}
+
+
THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) {
int interceptor_call_count = 0;
v8::HandleScope scope;
@@ -10325,6 +10604,108 @@
"i");
CHECK_EQ(255, result->Int32Value());
+ // Make sure that pixel array ICs recognize when a non-pixel array
+ // is passed to it.
+ result = CompileRun("function pa_load(p) {"
+ " var sum = 0;"
+ " for (var j = 0; j < 256; j++) { sum += p[j]; }"
+ " return sum;"
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "for (var i = 0; i < 10; ++i) { pa_load(pixels); }"
+ "just_ints = new Object();"
+ "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }"
+ "for (var i = 0; i < 10; ++i) {"
+ " result = pa_load(just_ints);"
+ "}"
+ "result");
+ CHECK_EQ(32640, result->Int32Value());
+
+ // Make sure that pixel array ICs recognize out-of-bound accesses.
+ result = CompileRun("function pa_load(p, start) {"
+ " var sum = 0;"
+ " for (var j = start; j < 256; j++) { sum += p[j]; }"
+ " return sum;"
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "for (var i = 0; i < 10; ++i) { pa_load(pixels,0); }"
+ "for (var i = 0; i < 10; ++i) {"
+ " result = pa_load(pixels,-10);"
+ "}"
+ "result");
+ CHECK_EQ(0, result->Int32Value());
+
+ // Make sure that generic ICs properly handles a pixel array.
+ result = CompileRun("function pa_load(p) {"
+ " var sum = 0;"
+ " for (var j = 0; j < 256; j++) { sum += p[j]; }"
+ " return sum;"
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "just_ints = new Object();"
+ "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }"
+ "for (var i = 0; i < 10; ++i) { pa_load(just_ints); }"
+ "for (var i = 0; i < 10; ++i) {"
+ " result = pa_load(pixels);"
+ "}"
+ "result");
+ CHECK_EQ(32640, result->Int32Value());
+
+ // Make sure that generic load ICs recognize out-of-bound accesses in
+ // pixel arrays.
+ result = CompileRun("function pa_load(p, start) {"
+ " var sum = 0;"
+ " for (var j = start; j < 256; j++) { sum += p[j]; }"
+ " return sum;"
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "just_ints = new Object();"
+ "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }"
+ "for (var i = 0; i < 10; ++i) { pa_load(just_ints,0); }"
+ "for (var i = 0; i < 10; ++i) { pa_load(pixels,0); }"
+ "for (var i = 0; i < 10; ++i) {"
+ " result = pa_load(pixels,-10);"
+ "}"
+ "result");
+ CHECK_EQ(0, result->Int32Value());
+
+ // Make sure that generic ICs properly handles other types than pixel
+ // arrays (that the inlined fast pixel array test leaves the right information
+ // in the right registers).
+ result = CompileRun("function pa_load(p) {"
+ " var sum = 0;"
+ " for (var j = 0; j < 256; j++) { sum += p[j]; }"
+ " return sum;"
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "just_ints = new Object();"
+ "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }"
+ "for (var i = 0; i < 10; ++i) { pa_load(just_ints); }"
+ "for (var i = 0; i < 10; ++i) { pa_load(pixels); }"
+ "sparse_array = new Object();"
+ "for (var i = 0; i < 256; ++i) { sparse_array[i] = i; }"
+ "sparse_array[1000000] = 3;"
+ "for (var i = 0; i < 10; ++i) {"
+ " result = pa_load(sparse_array);"
+ "}"
+ "result");
+ CHECK_EQ(32640, result->Int32Value());
+
+ // Make sure that pixel array loads are optimized by crankshaft.
+ result = CompileRun("function pa_load(p) {"
+ " var sum = 0;"
+ " for (var i=0; i<256; ++i) {"
+ " sum += p[i];"
+ " }"
+ " return sum; "
+ "}"
+ "for (var i = 0; i < 256; ++i) { pixels[i] = i; }"
+ "for (var i = 0; i < 10000; ++i) {"
+ " result = pa_load(pixels);"
+ "}"
+ "result");
+ CHECK_EQ(32640, result->Int32Value());
+
free(pixel_data);
}
@@ -10583,6 +10964,33 @@
CHECK_EQ(0, result->Int32Value());
CHECK_EQ(0,
i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value());
+
+ // Check truncation behavior of integral arrays.
+ const char* unsigned_data =
+ "var source_data = [0.6, 10.6];"
+ "var expected_results = [0, 10];";
+ const char* signed_data =
+ "var source_data = [0.6, 10.6, -0.6, -10.6];"
+ "var expected_results = [0, 10, 0, -10];";
+ bool is_unsigned =
+ (array_type == v8::kExternalUnsignedByteArray ||
+ array_type == v8::kExternalUnsignedShortArray ||
+ array_type == v8::kExternalUnsignedIntArray);
+
+ i::OS::SNPrintF(test_buf,
+ "%s"
+ "var all_passed = true;"
+ "for (var i = 0; i < source_data.length; i++) {"
+ " for (var j = 0; j < 8; j++) {"
+ " ext_array[j] = source_data[i];"
+ " }"
+ " all_passed = all_passed &&"
+ " (ext_array[5] == expected_results[i]);"
+ "}"
+ "all_passed;",
+ (is_unsigned ? unsigned_data : signed_data));
+ result = CompileRun(test_buf.start());
+ CHECK_EQ(true, result->BooleanValue());
}
result = CompileRun("ext_array[3] = 33;"
@@ -10977,6 +11385,26 @@
}
+TEST(CaptureStackTraceForUncaughtExceptionAndSetters) {
+ v8::HandleScope scope;
+ LocalContext env;
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(true,
+ 1024,
+ v8::StackTrace::kDetailed);
+
+ CompileRun(
+ "var setters = ['column', 'lineNumber', 'scriptName',\n"
+ " 'scriptNameOrSourceURL', 'functionName', 'isEval',\n"
+ " 'isConstructor'];\n"
+ "for (var i = 0; i < setters.length; i++) {\n"
+ " var prop = setters[i];\n"
+ " Object.prototype.__defineSetter__(prop, function() { throw prop; });\n"
+ "}\n");
+ CompileRun("throw 'exception';");
+ v8::V8::SetCaptureStackTraceForUncaughtExceptions(false);
+}
+
+
v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) {
v8::HandleScope scope;
v8::Handle<v8::StackTrace> stackTrace =
@@ -12147,6 +12575,25 @@
}
+THREADED_TEST(Equals) {
+ v8::HandleScope handleScope;
+ LocalContext localContext;
+
+ v8::Handle<v8::Object> globalProxy = localContext->Global();
+ v8::Handle<Value> global = globalProxy->GetPrototype();
+
+ CHECK(global->StrictEquals(global));
+ CHECK(!global->StrictEquals(globalProxy));
+ CHECK(!globalProxy->StrictEquals(global));
+ CHECK(globalProxy->StrictEquals(globalProxy));
+
+ CHECK(global->Equals(global));
+ CHECK(!global->Equals(globalProxy));
+ CHECK(!globalProxy->Equals(global));
+ CHECK(globalProxy->Equals(globalProxy));
+}
+
+
static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property,
const v8::AccessorInfo& info ) {
return v8_str("42!");
@@ -12173,3 +12620,19 @@
CHECK_EQ(1, result->Length());
CHECK_EQ(v8_str("universalAnswer"), result->Get(0));
}
+
+
+TEST(DefinePropertyPostDetach) {
+ v8::HandleScope scope;
+ LocalContext context;
+ v8::Handle<v8::Object> proxy = context->Global();
+ v8::Handle<v8::Function> define_property =
+ CompileRun("(function() {"
+ " Object.defineProperty("
+ " this,"
+ " 1,"
+ " { configurable: true, enumerable: true, value: 3 });"
+ "})").As<Function>();
+ context->DetachGlobal();
+ define_property->Call(proxy, 0, NULL);
+}