| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/interpreter/bytecode-generator.h" | 5 #include "src/interpreter/bytecode-generator.h" |
| 6 | 6 |
| 7 #include "src/ast/compile-time-value.h" | 7 #include "src/ast/compile-time-value.h" |
| 8 #include "src/ast/scopes.h" | 8 #include "src/ast/scopes.h" |
| 9 #include "src/code-stubs.h" | 9 #include "src/code-stubs.h" |
| 10 #include "src/compilation-info.h" | 10 #include "src/compilation-info.h" |
| (...skipping 2309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2320 } | 2320 } |
| 2321 case NAMED_SUPER_PROPERTY: | 2321 case NAMED_SUPER_PROPERTY: |
| 2322 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); | 2322 VisitNamedSuperPropertyLoad(expr, Register::invalid_value()); |
| 2323 break; | 2323 break; |
| 2324 case KEYED_SUPER_PROPERTY: | 2324 case KEYED_SUPER_PROPERTY: |
| 2325 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); | 2325 VisitKeyedSuperPropertyLoad(expr, Register::invalid_value()); |
| 2326 break; | 2326 break; |
| 2327 } | 2327 } |
| 2328 } | 2328 } |
| 2329 | 2329 |
| 2330 void BytecodeGenerator::VisitPropertyLoadForAccumulator(Register obj, | 2330 void BytecodeGenerator::VisitPropertyLoadForRegister(Register obj, |
| 2331 Property* expr) { | 2331 Property* expr, |
| 2332 Register destination) { |
| 2332 ValueResultScope result_scope(this); | 2333 ValueResultScope result_scope(this); |
| 2333 VisitPropertyLoad(obj, expr); | 2334 VisitPropertyLoad(obj, expr); |
| 2335 builder()->StoreAccumulatorInRegister(destination); |
| 2334 } | 2336 } |
| 2335 | 2337 |
| 2336 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, | 2338 void BytecodeGenerator::VisitNamedSuperPropertyLoad(Property* property, |
| 2337 Register opt_receiver_out) { | 2339 Register opt_receiver_out) { |
| 2338 RegisterAllocationScope register_scope(this); | 2340 RegisterAllocationScope register_scope(this); |
| 2339 SuperPropertyReference* super_property = | 2341 SuperPropertyReference* super_property = |
| 2340 property->obj()->AsSuperPropertyReference(); | 2342 property->obj()->AsSuperPropertyReference(); |
| 2341 RegisterList args = register_allocator()->NewRegisterList(3); | 2343 RegisterList args = register_allocator()->NewRegisterList(3); |
| 2342 VisitForRegisterValue(super_property->this_var(), args[0]); | 2344 VisitForRegisterValue(super_property->this_var(), args[0]); |
| 2343 VisitForRegisterValue(super_property->home_object(), args[1]); | 2345 VisitForRegisterValue(super_property->home_object(), args[1]); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 2372 if (property_kind != NAMED_SUPER_PROPERTY && | 2374 if (property_kind != NAMED_SUPER_PROPERTY && |
| 2373 property_kind != KEYED_SUPER_PROPERTY) { | 2375 property_kind != KEYED_SUPER_PROPERTY) { |
| 2374 Register obj = VisitForRegisterValue(expr->obj()); | 2376 Register obj = VisitForRegisterValue(expr->obj()); |
| 2375 VisitPropertyLoad(obj, expr); | 2377 VisitPropertyLoad(obj, expr); |
| 2376 } else { | 2378 } else { |
| 2377 VisitPropertyLoad(Register::invalid_value(), expr); | 2379 VisitPropertyLoad(Register::invalid_value(), expr); |
| 2378 } | 2380 } |
| 2379 } | 2381 } |
| 2380 | 2382 |
| 2381 void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args, | 2383 void BytecodeGenerator::VisitArguments(ZoneList<Expression*>* args, |
| 2382 RegisterList arg_regs, | 2384 RegisterList* arg_regs) { |
| 2383 size_t first_argument_register) { | |
| 2384 // Visit arguments. | 2385 // Visit arguments. |
| 2385 for (int i = 0; i < static_cast<int>(args->length()); i++) { | 2386 for (int i = 0; i < static_cast<int>(args->length()); i++) { |
| 2386 VisitForRegisterValue(args->at(i), arg_regs[first_argument_register + i]); | 2387 VisitAndPushIntoRegisterList(args->at(i), arg_regs); |
| 2387 } | 2388 } |
| 2388 } | 2389 } |
| 2389 | 2390 |
| 2390 void BytecodeGenerator::VisitCall(Call* expr) { | 2391 void BytecodeGenerator::VisitCall(Call* expr) { |
| 2391 Expression* callee_expr = expr->expression(); | 2392 Expression* callee_expr = expr->expression(); |
| 2392 Call::CallType call_type = expr->GetCallType(); | 2393 Call::CallType call_type = expr->GetCallType(); |
| 2393 | 2394 |
| 2394 if (call_type == Call::SUPER_CALL) { | 2395 if (call_type == Call::SUPER_CALL) { |
| 2395 return VisitCallSuper(expr); | 2396 return VisitCallSuper(expr); |
| 2396 } | 2397 } |
| 2397 | 2398 |
| 2398 Register callee = register_allocator()->NewRegister(); | 2399 Register callee = register_allocator()->NewRegister(); |
| 2399 | 2400 // Grow the args list as we visit receiver / arguments to avoid allocating all |
| 2400 // Add an argument register for the receiver. | 2401 // the registers up-front. Otherwise these registers are unavailable during |
| 2401 RegisterList args = | 2402 // receiver / argument visiting and we can end up with memory leaks due to |
| 2402 register_allocator()->NewRegisterList(expr->arguments()->length() + 1); | 2403 // registers keeping objects alive. |
| 2403 Register receiver = args[0]; | 2404 RegisterList args = register_allocator()->NewGrowableRegisterList(); |
| 2404 | 2405 |
| 2405 // Prepare the callee and the receiver to the function call. This depends on | 2406 // Prepare the callee and the receiver to the function call. This depends on |
| 2406 // the semantics of the underlying call type. | 2407 // the semantics of the underlying call type. |
| 2407 switch (call_type) { | 2408 switch (call_type) { |
| 2408 case Call::NAMED_PROPERTY_CALL: | 2409 case Call::NAMED_PROPERTY_CALL: |
| 2409 case Call::KEYED_PROPERTY_CALL: { | 2410 case Call::KEYED_PROPERTY_CALL: { |
| 2410 Property* property = callee_expr->AsProperty(); | 2411 Property* property = callee_expr->AsProperty(); |
| 2411 VisitForAccumulatorValue(property->obj()); | 2412 VisitAndPushIntoRegisterList(property->obj(), &args); |
| 2412 builder()->StoreAccumulatorInRegister(receiver); | 2413 VisitPropertyLoadForRegister(args[0], property, callee); |
| 2413 VisitPropertyLoadForAccumulator(receiver, property); | |
| 2414 builder()->StoreAccumulatorInRegister(callee); | |
| 2415 break; | 2414 break; |
| 2416 } | 2415 } |
| 2417 case Call::GLOBAL_CALL: { | 2416 case Call::GLOBAL_CALL: { |
| 2418 // Receiver is undefined for global calls. | 2417 // Receiver is undefined for global calls. |
| 2419 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2418 BuildPushUndefinedIntoRegisterList(&args); |
| 2420 // Load callee as a global variable. | 2419 // Load callee as a global variable. |
| 2421 VariableProxy* proxy = callee_expr->AsVariableProxy(); | 2420 VariableProxy* proxy = callee_expr->AsVariableProxy(); |
| 2422 BuildVariableLoadForAccumulatorValue(proxy->var(), | 2421 BuildVariableLoadForAccumulatorValue(proxy->var(), |
| 2423 proxy->VariableFeedbackSlot(), | 2422 proxy->VariableFeedbackSlot(), |
| 2424 proxy->hole_check_mode()); | 2423 proxy->hole_check_mode()); |
| 2425 builder()->StoreAccumulatorInRegister(callee); | 2424 builder()->StoreAccumulatorInRegister(callee); |
| 2426 break; | 2425 break; |
| 2427 } | 2426 } |
| 2428 case Call::WITH_CALL: { | 2427 case Call::WITH_CALL: { |
| 2428 Register receiver = register_allocator()->GrowRegisterList(&args); |
| 2429 DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot()); | 2429 DCHECK(callee_expr->AsVariableProxy()->var()->IsLookupSlot()); |
| 2430 RegisterAllocationScope inner_register_scope(this); | 2430 { |
| 2431 Register name = register_allocator()->NewRegister(); | 2431 RegisterAllocationScope inner_register_scope(this); |
| 2432 Register name = register_allocator()->NewRegister(); |
| 2432 | 2433 |
| 2433 // Call %LoadLookupSlotForCall to get the callee and receiver. | 2434 // Call %LoadLookupSlotForCall to get the callee and receiver. |
| 2434 DCHECK(Register::AreContiguous(callee, receiver)); | 2435 DCHECK(Register::AreContiguous(callee, receiver)); |
| 2435 RegisterList result_pair(callee.index(), 2); | 2436 RegisterList result_pair(callee.index(), 2); |
| 2436 Variable* variable = callee_expr->AsVariableProxy()->var(); | 2437 USE(receiver); |
| 2437 builder() | 2438 Variable* variable = callee_expr->AsVariableProxy()->var(); |
| 2438 ->LoadLiteral(variable->name()) | 2439 builder() |
| 2439 .StoreAccumulatorInRegister(name) | 2440 ->LoadLiteral(variable->name()) |
| 2440 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name, | 2441 .StoreAccumulatorInRegister(name) |
| 2441 result_pair); | 2442 .CallRuntimeForPair(Runtime::kLoadLookupSlotForCall, name, |
| 2443 result_pair); |
| 2444 } |
| 2442 break; | 2445 break; |
| 2443 } | 2446 } |
| 2444 case Call::OTHER_CALL: | 2447 case Call::OTHER_CALL: { |
| 2445 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | 2448 BuildPushUndefinedIntoRegisterList(&args); |
| 2446 VisitForRegisterValue(callee_expr, callee); | 2449 VisitForRegisterValue(callee_expr, callee); |
| 2447 break; | 2450 break; |
| 2451 } |
| 2448 case Call::NAMED_SUPER_PROPERTY_CALL: { | 2452 case Call::NAMED_SUPER_PROPERTY_CALL: { |
| 2453 Register receiver = register_allocator()->GrowRegisterList(&args); |
| 2449 Property* property = callee_expr->AsProperty(); | 2454 Property* property = callee_expr->AsProperty(); |
| 2450 VisitNamedSuperPropertyLoad(property, receiver); | 2455 VisitNamedSuperPropertyLoad(property, receiver); |
| 2451 builder()->StoreAccumulatorInRegister(callee); | 2456 builder()->StoreAccumulatorInRegister(callee); |
| 2452 break; | 2457 break; |
| 2453 } | 2458 } |
| 2454 case Call::KEYED_SUPER_PROPERTY_CALL: { | 2459 case Call::KEYED_SUPER_PROPERTY_CALL: { |
| 2460 Register receiver = register_allocator()->GrowRegisterList(&args); |
| 2455 Property* property = callee_expr->AsProperty(); | 2461 Property* property = callee_expr->AsProperty(); |
| 2456 VisitKeyedSuperPropertyLoad(property, receiver); | 2462 VisitKeyedSuperPropertyLoad(property, receiver); |
| 2457 builder()->StoreAccumulatorInRegister(callee); | 2463 builder()->StoreAccumulatorInRegister(callee); |
| 2458 break; | 2464 break; |
| 2459 } | 2465 } |
| 2460 case Call::SUPER_CALL: | 2466 case Call::SUPER_CALL: |
| 2461 UNREACHABLE(); | 2467 UNREACHABLE(); |
| 2462 break; | 2468 break; |
| 2463 } | 2469 } |
| 2464 | 2470 |
| 2465 // Evaluate all arguments to the function call and store in sequential args | 2471 // Evaluate all arguments to the function call and store in sequential args |
| 2466 // registers. | 2472 // registers. |
| 2467 VisitArguments(expr->arguments(), args, 1); | 2473 VisitArguments(expr->arguments(), &args); |
| 2474 CHECK_EQ(expr->arguments()->length() + 1, args.register_count()); |
| 2468 | 2475 |
| 2469 // Resolve callee for a potential direct eval call. This block will mutate the | 2476 // Resolve callee for a potential direct eval call. This block will mutate the |
| 2470 // callee value. | 2477 // callee value. |
| 2471 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { | 2478 if (expr->is_possibly_eval() && expr->arguments()->length() > 0) { |
| 2472 RegisterAllocationScope inner_register_scope(this); | 2479 RegisterAllocationScope inner_register_scope(this); |
| 2473 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source | 2480 // Set up arguments for ResolvePossiblyDirectEval by copying callee, source |
| 2474 // strings and function closure, and loading language and | 2481 // strings and function closure, and loading language and |
| 2475 // position. | 2482 // position. |
| 2476 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); | 2483 RegisterList runtime_call_args = register_allocator()->NewRegisterList(6); |
| 2477 builder() | 2484 builder() |
| (...skipping 30 matching lines...) Expand all Loading... |
| 2508 builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function); | 2515 builder()->CallRuntime(Runtime::kInlineGetSuperConstructor, this_function); |
| 2509 | 2516 |
| 2510 Register constructor = this_function; // Re-use dead this_function register. | 2517 Register constructor = this_function; // Re-use dead this_function register. |
| 2511 builder()->StoreAccumulatorInRegister(constructor); | 2518 builder()->StoreAccumulatorInRegister(constructor); |
| 2512 | 2519 |
| 2513 ZoneList<Expression*>* args = expr->arguments(); | 2520 ZoneList<Expression*>* args = expr->arguments(); |
| 2514 | 2521 |
| 2515 // When a super call contains a spread, a CallSuper AST node is only created | 2522 // When a super call contains a spread, a CallSuper AST node is only created |
| 2516 // if there is exactly one spread, and it is the last argument. | 2523 // if there is exactly one spread, and it is the last argument. |
| 2517 if (!args->is_empty() && args->last()->IsSpread()) { | 2524 if (!args->is_empty() && args->last()->IsSpread()) { |
| 2518 RegisterList args_regs = | 2525 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); |
| 2519 register_allocator()->NewRegisterList(args->length() + 2); | 2526 Register constructor_arg = |
| 2520 builder()->MoveRegister(constructor, args_regs[0]); | 2527 register_allocator()->GrowRegisterList(&args_regs); |
| 2521 VisitArguments(args, args_regs, 2); | 2528 builder()->MoveRegister(constructor, constructor_arg); |
| 2522 VisitForRegisterValue(super->new_target_var(), args_regs[1]); | 2529 // Reserve argument reg for new.target in correct place for runtime call. |
| 2530 // TODO(petermarshall): Remove this when changing bytecode to use the new |
| 2531 // stub. |
| 2532 Register new_target = register_allocator()->GrowRegisterList(&args_regs); |
| 2533 VisitArguments(args, &args_regs); |
| 2534 VisitForRegisterValue(super->new_target_var(), new_target); |
| 2523 builder()->NewWithSpread(args_regs); | 2535 builder()->NewWithSpread(args_regs); |
| 2524 } else { | 2536 } else { |
| 2525 RegisterList args_regs = | 2537 RegisterList args_regs = register_allocator()->NewGrowableRegisterList(); |
| 2526 register_allocator()->NewRegisterList(args->length()); | 2538 VisitArguments(args, &args_regs); |
| 2527 VisitArguments(args, args_regs); | |
| 2528 // The new target is loaded into the accumulator from the | 2539 // The new target is loaded into the accumulator from the |
| 2529 // {new.target} variable. | 2540 // {new.target} variable. |
| 2530 VisitForAccumulatorValue(super->new_target_var()); | 2541 VisitForAccumulatorValue(super->new_target_var()); |
| 2531 | 2542 |
| 2532 // Call construct. | 2543 // Call construct. |
| 2533 builder()->SetExpressionPosition(expr); | 2544 builder()->SetExpressionPosition(expr); |
| 2534 // TODO(turbofan): For now we do gather feedback on super constructor | 2545 // TODO(turbofan): For now we do gather feedback on super constructor |
| 2535 // calls, utilizing the existing machinery to inline the actual call | 2546 // calls, utilizing the existing machinery to inline the actual call |
| 2536 // target and the JSCreate for the implicit receiver allocation. This | 2547 // target and the JSCreate for the implicit receiver allocation. This |
| 2537 // is not an ideal solution for super constructor calls, but it gets | 2548 // is not an ideal solution for super constructor calls, but it gets |
| 2538 // the job done for now. In the long run we might want to revisit this | 2549 // the job done for now. In the long run we might want to revisit this |
| 2539 // and come up with a better way. | 2550 // and come up with a better way. |
| 2540 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); | 2551 int const feedback_slot_index = feedback_index(expr->CallFeedbackICSlot()); |
| 2541 builder()->New(constructor, args_regs, feedback_slot_index); | 2552 builder()->New(constructor, args_regs, feedback_slot_index); |
| 2542 } | 2553 } |
| 2543 } | 2554 } |
| 2544 | 2555 |
| 2545 void BytecodeGenerator::VisitCallNew(CallNew* expr) { | 2556 void BytecodeGenerator::VisitCallNew(CallNew* expr) { |
| 2546 Register constructor = VisitForRegisterValue(expr->expression()); | 2557 Register constructor = VisitForRegisterValue(expr->expression()); |
| 2547 RegisterList args = | 2558 RegisterList args = register_allocator()->NewGrowableRegisterList(); |
| 2548 register_allocator()->NewRegisterList(expr->arguments()->length()); | 2559 VisitArguments(expr->arguments(), &args); |
| 2549 VisitArguments(expr->arguments(), args); | |
| 2550 | 2560 |
| 2551 builder()->SetExpressionPosition(expr); | 2561 builder()->SetExpressionPosition(expr); |
| 2552 // The accumulator holds new target which is the same as the | 2562 // The accumulator holds new target which is the same as the |
| 2553 // constructor for CallNew. | 2563 // constructor for CallNew. |
| 2554 builder() | 2564 builder() |
| 2555 ->LoadAccumulatorWithRegister(constructor) | 2565 ->LoadAccumulatorWithRegister(constructor) |
| 2556 .New(constructor, args, feedback_index(expr->CallNewFeedbackSlot())); | 2566 .New(constructor, args, feedback_index(expr->CallNewFeedbackSlot())); |
| 2557 } | 2567 } |
| 2558 | 2568 |
| 2559 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { | 2569 void BytecodeGenerator::VisitCallRuntime(CallRuntime* expr) { |
| 2560 if (expr->is_jsruntime()) { | 2570 if (expr->is_jsruntime()) { |
| 2571 RegisterList args = register_allocator()->NewGrowableRegisterList(); |
| 2561 // Allocate a register for the receiver and load it with undefined. | 2572 // Allocate a register for the receiver and load it with undefined. |
| 2562 RegisterList args = | 2573 BuildPushUndefinedIntoRegisterList(&args); |
| 2563 register_allocator()->NewRegisterList(expr->arguments()->length() + 1); | 2574 VisitArguments(expr->arguments(), &args); |
| 2564 Register receiver = args[0]; | |
| 2565 builder()->LoadUndefined().StoreAccumulatorInRegister(receiver); | |
| 2566 VisitArguments(expr->arguments(), args, 1); | |
| 2567 builder()->CallJSRuntime(expr->context_index(), args); | 2575 builder()->CallJSRuntime(expr->context_index(), args); |
| 2568 } else { | 2576 } else { |
| 2569 // Evaluate all arguments to the runtime call. | 2577 // Evaluate all arguments to the runtime call. |
| 2570 RegisterList args = | 2578 RegisterList args = register_allocator()->NewGrowableRegisterList(); |
| 2571 register_allocator()->NewRegisterList(expr->arguments()->length()); | 2579 VisitArguments(expr->arguments(), &args); |
| 2572 VisitArguments(expr->arguments(), args); | |
| 2573 Runtime::FunctionId function_id = expr->function()->function_id; | 2580 Runtime::FunctionId function_id = expr->function()->function_id; |
| 2574 builder()->CallRuntime(function_id, args); | 2581 builder()->CallRuntime(function_id, args); |
| 2575 } | 2582 } |
| 2576 } | 2583 } |
| 2577 | 2584 |
| 2578 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { | 2585 void BytecodeGenerator::VisitVoid(UnaryOperation* expr) { |
| 2579 VisitForEffect(expr->expression()); | 2586 VisitForEffect(expr->expression()); |
| 2580 builder()->LoadUndefined(); | 2587 builder()->LoadUndefined(); |
| 2581 } | 2588 } |
| 2582 | 2589 |
| (...skipping 620 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3203 | 3210 |
| 3204 // Visits the expression |expr| and stores the expression result in | 3211 // Visits the expression |expr| and stores the expression result in |
| 3205 // |destination|. | 3212 // |destination|. |
| 3206 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, | 3213 void BytecodeGenerator::VisitForRegisterValue(Expression* expr, |
| 3207 Register destination) { | 3214 Register destination) { |
| 3208 ValueResultScope register_scope(this); | 3215 ValueResultScope register_scope(this); |
| 3209 Visit(expr); | 3216 Visit(expr); |
| 3210 builder()->StoreAccumulatorInRegister(destination); | 3217 builder()->StoreAccumulatorInRegister(destination); |
| 3211 } | 3218 } |
| 3212 | 3219 |
| 3220 // Visits the expression |expr| and pushes the result into a new register |
| 3221 // added to the end of |reg_list|. |
| 3222 void BytecodeGenerator::VisitAndPushIntoRegisterList(Expression* expr, |
| 3223 RegisterList* reg_list) { |
| 3224 { |
| 3225 ValueResultScope register_scope(this); |
| 3226 Visit(expr); |
| 3227 } |
| 3228 // Grow the register list after visiting the expression to avoid reserving |
| 3229 // the register across the expression evaluation, which could cause memory |
| 3230 // leaks for deep expressions due to dead objects being kept alive by pointers |
| 3231 // in registers. |
| 3232 Register destination = register_allocator()->GrowRegisterList(reg_list); |
| 3233 builder()->StoreAccumulatorInRegister(destination); |
| 3234 } |
| 3235 |
| 3236 void BytecodeGenerator::BuildPushUndefinedIntoRegisterList( |
| 3237 RegisterList* reg_list) { |
| 3238 Register reg = register_allocator()->GrowRegisterList(reg_list); |
| 3239 builder()->LoadUndefined().StoreAccumulatorInRegister(reg); |
| 3240 } |
| 3241 |
| 3213 // Visits the expression |expr| for testing its boolean value and jumping to the | 3242 // Visits the expression |expr| for testing its boolean value and jumping to the |
| 3214 // |then| or |other| label depending on value and short-circuit semantics | 3243 // |then| or |other| label depending on value and short-circuit semantics |
| 3215 void BytecodeGenerator::VisitForTest(Expression* expr, | 3244 void BytecodeGenerator::VisitForTest(Expression* expr, |
| 3216 BytecodeLabels* then_labels, | 3245 BytecodeLabels* then_labels, |
| 3217 BytecodeLabels* else_labels, | 3246 BytecodeLabels* else_labels, |
| 3218 TestFallthrough fallthrough) { | 3247 TestFallthrough fallthrough) { |
| 3219 bool result_consumed; | 3248 bool result_consumed; |
| 3220 { | 3249 { |
| 3221 // To make sure that all temporary registers are returned before generating | 3250 // To make sure that all temporary registers are returned before generating |
| 3222 // jumps below, we ensure that the result scope is deleted before doing so. | 3251 // jumps below, we ensure that the result scope is deleted before doing so. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3260 } | 3289 } |
| 3261 | 3290 |
| 3262 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { | 3291 Runtime::FunctionId BytecodeGenerator::StoreKeyedToSuperRuntimeId() { |
| 3263 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict | 3292 return is_strict(language_mode()) ? Runtime::kStoreKeyedToSuper_Strict |
| 3264 : Runtime::kStoreKeyedToSuper_Sloppy; | 3293 : Runtime::kStoreKeyedToSuper_Sloppy; |
| 3265 } | 3294 } |
| 3266 | 3295 |
| 3267 } // namespace interpreter | 3296 } // namespace interpreter |
| 3268 } // namespace internal | 3297 } // namespace internal |
| 3269 } // namespace v8 | 3298 } // namespace v8 |
| OLD | NEW |