| 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 |
| 11 // with the distribution. | 11 // with the distribution. |
| 12 // * Neither the name of Google Inc. nor the names of its | 12 // * Neither the name of Google Inc. nor the names of its |
| 13 // contributors may be used to endorse or promote products derived | 13 // contributors may be used to endorse or promote products derived |
| 14 // from this software without specific prior written permission. | 14 // from this software without specific prior written permission. |
| 15 // | 15 // |
| 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
| 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
| 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
| 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
| 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
| 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
| 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
| 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
| 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
| 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
| 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
| 27 | 27 |
| 28 // TODO(jochen): Remove this after the setting is turned on globally. |
| 29 #define V8_IMMINENT_DEPRECATION_WARNINGS |
| 30 |
| 28 #include <stdlib.h> | 31 #include <stdlib.h> |
| 29 #include <wchar.h> | 32 #include <wchar.h> |
| 30 | 33 |
| 31 #include "src/v8.h" | 34 #include "src/v8.h" |
| 32 | 35 |
| 33 #include "src/compiler.h" | 36 #include "src/compiler.h" |
| 34 #include "src/disasm.h" | 37 #include "src/disasm.h" |
| 35 #include "src/parser.h" | 38 #include "src/parser.h" |
| 36 #include "test/cctest/cctest.h" | 39 #include "test/cctest/cctest.h" |
| 37 | 40 |
| (...skipping 217 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 script->set_source(CcTest::heap()->undefined_value()); | 258 script->set_source(CcTest::heap()->undefined_value()); |
| 256 CHECK_EQ(-1, Script::GetLineNumber(script, 0)); | 259 CHECK_EQ(-1, Script::GetLineNumber(script, 0)); |
| 257 CHECK_EQ(-1, Script::GetLineNumber(script, 100)); | 260 CHECK_EQ(-1, Script::GetLineNumber(script, 100)); |
| 258 CHECK_EQ(-1, Script::GetLineNumber(script, -1)); | 261 CHECK_EQ(-1, Script::GetLineNumber(script, -1)); |
| 259 } | 262 } |
| 260 | 263 |
| 261 | 264 |
| 262 TEST(GetScriptLineNumber) { | 265 TEST(GetScriptLineNumber) { |
| 263 LocalContext context; | 266 LocalContext context; |
| 264 v8::HandleScope scope(CcTest::isolate()); | 267 v8::HandleScope scope(CcTest::isolate()); |
| 265 v8::ScriptOrigin origin = | 268 v8::ScriptOrigin origin = v8::ScriptOrigin(v8_str("test")); |
| 266 v8::ScriptOrigin(v8::String::NewFromUtf8(CcTest::isolate(), "test")); | |
| 267 const char function_f[] = "function f() {}"; | 269 const char function_f[] = "function f() {}"; |
| 268 const int max_rows = 1000; | 270 const int max_rows = 1000; |
| 269 const int buffer_size = max_rows + sizeof(function_f); | 271 const int buffer_size = max_rows + sizeof(function_f); |
| 270 ScopedVector<char> buffer(buffer_size); | 272 ScopedVector<char> buffer(buffer_size); |
| 271 memset(buffer.start(), '\n', buffer_size - 1); | 273 memset(buffer.start(), '\n', buffer_size - 1); |
| 272 buffer[buffer_size - 1] = '\0'; | 274 buffer[buffer_size - 1] = '\0'; |
| 273 | 275 |
| 274 for (int i = 0; i < max_rows; ++i) { | 276 for (int i = 0; i < max_rows; ++i) { |
| 275 if (i > 0) | 277 if (i > 0) |
| 276 buffer[i - 1] = '\n'; | 278 buffer[i - 1] = '\n'; |
| 277 MemCopy(&buffer[i], function_f, sizeof(function_f) - 1); | 279 MemCopy(&buffer[i], function_f, sizeof(function_f) - 1); |
| 278 v8::Handle<v8::String> script_body = | 280 v8::Local<v8::String> script_body = v8_str(buffer.start()); |
| 279 v8::String::NewFromUtf8(CcTest::isolate(), buffer.start()); | 281 v8::Script::Compile(context.local(), script_body, &origin) |
| 280 v8::Script::Compile(script_body, &origin)->Run(); | 282 .ToLocalChecked() |
| 281 v8::Local<v8::Function> f = | 283 ->Run(context.local()) |
| 282 v8::Local<v8::Function>::Cast(context->Global()->Get( | 284 .ToLocalChecked(); |
| 283 v8::String::NewFromUtf8(CcTest::isolate(), "f"))); | 285 v8::Local<v8::Function> f = v8::Local<v8::Function>::Cast( |
| 286 context->Global()->Get(context.local(), v8_str("f")).ToLocalChecked()); |
| 284 CHECK_EQ(i, f->GetScriptLineNumber()); | 287 CHECK_EQ(i, f->GetScriptLineNumber()); |
| 285 } | 288 } |
| 286 } | 289 } |
| 287 | 290 |
| 288 | 291 |
| 289 TEST(FeedbackVectorPreservedAcrossRecompiles) { | 292 TEST(FeedbackVectorPreservedAcrossRecompiles) { |
| 290 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; | 293 if (i::FLAG_always_opt || !i::FLAG_crankshaft) return; |
| 291 i::FLAG_allow_natives_syntax = true; | 294 i::FLAG_allow_natives_syntax = true; |
| 292 CcTest::InitializeVM(); | 295 CcTest::InitializeVM(); |
| 293 if (!CcTest::i_isolate()->use_crankshaft()) return; | 296 if (!CcTest::i_isolate()->use_crankshaft()) return; |
| 294 v8::HandleScope scope(CcTest::isolate()); | 297 v8::HandleScope scope(CcTest::isolate()); |
| 298 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 295 | 299 |
| 296 // Make sure function f has a call that uses a type feedback slot. | 300 // Make sure function f has a call that uses a type feedback slot. |
| 297 CompileRun("function fun() {};" | 301 CompileRun("function fun() {};" |
| 298 "fun1 = fun;" | 302 "fun1 = fun;" |
| 299 "function f(a) { a(); } f(fun1);"); | 303 "function f(a) { a(); } f(fun1);"); |
| 300 | 304 |
| 301 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( | 305 Handle<JSFunction> f = Handle<JSFunction>::cast( |
| 302 *v8::Handle<v8::Function>::Cast(CcTest::global()->Get(v8_str("f"))))); | 306 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 307 CcTest::global()->Get(context, v8_str("f")).ToLocalChecked()))); |
| 303 | 308 |
| 304 // We shouldn't have deoptimization support. We want to recompile and | 309 // We shouldn't have deoptimization support. We want to recompile and |
| 305 // verify that our feedback vector preserves information. | 310 // verify that our feedback vector preserves information. |
| 306 CHECK(!f->shared()->has_deoptimization_support()); | 311 CHECK(!f->shared()->has_deoptimization_support()); |
| 307 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); | 312 Handle<TypeFeedbackVector> feedback_vector(f->shared()->feedback_vector()); |
| 308 | 313 |
| 309 // Verify that we gathered feedback. | 314 // Verify that we gathered feedback. |
| 310 CHECK(!feedback_vector->is_empty()); | 315 CHECK(!feedback_vector->is_empty()); |
| 311 FeedbackVectorSlot slot_for_a(0); | 316 FeedbackVectorSlot slot_for_a(0); |
| 312 Object* object = feedback_vector->Get(slot_for_a); | 317 Object* object = feedback_vector->Get(slot_for_a); |
| 313 CHECK(object->IsWeakCell() && | 318 CHECK(object->IsWeakCell() && |
| 314 WeakCell::cast(object)->value()->IsJSFunction()); | 319 WeakCell::cast(object)->value()->IsJSFunction()); |
| 315 | 320 |
| 316 CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);"); | 321 CompileRun("%OptimizeFunctionOnNextCall(f); f(fun1);"); |
| 317 | 322 |
| 318 // Verify that the feedback is still "gathered" despite a recompilation | 323 // Verify that the feedback is still "gathered" despite a recompilation |
| 319 // of the full code. | 324 // of the full code. |
| 320 CHECK(f->IsOptimized()); | 325 CHECK(f->IsOptimized()); |
| 321 CHECK(f->shared()->has_deoptimization_support()); | 326 CHECK(f->shared()->has_deoptimization_support()); |
| 322 object = f->shared()->feedback_vector()->Get(slot_for_a); | 327 object = f->shared()->feedback_vector()->Get(slot_for_a); |
| 323 CHECK(object->IsWeakCell() && | 328 CHECK(object->IsWeakCell() && |
| 324 WeakCell::cast(object)->value()->IsJSFunction()); | 329 WeakCell::cast(object)->value()->IsJSFunction()); |
| 325 } | 330 } |
| 326 | 331 |
| 327 | 332 |
| 328 TEST(FeedbackVectorUnaffectedByScopeChanges) { | 333 TEST(FeedbackVectorUnaffectedByScopeChanges) { |
| 329 if (i::FLAG_always_opt || !i::FLAG_lazy) return; | 334 if (i::FLAG_always_opt || !i::FLAG_lazy) return; |
| 330 CcTest::InitializeVM(); | 335 CcTest::InitializeVM(); |
| 331 v8::HandleScope scope(CcTest::isolate()); | 336 v8::HandleScope scope(CcTest::isolate()); |
| 337 v8::Local<v8::Context> context = CcTest::isolate()->GetCurrentContext(); |
| 332 | 338 |
| 333 CompileRun("function builder() {" | 339 CompileRun("function builder() {" |
| 334 " call_target = function() { return 3; };" | 340 " call_target = function() { return 3; };" |
| 335 " return (function() {" | 341 " return (function() {" |
| 336 " eval('');" | 342 " eval('');" |
| 337 " return function() {" | 343 " return function() {" |
| 338 " 'use strict';" | 344 " 'use strict';" |
| 339 " call_target();" | 345 " call_target();" |
| 340 " }" | 346 " }" |
| 341 " })();" | 347 " })();" |
| 342 "}" | 348 "}" |
| 343 "morphing_call = builder();"); | 349 "morphing_call = builder();"); |
| 344 | 350 |
| 345 Handle<JSFunction> f = Handle<JSFunction>::cast( | 351 Handle<JSFunction> f = Handle<JSFunction>::cast(v8::Utils::OpenHandle( |
| 346 v8::Utils::OpenHandle(*v8::Handle<v8::Function>::Cast( | 352 *v8::Local<v8::Function>::Cast(CcTest::global() |
| 347 CcTest::global()->Get(v8_str("morphing_call"))))); | 353 ->Get(context, v8_str("morphing_call")) |
| 354 .ToLocalChecked()))); |
| 348 | 355 |
| 349 // Not compiled, and so no feedback vector allocated yet. | 356 // Not compiled, and so no feedback vector allocated yet. |
| 350 CHECK(!f->shared()->is_compiled()); | 357 CHECK(!f->shared()->is_compiled()); |
| 351 CHECK(f->shared()->feedback_vector()->is_empty()); | 358 CHECK(f->shared()->feedback_vector()->is_empty()); |
| 352 | 359 |
| 353 CompileRun("morphing_call();"); | 360 CompileRun("morphing_call();"); |
| 354 | 361 |
| 355 // Now a feedback vector is allocated. | 362 // Now a feedback vector is allocated. |
| 356 CHECK(f->shared()->is_compiled()); | 363 CHECK(f->shared()->is_compiled()); |
| 357 CHECK(!f->shared()->feedback_vector()->is_empty()); | 364 CHECK(!f->shared()->feedback_vector()->is_empty()); |
| 358 } | 365 } |
| 359 | 366 |
| 360 | 367 |
| 361 // Test that optimized code for different closures is actually shared | 368 // Test that optimized code for different closures is actually shared |
| 362 // immediately by the FastNewClosureStub when run in the same context. | 369 // immediately by the FastNewClosureStub when run in the same context. |
| 363 TEST(OptimizedCodeSharing1) { | 370 TEST(OptimizedCodeSharing1) { |
| 364 FLAG_stress_compaction = false; | 371 FLAG_stress_compaction = false; |
| 365 FLAG_allow_natives_syntax = true; | 372 FLAG_allow_natives_syntax = true; |
| 366 CcTest::InitializeVM(); | 373 CcTest::InitializeVM(); |
| 367 v8::HandleScope scope(CcTest::isolate()); | 374 v8::HandleScope scope(CcTest::isolate()); |
| 368 for (int i = 0; i < 3; i++) { | 375 for (int i = 0; i < 3; i++) { |
| 369 LocalContext env; | 376 LocalContext env; |
| 370 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), | 377 env->Global() |
| 371 v8::Integer::New(CcTest::isolate(), i)); | 378 ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) |
| 379 .FromJust(); |
| 372 CompileRun( | 380 CompileRun( |
| 373 "function MakeClosure() {" | 381 "function MakeClosure() {" |
| 374 " return function() { return x; };" | 382 " return function() { return x; };" |
| 375 "}" | 383 "}" |
| 376 "var closure0 = MakeClosure();" | 384 "var closure0 = MakeClosure();" |
| 377 "%DebugPrint(closure0());" | 385 "%DebugPrint(closure0());" |
| 378 "%OptimizeFunctionOnNextCall(closure0);" | 386 "%OptimizeFunctionOnNextCall(closure0);" |
| 379 "%DebugPrint(closure0());" | 387 "%DebugPrint(closure0());" |
| 380 "var closure1 = MakeClosure();" | 388 "var closure1 = MakeClosure();" |
| 381 "var closure2 = MakeClosure();"); | 389 "var closure2 = MakeClosure();"); |
| 382 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( | 390 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( |
| 383 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 391 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 384 env->Global()->Get(v8_str("closure1"))))); | 392 env->Global() |
| 393 ->Get(env.local(), v8_str("closure1")) |
| 394 .ToLocalChecked()))); |
| 385 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( | 395 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( |
| 386 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 396 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 387 env->Global()->Get(v8_str("closure2"))))); | 397 env->Global() |
| 398 ->Get(env.local(), v8_str("closure2")) |
| 399 .ToLocalChecked()))); |
| 388 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 400 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 389 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 401 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 390 CHECK_EQ(fun1->code(), fun2->code()); | 402 CHECK_EQ(fun1->code(), fun2->code()); |
| 391 } | 403 } |
| 392 } | 404 } |
| 393 | 405 |
| 394 | 406 |
| 395 // Test that optimized code for different closures is actually shared | 407 // Test that optimized code for different closures is actually shared |
| 396 // immediately by the FastNewClosureStub when run different contexts. | 408 // immediately by the FastNewClosureStub when run different contexts. |
| 397 TEST(OptimizedCodeSharing2) { | 409 TEST(OptimizedCodeSharing2) { |
| 398 if (FLAG_stress_compaction) return; | 410 if (FLAG_stress_compaction) return; |
| 399 FLAG_allow_natives_syntax = true; | 411 FLAG_allow_natives_syntax = true; |
| 400 FLAG_native_context_specialization = false; | 412 FLAG_native_context_specialization = false; |
| 401 FLAG_turbo_cache_shared_code = true; | 413 FLAG_turbo_cache_shared_code = true; |
| 402 const char* flag = "--turbo-filter=*"; | 414 const char* flag = "--turbo-filter=*"; |
| 403 FlagList::SetFlagsFromString(flag, StrLength(flag)); | 415 FlagList::SetFlagsFromString(flag, StrLength(flag)); |
| 404 CcTest::InitializeVM(); | 416 CcTest::InitializeVM(); |
| 405 v8::HandleScope scope(CcTest::isolate()); | 417 v8::HandleScope scope(CcTest::isolate()); |
| 406 v8::Local<v8::Script> script = v8_compile( | 418 v8::Local<v8::Script> script = v8_compile( |
| 407 "function MakeClosure() {" | 419 "function MakeClosure() {" |
| 408 " return function() { return x; };" | 420 " return function() { return x; };" |
| 409 "}"); | 421 "}"); |
| 410 Handle<Code> reference_code; | 422 Handle<Code> reference_code; |
| 411 { | 423 { |
| 412 LocalContext env; | 424 LocalContext env; |
| 413 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), | 425 env->Global() |
| 414 v8::Integer::New(CcTest::isolate(), 23)); | 426 ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), 23)) |
| 415 script->GetUnboundScript()->BindToCurrentContext()->Run(); | 427 .FromJust(); |
| 428 script->GetUnboundScript() |
| 429 ->BindToCurrentContext() |
| 430 ->Run(env.local()) |
| 431 .ToLocalChecked(); |
| 416 CompileRun( | 432 CompileRun( |
| 417 "var closure0 = MakeClosure();" | 433 "var closure0 = MakeClosure();" |
| 418 "%DebugPrint(closure0());" | 434 "%DebugPrint(closure0());" |
| 419 "%OptimizeFunctionOnNextCall(closure0);" | 435 "%OptimizeFunctionOnNextCall(closure0);" |
| 420 "%DebugPrint(closure0());"); | 436 "%DebugPrint(closure0());"); |
| 421 Handle<JSFunction> fun0 = Handle<JSFunction>::cast( | 437 Handle<JSFunction> fun0 = Handle<JSFunction>::cast( |
| 422 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 438 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 423 env->Global()->Get(v8_str("closure0"))))); | 439 env->Global() |
| 440 ->Get(env.local(), v8_str("closure0")) |
| 441 .ToLocalChecked()))); |
| 424 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 442 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 425 reference_code = handle(fun0->code()); | 443 reference_code = handle(fun0->code()); |
| 426 } | 444 } |
| 427 for (int i = 0; i < 3; i++) { | 445 for (int i = 0; i < 3; i++) { |
| 428 LocalContext env; | 446 LocalContext env; |
| 429 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), | 447 env->Global() |
| 430 v8::Integer::New(CcTest::isolate(), i)); | 448 ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) |
| 431 script->GetUnboundScript()->BindToCurrentContext()->Run(); | 449 .FromJust(); |
| 450 script->GetUnboundScript() |
| 451 ->BindToCurrentContext() |
| 452 ->Run(env.local()) |
| 453 .ToLocalChecked(); |
| 432 CompileRun( | 454 CompileRun( |
| 433 "var closure0 = MakeClosure();" | 455 "var closure0 = MakeClosure();" |
| 434 "%DebugPrint(closure0());" | 456 "%DebugPrint(closure0());" |
| 435 "%OptimizeFunctionOnNextCall(closure0);" | 457 "%OptimizeFunctionOnNextCall(closure0);" |
| 436 "%DebugPrint(closure0());" | 458 "%DebugPrint(closure0());" |
| 437 "var closure1 = MakeClosure();" | 459 "var closure1 = MakeClosure();" |
| 438 "var closure2 = MakeClosure();"); | 460 "var closure2 = MakeClosure();"); |
| 439 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( | 461 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( |
| 440 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 462 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 441 env->Global()->Get(v8_str("closure1"))))); | 463 env->Global() |
| 464 ->Get(env.local(), v8_str("closure1")) |
| 465 .ToLocalChecked()))); |
| 442 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( | 466 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( |
| 443 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 467 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 444 env->Global()->Get(v8_str("closure2"))))); | 468 env->Global() |
| 469 ->Get(env.local(), v8_str("closure2")) |
| 470 .ToLocalChecked()))); |
| 445 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 471 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 446 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 472 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 447 CHECK_EQ(*reference_code, fun1->code()); | 473 CHECK_EQ(*reference_code, fun1->code()); |
| 448 CHECK_EQ(*reference_code, fun2->code()); | 474 CHECK_EQ(*reference_code, fun2->code()); |
| 449 } | 475 } |
| 450 } | 476 } |
| 451 | 477 |
| 452 | 478 |
| 453 // Test that optimized code for different closures is actually shared | 479 // Test that optimized code for different closures is actually shared |
| 454 // immediately by the FastNewClosureStub without context-dependent entries. | 480 // immediately by the FastNewClosureStub without context-dependent entries. |
| 455 TEST(OptimizedCodeSharing3) { | 481 TEST(OptimizedCodeSharing3) { |
| 456 if (FLAG_stress_compaction) return; | 482 if (FLAG_stress_compaction) return; |
| 457 FLAG_allow_natives_syntax = true; | 483 FLAG_allow_natives_syntax = true; |
| 458 FLAG_native_context_specialization = false; | 484 FLAG_native_context_specialization = false; |
| 459 FLAG_turbo_cache_shared_code = true; | 485 FLAG_turbo_cache_shared_code = true; |
| 460 const char* flag = "--turbo-filter=*"; | 486 const char* flag = "--turbo-filter=*"; |
| 461 FlagList::SetFlagsFromString(flag, StrLength(flag)); | 487 FlagList::SetFlagsFromString(flag, StrLength(flag)); |
| 462 CcTest::InitializeVM(); | 488 CcTest::InitializeVM(); |
| 463 v8::HandleScope scope(CcTest::isolate()); | 489 v8::HandleScope scope(CcTest::isolate()); |
| 464 v8::Local<v8::Script> script = v8_compile( | 490 v8::Local<v8::Script> script = v8_compile( |
| 465 "function MakeClosure() {" | 491 "function MakeClosure() {" |
| 466 " return function() { return x; };" | 492 " return function() { return x; };" |
| 467 "}"); | 493 "}"); |
| 468 Handle<Code> reference_code; | 494 Handle<Code> reference_code; |
| 469 { | 495 { |
| 470 LocalContext env; | 496 LocalContext env; |
| 471 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), | 497 env->Global() |
| 472 v8::Integer::New(CcTest::isolate(), 23)); | 498 ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), 23)) |
| 473 script->GetUnboundScript()->BindToCurrentContext()->Run(); | 499 .FromJust(); |
| 500 script->GetUnboundScript() |
| 501 ->BindToCurrentContext() |
| 502 ->Run(env.local()) |
| 503 .ToLocalChecked(); |
| 474 CompileRun( | 504 CompileRun( |
| 475 "var closure0 = MakeClosure();" | 505 "var closure0 = MakeClosure();" |
| 476 "%DebugPrint(closure0());" | 506 "%DebugPrint(closure0());" |
| 477 "%OptimizeFunctionOnNextCall(closure0);" | 507 "%OptimizeFunctionOnNextCall(closure0);" |
| 478 "%DebugPrint(closure0());"); | 508 "%DebugPrint(closure0());"); |
| 479 Handle<JSFunction> fun0 = Handle<JSFunction>::cast( | 509 Handle<JSFunction> fun0 = Handle<JSFunction>::cast( |
| 480 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 510 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 481 env->Global()->Get(v8_str("closure0"))))); | 511 env->Global() |
| 512 ->Get(env.local(), v8_str("closure0")) |
| 513 .ToLocalChecked()))); |
| 482 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 514 CHECK(fun0->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 483 reference_code = handle(fun0->code()); | 515 reference_code = handle(fun0->code()); |
| 484 // Evict only the context-dependent entry from the optimized code map. This | 516 // Evict only the context-dependent entry from the optimized code map. This |
| 485 // leaves it in a state where only the context-independent entry exists. | 517 // leaves it in a state where only the context-independent entry exists. |
| 486 fun0->shared()->TrimOptimizedCodeMap(SharedFunctionInfo::kEntryLength); | 518 fun0->shared()->TrimOptimizedCodeMap(SharedFunctionInfo::kEntryLength); |
| 487 } | 519 } |
| 488 for (int i = 0; i < 3; i++) { | 520 for (int i = 0; i < 3; i++) { |
| 489 LocalContext env; | 521 LocalContext env; |
| 490 env->Global()->Set(v8::String::NewFromUtf8(CcTest::isolate(), "x"), | 522 env->Global() |
| 491 v8::Integer::New(CcTest::isolate(), i)); | 523 ->Set(env.local(), v8_str("x"), v8::Integer::New(CcTest::isolate(), i)) |
| 492 script->GetUnboundScript()->BindToCurrentContext()->Run(); | 524 .FromJust(); |
| 525 script->GetUnboundScript() |
| 526 ->BindToCurrentContext() |
| 527 ->Run(env.local()) |
| 528 .ToLocalChecked(); |
| 493 CompileRun( | 529 CompileRun( |
| 494 "var closure0 = MakeClosure();" | 530 "var closure0 = MakeClosure();" |
| 495 "%DebugPrint(closure0());" | 531 "%DebugPrint(closure0());" |
| 496 "%OptimizeFunctionOnNextCall(closure0);" | 532 "%OptimizeFunctionOnNextCall(closure0);" |
| 497 "%DebugPrint(closure0());" | 533 "%DebugPrint(closure0());" |
| 498 "var closure1 = MakeClosure();" | 534 "var closure1 = MakeClosure();" |
| 499 "var closure2 = MakeClosure();"); | 535 "var closure2 = MakeClosure();"); |
| 500 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( | 536 Handle<JSFunction> fun1 = Handle<JSFunction>::cast( |
| 501 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 537 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 502 env->Global()->Get(v8_str("closure1"))))); | 538 env->Global() |
| 539 ->Get(env.local(), v8_str("closure1")) |
| 540 .ToLocalChecked()))); |
| 503 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( | 541 Handle<JSFunction> fun2 = Handle<JSFunction>::cast( |
| 504 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( | 542 v8::Utils::OpenHandle(*v8::Local<v8::Function>::Cast( |
| 505 env->Global()->Get(v8_str("closure2"))))); | 543 env->Global() |
| 544 ->Get(env.local(), v8_str("closure2")) |
| 545 .ToLocalChecked()))); |
| 506 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 546 CHECK(fun1->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 507 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); | 547 CHECK(fun2->IsOptimized() || !CcTest::i_isolate()->use_crankshaft()); |
| 508 CHECK_EQ(*reference_code, fun1->code()); | 548 CHECK_EQ(*reference_code, fun1->code()); |
| 509 CHECK_EQ(*reference_code, fun2->code()); | 549 CHECK_EQ(*reference_code, fun2->code()); |
| 510 } | 550 } |
| 511 } | 551 } |
| 512 | 552 |
| 513 | 553 |
| 514 TEST(CompileFunctionInContext) { | 554 TEST(CompileFunctionInContext) { |
| 515 CcTest::InitializeVM(); | 555 CcTest::InitializeVM(); |
| 516 v8::HandleScope scope(CcTest::isolate()); | 556 v8::HandleScope scope(CcTest::isolate()); |
| 517 LocalContext env; | 557 LocalContext env; |
| 518 CompileRun("var r = 10;"); | 558 CompileRun("var r = 10;"); |
| 519 v8::Local<v8::Object> math = | 559 v8::Local<v8::Object> math = v8::Local<v8::Object>::Cast( |
| 520 v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("Math"))); | 560 env->Global()->Get(env.local(), v8_str("Math")).ToLocalChecked()); |
| 521 v8::ScriptCompiler::Source script_source(v8_str( | 561 v8::ScriptCompiler::Source script_source(v8_str( |
| 522 "a = PI * r * r;" | 562 "a = PI * r * r;" |
| 523 "x = r * cos(PI);" | 563 "x = r * cos(PI);" |
| 524 "y = r * sin(PI / 2);")); | 564 "y = r * sin(PI / 2);")); |
| 525 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 565 v8::Local<v8::Function> fun = |
| 526 CcTest::isolate(), &script_source, env.local(), 0, NULL, 1, &math); | 566 v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, |
| 567 0, NULL, 1, &math) |
| 568 .ToLocalChecked(); |
| 527 CHECK(!fun.IsEmpty()); | 569 CHECK(!fun.IsEmpty()); |
| 528 fun->Call(env->Global(), 0, NULL); | 570 fun->Call(env.local(), env->Global(), 0, NULL).ToLocalChecked(); |
| 529 CHECK(env->Global()->Has(v8_str("a"))); | 571 CHECK(env->Global()->Has(env.local(), v8_str("a")).FromJust()); |
| 530 v8::Local<v8::Value> a = env->Global()->Get(v8_str("a")); | 572 v8::Local<v8::Value> a = |
| 573 env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked(); |
| 531 CHECK(a->IsNumber()); | 574 CHECK(a->IsNumber()); |
| 532 CHECK(env->Global()->Has(v8_str("x"))); | 575 CHECK(env->Global()->Has(env.local(), v8_str("x")).FromJust()); |
| 533 v8::Local<v8::Value> x = env->Global()->Get(v8_str("x")); | 576 v8::Local<v8::Value> x = |
| 577 env->Global()->Get(env.local(), v8_str("x")).ToLocalChecked(); |
| 534 CHECK(x->IsNumber()); | 578 CHECK(x->IsNumber()); |
| 535 CHECK(env->Global()->Has(v8_str("y"))); | 579 CHECK(env->Global()->Has(env.local(), v8_str("y")).FromJust()); |
| 536 v8::Local<v8::Value> y = env->Global()->Get(v8_str("y")); | 580 v8::Local<v8::Value> y = |
| 581 env->Global()->Get(env.local(), v8_str("y")).ToLocalChecked(); |
| 537 CHECK(y->IsNumber()); | 582 CHECK(y->IsNumber()); |
| 538 CHECK_EQ(314.1592653589793, a->NumberValue()); | 583 CHECK_EQ(314.1592653589793, a->NumberValue(env.local()).FromJust()); |
| 539 CHECK_EQ(-10.0, x->NumberValue()); | 584 CHECK_EQ(-10.0, x->NumberValue(env.local()).FromJust()); |
| 540 CHECK_EQ(10.0, y->NumberValue()); | 585 CHECK_EQ(10.0, y->NumberValue(env.local()).FromJust()); |
| 541 } | 586 } |
| 542 | 587 |
| 543 | 588 |
| 544 TEST(CompileFunctionInContextComplex) { | 589 TEST(CompileFunctionInContextComplex) { |
| 545 CcTest::InitializeVM(); | 590 CcTest::InitializeVM(); |
| 546 v8::HandleScope scope(CcTest::isolate()); | 591 v8::HandleScope scope(CcTest::isolate()); |
| 547 LocalContext env; | 592 LocalContext env; |
| 548 CompileRun( | 593 CompileRun( |
| 549 "var x = 1;" | 594 "var x = 1;" |
| 550 "var y = 2;" | 595 "var y = 2;" |
| 551 "var z = 4;" | 596 "var z = 4;" |
| 552 "var a = {x: 8, y: 16};" | 597 "var a = {x: 8, y: 16};" |
| 553 "var b = {x: 32};"); | 598 "var b = {x: 32};"); |
| 554 v8::Local<v8::Object> ext[2]; | 599 v8::Local<v8::Object> ext[2]; |
| 555 ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); | 600 ext[0] = v8::Local<v8::Object>::Cast( |
| 556 ext[1] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("b"))); | 601 env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); |
| 602 ext[1] = v8::Local<v8::Object>::Cast( |
| 603 env->Global()->Get(env.local(), v8_str("b")).ToLocalChecked()); |
| 557 v8::ScriptCompiler::Source script_source(v8_str("result = x + y + z")); | 604 v8::ScriptCompiler::Source script_source(v8_str("result = x + y + z")); |
| 558 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 605 v8::Local<v8::Function> fun = |
| 559 CcTest::isolate(), &script_source, env.local(), 0, NULL, 2, ext); | 606 v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, |
| 607 0, NULL, 2, ext) |
| 608 .ToLocalChecked(); |
| 560 CHECK(!fun.IsEmpty()); | 609 CHECK(!fun.IsEmpty()); |
| 561 fun->Call(env->Global(), 0, NULL); | 610 fun->Call(env.local(), env->Global(), 0, NULL).ToLocalChecked(); |
| 562 CHECK(env->Global()->Has(v8_str("result"))); | 611 CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); |
| 563 v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); | 612 v8::Local<v8::Value> result = |
| 613 env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); |
| 564 CHECK(result->IsNumber()); | 614 CHECK(result->IsNumber()); |
| 565 CHECK_EQ(52.0, result->NumberValue()); | 615 CHECK_EQ(52.0, result->NumberValue(env.local()).FromJust()); |
| 566 } | 616 } |
| 567 | 617 |
| 568 | 618 |
| 569 TEST(CompileFunctionInContextArgs) { | 619 TEST(CompileFunctionInContextArgs) { |
| 570 CcTest::InitializeVM(); | 620 CcTest::InitializeVM(); |
| 571 v8::HandleScope scope(CcTest::isolate()); | 621 v8::HandleScope scope(CcTest::isolate()); |
| 572 LocalContext env; | 622 LocalContext env; |
| 573 CompileRun("var a = {x: 23};"); | 623 CompileRun("var a = {x: 23};"); |
| 574 v8::Local<v8::Object> ext[1]; | 624 v8::Local<v8::Object> ext[1]; |
| 575 ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); | 625 ext[0] = v8::Local<v8::Object>::Cast( |
| 626 env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); |
| 576 v8::ScriptCompiler::Source script_source(v8_str("result = x + b")); | 627 v8::ScriptCompiler::Source script_source(v8_str("result = x + b")); |
| 577 v8::Local<v8::String> arg = v8_str("b"); | 628 v8::Local<v8::String> arg = v8_str("b"); |
| 578 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 629 v8::Local<v8::Function> fun = |
| 579 CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext); | 630 v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, |
| 631 1, &arg, 1, ext) |
| 632 .ToLocalChecked(); |
| 580 CHECK(!fun.IsEmpty()); | 633 CHECK(!fun.IsEmpty()); |
| 581 v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); | 634 v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); |
| 582 fun->Call(env->Global(), 1, &b_value); | 635 fun->Call(env.local(), env->Global(), 1, &b_value).ToLocalChecked(); |
| 583 CHECK(env->Global()->Has(v8_str("result"))); | 636 CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); |
| 584 v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); | 637 v8::Local<v8::Value> result = |
| 638 env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); |
| 585 CHECK(result->IsNumber()); | 639 CHECK(result->IsNumber()); |
| 586 CHECK_EQ(65.0, result->NumberValue()); | 640 CHECK_EQ(65.0, result->NumberValue(env.local()).FromJust()); |
| 587 } | 641 } |
| 588 | 642 |
| 589 | 643 |
| 590 TEST(CompileFunctionInContextComments) { | 644 TEST(CompileFunctionInContextComments) { |
| 591 CcTest::InitializeVM(); | 645 CcTest::InitializeVM(); |
| 592 v8::HandleScope scope(CcTest::isolate()); | 646 v8::HandleScope scope(CcTest::isolate()); |
| 593 LocalContext env; | 647 LocalContext env; |
| 594 CompileRun("var a = {x: 23, y: 1, z: 2};"); | 648 CompileRun("var a = {x: 23, y: 1, z: 2};"); |
| 595 v8::Local<v8::Object> ext[1]; | 649 v8::Local<v8::Object> ext[1]; |
| 596 ext[0] = v8::Local<v8::Object>::Cast(env->Global()->Get(v8_str("a"))); | 650 ext[0] = v8::Local<v8::Object>::Cast( |
| 651 env->Global()->Get(env.local(), v8_str("a")).ToLocalChecked()); |
| 597 v8::ScriptCompiler::Source script_source( | 652 v8::ScriptCompiler::Source script_source( |
| 598 v8_str("result = /* y + */ x + b // + z")); | 653 v8_str("result = /* y + */ x + b // + z")); |
| 599 v8::Local<v8::String> arg = v8_str("b"); | 654 v8::Local<v8::String> arg = v8_str("b"); |
| 600 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 655 v8::Local<v8::Function> fun = |
| 601 CcTest::isolate(), &script_source, env.local(), 1, &arg, 1, ext); | 656 v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, |
| 657 1, &arg, 1, ext) |
| 658 .ToLocalChecked(); |
| 602 CHECK(!fun.IsEmpty()); | 659 CHECK(!fun.IsEmpty()); |
| 603 v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); | 660 v8::Local<v8::Value> b_value = v8::Number::New(CcTest::isolate(), 42.0); |
| 604 fun->Call(env->Global(), 1, &b_value); | 661 fun->Call(env.local(), env->Global(), 1, &b_value).ToLocalChecked(); |
| 605 CHECK(env->Global()->Has(v8_str("result"))); | 662 CHECK(env->Global()->Has(env.local(), v8_str("result")).FromJust()); |
| 606 v8::Local<v8::Value> result = env->Global()->Get(v8_str("result")); | 663 v8::Local<v8::Value> result = |
| 664 env->Global()->Get(env.local(), v8_str("result")).ToLocalChecked(); |
| 607 CHECK(result->IsNumber()); | 665 CHECK(result->IsNumber()); |
| 608 CHECK_EQ(65.0, result->NumberValue()); | 666 CHECK_EQ(65.0, result->NumberValue(env.local()).FromJust()); |
| 609 } | 667 } |
| 610 | 668 |
| 611 | 669 |
| 612 TEST(CompileFunctionInContextNonIdentifierArgs) { | 670 TEST(CompileFunctionInContextNonIdentifierArgs) { |
| 613 CcTest::InitializeVM(); | 671 CcTest::InitializeVM(); |
| 614 v8::HandleScope scope(CcTest::isolate()); | 672 v8::HandleScope scope(CcTest::isolate()); |
| 615 LocalContext env; | 673 LocalContext env; |
| 616 v8::ScriptCompiler::Source script_source(v8_str("result = 1")); | 674 v8::ScriptCompiler::Source script_source(v8_str("result = 1")); |
| 617 v8::Local<v8::String> arg = v8_str("b }"); | 675 v8::Local<v8::String> arg = v8_str("b }"); |
| 618 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 676 CHECK(v8::ScriptCompiler::CompileFunctionInContext( |
| 619 CcTest::isolate(), &script_source, env.local(), 1, &arg, 0, NULL); | 677 env.local(), &script_source, 1, &arg, 0, NULL) |
| 620 CHECK(fun.IsEmpty()); | 678 .IsEmpty()); |
| 621 } | 679 } |
| 622 | 680 |
| 623 | 681 |
| 624 TEST(CompileFunctionInContextScriptOrigin) { | 682 TEST(CompileFunctionInContextScriptOrigin) { |
| 625 CcTest::InitializeVM(); | 683 CcTest::InitializeVM(); |
| 626 v8::HandleScope scope(CcTest::isolate()); | 684 v8::HandleScope scope(CcTest::isolate()); |
| 627 LocalContext env; | 685 LocalContext env; |
| 628 v8::ScriptOrigin origin(v8_str("test"), | 686 v8::ScriptOrigin origin(v8_str("test"), |
| 629 v8::Integer::New(CcTest::isolate(), 22), | 687 v8::Integer::New(CcTest::isolate(), 22), |
| 630 v8::Integer::New(CcTest::isolate(), 41)); | 688 v8::Integer::New(CcTest::isolate(), 41)); |
| 631 v8::ScriptCompiler::Source script_source(v8_str("throw new Error()"), origin); | 689 v8::ScriptCompiler::Source script_source(v8_str("throw new Error()"), origin); |
| 632 v8::Local<v8::Function> fun = v8::ScriptCompiler::CompileFunctionInContext( | 690 v8::Local<v8::Function> fun = |
| 633 CcTest::isolate(), &script_source, env.local(), 0, NULL, 0, NULL); | 691 v8::ScriptCompiler::CompileFunctionInContext(env.local(), &script_source, |
| 692 0, NULL, 0, NULL) |
| 693 .ToLocalChecked(); |
| 634 CHECK(!fun.IsEmpty()); | 694 CHECK(!fun.IsEmpty()); |
| 635 v8::TryCatch try_catch; | 695 v8::TryCatch try_catch(CcTest::isolate()); |
| 636 CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true); | 696 CcTest::isolate()->SetCaptureStackTraceForUncaughtExceptions(true); |
| 637 fun->Call(env->Global(), 0, NULL); | 697 CHECK(fun->Call(env.local(), env->Global(), 0, NULL).IsEmpty()); |
| 638 CHECK(try_catch.HasCaught()); | 698 CHECK(try_catch.HasCaught()); |
| 639 CHECK(!try_catch.Exception().IsEmpty()); | 699 CHECK(!try_catch.Exception().IsEmpty()); |
| 640 v8::Local<v8::StackTrace> stack = | 700 v8::Local<v8::StackTrace> stack = |
| 641 v8::Exception::GetStackTrace(try_catch.Exception()); | 701 v8::Exception::GetStackTrace(try_catch.Exception()); |
| 642 CHECK(!stack.IsEmpty()); | 702 CHECK(!stack.IsEmpty()); |
| 643 CHECK(stack->GetFrameCount() > 0); | 703 CHECK(stack->GetFrameCount() > 0); |
| 644 v8::Local<v8::StackFrame> frame = stack->GetFrame(0); | 704 v8::Local<v8::StackFrame> frame = stack->GetFrame(0); |
| 645 CHECK_EQ(23, frame->GetLineNumber()); | 705 CHECK_EQ(23, frame->GetLineNumber()); |
| 646 CHECK_EQ(42 + strlen("throw "), static_cast<unsigned>(frame->GetColumn())); | 706 CHECK_EQ(42 + strlen("throw "), static_cast<unsigned>(frame->GetColumn())); |
| 647 } | 707 } |
| 648 | 708 |
| 649 | 709 |
| 650 #ifdef ENABLE_DISASSEMBLER | 710 #ifdef ENABLE_DISASSEMBLER |
| 651 static Handle<JSFunction> GetJSFunction(v8::Handle<v8::Object> obj, | 711 static Handle<JSFunction> GetJSFunction(v8::Local<v8::Object> obj, |
| 652 const char* property_name) { | 712 const char* property_name) { |
| 653 v8::Local<v8::Function> fun = | 713 v8::Local<v8::Function> fun = v8::Local<v8::Function>::Cast( |
| 654 v8::Local<v8::Function>::Cast(obj->Get(v8_str(property_name))); | 714 obj->Get(CcTest::isolate()->GetCurrentContext(), v8_str(property_name)) |
| 715 .ToLocalChecked()); |
| 655 return Handle<JSFunction>::cast(v8::Utils::OpenHandle(*fun)); | 716 return Handle<JSFunction>::cast(v8::Utils::OpenHandle(*fun)); |
| 656 } | 717 } |
| 657 | 718 |
| 658 | 719 |
| 659 static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) { | 720 static void CheckCodeForUnsafeLiteral(Handle<JSFunction> f) { |
| 660 // Create a disassembler with default name lookup. | 721 // Create a disassembler with default name lookup. |
| 661 disasm::NameConverter name_converter; | 722 disasm::NameConverter name_converter; |
| 662 disasm::Disassembler d(name_converter); | 723 disasm::Disassembler d(name_converter); |
| 663 | 724 |
| 664 if (f->code()->kind() == Code::FUNCTION) { | 725 if (f->code()->kind() == Code::FUNCTION) { |
| (...skipping 30 matching lines...) Expand all Loading... |
| 695 CompileRun("function f() { a = 12345678 }; f();"); | 756 CompileRun("function f() { a = 12345678 }; f();"); |
| 696 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); | 757 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); |
| 697 CompileRun("function f(x) { a = 12345678 + x}; f(1);"); | 758 CompileRun("function f(x) { a = 12345678 + x}; f(1);"); |
| 698 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); | 759 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); |
| 699 CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);"); | 760 CompileRun("function f(x) { var arguments = 1; x += 12345678}; f(1);"); |
| 700 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); | 761 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); |
| 701 CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);"); | 762 CompileRun("function f(x) { var arguments = 1; x = 12345678}; f(1);"); |
| 702 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); | 763 CheckCodeForUnsafeLiteral(GetJSFunction(context->Global(), "f")); |
| 703 } | 764 } |
| 704 #endif | 765 #endif |
| OLD | NEW |