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 3199 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3210 // TODO(sigurds) Figure out if is_used should survive context serialization. | 3210 // TODO(sigurds) Figure out if is_used should survive context serialization. |
3211 } | 3211 } |
3212 | 3212 |
3213 | 3213 |
3214 TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) { | 3214 TEST(IfArgumentsArrayAccessedThenParametersMaybeAssigned) { |
3215 i::Isolate* isolate = CcTest::i_isolate(); | 3215 i::Isolate* isolate = CcTest::i_isolate(); |
3216 i::Factory* factory = isolate->factory(); | 3216 i::Factory* factory = isolate->factory(); |
3217 i::HandleScope scope(isolate); | 3217 i::HandleScope scope(isolate); |
3218 LocalContext env; | 3218 LocalContext env; |
3219 | 3219 |
3220 | |
3221 const char* src = | 3220 const char* src = |
3222 "function f(x) {" | 3221 "function f(x) {" |
3223 " var a = arguments;" | 3222 " var a = arguments;" |
3224 " function g(i) {" | 3223 " function g(i) {" |
3225 " ++a[0];" | 3224 " ++a[0];" |
3226 " };" | 3225 " };" |
3227 " return g;" | 3226 " return g;" |
3228 " }" | 3227 " }" |
3229 "f(0);"; | 3228 "f(0);"; |
3230 | 3229 |
3231 i::ScopedVector<char> program(Utf8LengthHelper(src) + 1); | 3230 i::ScopedVector<char> program(Utf8LengthHelper(src) + 1); |
3232 i::SNPrintF(program, "%s", src); | 3231 i::SNPrintF(program, "%s", src); |
3233 i::Handle<i::String> source = factory->InternalizeUtf8String(program.start()); | 3232 i::Handle<i::String> source = factory->InternalizeUtf8String(program.start()); |
3234 source->PrintOn(stdout); | 3233 source->PrintOn(stdout); |
3235 printf("\n"); | 3234 printf("\n"); |
3236 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 3235 i::Zone zone(isolate->allocator(), ZONE_NAME); |
3237 v8::Local<v8::Value> v = CompileRun(src); | 3236 v8::Local<v8::Value> v = CompileRun(src); |
3238 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); | 3237 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); |
3239 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); | 3238 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); |
3240 i::Context* context = f->context(); | 3239 i::Context* context = f->context(); |
3241 i::AstValueFactory avf(&zone, isolate->heap()->HashSeed()); | 3240 i::AstValueFactory avf(&zone, isolate->heap()->HashSeed()); |
3242 const i::AstRawString* name_x = avf.GetOneByteString("x"); | 3241 const i::AstRawString* name_x = avf.GetOneByteString("x"); |
3243 avf.Internalize(isolate); | 3242 avf.Internalize(isolate); |
3244 | 3243 |
3245 i::DeclarationScope* script_scope = | 3244 i::DeclarationScope* script_scope = |
3246 new (&zone) i::DeclarationScope(&zone, &avf); | 3245 new (&zone) i::DeclarationScope(&zone, &avf); |
(...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3355 if (outers[i].strict && inners[j].with) continue; | 3354 if (outers[i].strict && inners[j].with) continue; |
3356 const char* inner = inners[j].source; | 3355 const char* inner = inners[j].source; |
3357 int inner_len = Utf8LengthHelper(inner); | 3356 int inner_len = Utf8LengthHelper(inner); |
3358 | 3357 |
3359 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len; | 3358 int len = prefix_len + outer_len + midfix_len + inner_len + suffix_len; |
3360 i::ScopedVector<char> program(len + 1); | 3359 i::ScopedVector<char> program(len + 1); |
3361 | 3360 |
3362 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, | 3361 i::SNPrintF(program, "%s%s%s%s%s", prefix, outer, midfix, inner, |
3363 suffix); | 3362 suffix); |
3364 | 3363 |
3365 i::Zone zone(CcTest::i_isolate()->allocator(), ZONE_NAME); | 3364 i::Zone zone(isolate->allocator(), ZONE_NAME); |
3366 std::unique_ptr<i::ParseInfo> info; | 3365 std::unique_ptr<i::ParseInfo> info; |
3367 if (lazy) { | 3366 if (lazy) { |
3368 printf("%s\n", program.start()); | 3367 printf("%s\n", program.start()); |
3369 v8::Local<v8::Value> v = CompileRun(program.start()); | 3368 v8::Local<v8::Value> v = CompileRun(program.start()); |
3370 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); | 3369 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); |
3371 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); | 3370 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); |
3372 i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared()); | 3371 i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared()); |
3373 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared)); | 3372 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared)); |
3374 } else { | 3373 } else { |
3375 i::Handle<i::String> source = | 3374 i::Handle<i::String> source = |
(...skipping 29 matching lines...) Expand all Loading... |
3405 } else { | 3404 } else { |
3406 CHECK(is_maybe_assigned == expected); | 3405 CHECK(is_maybe_assigned == expected); |
3407 } | 3406 } |
3408 } | 3407 } |
3409 } | 3408 } |
3410 } | 3409 } |
3411 } | 3410 } |
3412 | 3411 |
3413 namespace { | 3412 namespace { |
3414 | 3413 |
| 3414 i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone, |
| 3415 i::Handle<i::JSObject> m, const char* name) { |
| 3416 i::AstValueFactory avf(zone, isolate->heap()->HashSeed()); |
| 3417 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast( |
| 3418 i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked()); |
| 3419 i::DeclarationScope* script_scope = |
| 3420 new (zone) i::DeclarationScope(zone, &avf); |
| 3421 i::Scope* s = i::Scope::DeserializeScopeChain( |
| 3422 isolate, zone, f->context()->scope_info(), script_scope, &avf, |
| 3423 i::Scope::DeserializationMode::kIncludingVariables); |
| 3424 return s; |
| 3425 } |
| 3426 |
| 3427 } // namespace |
| 3428 |
| 3429 TEST(AsmModuleFlag) { |
| 3430 i::Isolate* isolate = CcTest::i_isolate(); |
| 3431 i::HandleScope scope(isolate); |
| 3432 LocalContext env; |
| 3433 |
| 3434 const char* src = |
| 3435 "function m() {" |
| 3436 " 'use asm';" |
| 3437 " var x = 0;" |
| 3438 " function f() { return x };" |
| 3439 " return { f:f };" |
| 3440 "}" |
| 3441 "m();"; |
| 3442 |
| 3443 i::Zone zone(isolate->allocator(), ZONE_NAME); |
| 3444 v8::Local<v8::Value> v = CompileRun(src); |
| 3445 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); |
| 3446 i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o); |
| 3447 |
| 3448 // The asm.js module should be marked as such. |
| 3449 i::Scope* s = DeserializeFunctionScope(isolate, &zone, m, "f"); |
| 3450 CHECK(s->IsAsmModule() && s->AsDeclarationScope()->asm_module()); |
| 3451 CHECK(!s->IsAsmFunction() && !s->AsDeclarationScope()->asm_function()); |
| 3452 } |
| 3453 |
| 3454 TEST(AsmFunctionFlag) { |
| 3455 i::Isolate* isolate = CcTest::i_isolate(); |
| 3456 i::HandleScope scope(isolate); |
| 3457 LocalContext env; |
| 3458 |
| 3459 const char* src = |
| 3460 "function m() {" |
| 3461 " 'use asm';" |
| 3462 " var x = 0;" |
| 3463 " function f1(a) {" |
| 3464 " var y = 0; return () => x + y;" |
| 3465 " };" |
| 3466 " do { function f2() {" |
| 3467 " var y = 0; return () => x + y;" |
| 3468 " } } while(false);" |
| 3469 " var f3 = (function() {" |
| 3470 " var y = 0; return () => x + y;" |
| 3471 " });" |
| 3472 " var f4 = (function() { return (function() {" |
| 3473 " var y = 0; return () => x + y;" |
| 3474 " }) })();" |
| 3475 " return { f1:f1(), f2:f2(), f3:f3(), f4:f4() };" |
| 3476 "}" |
| 3477 "m();"; |
| 3478 |
| 3479 i::Zone zone(isolate->allocator(), ZONE_NAME); |
| 3480 v8::Local<v8::Value> v = CompileRun(src); |
| 3481 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); |
| 3482 i::Handle<i::JSObject> m = i::Handle<i::JSObject>::cast(o); |
| 3483 |
| 3484 // The asm.js function {f1} should be marked as such. |
| 3485 i::Scope* s1 = DeserializeFunctionScope(isolate, &zone, m, "f1"); |
| 3486 CHECK(!s1->IsAsmModule() && !s1->AsDeclarationScope()->asm_module()); |
| 3487 CHECK(s1->IsAsmFunction() && s1->AsDeclarationScope()->asm_function()); |
| 3488 |
| 3489 // The asm.js function {f2} should be marked as such. |
| 3490 // TODO(5653): If the block surrounding {f2} where to allocate a context we |
| 3491 // would actually determine {f2} not to be an asm.js function. That decision |
| 3492 // is fine but we should be consistent independent of whether a context is |
| 3493 // allocated for the surrounding block scope! |
| 3494 i::Scope* s2 = DeserializeFunctionScope(isolate, &zone, m, "f2"); |
| 3495 CHECK(!s2->IsAsmModule() && !s2->AsDeclarationScope()->asm_module()); |
| 3496 CHECK(s2->IsAsmFunction() && s2->AsDeclarationScope()->asm_function()); |
| 3497 |
| 3498 // The asm.js function {f3} should be marked as such. |
| 3499 i::Scope* s3 = DeserializeFunctionScope(isolate, &zone, m, "f3"); |
| 3500 CHECK(!s3->IsAsmModule() && !s3->AsDeclarationScope()->asm_module()); |
| 3501 CHECK(s3->IsAsmFunction() && s3->AsDeclarationScope()->asm_function()); |
| 3502 |
| 3503 // The nested function {f4} is not an asm.js function. |
| 3504 i::Scope* s4 = DeserializeFunctionScope(isolate, &zone, m, "f4"); |
| 3505 CHECK(!s4->IsAsmModule() && !s4->AsDeclarationScope()->asm_module()); |
| 3506 CHECK(!s4->IsAsmFunction() && !s4->AsDeclarationScope()->asm_function()); |
| 3507 } |
| 3508 |
| 3509 namespace { |
| 3510 |
3415 int* global_use_counts = NULL; | 3511 int* global_use_counts = NULL; |
3416 | 3512 |
3417 void MockUseCounterCallback(v8::Isolate* isolate, | 3513 void MockUseCounterCallback(v8::Isolate* isolate, |
3418 v8::Isolate::UseCounterFeature feature) { | 3514 v8::Isolate::UseCounterFeature feature) { |
3419 ++global_use_counts[feature]; | 3515 ++global_use_counts[feature]; |
3420 } | 3516 } |
3421 | 3517 |
3422 } | 3518 } // namespace |
3423 | |
3424 | 3519 |
3425 TEST(UseAsmUseCount) { | 3520 TEST(UseAsmUseCount) { |
3426 i::Isolate* isolate = CcTest::i_isolate(); | 3521 i::Isolate* isolate = CcTest::i_isolate(); |
3427 i::HandleScope scope(isolate); | 3522 i::HandleScope scope(isolate); |
3428 LocalContext env; | 3523 LocalContext env; |
3429 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; | 3524 int use_counts[v8::Isolate::kUseCounterFeatureCount] = {}; |
3430 global_use_counts = use_counts; | 3525 global_use_counts = use_counts; |
3431 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); | 3526 CcTest::isolate()->SetUseCounterCallback(MockUseCounterCallback); |
3432 CompileRun("\"use asm\";\n" | 3527 CompileRun("\"use asm\";\n" |
3433 "var foo = 1;\n" | 3528 "var foo = 1;\n" |
(...skipping 4871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8305 const char* data[] = { | 8400 const char* data[] = { |
8306 "const arguments = 1", | 8401 "const arguments = 1", |
8307 "let arguments", | 8402 "let arguments", |
8308 "var arguments", | 8403 "var arguments", |
8309 NULL | 8404 NULL |
8310 }; | 8405 }; |
8311 // clang-format on | 8406 // clang-format on |
8312 RunParserSyncTest(context_data, data, kSuccess); | 8407 RunParserSyncTest(context_data, data, kSuccess); |
8313 } | 8408 } |
8314 } | 8409 } |
OLD | NEW |