| OLD | NEW |
| 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2007-2009 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 807 | 807 |
| 808 Local<Value> result = v8_compile("(new obj()).toString()")->Run(); | 808 Local<Value> result = v8_compile("(new obj()).toString()")->Run(); |
| 809 CHECK_EQ(v8_str("[object funky]"), result); | 809 CHECK_EQ(v8_str("[object funky]"), result); |
| 810 | 810 |
| 811 result = v8_compile("(new obj()).m")->Run(); | 811 result = v8_compile("(new obj()).m")->Run(); |
| 812 CHECK_EQ(239, result->Int32Value()); | 812 CHECK_EQ(239, result->Int32Value()); |
| 813 } | 813 } |
| 814 } | 814 } |
| 815 | 815 |
| 816 | 816 |
| 817 static void* expected_ptr; |
| 818 static v8::Handle<v8::Value> callback(const v8::Arguments& args) { |
| 819 void* ptr = v8::External::Unwrap(args.Data()); |
| 820 CHECK_EQ(expected_ptr, ptr); |
| 821 return v8::Boolean::New(true); |
| 822 } |
| 823 |
| 824 |
| 825 static void TestExternalPointerWrapping() { |
| 826 v8::HandleScope scope; |
| 827 LocalContext env; |
| 828 |
| 829 v8::Handle<v8::Value> data = v8::External::Wrap(expected_ptr); |
| 830 |
| 831 v8::Handle<v8::Object> obj = v8::Object::New(); |
| 832 obj->Set(v8_str("func"), |
| 833 v8::FunctionTemplate::New(callback, data)->GetFunction()); |
| 834 env->Global()->Set(v8_str("obj"), obj); |
| 835 |
| 836 CHECK(CompileRun( |
| 837 "function foo() {\n" |
| 838 " for (var i = 0; i < 13; i++) obj.func();\n" |
| 839 "}\n" |
| 840 "foo(), true")->BooleanValue()); |
| 841 } |
| 842 |
| 843 |
| 844 THREADED_TEST(ExternalWrap) { |
| 845 // Check heap allocated object. |
| 846 int* ptr = new int; |
| 847 expected_ptr = ptr; |
| 848 TestExternalPointerWrapping(); |
| 849 delete ptr; |
| 850 |
| 851 // Check stack allocated object. |
| 852 int foo; |
| 853 expected_ptr = &foo; |
| 854 TestExternalPointerWrapping(); |
| 855 |
| 856 // Check not aligned addresses. |
| 857 const int n = 100; |
| 858 char* s = new char[n]; |
| 859 for (int i = 0; i < n; i++) { |
| 860 expected_ptr = s + i; |
| 861 TestExternalPointerWrapping(); |
| 862 } |
| 863 |
| 864 delete[] s; |
| 865 |
| 866 // Check several invalid addresses. |
| 867 expected_ptr = reinterpret_cast<void*>(1); |
| 868 TestExternalPointerWrapping(); |
| 869 |
| 870 expected_ptr = reinterpret_cast<void*>(0xdeadbeef); |
| 871 TestExternalPointerWrapping(); |
| 872 |
| 873 expected_ptr = reinterpret_cast<void*>(0xdeadbeef + 1); |
| 874 TestExternalPointerWrapping(); |
| 875 |
| 876 #if defined(V8_HOST_ARCH_X64) |
| 877 // Check a value with a leading 1 bit in x64 Smi encoding. |
| 878 expected_ptr = reinterpret_cast<void*>(0x400000000); |
| 879 TestExternalPointerWrapping(); |
| 880 |
| 881 expected_ptr = reinterpret_cast<void*>(0xdeadbeefdeadbeef); |
| 882 TestExternalPointerWrapping(); |
| 883 |
| 884 expected_ptr = reinterpret_cast<void*>(0xdeadbeefdeadbeef + 1); |
| 885 TestExternalPointerWrapping(); |
| 886 #endif |
| 887 } |
| 888 |
| 889 |
| 817 THREADED_TEST(FindInstanceInPrototypeChain) { | 890 THREADED_TEST(FindInstanceInPrototypeChain) { |
| 818 v8::HandleScope scope; | 891 v8::HandleScope scope; |
| 819 LocalContext env; | 892 LocalContext env; |
| 820 | 893 |
| 821 Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New(); | 894 Local<v8::FunctionTemplate> base = v8::FunctionTemplate::New(); |
| 822 Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New(); | 895 Local<v8::FunctionTemplate> derived = v8::FunctionTemplate::New(); |
| 823 Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(); | 896 Local<v8::FunctionTemplate> other = v8::FunctionTemplate::New(); |
| 824 derived->Inherit(base); | 897 derived->Inherit(base); |
| 825 | 898 |
| 826 Local<v8::Function> base_function = base->GetFunction(); | 899 Local<v8::Function> base_function = base->GetFunction(); |
| (...skipping 742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1569 // the random number generator should be evaluated. | 1642 // the random number generator should be evaluated. |
| 1570 CHECK_NE(hash, hash2); | 1643 CHECK_NE(hash, hash2); |
| 1571 i::Heap::CollectAllGarbage(false); | 1644 i::Heap::CollectAllGarbage(false); |
| 1572 int hash3 = v8::Object::New()->GetIdentityHash(); | 1645 int hash3 = v8::Object::New()->GetIdentityHash(); |
| 1573 // Make sure that the identity hash is not based on the initial address of | 1646 // Make sure that the identity hash is not based on the initial address of |
| 1574 // the object alone. If the test below fails the random number generator | 1647 // the object alone. If the test below fails the random number generator |
| 1575 // should be evaluated. | 1648 // should be evaluated. |
| 1576 CHECK_NE(hash, hash3); | 1649 CHECK_NE(hash, hash3); |
| 1577 int hash4 = obj->GetIdentityHash(); | 1650 int hash4 = obj->GetIdentityHash(); |
| 1578 CHECK_EQ(hash, hash4); | 1651 CHECK_EQ(hash, hash4); |
| 1652 |
| 1653 // Check identity hashes behaviour in the presence of JS accessors. |
| 1654 // Put a getter for 'v8::IdentityHash' on the Object's prototype: |
| 1655 { |
| 1656 CompileRun("Object.prototype['v8::IdentityHash'] = 42;\n"); |
| 1657 Local<v8::Object> o1 = v8::Object::New(); |
| 1658 Local<v8::Object> o2 = v8::Object::New(); |
| 1659 CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash()); |
| 1660 } |
| 1661 { |
| 1662 CompileRun( |
| 1663 "function cnst() { return 42; };\n" |
| 1664 "Object.prototype.__defineGetter__('v8::IdentityHash', cnst);\n"); |
| 1665 Local<v8::Object> o1 = v8::Object::New(); |
| 1666 Local<v8::Object> o2 = v8::Object::New(); |
| 1667 CHECK_NE(o1->GetIdentityHash(), o2->GetIdentityHash()); |
| 1668 } |
| 1579 } | 1669 } |
| 1580 | 1670 |
| 1581 | 1671 |
| 1582 THREADED_TEST(HiddenProperties) { | 1672 THREADED_TEST(HiddenProperties) { |
| 1583 v8::HandleScope scope; | 1673 v8::HandleScope scope; |
| 1584 LocalContext env; | 1674 LocalContext env; |
| 1585 | 1675 |
| 1586 v8::Local<v8::Object> obj = v8::Object::New(); | 1676 v8::Local<v8::Object> obj = v8::Object::New(); |
| 1587 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); | 1677 v8::Local<v8::String> key = v8_str("api-test::hidden-key"); |
| 1588 v8::Local<v8::String> empty = v8_str(""); | 1678 v8::Local<v8::String> empty = v8_str(""); |
| (...skipping 692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2281 " try {" | 2371 " try {" |
| 2282 " CCatcher('throw 7;');" | 2372 " CCatcher('throw 7;');" |
| 2283 " } finally {" | 2373 " } finally {" |
| 2284 " }" | 2374 " }" |
| 2285 "} catch (e) {" | 2375 "} catch (e) {" |
| 2286 "}"); | 2376 "}"); |
| 2287 CHECK(result->IsTrue()); | 2377 CHECK(result->IsTrue()); |
| 2288 } | 2378 } |
| 2289 | 2379 |
| 2290 | 2380 |
| 2381 static void check_reference_error_message( |
| 2382 v8::Handle<v8::Message> message, |
| 2383 v8::Handle<v8::Value> data) { |
| 2384 const char* reference_error = "Uncaught ReferenceError: asdf is not defined"; |
| 2385 CHECK(message->Get()->Equals(v8_str(reference_error))); |
| 2386 } |
| 2387 |
| 2388 |
| 2389 static v8::Handle<Value> Fail(const v8::Arguments& args) { |
| 2390 ApiTestFuzzer::Fuzz(); |
| 2391 CHECK(false); |
| 2392 return v8::Undefined(); |
| 2393 } |
| 2394 |
| 2395 |
| 2396 // Test that overwritten methods are not invoked on uncaught exception |
| 2397 // formatting. However, they are invoked when performing normal error |
| 2398 // string conversions. |
| 2399 TEST(APIThrowMessageOverwrittenToString) { |
| 2400 v8::HandleScope scope; |
| 2401 v8::V8::AddMessageListener(check_reference_error_message); |
| 2402 Local<ObjectTemplate> templ = ObjectTemplate::New(); |
| 2403 templ->Set(v8_str("fail"), v8::FunctionTemplate::New(Fail)); |
| 2404 LocalContext context(NULL, templ); |
| 2405 CompileRun("asdf;"); |
| 2406 CompileRun("var limit = {};" |
| 2407 "limit.valueOf = fail;" |
| 2408 "Error.stackTraceLimit = limit;"); |
| 2409 CompileRun("asdf"); |
| 2410 CompileRun("Array.prototype.pop = fail;"); |
| 2411 CompileRun("Object.prototype.hasOwnProperty = fail;"); |
| 2412 CompileRun("Object.prototype.toString = function f() { return 'Yikes'; }"); |
| 2413 CompileRun("Number.prototype.toString = function f() { return 'Yikes'; }"); |
| 2414 CompileRun("String.prototype.toString = function f() { return 'Yikes'; }"); |
| 2415 CompileRun("ReferenceError.prototype.toString =" |
| 2416 " function() { return 'Whoops' }"); |
| 2417 CompileRun("asdf;"); |
| 2418 CompileRun("ReferenceError.prototype.constructor.name = void 0;"); |
| 2419 CompileRun("asdf;"); |
| 2420 CompileRun("ReferenceError.prototype.constructor = void 0;"); |
| 2421 CompileRun("asdf;"); |
| 2422 CompileRun("ReferenceError.prototype.__proto__ = new Object();"); |
| 2423 CompileRun("asdf;"); |
| 2424 CompileRun("ReferenceError.prototype = new Object();"); |
| 2425 CompileRun("asdf;"); |
| 2426 v8::Handle<Value> string = CompileRun("try { asdf; } catch(e) { e + ''; }"); |
| 2427 CHECK(string->Equals(v8_str("Whoops"))); |
| 2428 CompileRun("ReferenceError.prototype.constructor = new Object();" |
| 2429 "ReferenceError.prototype.constructor.name = 1;" |
| 2430 "Number.prototype.toString = function() { return 'Whoops'; };" |
| 2431 "ReferenceError.prototype.toString = Object.prototype.toString;"); |
| 2432 CompileRun("asdf;"); |
| 2433 v8::V8::RemoveMessageListeners(check_message); |
| 2434 } |
| 2435 |
| 2436 |
| 2291 static void receive_message(v8::Handle<v8::Message> message, | 2437 static void receive_message(v8::Handle<v8::Message> message, |
| 2292 v8::Handle<v8::Value> data) { | 2438 v8::Handle<v8::Value> data) { |
| 2293 message->Get(); | 2439 message->Get(); |
| 2294 message_received = true; | 2440 message_received = true; |
| 2295 } | 2441 } |
| 2296 | 2442 |
| 2297 | 2443 |
| 2298 TEST(APIThrowMessage) { | 2444 TEST(APIThrowMessage) { |
| 2299 message_received = false; | 2445 message_received = false; |
| 2300 v8::HandleScope scope; | 2446 v8::HandleScope scope; |
| (...skipping 2872 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5173 // the global object for env2 which has the same security token as env1. | 5319 // the global object for env2 which has the same security token as env1. |
| 5174 result = CompileRun("other.p"); | 5320 result = CompileRun("other.p"); |
| 5175 CHECK(result->IsInt32()); | 5321 CHECK(result->IsInt32()); |
| 5176 CHECK_EQ(42, result->Int32Value()); | 5322 CHECK_EQ(42, result->Int32Value()); |
| 5177 | 5323 |
| 5178 env2.Dispose(); | 5324 env2.Dispose(); |
| 5179 env3.Dispose(); | 5325 env3.Dispose(); |
| 5180 } | 5326 } |
| 5181 | 5327 |
| 5182 | 5328 |
| 5329 static bool allowed_access_type[v8::ACCESS_KEYS + 1] = { false }; |
| 5183 static bool NamedAccessBlocker(Local<v8::Object> global, | 5330 static bool NamedAccessBlocker(Local<v8::Object> global, |
| 5184 Local<Value> name, | 5331 Local<Value> name, |
| 5185 v8::AccessType type, | 5332 v8::AccessType type, |
| 5186 Local<Value> data) { | 5333 Local<Value> data) { |
| 5187 return Context::GetCurrent()->Global()->Equals(global); | 5334 return Context::GetCurrent()->Global()->Equals(global) || |
| 5335 allowed_access_type[type]; |
| 5188 } | 5336 } |
| 5189 | 5337 |
| 5190 | 5338 |
| 5191 static bool IndexedAccessBlocker(Local<v8::Object> global, | 5339 static bool IndexedAccessBlocker(Local<v8::Object> global, |
| 5192 uint32_t key, | 5340 uint32_t key, |
| 5193 v8::AccessType type, | 5341 v8::AccessType type, |
| 5194 Local<Value> data) { | 5342 Local<Value> data) { |
| 5195 return Context::GetCurrent()->Global()->Equals(global); | 5343 return Context::GetCurrent()->Global()->Equals(global) || |
| 5344 allowed_access_type[type]; |
| 5196 } | 5345 } |
| 5197 | 5346 |
| 5198 | 5347 |
| 5199 static int g_echo_value = -1; | 5348 static int g_echo_value = -1; |
| 5200 static v8::Handle<Value> EchoGetter(Local<String> name, | 5349 static v8::Handle<Value> EchoGetter(Local<String> name, |
| 5201 const AccessorInfo& info) { | 5350 const AccessorInfo& info) { |
| 5202 return v8_num(g_echo_value); | 5351 return v8_num(g_echo_value); |
| 5203 } | 5352 } |
| 5204 | 5353 |
| 5205 | 5354 |
| (...skipping 11 matching lines...) Expand all Loading... |
| 5217 return v8::Undefined(); | 5366 return v8::Undefined(); |
| 5218 } | 5367 } |
| 5219 | 5368 |
| 5220 | 5369 |
| 5221 static void UnreachableSetter(Local<String>, Local<Value>, | 5370 static void UnreachableSetter(Local<String>, Local<Value>, |
| 5222 const AccessorInfo&) { | 5371 const AccessorInfo&) { |
| 5223 CHECK(false); // This function should nto be called. | 5372 CHECK(false); // This function should nto be called. |
| 5224 } | 5373 } |
| 5225 | 5374 |
| 5226 | 5375 |
| 5227 THREADED_TEST(AccessControl) { | 5376 TEST(AccessControl) { |
| 5228 v8::HandleScope handle_scope; | 5377 v8::HandleScope handle_scope; |
| 5229 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); | 5378 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 5230 | 5379 |
| 5231 global_template->SetAccessCheckCallbacks(NamedAccessBlocker, | 5380 global_template->SetAccessCheckCallbacks(NamedAccessBlocker, |
| 5232 IndexedAccessBlocker); | 5381 IndexedAccessBlocker); |
| 5233 | 5382 |
| 5234 // Add an accessor accessible by cross-domain JS code. | 5383 // Add an accessor accessible by cross-domain JS code. |
| 5235 global_template->SetAccessor( | 5384 global_template->SetAccessor( |
| 5236 v8_str("accessible_prop"), | 5385 v8_str("accessible_prop"), |
| 5237 EchoGetter, EchoSetter, | 5386 EchoGetter, EchoSetter, |
| 5238 v8::Handle<Value>(), | 5387 v8::Handle<Value>(), |
| 5239 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); | 5388 v8::AccessControl(v8::ALL_CAN_READ | v8::ALL_CAN_WRITE)); |
| 5240 | 5389 |
| 5241 // Add an accessor that is not accessible by cross-domain JS code. | 5390 // Add an accessor that is not accessible by cross-domain JS code. |
| 5242 global_template->SetAccessor(v8_str("blocked_prop"), | 5391 global_template->SetAccessor(v8_str("blocked_prop"), |
| 5243 UnreachableGetter, UnreachableSetter, | 5392 UnreachableGetter, UnreachableSetter, |
| 5244 v8::Handle<Value>(), | 5393 v8::Handle<Value>(), |
| 5245 v8::DEFAULT); | 5394 v8::DEFAULT); |
| 5246 | 5395 |
| 5247 // Create an environment | 5396 // Create an environment |
| 5248 v8::Persistent<Context> context0 = Context::New(NULL, global_template); | 5397 v8::Persistent<Context> context0 = Context::New(NULL, global_template); |
| 5249 context0->Enter(); | 5398 context0->Enter(); |
| 5250 | 5399 |
| 5251 v8::Handle<v8::Object> global0 = context0->Global(); | 5400 v8::Handle<v8::Object> global0 = context0->Global(); |
| 5252 | 5401 |
| 5402 // Define a property with JS getter and setter. |
| 5403 CompileRun( |
| 5404 "function getter() { return 'getter'; };\n" |
| 5405 "function setter() { return 'setter'; }\n" |
| 5406 "Object.defineProperty(this, 'js_accessor_p', {get:getter, set:setter})"); |
| 5407 |
| 5408 Local<Value> getter = global0->Get(v8_str("getter")); |
| 5409 Local<Value> setter = global0->Get(v8_str("setter")); |
| 5410 |
| 5411 // And define normal element. |
| 5412 global0->Set(239, v8_str("239")); |
| 5413 |
| 5414 // Define an element with JS getter and setter. |
| 5415 CompileRun( |
| 5416 "function el_getter() { return 'el_getter'; };\n" |
| 5417 "function el_setter() { return 'el_setter'; };\n" |
| 5418 "Object.defineProperty(this, '42', {get: el_getter, set: el_setter});"); |
| 5419 |
| 5420 Local<Value> el_getter = global0->Get(v8_str("el_getter")); |
| 5421 Local<Value> el_setter = global0->Get(v8_str("el_setter")); |
| 5422 |
| 5253 v8::HandleScope scope1; | 5423 v8::HandleScope scope1; |
| 5254 | 5424 |
| 5255 v8::Persistent<Context> context1 = Context::New(); | 5425 v8::Persistent<Context> context1 = Context::New(); |
| 5256 context1->Enter(); | 5426 context1->Enter(); |
| 5257 | 5427 |
| 5258 v8::Handle<v8::Object> global1 = context1->Global(); | 5428 v8::Handle<v8::Object> global1 = context1->Global(); |
| 5259 global1->Set(v8_str("other"), global0); | 5429 global1->Set(v8_str("other"), global0); |
| 5260 | 5430 |
| 5431 // Access blocked property. |
| 5432 CompileRun("other.blocked_prop = 1"); |
| 5433 |
| 5434 ExpectUndefined("other.blocked_prop"); |
| 5435 ExpectUndefined( |
| 5436 "Object.getOwnPropertyDescriptor(other, 'blocked_prop')"); |
| 5437 ExpectFalse("propertyIsEnumerable.call(other, 'blocked_prop')"); |
| 5438 |
| 5439 // Enable ACCESS_HAS |
| 5440 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5441 ExpectUndefined("other.blocked_prop"); |
| 5442 // ... and now we can get the descriptor... |
| 5443 ExpectUndefined( |
| 5444 "Object.getOwnPropertyDescriptor(other, 'blocked_prop').value"); |
| 5445 // ... and enumerate the property. |
| 5446 ExpectTrue("propertyIsEnumerable.call(other, 'blocked_prop')"); |
| 5447 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5448 |
| 5449 // Access blocked element. |
| 5450 CompileRun("other[239] = 1"); |
| 5451 |
| 5452 ExpectUndefined("other[239]"); |
| 5453 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239')"); |
| 5454 ExpectFalse("propertyIsEnumerable.call(other, '239')"); |
| 5455 |
| 5456 // Enable ACCESS_HAS |
| 5457 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5458 ExpectUndefined("other[239]"); |
| 5459 // ... and now we can get the descriptor... |
| 5460 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '239').value"); |
| 5461 // ... and enumerate the property. |
| 5462 ExpectTrue("propertyIsEnumerable.call(other, '239')"); |
| 5463 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5464 |
| 5465 // Access a property with JS accessor. |
| 5466 CompileRun("other.js_accessor_p = 2"); |
| 5467 |
| 5468 ExpectUndefined("other.js_accessor_p"); |
| 5469 ExpectUndefined( |
| 5470 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p')"); |
| 5471 |
| 5472 // Enable ACCESS_HAS. |
| 5473 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5474 ExpectUndefined("other.js_accessor_p"); |
| 5475 ExpectUndefined( |
| 5476 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get"); |
| 5477 ExpectUndefined( |
| 5478 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set"); |
| 5479 ExpectUndefined( |
| 5480 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
| 5481 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5482 |
| 5483 // Enable both ACCESS_HAS and ACCESS_GET. |
| 5484 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5485 allowed_access_type[v8::ACCESS_GET] = true; |
| 5486 |
| 5487 ExpectString("other.js_accessor_p", "getter"); |
| 5488 ExpectObject( |
| 5489 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); |
| 5490 ExpectUndefined( |
| 5491 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set"); |
| 5492 ExpectUndefined( |
| 5493 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
| 5494 |
| 5495 allowed_access_type[v8::ACCESS_GET] = false; |
| 5496 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5497 |
| 5498 // Enable both ACCESS_HAS and ACCESS_SET. |
| 5499 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5500 allowed_access_type[v8::ACCESS_SET] = true; |
| 5501 |
| 5502 ExpectUndefined("other.js_accessor_p"); |
| 5503 ExpectUndefined( |
| 5504 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get"); |
| 5505 ExpectObject( |
| 5506 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); |
| 5507 ExpectUndefined( |
| 5508 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
| 5509 |
| 5510 allowed_access_type[v8::ACCESS_SET] = false; |
| 5511 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5512 |
| 5513 // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET. |
| 5514 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5515 allowed_access_type[v8::ACCESS_GET] = true; |
| 5516 allowed_access_type[v8::ACCESS_SET] = true; |
| 5517 |
| 5518 ExpectString("other.js_accessor_p", "getter"); |
| 5519 ExpectObject( |
| 5520 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').get", getter); |
| 5521 ExpectObject( |
| 5522 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').set", setter); |
| 5523 ExpectUndefined( |
| 5524 "Object.getOwnPropertyDescriptor(other, 'js_accessor_p').value"); |
| 5525 |
| 5526 allowed_access_type[v8::ACCESS_SET] = false; |
| 5527 allowed_access_type[v8::ACCESS_GET] = false; |
| 5528 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5529 |
| 5530 // Access an element with JS accessor. |
| 5531 CompileRun("other[42] = 2"); |
| 5532 |
| 5533 ExpectUndefined("other[42]"); |
| 5534 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42')"); |
| 5535 |
| 5536 // Enable ACCESS_HAS. |
| 5537 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5538 ExpectUndefined("other[42]"); |
| 5539 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get"); |
| 5540 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set"); |
| 5541 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
| 5542 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5543 |
| 5544 // Enable both ACCESS_HAS and ACCESS_GET. |
| 5545 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5546 allowed_access_type[v8::ACCESS_GET] = true; |
| 5547 |
| 5548 ExpectString("other[42]", "el_getter"); |
| 5549 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); |
| 5550 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').set"); |
| 5551 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
| 5552 |
| 5553 allowed_access_type[v8::ACCESS_GET] = false; |
| 5554 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5555 |
| 5556 // Enable both ACCESS_HAS and ACCESS_SET. |
| 5557 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5558 allowed_access_type[v8::ACCESS_SET] = true; |
| 5559 |
| 5560 ExpectUndefined("other[42]"); |
| 5561 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').get"); |
| 5562 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); |
| 5563 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
| 5564 |
| 5565 allowed_access_type[v8::ACCESS_SET] = false; |
| 5566 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5567 |
| 5568 // Enable both ACCESS_HAS, ACCESS_GET and ACCESS_SET. |
| 5569 allowed_access_type[v8::ACCESS_HAS] = true; |
| 5570 allowed_access_type[v8::ACCESS_GET] = true; |
| 5571 allowed_access_type[v8::ACCESS_SET] = true; |
| 5572 |
| 5573 ExpectString("other[42]", "el_getter"); |
| 5574 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').get", el_getter); |
| 5575 ExpectObject("Object.getOwnPropertyDescriptor(other, '42').set", el_setter); |
| 5576 ExpectUndefined("Object.getOwnPropertyDescriptor(other, '42').value"); |
| 5577 |
| 5578 allowed_access_type[v8::ACCESS_SET] = false; |
| 5579 allowed_access_type[v8::ACCESS_GET] = false; |
| 5580 allowed_access_type[v8::ACCESS_HAS] = false; |
| 5581 |
| 5261 v8::Handle<Value> value; | 5582 v8::Handle<Value> value; |
| 5262 | 5583 |
| 5263 // Access blocked property | |
| 5264 value = v8_compile("other.blocked_prop = 1")->Run(); | |
| 5265 value = v8_compile("other.blocked_prop")->Run(); | |
| 5266 CHECK(value->IsUndefined()); | |
| 5267 | |
| 5268 value = v8_compile("propertyIsEnumerable.call(other, 'blocked_prop')")->Run(); | |
| 5269 CHECK(value->IsFalse()); | |
| 5270 | |
| 5271 // Access accessible property | 5584 // Access accessible property |
| 5272 value = v8_compile("other.accessible_prop = 3")->Run(); | 5585 value = CompileRun("other.accessible_prop = 3"); |
| 5273 CHECK(value->IsNumber()); | 5586 CHECK(value->IsNumber()); |
| 5274 CHECK_EQ(3, value->Int32Value()); | 5587 CHECK_EQ(3, value->Int32Value()); |
| 5275 CHECK_EQ(3, g_echo_value); | 5588 CHECK_EQ(3, g_echo_value); |
| 5276 | 5589 |
| 5277 value = v8_compile("other.accessible_prop")->Run(); | 5590 value = CompileRun("other.accessible_prop"); |
| 5278 CHECK(value->IsNumber()); | 5591 CHECK(value->IsNumber()); |
| 5279 CHECK_EQ(3, value->Int32Value()); | 5592 CHECK_EQ(3, value->Int32Value()); |
| 5280 | 5593 |
| 5281 value = | 5594 value = CompileRun( |
| 5282 v8_compile("propertyIsEnumerable.call(other, 'accessible_prop')")->Run(); | 5595 "Object.getOwnPropertyDescriptor(other, 'accessible_prop').value"); |
| 5596 CHECK(value->IsNumber()); |
| 5597 CHECK_EQ(3, value->Int32Value()); |
| 5598 |
| 5599 value = CompileRun("propertyIsEnumerable.call(other, 'accessible_prop')"); |
| 5283 CHECK(value->IsTrue()); | 5600 CHECK(value->IsTrue()); |
| 5284 | 5601 |
| 5285 // Enumeration doesn't enumerate accessors from inaccessible objects in | 5602 // Enumeration doesn't enumerate accessors from inaccessible objects in |
| 5286 // the prototype chain even if the accessors are in themselves accessible. | 5603 // the prototype chain even if the accessors are in themselves accessible. |
| 5287 Local<Value> result = | 5604 value = |
| 5288 CompileRun("(function(){var obj = {'__proto__':other};" | 5605 CompileRun("(function(){var obj = {'__proto__':other};" |
| 5289 "for (var p in obj)" | 5606 "for (var p in obj)" |
| 5290 " if (p == 'accessible_prop' || p == 'blocked_prop') {" | 5607 " if (p == 'accessible_prop' || p == 'blocked_prop') {" |
| 5291 " return false;" | 5608 " return false;" |
| 5292 " }" | 5609 " }" |
| 5293 "return true;})()"); | 5610 "return true;})()"); |
| 5294 CHECK(result->IsTrue()); | 5611 CHECK(value->IsTrue()); |
| 5295 | 5612 |
| 5296 context1->Exit(); | 5613 context1->Exit(); |
| 5297 context0->Exit(); | 5614 context0->Exit(); |
| 5298 context1.Dispose(); | 5615 context1.Dispose(); |
| 5299 context0.Dispose(); | 5616 context0.Dispose(); |
| 5300 } | 5617 } |
| 5301 | 5618 |
| 5302 | 5619 |
| 5620 // This is a regression test for issue 1154. |
| 5621 TEST(AccessControlObjectKeys) { |
| 5622 v8::HandleScope handle_scope; |
| 5623 v8::Handle<v8::ObjectTemplate> global_template = v8::ObjectTemplate::New(); |
| 5624 |
| 5625 global_template->SetAccessCheckCallbacks(NamedAccessBlocker, |
| 5626 IndexedAccessBlocker); |
| 5627 |
| 5628 // Add an accessor that is not accessible by cross-domain JS code. |
| 5629 global_template->SetAccessor(v8_str("blocked_prop"), |
| 5630 UnreachableGetter, UnreachableSetter, |
| 5631 v8::Handle<Value>(), |
| 5632 v8::DEFAULT); |
| 5633 |
| 5634 // Create an environment |
| 5635 v8::Persistent<Context> context0 = Context::New(NULL, global_template); |
| 5636 context0->Enter(); |
| 5637 |
| 5638 v8::Handle<v8::Object> global0 = context0->Global(); |
| 5639 |
| 5640 v8::Persistent<Context> context1 = Context::New(); |
| 5641 context1->Enter(); |
| 5642 v8::Handle<v8::Object> global1 = context1->Global(); |
| 5643 global1->Set(v8_str("other"), global0); |
| 5644 |
| 5645 ExpectTrue("Object.keys(other).indexOf('blocked_prop') == -1"); |
| 5646 } |
| 5647 |
| 5648 |
| 5303 static bool GetOwnPropertyNamesNamedBlocker(Local<v8::Object> global, | 5649 static bool GetOwnPropertyNamesNamedBlocker(Local<v8::Object> global, |
| 5304 Local<Value> name, | 5650 Local<Value> name, |
| 5305 v8::AccessType type, | 5651 v8::AccessType type, |
| 5306 Local<Value> data) { | 5652 Local<Value> data) { |
| 5307 return false; | 5653 return false; |
| 5308 } | 5654 } |
| 5309 | 5655 |
| 5310 | 5656 |
| 5311 static bool GetOwnPropertyNamesIndexedBlocker(Local<v8::Object> global, | 5657 static bool GetOwnPropertyNamesIndexedBlocker(Local<v8::Object> global, |
| 5312 uint32_t key, | 5658 uint32_t key, |
| (...skipping 816 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6129 Local<Function> cons = templ->GetFunction(); | 6475 Local<Function> cons = templ->GetFunction(); |
| 6130 context->Global()->Set(v8_str("Fun"), cons); | 6476 context->Global()->Set(v8_str("Fun"), cons); |
| 6131 Local<Value> value = CompileRun( | 6477 Local<Value> value = CompileRun( |
| 6132 "function test() {" | 6478 "function test() {" |
| 6133 " try {" | 6479 " try {" |
| 6134 " (new Fun()).blah()" | 6480 " (new Fun()).blah()" |
| 6135 " } catch (e) {" | 6481 " } catch (e) {" |
| 6136 " var str = String(e);" | 6482 " var str = String(e);" |
| 6137 " if (str.indexOf('TypeError') == -1) return 1;" | 6483 " if (str.indexOf('TypeError') == -1) return 1;" |
| 6138 " if (str.indexOf('[object Fun]') != -1) return 2;" | 6484 " if (str.indexOf('[object Fun]') != -1) return 2;" |
| 6139 " if (str.indexOf('#<a Fun>') == -1) return 3;" | 6485 " if (str.indexOf('#<Fun>') == -1) return 3;" |
| 6140 " return 0;" | 6486 " return 0;" |
| 6141 " }" | 6487 " }" |
| 6142 " return 4;" | 6488 " return 4;" |
| 6143 "}" | 6489 "}" |
| 6144 "test();"); | 6490 "test();"); |
| 6145 CHECK_EQ(0, value->Int32Value()); | 6491 CHECK_EQ(0, value->Int32Value()); |
| 6146 } | 6492 } |
| 6147 | 6493 |
| 6148 | 6494 |
| 6149 THREADED_TEST(EvalAliasedDynamic) { | 6495 THREADED_TEST(EvalAliasedDynamic) { |
| (...skipping 1068 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7218 // Helper to maximize the odds of object moving. | 7564 // Helper to maximize the odds of object moving. |
| 7219 static void GenerateSomeGarbage() { | 7565 static void GenerateSomeGarbage() { |
| 7220 CompileRun( | 7566 CompileRun( |
| 7221 "var garbage;" | 7567 "var garbage;" |
| 7222 "for (var i = 0; i < 1000; i++) {" | 7568 "for (var i = 0; i < 1000; i++) {" |
| 7223 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" | 7569 " garbage = [1/i, \"garbage\" + i, garbage, {foo: garbage}];" |
| 7224 "}" | 7570 "}" |
| 7225 "garbage = undefined;"); | 7571 "garbage = undefined;"); |
| 7226 } | 7572 } |
| 7227 | 7573 |
| 7574 v8::Handle<v8::Value> DirectApiCallback(const v8::Arguments& args) { |
| 7575 static int count = 0; |
| 7576 if (count++ % 3 == 0) { |
| 7577 v8::V8::LowMemoryNotification(); // This should move the stub |
| 7578 GenerateSomeGarbage(); // This should ensure the old stub memory is flushed |
| 7579 } |
| 7580 return v8::Handle<v8::Value>(); |
| 7581 } |
| 7582 |
| 7583 |
| 7584 THREADED_TEST(CallICFastApi_DirectCall_GCMoveStub) { |
| 7585 v8::HandleScope scope; |
| 7586 LocalContext context; |
| 7587 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); |
| 7588 nativeobject_templ->Set("callback", |
| 7589 v8::FunctionTemplate::New(DirectApiCallback)); |
| 7590 v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); |
| 7591 context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); |
| 7592 // call the api function multiple times to ensure direct call stub creation. |
| 7593 CompileRun( |
| 7594 "function f() {" |
| 7595 " for (var i = 1; i <= 30; i++) {" |
| 7596 " nativeobject.callback();" |
| 7597 " }" |
| 7598 "}" |
| 7599 "f();"); |
| 7600 } |
| 7601 |
| 7602 |
| 7603 v8::Handle<v8::Value> ThrowingDirectApiCallback(const v8::Arguments& args) { |
| 7604 return v8::ThrowException(v8_str("g")); |
| 7605 } |
| 7606 |
| 7607 |
| 7608 THREADED_TEST(CallICFastApi_DirectCall_Throw) { |
| 7609 v8::HandleScope scope; |
| 7610 LocalContext context; |
| 7611 v8::Handle<v8::ObjectTemplate> nativeobject_templ = v8::ObjectTemplate::New(); |
| 7612 nativeobject_templ->Set("callback", |
| 7613 v8::FunctionTemplate::New(ThrowingDirectApiCallback)); |
| 7614 v8::Local<v8::Object> nativeobject_obj = nativeobject_templ->NewInstance(); |
| 7615 context->Global()->Set(v8_str("nativeobject"), nativeobject_obj); |
| 7616 // call the api function multiple times to ensure direct call stub creation. |
| 7617 v8::Handle<Value> result = CompileRun( |
| 7618 "var result = '';" |
| 7619 "function f() {" |
| 7620 " for (var i = 1; i <= 5; i++) {" |
| 7621 " try { nativeobject.callback(); } catch (e) { result += e; }" |
| 7622 " }" |
| 7623 "}" |
| 7624 "f(); result;"); |
| 7625 CHECK_EQ(v8_str("ggggg"), result); |
| 7626 } |
| 7627 |
| 7628 |
| 7228 THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) { | 7629 THREADED_TEST(InterceptorCallICFastApi_TrivialSignature) { |
| 7229 int interceptor_call_count = 0; | 7630 int interceptor_call_count = 0; |
| 7230 v8::HandleScope scope; | 7631 v8::HandleScope scope; |
| 7231 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); | 7632 v8::Handle<v8::FunctionTemplate> fun_templ = v8::FunctionTemplate::New(); |
| 7232 v8::Handle<v8::FunctionTemplate> method_templ = | 7633 v8::Handle<v8::FunctionTemplate> method_templ = |
| 7233 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, | 7634 v8::FunctionTemplate::New(FastApiCallback_TrivialSignature, |
| 7234 v8_str("method_data"), | 7635 v8_str("method_data"), |
| 7235 v8::Handle<v8::Signature>()); | 7636 v8::Handle<v8::Signature>()); |
| 7236 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); | 7637 v8::Handle<v8::ObjectTemplate> proto_templ = fun_templ->PrototypeTemplate(); |
| 7237 proto_templ->Set(v8_str("method"), method_templ); | 7638 proto_templ->Set(v8_str("method"), method_templ); |
| (...skipping 2987 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10225 | 10626 |
| 10226 // Test for index greater than 255. Regression test for: | 10627 // Test for index greater than 255. Regression test for: |
| 10227 // http://code.google.com/p/chromium/issues/detail?id=26337. | 10628 // http://code.google.com/p/chromium/issues/detail?id=26337. |
| 10228 result = CompileRun("pixels[256] = 255;"); | 10629 result = CompileRun("pixels[256] = 255;"); |
| 10229 CHECK_EQ(255, result->Int32Value()); | 10630 CHECK_EQ(255, result->Int32Value()); |
| 10230 result = CompileRun("var i = 0;" | 10631 result = CompileRun("var i = 0;" |
| 10231 "for (var j = 0; j < 8; j++) { i = pixels[256]; }" | 10632 "for (var j = 0; j < 8; j++) { i = pixels[256]; }" |
| 10232 "i"); | 10633 "i"); |
| 10233 CHECK_EQ(255, result->Int32Value()); | 10634 CHECK_EQ(255, result->Int32Value()); |
| 10234 | 10635 |
| 10636 // Make sure that pixel array ICs recognize when a non-pixel array |
| 10637 // is passed to it. |
| 10638 result = CompileRun("function pa_load(p) {" |
| 10639 " var sum = 0;" |
| 10640 " for (var j = 0; j < 256; j++) { sum += p[j]; }" |
| 10641 " return sum;" |
| 10642 "}" |
| 10643 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10644 "for (var i = 0; i < 10; ++i) { pa_load(pixels); }" |
| 10645 "just_ints = new Object();" |
| 10646 "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }" |
| 10647 "for (var i = 0; i < 10; ++i) {" |
| 10648 " result = pa_load(just_ints);" |
| 10649 "}" |
| 10650 "result"); |
| 10651 CHECK_EQ(32640, result->Int32Value()); |
| 10652 |
| 10653 // Make sure that pixel array ICs recognize out-of-bound accesses. |
| 10654 result = CompileRun("function pa_load(p, start) {" |
| 10655 " var sum = 0;" |
| 10656 " for (var j = start; j < 256; j++) { sum += p[j]; }" |
| 10657 " return sum;" |
| 10658 "}" |
| 10659 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10660 "for (var i = 0; i < 10; ++i) { pa_load(pixels,0); }" |
| 10661 "for (var i = 0; i < 10; ++i) {" |
| 10662 " result = pa_load(pixels,-10);" |
| 10663 "}" |
| 10664 "result"); |
| 10665 CHECK_EQ(0, result->Int32Value()); |
| 10666 |
| 10667 // Make sure that generic ICs properly handles a pixel array. |
| 10668 result = CompileRun("function pa_load(p) {" |
| 10669 " var sum = 0;" |
| 10670 " for (var j = 0; j < 256; j++) { sum += p[j]; }" |
| 10671 " return sum;" |
| 10672 "}" |
| 10673 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10674 "just_ints = new Object();" |
| 10675 "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }" |
| 10676 "for (var i = 0; i < 10; ++i) { pa_load(just_ints); }" |
| 10677 "for (var i = 0; i < 10; ++i) {" |
| 10678 " result = pa_load(pixels);" |
| 10679 "}" |
| 10680 "result"); |
| 10681 CHECK_EQ(32640, result->Int32Value()); |
| 10682 |
| 10683 // Make sure that generic load ICs recognize out-of-bound accesses in |
| 10684 // pixel arrays. |
| 10685 result = CompileRun("function pa_load(p, start) {" |
| 10686 " var sum = 0;" |
| 10687 " for (var j = start; j < 256; j++) { sum += p[j]; }" |
| 10688 " return sum;" |
| 10689 "}" |
| 10690 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10691 "just_ints = new Object();" |
| 10692 "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }" |
| 10693 "for (var i = 0; i < 10; ++i) { pa_load(just_ints,0); }" |
| 10694 "for (var i = 0; i < 10; ++i) { pa_load(pixels,0); }" |
| 10695 "for (var i = 0; i < 10; ++i) {" |
| 10696 " result = pa_load(pixels,-10);" |
| 10697 "}" |
| 10698 "result"); |
| 10699 CHECK_EQ(0, result->Int32Value()); |
| 10700 |
| 10701 // Make sure that generic ICs properly handles other types than pixel |
| 10702 // arrays (that the inlined fast pixel array test leaves the right information |
| 10703 // in the right registers). |
| 10704 result = CompileRun("function pa_load(p) {" |
| 10705 " var sum = 0;" |
| 10706 " for (var j = 0; j < 256; j++) { sum += p[j]; }" |
| 10707 " return sum;" |
| 10708 "}" |
| 10709 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10710 "just_ints = new Object();" |
| 10711 "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }" |
| 10712 "for (var i = 0; i < 10; ++i) { pa_load(just_ints); }" |
| 10713 "for (var i = 0; i < 10; ++i) { pa_load(pixels); }" |
| 10714 "sparse_array = new Object();" |
| 10715 "for (var i = 0; i < 256; ++i) { sparse_array[i] = i; }" |
| 10716 "sparse_array[1000000] = 3;" |
| 10717 "for (var i = 0; i < 10; ++i) {" |
| 10718 " result = pa_load(sparse_array);" |
| 10719 "}" |
| 10720 "result"); |
| 10721 CHECK_EQ(32640, result->Int32Value()); |
| 10722 |
| 10723 // Make sure that pixel array store ICs clamp values correctly. |
| 10724 result = CompileRun("function pa_store(p) {" |
| 10725 " for (var j = 0; j < 256; j++) { p[j] = j * 2; }" |
| 10726 "}" |
| 10727 "pa_store(pixels);" |
| 10728 "var sum = 0;" |
| 10729 "for (var j = 0; j < 256; j++) { sum += pixels[j]; }" |
| 10730 "sum"); |
| 10731 CHECK_EQ(48896, result->Int32Value()); |
| 10732 |
| 10733 // Make sure that pixel array stores correctly handle accesses outside |
| 10734 // of the pixel array.. |
| 10735 result = CompileRun("function pa_store(p,start) {" |
| 10736 " for (var j = 0; j < 256; j++) {" |
| 10737 " p[j+start] = j * 2;" |
| 10738 " }" |
| 10739 "}" |
| 10740 "pa_store(pixels,0);" |
| 10741 "pa_store(pixels,-128);" |
| 10742 "var sum = 0;" |
| 10743 "for (var j = 0; j < 256; j++) { sum += pixels[j]; }" |
| 10744 "sum"); |
| 10745 CHECK_EQ(65280, result->Int32Value()); |
| 10746 |
| 10747 // Make sure that the generic store stub correctly handle accesses outside |
| 10748 // of the pixel array.. |
| 10749 result = CompileRun("function pa_store(p,start) {" |
| 10750 " for (var j = 0; j < 256; j++) {" |
| 10751 " p[j+start] = j * 2;" |
| 10752 " }" |
| 10753 "}" |
| 10754 "pa_store(pixels,0);" |
| 10755 "just_ints = new Object();" |
| 10756 "for (var i = 0; i < 256; ++i) { just_ints[i] = i; }" |
| 10757 "pa_store(just_ints, 0);" |
| 10758 "pa_store(pixels,-128);" |
| 10759 "var sum = 0;" |
| 10760 "for (var j = 0; j < 256; j++) { sum += pixels[j]; }" |
| 10761 "sum"); |
| 10762 CHECK_EQ(65280, result->Int32Value()); |
| 10763 |
| 10764 // Make sure that the generic keyed store stub clamps pixel array values |
| 10765 // correctly. |
| 10766 result = CompileRun("function pa_store(p) {" |
| 10767 " for (var j = 0; j < 256; j++) { p[j] = j * 2; }" |
| 10768 "}" |
| 10769 "pa_store(pixels);" |
| 10770 "just_ints = new Object();" |
| 10771 "pa_store(just_ints);" |
| 10772 "pa_store(pixels);" |
| 10773 "var sum = 0;" |
| 10774 "for (var j = 0; j < 256; j++) { sum += pixels[j]; }" |
| 10775 "sum"); |
| 10776 CHECK_EQ(48896, result->Int32Value()); |
| 10777 |
| 10778 // Make sure that pixel array loads are optimized by crankshaft. |
| 10779 result = CompileRun("function pa_load(p) {" |
| 10780 " var sum = 0;" |
| 10781 " for (var i=0; i<256; ++i) {" |
| 10782 " sum += p[i];" |
| 10783 " }" |
| 10784 " return sum; " |
| 10785 "}" |
| 10786 "for (var i = 0; i < 256; ++i) { pixels[i] = i; }" |
| 10787 "for (var i = 0; i < 10000; ++i) {" |
| 10788 " result = pa_load(pixels);" |
| 10789 "}" |
| 10790 "result"); |
| 10791 CHECK_EQ(32640, result->Int32Value()); |
| 10792 |
| 10235 free(pixel_data); | 10793 free(pixel_data); |
| 10236 } | 10794 } |
| 10237 | 10795 |
| 10238 | 10796 |
| 10239 THREADED_TEST(PixelArrayInfo) { | 10797 THREADED_TEST(PixelArrayInfo) { |
| 10240 v8::HandleScope scope; | 10798 v8::HandleScope scope; |
| 10241 LocalContext context; | 10799 LocalContext context; |
| 10242 for (int size = 0; size < 100; size += 10) { | 10800 for (int size = 0; size < 100; size += 10) { |
| 10243 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(size)); | 10801 uint8_t* pixel_data = reinterpret_cast<uint8_t*>(malloc(size)); |
| 10244 v8::Handle<v8::Object> obj = v8::Object::New(); | 10802 v8::Handle<v8::Object> obj = v8::Object::New(); |
| (...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10483 result = CompileRun("for (var i = 0; i < 8; i++) {" | 11041 result = CompileRun("for (var i = 0; i < 8; i++) {" |
| 10484 " ext_array[i] = 5;" | 11042 " ext_array[i] = 5;" |
| 10485 "}" | 11043 "}" |
| 10486 "for (var i = 0; i < 8; i++) {" | 11044 "for (var i = 0; i < 8; i++) {" |
| 10487 " ext_array[i] = -Infinity;" | 11045 " ext_array[i] = -Infinity;" |
| 10488 "}" | 11046 "}" |
| 10489 "ext_array[5];"); | 11047 "ext_array[5];"); |
| 10490 CHECK_EQ(0, result->Int32Value()); | 11048 CHECK_EQ(0, result->Int32Value()); |
| 10491 CHECK_EQ(0, | 11049 CHECK_EQ(0, |
| 10492 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value()); | 11050 i::Smi::cast(jsobj->GetElement(5)->ToObjectChecked())->value()); |
| 11051 |
| 11052 // Check truncation behavior of integral arrays. |
| 11053 const char* unsigned_data = |
| 11054 "var source_data = [0.6, 10.6];" |
| 11055 "var expected_results = [0, 10];"; |
| 11056 const char* signed_data = |
| 11057 "var source_data = [0.6, 10.6, -0.6, -10.6];" |
| 11058 "var expected_results = [0, 10, 0, -10];"; |
| 11059 bool is_unsigned = |
| 11060 (array_type == v8::kExternalUnsignedByteArray || |
| 11061 array_type == v8::kExternalUnsignedShortArray || |
| 11062 array_type == v8::kExternalUnsignedIntArray); |
| 11063 |
| 11064 i::OS::SNPrintF(test_buf, |
| 11065 "%s" |
| 11066 "var all_passed = true;" |
| 11067 "for (var i = 0; i < source_data.length; i++) {" |
| 11068 " for (var j = 0; j < 8; j++) {" |
| 11069 " ext_array[j] = source_data[i];" |
| 11070 " }" |
| 11071 " all_passed = all_passed &&" |
| 11072 " (ext_array[5] == expected_results[i]);" |
| 11073 "}" |
| 11074 "all_passed;", |
| 11075 (is_unsigned ? unsigned_data : signed_data)); |
| 11076 result = CompileRun(test_buf.start()); |
| 11077 CHECK_EQ(true, result->BooleanValue()); |
| 10493 } | 11078 } |
| 10494 | 11079 |
| 10495 result = CompileRun("ext_array[3] = 33;" | 11080 result = CompileRun("ext_array[3] = 33;" |
| 10496 "delete ext_array[3];" | 11081 "delete ext_array[3];" |
| 10497 "ext_array[3];"); | 11082 "ext_array[3];"); |
| 10498 CHECK_EQ(33, result->Int32Value()); | 11083 CHECK_EQ(33, result->Int32Value()); |
| 10499 | 11084 |
| 10500 result = CompileRun("ext_array[0] = 10; ext_array[1] = 11;" | 11085 result = CompileRun("ext_array[0] = 10; ext_array[1] = 11;" |
| 10501 "ext_array[2] = 12; ext_array[3] = 13;" | 11086 "ext_array[2] = 12; ext_array[3] = 13;" |
| 10502 "ext_array.__defineGetter__('2'," | 11087 "ext_array.__defineGetter__('2'," |
| (...skipping 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10877 v8_str("origin"))->Run(); | 11462 v8_str("origin"))->Run(); |
| 10878 v8::Local<v8::Object> global = env->Global(); | 11463 v8::Local<v8::Object> global = env->Global(); |
| 10879 Local<Value> trouble = global->Get(v8_str("bar")); | 11464 Local<Value> trouble = global->Get(v8_str("bar")); |
| 10880 CHECK(trouble->IsFunction()); | 11465 CHECK(trouble->IsFunction()); |
| 10881 Function::Cast(*trouble)->Call(global, 0, NULL); | 11466 Function::Cast(*trouble)->Call(global, 0, NULL); |
| 10882 v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); | 11467 v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); |
| 10883 v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener); | 11468 v8::V8::RemoveMessageListeners(StackTraceForUncaughtExceptionListener); |
| 10884 } | 11469 } |
| 10885 | 11470 |
| 10886 | 11471 |
| 11472 TEST(CaptureStackTraceForUncaughtExceptionAndSetters) { |
| 11473 v8::HandleScope scope; |
| 11474 LocalContext env; |
| 11475 v8::V8::SetCaptureStackTraceForUncaughtExceptions(true, |
| 11476 1024, |
| 11477 v8::StackTrace::kDetailed); |
| 11478 |
| 11479 CompileRun( |
| 11480 "var setters = ['column', 'lineNumber', 'scriptName',\n" |
| 11481 " 'scriptNameOrSourceURL', 'functionName', 'isEval',\n" |
| 11482 " 'isConstructor'];\n" |
| 11483 "for (var i = 0; i < setters.length; i++) {\n" |
| 11484 " var prop = setters[i];\n" |
| 11485 " Object.prototype.__defineSetter__(prop, function() { throw prop; });\n" |
| 11486 "}\n"); |
| 11487 CompileRun("throw 'exception';"); |
| 11488 v8::V8::SetCaptureStackTraceForUncaughtExceptions(false); |
| 11489 } |
| 11490 |
| 11491 |
| 10887 v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) { | 11492 v8::Handle<Value> AnalyzeStackOfEvalWithSourceURL(const v8::Arguments& args) { |
| 10888 v8::HandleScope scope; | 11493 v8::HandleScope scope; |
| 10889 v8::Handle<v8::StackTrace> stackTrace = | 11494 v8::Handle<v8::StackTrace> stackTrace = |
| 10890 v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); | 11495 v8::StackTrace::CurrentStackTrace(10, v8::StackTrace::kDetailed); |
| 10891 CHECK_EQ(5, stackTrace->GetFrameCount()); | 11496 CHECK_EQ(5, stackTrace->GetFrameCount()); |
| 10892 v8::Handle<v8::String> url = v8_str("eval_url"); | 11497 v8::Handle<v8::String> url = v8_str("eval_url"); |
| 10893 for (int i = 0; i < 3; i++) { | 11498 for (int i = 0; i < 3; i++) { |
| 10894 v8::Handle<v8::String> name = | 11499 v8::Handle<v8::String> name = |
| 10895 stackTrace->GetFrame(i)->GetScriptNameOrSourceURL(); | 11500 stackTrace->GetFrame(i)->GetScriptNameOrSourceURL(); |
| 10896 CHECK(!name.IsEmpty()); | 11501 CHECK(!name.IsEmpty()); |
| (...skipping 1150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12047 | 12652 |
| 12048 v8::TryCatch try_catch; | 12653 v8::TryCatch try_catch; |
| 12049 re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone); | 12654 re = v8::RegExp::New(v8_str("foo["), v8::RegExp::kNone); |
| 12050 CHECK(re.IsEmpty()); | 12655 CHECK(re.IsEmpty()); |
| 12051 CHECK(try_catch.HasCaught()); | 12656 CHECK(try_catch.HasCaught()); |
| 12052 context->Global()->Set(v8_str("ex"), try_catch.Exception()); | 12657 context->Global()->Set(v8_str("ex"), try_catch.Exception()); |
| 12053 ExpectTrue("ex instanceof SyntaxError"); | 12658 ExpectTrue("ex instanceof SyntaxError"); |
| 12054 } | 12659 } |
| 12055 | 12660 |
| 12056 | 12661 |
| 12662 THREADED_TEST(Equals) { |
| 12663 v8::HandleScope handleScope; |
| 12664 LocalContext localContext; |
| 12665 |
| 12666 v8::Handle<v8::Object> globalProxy = localContext->Global(); |
| 12667 v8::Handle<Value> global = globalProxy->GetPrototype(); |
| 12668 |
| 12669 CHECK(global->StrictEquals(global)); |
| 12670 CHECK(!global->StrictEquals(globalProxy)); |
| 12671 CHECK(!globalProxy->StrictEquals(global)); |
| 12672 CHECK(globalProxy->StrictEquals(globalProxy)); |
| 12673 |
| 12674 CHECK(global->Equals(global)); |
| 12675 CHECK(!global->Equals(globalProxy)); |
| 12676 CHECK(!globalProxy->Equals(global)); |
| 12677 CHECK(globalProxy->Equals(globalProxy)); |
| 12678 } |
| 12679 |
| 12680 |
| 12057 static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, | 12681 static v8::Handle<v8::Value> Getter(v8::Local<v8::String> property, |
| 12058 const v8::AccessorInfo& info ) { | 12682 const v8::AccessorInfo& info ) { |
| 12059 return v8_str("42!"); | 12683 return v8_str("42!"); |
| 12060 } | 12684 } |
| 12061 | 12685 |
| 12062 | 12686 |
| 12063 static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo& info) { | 12687 static v8::Handle<v8::Array> Enumerator(const v8::AccessorInfo& info) { |
| 12064 v8::Handle<v8::Array> result = v8::Array::New(); | 12688 v8::Handle<v8::Array> result = v8::Array::New(); |
| 12065 result->Set(0, v8_str("universalAnswer")); | 12689 result->Set(0, v8_str("universalAnswer")); |
| 12066 return result; | 12690 return result; |
| 12067 } | 12691 } |
| 12068 | 12692 |
| 12069 | 12693 |
| 12070 TEST(NamedEnumeratorAndForIn) { | 12694 TEST(NamedEnumeratorAndForIn) { |
| 12071 v8::HandleScope handle_scope; | 12695 v8::HandleScope handle_scope; |
| 12072 LocalContext context; | 12696 LocalContext context; |
| 12073 v8::Context::Scope context_scope(context.local()); | 12697 v8::Context::Scope context_scope(context.local()); |
| 12074 | 12698 |
| 12075 v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(); | 12699 v8::Handle<v8::ObjectTemplate> tmpl = v8::ObjectTemplate::New(); |
| 12076 tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator); | 12700 tmpl->SetNamedPropertyHandler(Getter, NULL, NULL, NULL, Enumerator); |
| 12077 context->Global()->Set(v8_str("o"), tmpl->NewInstance()); | 12701 context->Global()->Set(v8_str("o"), tmpl->NewInstance()); |
| 12078 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( | 12702 v8::Handle<v8::Array> result = v8::Handle<v8::Array>::Cast(CompileRun( |
| 12079 "var result = []; for (var k in o) result.push(k); result")); | 12703 "var result = []; for (var k in o) result.push(k); result")); |
| 12080 CHECK_EQ(1, result->Length()); | 12704 CHECK_EQ(1, result->Length()); |
| 12081 CHECK_EQ(v8_str("universalAnswer"), result->Get(0)); | 12705 CHECK_EQ(v8_str("universalAnswer"), result->Get(0)); |
| 12082 } | 12706 } |
| 12707 |
| 12708 |
| 12709 TEST(DefinePropertyPostDetach) { |
| 12710 v8::HandleScope scope; |
| 12711 LocalContext context; |
| 12712 v8::Handle<v8::Object> proxy = context->Global(); |
| 12713 v8::Handle<v8::Function> define_property = |
| 12714 CompileRun("(function() {" |
| 12715 " Object.defineProperty(" |
| 12716 " this," |
| 12717 " 1," |
| 12718 " { configurable: true, enumerable: true, value: 3 });" |
| 12719 "})").As<Function>(); |
| 12720 context->DetachGlobal(); |
| 12721 define_property->Call(proxy, 0, NULL); |
| 12722 } |
| OLD | NEW |