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 3414 matching lines...) Loading... | |
3425 CHECK(is_maybe_assigned == expected || | 3425 CHECK(is_maybe_assigned == expected || |
3426 (is_maybe_assigned && inners[j].allow_error_in_inner_function)); | 3426 (is_maybe_assigned && inners[j].allow_error_in_inner_function)); |
3427 } else { | 3427 } else { |
3428 CHECK_EQ(is_maybe_assigned, expected); | 3428 CHECK_EQ(is_maybe_assigned, expected); |
3429 } | 3429 } |
3430 } | 3430 } |
3431 } | 3431 } |
3432 } | 3432 } |
3433 } | 3433 } |
3434 | 3434 |
3435 TEST(MaybeAssignedParameters) { | |
3436 i::Isolate* isolate = CcTest::i_isolate(); | |
3437 i::Factory* factory = isolate->factory(); | |
3438 i::HandleScope scope(isolate); | |
3439 LocalContext env; | |
3440 | |
3441 struct { | |
3442 bool arg_assigned; | |
3443 const char* source; | |
3444 } tests[] = { | |
3445 {false, "(function f(arg) {})"}, | |
3446 {false, "(function f(arg) {g(arg)})"}, | |
3447 {false, "(function f(arg) {function h() { g(arg) }; h()})"}, | |
3448 {false, "(function f(arg) {function h() { g(arg) }; return h})"}, | |
3449 {false, "(function f(arg) {function h() { g(arg) }; return h})"}, | |
3450 {false, "(function f(arg=1) {})"}, | |
3451 {false, "(function f(arg=1) {g(arg)})"}, | |
adamk
2016/12/15 11:58:36
Can you add a few tests with an argument called "a
| |
3452 | |
3453 // strict arguments object | |
3454 {false, "(function f(arg, x=1) {g(arg); arguments[0] = 42; g(arg)})"}, | |
3455 {false, "(function f(arg, ...x) {g(arg); arguments[0] = 42; g(arg)})"}, | |
3456 {false, "(function f(arg=1) {g(arg); arguments[0] = 42; g(arg)})"}, | |
3457 {false, | |
3458 "(function f(arg) {'use strict'; g(arg); arguments[0] = 42; g(arg)})"}, | |
3459 {false, "(function f(arg) {g(arg); f.arguments[0] = 42; g(arg)})"}, | |
3460 | |
3461 {true, "(function f(arg) {g(arg); arg = 42; g(arg)})"}, | |
3462 {true, "(function f(arg) {g(arg); eval('arg = 42'); g(arg)})"}, | |
3463 {true, "(function f(arg) {g(arg); var arg = 42; g(arg)})"}, | |
3464 {true, "(function f(arg, x=1) {g(arg); arg = 42; g(arg)})"}, | |
3465 {true, "(function f(arg, ...x) {g(arg); arg = 42; g(arg)})"}, | |
3466 {true, "(function f(arg=1) {g(arg); arg = 42; g(arg)})"}, | |
3467 {true, "(function f(arg) {'use strict'; g(arg); arg = 42; g(arg)})"}, | |
3468 {true, "(function f(arg, {a=(g(arg), arg=42)}) {g(arg)})"}, | |
3469 | |
3470 // sloppy arguments object | |
3471 {true, "(function f(arg) {g(arg); arguments[0] = 42; g(arg)})"}, | |
3472 {true, "(function f(arg) {g(arg); h(arguments); g(arg)})"}, | |
3473 {true, | |
3474 "(function f(arg) {((args) => {arguments[0] = 42})(arguments); " | |
3475 "g(arg)})"}, | |
3476 {true, "(function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)})"}, | |
3477 }; | |
3478 | |
3479 for (unsigned i = 0; i < arraysize(tests); ++i) { | |
3480 bool assigned = tests[i].arg_assigned; | |
3481 const char* source = tests[i].source; | |
3482 int length = Utf8LengthHelper(source); | |
3483 for (unsigned lazy = 0; lazy < 2; ++lazy) { | |
3484 i::ScopedVector<char> program(length + 1); | |
3485 i::SNPrintF(program, "%s", source); | |
3486 i::Zone zone(isolate->allocator(), ZONE_NAME); | |
3487 std::unique_ptr<i::ParseInfo> info; | |
3488 if (lazy) { | |
3489 printf("%s\n", program.start()); | |
3490 v8::Local<v8::Value> v = CompileRun(program.start()); | |
3491 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); | |
3492 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); | |
3493 i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared()); | |
3494 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared)); | |
3495 DCHECK(i::parsing::ParseFunction(info.get())); | |
3496 } else { | |
3497 i::Handle<i::String> source = | |
3498 factory->InternalizeUtf8String(program.start()); | |
3499 source->PrintOn(stdout); | |
3500 printf("\n"); | |
3501 i::Handle<i::Script> script = factory->NewScript(source); | |
3502 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, script)); | |
3503 info->set_allow_lazy_parsing(false); | |
3504 DCHECK(i::parsing::ParseProgram(info.get())); | |
3505 } | |
3506 DCHECK(i::Compiler::Analyze(info.get())); | |
3507 DCHECK_NOT_NULL(info->literal()); | |
3508 | |
3509 i::Scope* scope = info->literal()->scope(); | |
3510 if (!lazy) { | |
3511 scope = scope->inner_scope(); | |
3512 } | |
3513 DCHECK_NULL(scope->sibling()); | |
3514 DCHECK(scope->is_function_scope()); | |
3515 const i::AstRawString* var_name = | |
3516 info->ast_value_factory()->GetOneByteString("arg"); | |
3517 i::Variable* var = scope->Lookup(var_name); | |
3518 DCHECK(var->is_used() || !assigned); | |
3519 bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned; | |
3520 CHECK_EQ(is_maybe_assigned, assigned); | |
3521 } | |
3522 } | |
3523 } | |
3524 | |
3435 namespace { | 3525 namespace { |
3436 | 3526 |
3437 i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone, | 3527 i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone, |
3438 i::Handle<i::JSObject> m, const char* name) { | 3528 i::Handle<i::JSObject> m, const char* name) { |
3439 i::AstValueFactory avf(zone, isolate->heap()->HashSeed()); | 3529 i::AstValueFactory avf(zone, isolate->heap()->HashSeed()); |
3440 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast( | 3530 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast( |
3441 i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked()); | 3531 i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked()); |
3442 i::DeclarationScope* script_scope = | 3532 i::DeclarationScope* script_scope = |
3443 new (zone) i::DeclarationScope(zone, &avf); | 3533 new (zone) i::DeclarationScope(zone, &avf); |
3444 i::Scope* s = i::Scope::DeserializeScopeChain( | 3534 i::Scope* s = i::Scope::DeserializeScopeChain( |
(...skipping 5116 matching lines...) Loading... | |
8561 DCHECK_NOT_NULL(scope); | 8651 DCHECK_NOT_NULL(scope); |
8562 DCHECK_NULL(scope->sibling()); | 8652 DCHECK_NULL(scope->sibling()); |
8563 DCHECK(scope->is_function_scope()); | 8653 DCHECK(scope->is_function_scope()); |
8564 const i::AstRawString* var_name = | 8654 const i::AstRawString* var_name = |
8565 info.ast_value_factory()->GetOneByteString("my_var"); | 8655 info.ast_value_factory()->GetOneByteString("my_var"); |
8566 i::Variable* var = scope->Lookup(var_name); | 8656 i::Variable* var = scope->Lookup(var_name); |
8567 CHECK_EQ(inners[i].ctxt_allocate, | 8657 CHECK_EQ(inners[i].ctxt_allocate, |
8568 i::ScopeTestHelper::MustAllocateInContext(var)); | 8658 i::ScopeTestHelper::MustAllocateInContext(var)); |
8569 } | 8659 } |
8570 } | 8660 } |
OLD | NEW |