Chromium Code Reviews| 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...) Expand 10 before | Expand all | Expand 10 after 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) {})"}, | |
|
marja
2016/12/15 13:35:29
Routing offline discussion here: The two cases you
| |
| 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})"}, | |
|
gsathya
2016/12/15 14:05:31
isn't this same as the previous one?
| |
| 3450 {false, "(function f(arg=1) {})"}, | |
| 3451 {false, "(function f(arg=1) {g(arg)})"}, | |
| 3452 {false, | |
| 3453 "(function f(arg, arguments) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3454 {false, | |
| 3455 "(function f(arg, ...arguments) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3456 {false, | |
| 3457 "(function f(arg, arguments=[]) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3458 | |
| 3459 // strict arguments object | |
| 3460 {false, "(function f(arg, x=1) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3461 {false, "(function f(arg, ...x) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3462 {false, "(function f(arg=1) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3463 {false, | |
| 3464 "(function f(arg) {'use strict'; g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3465 {false, "(function f(arg) {g(arg); f.arguments[0] = 42; g(arg)})"}, | |
| 3466 {false, | |
| 3467 "(function f(arg, args=arguments) {g(arg); args[0] = 42; g(arg)})"}, | |
| 3468 | |
| 3469 {true, "(function f(arg) {g(arg); arg = 42; g(arg)})"}, | |
| 3470 {true, "(function f(arg) {g(arg); eval('arg = 42'); g(arg)})"}, | |
| 3471 {true, "(function f(arg) {g(arg); var arg = 42; g(arg)})"}, | |
| 3472 {true, "(function f(arg, x=1) {g(arg); arg = 42; g(arg)})"}, | |
| 3473 {true, "(function f(arg, ...x) {g(arg); arg = 42; g(arg)})"}, | |
| 3474 {true, "(function f(arg=1) {g(arg); arg = 42; g(arg)})"}, | |
| 3475 {true, "(function f(arg) {'use strict'; g(arg); arg = 42; g(arg)})"}, | |
| 3476 {true, "(function f(arg, {a=(g(arg), arg=42)}) {g(arg)})"}, | |
| 3477 | |
| 3478 // sloppy arguments object | |
| 3479 {true, "(function f(arg) {g(arg); arguments[0] = 42; g(arg)})"}, | |
| 3480 {true, "(function f(arg) {g(arg); h(arguments); g(arg)})"}, | |
| 3481 {true, | |
| 3482 "(function f(arg) {((args) => {arguments[0] = 42})(arguments); " | |
| 3483 "g(arg)})"}, | |
| 3484 {true, "(function f(arg) {g(arg); eval('arguments[0] = 42'); g(arg)})"}, | |
|
marja
2016/12/15 13:09:54
Can you add a test where arg is the rest parameter
| |
| 3485 }; | |
| 3486 | |
| 3487 for (unsigned i = 0; i < arraysize(tests); ++i) { | |
| 3488 bool assigned = tests[i].arg_assigned; | |
| 3489 const char* source = tests[i].source; | |
| 3490 int length = Utf8LengthHelper(source); | |
| 3491 for (unsigned lazy = 0; lazy < 2; ++lazy) { | |
| 3492 i::ScopedVector<char> program(length + 1); | |
| 3493 i::SNPrintF(program, "%s", source); | |
| 3494 i::Zone zone(isolate->allocator(), ZONE_NAME); | |
| 3495 std::unique_ptr<i::ParseInfo> info; | |
| 3496 if (lazy) { | |
| 3497 printf("%s\n", program.start()); | |
| 3498 v8::Local<v8::Value> v = CompileRun(program.start()); | |
| 3499 i::Handle<i::Object> o = v8::Utils::OpenHandle(*v); | |
| 3500 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast(o); | |
| 3501 i::Handle<i::SharedFunctionInfo> shared = i::handle(f->shared()); | |
| 3502 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, shared)); | |
| 3503 CHECK(i::parsing::ParseFunction(info.get())); | |
| 3504 } else { | |
| 3505 i::Handle<i::String> source = | |
| 3506 factory->InternalizeUtf8String(program.start()); | |
| 3507 source->PrintOn(stdout); | |
| 3508 printf("\n"); | |
| 3509 i::Handle<i::Script> script = factory->NewScript(source); | |
| 3510 info = std::unique_ptr<i::ParseInfo>(new i::ParseInfo(&zone, script)); | |
| 3511 info->set_allow_lazy_parsing(false); | |
| 3512 CHECK(i::parsing::ParseProgram(info.get())); | |
| 3513 } | |
| 3514 CHECK(i::Compiler::Analyze(info.get())); | |
| 3515 CHECK_NOT_NULL(info->literal()); | |
| 3516 | |
| 3517 i::Scope* scope = info->literal()->scope(); | |
| 3518 if (!lazy) { | |
| 3519 scope = scope->inner_scope(); | |
| 3520 } | |
| 3521 CHECK_NULL(scope->sibling()); | |
| 3522 CHECK(scope->is_function_scope()); | |
| 3523 const i::AstRawString* var_name = | |
| 3524 info->ast_value_factory()->GetOneByteString("arg"); | |
| 3525 i::Variable* var = scope->Lookup(var_name); | |
| 3526 CHECK(var->is_used() || !assigned); | |
| 3527 bool is_maybe_assigned = var->maybe_assigned() == i::kMaybeAssigned; | |
| 3528 CHECK_EQ(is_maybe_assigned, assigned); | |
| 3529 } | |
| 3530 } | |
| 3531 } | |
| 3532 | |
| 3435 namespace { | 3533 namespace { |
| 3436 | 3534 |
| 3437 i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone, | 3535 i::Scope* DeserializeFunctionScope(i::Isolate* isolate, i::Zone* zone, |
| 3438 i::Handle<i::JSObject> m, const char* name) { | 3536 i::Handle<i::JSObject> m, const char* name) { |
| 3439 i::AstValueFactory avf(zone, isolate->heap()->HashSeed()); | 3537 i::AstValueFactory avf(zone, isolate->heap()->HashSeed()); |
| 3440 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast( | 3538 i::Handle<i::JSFunction> f = i::Handle<i::JSFunction>::cast( |
| 3441 i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked()); | 3539 i::JSReceiver::GetProperty(isolate, m, name).ToHandleChecked()); |
| 3442 i::DeclarationScope* script_scope = | 3540 i::DeclarationScope* script_scope = |
| 3443 new (zone) i::DeclarationScope(zone, &avf); | 3541 new (zone) i::DeclarationScope(zone, &avf); |
| 3444 i::Scope* s = i::Scope::DeserializeScopeChain( | 3542 i::Scope* s = i::Scope::DeserializeScopeChain( |
| (...skipping 5161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 8606 DCHECK_NOT_NULL(scope); | 8704 DCHECK_NOT_NULL(scope); |
| 8607 DCHECK_NULL(scope->sibling()); | 8705 DCHECK_NULL(scope->sibling()); |
| 8608 DCHECK(scope->is_function_scope()); | 8706 DCHECK(scope->is_function_scope()); |
| 8609 const i::AstRawString* var_name = | 8707 const i::AstRawString* var_name = |
| 8610 info.ast_value_factory()->GetOneByteString("my_var"); | 8708 info.ast_value_factory()->GetOneByteString("my_var"); |
| 8611 i::Variable* var = scope->Lookup(var_name); | 8709 i::Variable* var = scope->Lookup(var_name); |
| 8612 CHECK_EQ(inners[i].ctxt_allocate, | 8710 CHECK_EQ(inners[i].ctxt_allocate, |
| 8613 i::ScopeTestHelper::MustAllocateInContext(var)); | 8711 i::ScopeTestHelper::MustAllocateInContext(var)); |
| 8614 } | 8712 } |
| 8615 } | 8713 } |
| OLD | NEW |