OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 16203 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16214 CHECK_EQ(1, force_set_set_count); | 16214 CHECK_EQ(1, force_set_set_count); |
16215 CHECK_EQ(5, force_set_get_count); | 16215 CHECK_EQ(5, force_set_get_count); |
16216 // The interceptor should also work for other properties | 16216 // The interceptor should also work for other properties |
16217 CHECK_EQ(3, global->Get(v8::String::NewFromUtf8(isolate, "b")) | 16217 CHECK_EQ(3, global->Get(v8::String::NewFromUtf8(isolate, "b")) |
16218 ->Int32Value()); | 16218 ->Int32Value()); |
16219 CHECK_EQ(1, force_set_set_count); | 16219 CHECK_EQ(1, force_set_set_count); |
16220 CHECK_EQ(6, force_set_get_count); | 16220 CHECK_EQ(6, force_set_get_count); |
16221 } | 16221 } |
16222 | 16222 |
16223 | 16223 |
16224 THREADED_TEST(ForceDelete) { | |
16225 v8::Isolate* isolate = CcTest::isolate(); | |
16226 v8::HandleScope scope(isolate); | |
16227 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); | |
16228 LocalContext context(NULL, templ); | |
16229 v8::Handle<v8::Object> global = context->Global(); | |
16230 | |
16231 // Ordinary properties | |
16232 v8::Handle<v8::String> simple_property = | |
16233 v8::String::NewFromUtf8(isolate, "p"); | |
16234 global->ForceSet(simple_property, v8::Int32::New(isolate, 4), v8::DontDelete); | |
16235 CHECK_EQ(4, global->Get(simple_property)->Int32Value()); | |
16236 // This should fail because the property is dont-delete. | |
16237 CHECK(!global->Delete(simple_property)); | |
16238 CHECK_EQ(4, global->Get(simple_property)->Int32Value()); | |
16239 // This should succeed even though the property is dont-delete. | |
16240 CHECK(global->ForceDelete(simple_property)); | |
16241 CHECK(global->Get(simple_property)->IsUndefined()); | |
16242 } | |
16243 | |
16244 | |
16245 static int force_delete_interceptor_count = 0; | |
16246 static bool pass_on_delete = false; | |
16247 | |
16248 | |
16249 static void ForceDeleteDeleter( | |
16250 v8::Local<v8::Name> name, | |
16251 const v8::PropertyCallbackInfo<v8::Boolean>& info) { | |
16252 force_delete_interceptor_count++; | |
16253 if (pass_on_delete) return; | |
16254 info.GetReturnValue().Set(true); | |
16255 } | |
16256 | |
16257 | |
16258 THREADED_TEST(ForceDeleteWithInterceptor) { | |
16259 force_delete_interceptor_count = 0; | |
16260 pass_on_delete = false; | |
16261 | |
16262 v8::Isolate* isolate = CcTest::isolate(); | |
16263 v8::HandleScope scope(isolate); | |
16264 v8::Handle<v8::ObjectTemplate> templ = v8::ObjectTemplate::New(isolate); | |
16265 templ->SetHandler( | |
16266 v8::NamedPropertyHandlerConfiguration(0, 0, 0, ForceDeleteDeleter)); | |
16267 LocalContext context(NULL, templ); | |
16268 v8::Handle<v8::Object> global = context->Global(); | |
16269 | |
16270 v8::Handle<v8::String> some_property = | |
16271 v8::String::NewFromUtf8(isolate, "a"); | |
16272 global->ForceSet(some_property, v8::Integer::New(isolate, 42), | |
16273 v8::DontDelete); | |
16274 | |
16275 // Deleting a property should get intercepted and nothing should | |
16276 // happen. | |
16277 CHECK_EQ(0, force_delete_interceptor_count); | |
16278 CHECK(global->Delete(some_property)); | |
16279 CHECK_EQ(1, force_delete_interceptor_count); | |
16280 CHECK_EQ(42, global->Get(some_property)->Int32Value()); | |
16281 // Deleting the property when the interceptor returns an empty | |
16282 // handle should not delete the property since it is DontDelete. | |
16283 pass_on_delete = true; | |
16284 CHECK(!global->Delete(some_property)); | |
16285 CHECK_EQ(2, force_delete_interceptor_count); | |
16286 CHECK_EQ(42, global->Get(some_property)->Int32Value()); | |
16287 // Forcing the property to be deleted should delete the value | |
16288 // without calling the interceptor. | |
16289 CHECK(global->ForceDelete(some_property)); | |
16290 CHECK(global->Get(some_property)->IsUndefined()); | |
16291 CHECK_EQ(2, force_delete_interceptor_count); | |
16292 } | |
16293 | |
16294 | |
16295 // Make sure that forcing a delete invalidates any IC stubs, so we | |
16296 // don't read the hole value. | |
16297 THREADED_TEST(ForceDeleteIC) { | |
16298 LocalContext context; | |
16299 v8::HandleScope scope(context->GetIsolate()); | |
16300 // Create a DontDelete variable on the global object. | |
16301 CompileRun("this.__proto__ = { foo: 'horse' };" | |
16302 "var foo = 'fish';" | |
16303 "function f() { return foo.length; }"); | |
16304 // Initialize the IC for foo in f. | |
16305 CompileRun("for (var i = 0; i < 4; i++) f();"); | |
16306 // Make sure the value of foo is correct before the deletion. | |
16307 CHECK_EQ(4, CompileRun("f()")->Int32Value()); | |
16308 // Force the deletion of foo. | |
16309 CHECK(context->Global()->ForceDelete(v8_str("foo"))); | |
16310 // Make sure the value for foo is read from the prototype, and that | |
16311 // we don't get in trouble with reading the deleted cell value | |
16312 // sentinel. | |
16313 CHECK_EQ(5, CompileRun("f()")->Int32Value()); | |
16314 } | |
16315 | |
16316 | |
16317 TEST(InlinedFunctionAcrossContexts) { | |
16318 i::FLAG_allow_natives_syntax = true; | |
16319 v8::Isolate* isolate = CcTest::isolate(); | |
16320 v8::HandleScope outer_scope(isolate); | |
16321 v8::Local<v8::Context> ctx1 = v8::Context::New(isolate); | |
16322 v8::Local<v8::Context> ctx2 = v8::Context::New(isolate); | |
16323 ctx1->Enter(); | |
16324 | |
16325 { | |
16326 v8::HandleScope inner_scope(CcTest::isolate()); | |
16327 CompileRun("var G = 42; function foo() { return G; }"); | |
16328 v8::Local<v8::Value> foo = ctx1->Global()->Get(v8_str("foo")); | |
16329 ctx2->Enter(); | |
16330 ctx2->Global()->Set(v8_str("o"), foo); | |
16331 v8::Local<v8::Value> res = CompileRun( | |
16332 "function f() { return o(); }" | |
16333 "for (var i = 0; i < 10; ++i) f();" | |
16334 "%OptimizeFunctionOnNextCall(f);" | |
16335 "f();"); | |
16336 CHECK_EQ(42, res->Int32Value()); | |
16337 ctx2->Exit(); | |
16338 v8::Handle<v8::String> G_property = | |
16339 v8::String::NewFromUtf8(CcTest::isolate(), "G"); | |
16340 CHECK(ctx1->Global()->ForceDelete(G_property)); | |
16341 ctx2->Enter(); | |
16342 ExpectString( | |
16343 "(function() {" | |
16344 " try {" | |
16345 " return f();" | |
16346 " } catch(e) {" | |
16347 " return e.toString();" | |
16348 " }" | |
16349 " })()", | |
16350 "ReferenceError: G is not defined"); | |
16351 ctx2->Exit(); | |
16352 ctx1->Exit(); | |
16353 } | |
16354 } | |
16355 | |
16356 | |
16357 static v8::Local<Context> calling_context0; | 16224 static v8::Local<Context> calling_context0; |
16358 static v8::Local<Context> calling_context1; | 16225 static v8::Local<Context> calling_context1; |
16359 static v8::Local<Context> calling_context2; | 16226 static v8::Local<Context> calling_context2; |
16360 | 16227 |
16361 | 16228 |
16362 // Check that the call to the callback is initiated in | 16229 // Check that the call to the callback is initiated in |
16363 // calling_context2, the directly calling context is calling_context1 | 16230 // calling_context2, the directly calling context is calling_context1 |
16364 // and the callback itself is in calling_context0. | 16231 // and the callback itself is in calling_context0. |
16365 static void GetCallingContextCallback( | 16232 static void GetCallingContextCallback( |
16366 const v8::FunctionCallbackInfo<v8::Value>& args) { | 16233 const v8::FunctionCallbackInfo<v8::Value>& args) { |
(...skipping 4447 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
20814 "})()", | 20681 "})()", |
20815 "ReferenceError: cell is not defined"); | 20682 "ReferenceError: cell is not defined"); |
20816 CompileRun("cell = \"new_second\";"); | 20683 CompileRun("cell = \"new_second\";"); |
20817 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); | 20684 CcTest::heap()->CollectAllGarbage(i::Heap::kNoGCFlags); |
20818 ExpectString("readCell()", "new_second"); | 20685 ExpectString("readCell()", "new_second"); |
20819 ExpectString("readCell()", "new_second"); | 20686 ExpectString("readCell()", "new_second"); |
20820 } | 20687 } |
20821 } | 20688 } |
20822 | 20689 |
20823 | 20690 |
20824 TEST(DontDeleteCellLoadICForceDelete) { | |
20825 const char* function_code = | |
20826 "function readCell() { while (true) { return cell; } }"; | |
20827 | |
20828 // Run the code twice to initialize the load IC for a don't delete | |
20829 // cell. | |
20830 LocalContext context; | |
20831 v8::HandleScope scope(context->GetIsolate()); | |
20832 CompileRun("var cell = \"value\";"); | |
20833 ExpectBoolean("delete cell", false); | |
20834 CompileRun(function_code); | |
20835 ExpectString("readCell()", "value"); | |
20836 ExpectString("readCell()", "value"); | |
20837 | |
20838 // Delete the cell using the API and check the inlined code works | |
20839 // correctly. | |
20840 CHECK(context->Global()->ForceDelete(v8_str("cell"))); | |
20841 ExpectString("(function() {" | |
20842 " try {" | |
20843 " return readCell();" | |
20844 " } catch(e) {" | |
20845 " return e.toString();" | |
20846 " }" | |
20847 "})()", | |
20848 "ReferenceError: cell is not defined"); | |
20849 } | |
20850 | |
20851 | |
20852 TEST(DontDeleteCellLoadICAPI) { | |
20853 const char* function_code = | |
20854 "function readCell() { while (true) { return cell; } }"; | |
20855 | |
20856 // Run the code twice to initialize the load IC for a don't delete | |
20857 // cell created using the API. | |
20858 LocalContext context; | |
20859 v8::HandleScope scope(context->GetIsolate()); | |
20860 context->Global()->ForceSet(v8_str("cell"), v8_str("value"), v8::DontDelete); | |
20861 ExpectBoolean("delete cell", false); | |
20862 CompileRun(function_code); | |
20863 ExpectString("readCell()", "value"); | |
20864 ExpectString("readCell()", "value"); | |
20865 | |
20866 // Delete the cell using the API and check the inlined code works | |
20867 // correctly. | |
20868 CHECK(context->Global()->ForceDelete(v8_str("cell"))); | |
20869 ExpectString("(function() {" | |
20870 " try {" | |
20871 " return readCell();" | |
20872 " } catch(e) {" | |
20873 " return e.toString();" | |
20874 " }" | |
20875 "})()", | |
20876 "ReferenceError: cell is not defined"); | |
20877 } | |
20878 | |
20879 | |
20880 class Visitor42 : public v8::PersistentHandleVisitor { | 20691 class Visitor42 : public v8::PersistentHandleVisitor { |
20881 public: | 20692 public: |
20882 explicit Visitor42(v8::Persistent<v8::Object>* object) | 20693 explicit Visitor42(v8::Persistent<v8::Object>* object) |
20883 : counter_(0), object_(object) { } | 20694 : counter_(0), object_(object) { } |
20884 | 20695 |
20885 virtual void VisitPersistentHandle(Persistent<Value>* value, | 20696 virtual void VisitPersistentHandle(Persistent<Value>* value, |
20886 uint16_t class_id) { | 20697 uint16_t class_id) { |
20887 if (class_id != 42) return; | 20698 if (class_id != 42) return; |
20888 CHECK_EQ(42, value->WrapperClassId()); | 20699 CHECK_EQ(42, value->WrapperClassId()); |
20889 v8::Isolate* isolate = CcTest::isolate(); | 20700 v8::Isolate* isolate = CcTest::isolate(); |
(...skipping 3784 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
24674 "bar2.js"); | 24485 "bar2.js"); |
24675 } | 24486 } |
24676 | 24487 |
24677 | 24488 |
24678 TEST(StreamingScriptWithSourceMappingURLInTheMiddle) { | 24489 TEST(StreamingScriptWithSourceMappingURLInTheMiddle) { |
24679 const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#", | 24490 const char* chunks[] = {"function foo() { ret", "urn 13; }\n//#", |
24680 " sourceMappingURL=bar2.js\n", "foo();", NULL}; | 24491 " sourceMappingURL=bar2.js\n", "foo();", NULL}; |
24681 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL, | 24492 RunStreamingTest(chunks, v8::ScriptCompiler::StreamedSource::UTF8, true, NULL, |
24682 "bar2.js"); | 24493 "bar2.js"); |
24683 } | 24494 } |
OLD | NEW |