| OLD | NEW | 
|---|
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 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/compiler/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" | 
| 6 | 6 | 
| 7 #include "src/compiler.h" | 7 #include "src/compiler.h" | 
| 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 
| 9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" | 
| 10 #include "src/compiler/js-type-feedback.h" | 10 #include "src/compiler/js-type-feedback.h" | 
| (...skipping 2495 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 2506   const Operator* op = javascript()->CallRuntime(Runtime::kGetPrototype, 1); | 2506   const Operator* op = javascript()->CallRuntime(Runtime::kGetPrototype, 1); | 
| 2507   Node* super_function = NewNode(op, this_function); | 2507   Node* super_function = NewNode(op, this_function); | 
| 2508   // TODO(mstarzinger): This probably needs a proper bailout id. | 2508   // TODO(mstarzinger): This probably needs a proper bailout id. | 
| 2509   PrepareFrameState(super_function, BailoutId::None()); | 2509   PrepareFrameState(super_function, BailoutId::None()); | 
| 2510   environment()->Push(super_function); | 2510   environment()->Push(super_function); | 
| 2511 | 2511 | 
| 2512   // Evaluate all arguments to the super call. | 2512   // Evaluate all arguments to the super call. | 
| 2513   ZoneList<Expression*>* args = expr->arguments(); | 2513   ZoneList<Expression*>* args = expr->arguments(); | 
| 2514   VisitForValues(args); | 2514   VisitForValues(args); | 
| 2515 | 2515 | 
| 2516   // Original receiver is loaded from the {new.target} variable. | 2516   // Original constructor is loaded from the {new.target} variable. | 
| 2517   VisitForValue(super->new_target_var()); | 2517   VisitForValue(super->new_target_var()); | 
| 2518 | 2518 | 
| 2519   // Create node to perform the super call. | 2519   // Create node to perform the super call. | 
| 2520   const Operator* call = javascript()->CallConstruct(args->length() + 2); | 2520   const Operator* call = javascript()->CallConstruct(args->length() + 2); | 
| 2521   Node* value = ProcessArguments(call, args->length() + 2); | 2521   Node* value = ProcessArguments(call, args->length() + 2); | 
| 2522   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2522   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 2523 | 2523 | 
| 2524   // TODO(mstarzinger): It sure would be nice if this were desugared. Also we | 2524   // TODO(mstarzinger): It sure would be nice if this were desugared. | 
| 2525   // are still missing the hole-check in the assignment below, fix that. |  | 
| 2526   FrameStateBeforeAndAfter states(this, BailoutId::None()); | 2525   FrameStateBeforeAndAfter states(this, BailoutId::None()); | 
| 2527   BuildVariableAssignment(super->this_var()->var(), value, Token::INIT_CONST, | 2526   BuildVariableAssignment(super->this_var()->var(), value, Token::INIT_CONST, | 
| 2528                           VectorSlotPair(), BailoutId::None(), states); | 2527                           VectorSlotPair(), expr->id(), states); | 
| 2529 |  | 
| 2530   // TODO(mstarzinger): Remove bailout once lowering is correct. |  | 
| 2531   SetStackOverflow(); |  | 
| 2532 | 2528 | 
| 2533   ast_context()->ProduceValue(value); | 2529   ast_context()->ProduceValue(value); | 
| 2534 } | 2530 } | 
| 2535 | 2531 | 
| 2536 | 2532 | 
| 2537 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 2533 void AstGraphBuilder::VisitCallNew(CallNew* expr) { | 
| 2538   VisitForValue(expr->expression()); | 2534   VisitForValue(expr->expression()); | 
| 2539 | 2535 | 
| 2540   // Evaluate all arguments to the construct call. | 2536   // Evaluate all arguments to the construct call. | 
| 2541   ZoneList<Expression*>* args = expr->arguments(); | 2537   ZoneList<Expression*>* args = expr->arguments(); | 
| 2542   VisitForValues(args); | 2538   VisitForValues(args); | 
| 2543 | 2539 | 
| 2544   // Original receiver is the same as the callee. | 2540   // Original constructor is the same as the callee. | 
| 2545   environment()->Push(environment()->Peek(args->length())); | 2541   environment()->Push(environment()->Peek(args->length())); | 
| 2546 | 2542 | 
| 2547   // Create node to perform the construct call. | 2543   // Create node to perform the construct call. | 
| 2548   const Operator* call = javascript()->CallConstruct(args->length() + 2); | 2544   const Operator* call = javascript()->CallConstruct(args->length() + 2); | 
| 2549   Node* value = ProcessArguments(call, args->length() + 2); | 2545   Node* value = ProcessArguments(call, args->length() + 2); | 
| 2550   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2546   PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 
| 2551   ast_context()->ProduceValue(value); | 2547   ast_context()->ProduceValue(value); | 
| 2552 } | 2548 } | 
| 2553 | 2549 | 
| 2554 | 2550 | 
| (...skipping 710 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3265 | 3261 | 
| 3266 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 3262 Node* AstGraphBuilder::BuildHoleCheckSilent(Node* value, Node* for_hole, | 
| 3267                                             Node* not_hole) { | 3263                                             Node* not_hole) { | 
| 3268   Node* the_hole = jsgraph()->TheHoleConstant(); | 3264   Node* the_hole = jsgraph()->TheHoleConstant(); | 
| 3269   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3265   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 
| 3270   return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 3266   return NewNode(common()->Select(kMachAnyTagged, BranchHint::kFalse), check, | 
| 3271                  for_hole, not_hole); | 3267                  for_hole, not_hole); | 
| 3272 } | 3268 } | 
| 3273 | 3269 | 
| 3274 | 3270 | 
| 3275 Node* AstGraphBuilder::BuildHoleCheckThrow(Node* value, Variable* variable, | 3271 Node* AstGraphBuilder::BuildHoleCheckThenThrow(Node* value, Variable* variable, | 
| 3276                                            Node* not_hole, | 3272                                                Node* not_hole, | 
| 3277                                            BailoutId bailout_id) { | 3273                                                BailoutId bailout_id) { | 
| 3278   IfBuilder hole_check(this); | 3274   IfBuilder hole_check(this); | 
| 3279   Node* the_hole = jsgraph()->TheHoleConstant(); | 3275   Node* the_hole = jsgraph()->TheHoleConstant(); | 
| 3280   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 3276   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 
| 3281   hole_check.If(check); | 3277   hole_check.If(check); | 
| 3282   hole_check.Then(); | 3278   hole_check.Then(); | 
| 3283   Node* error = BuildThrowReferenceError(variable, bailout_id); | 3279   Node* error = BuildThrowReferenceError(variable, bailout_id); | 
| 3284   environment()->Push(error); | 3280   environment()->Push(error); | 
| 3285   hole_check.Else(); | 3281   hole_check.Else(); | 
| 3286   environment()->Push(not_hole); | 3282   environment()->Push(not_hole); | 
| 3287   hole_check.End(); | 3283   hole_check.End(); | 
| 3288   return environment()->Pop(); | 3284   return environment()->Pop(); | 
| 3289 } | 3285 } | 
| 3290 | 3286 | 
| 3291 | 3287 | 
|  | 3288 Node* AstGraphBuilder::BuildHoleCheckElseThrow(Node* value, Variable* variable, | 
|  | 3289                                                Node* for_hole, | 
|  | 3290                                                BailoutId bailout_id) { | 
|  | 3291   IfBuilder hole_check(this); | 
|  | 3292   Node* the_hole = jsgraph()->TheHoleConstant(); | 
|  | 3293   Node* check = NewNode(javascript()->StrictEqual(), value, the_hole); | 
|  | 3294   hole_check.If(check); | 
|  | 3295   hole_check.Then(); | 
|  | 3296   environment()->Push(for_hole); | 
|  | 3297   hole_check.Else(); | 
|  | 3298   Node* error = BuildThrowReferenceError(variable, bailout_id); | 
|  | 3299   environment()->Push(error); | 
|  | 3300   hole_check.End(); | 
|  | 3301   return environment()->Pop(); | 
|  | 3302 } | 
|  | 3303 | 
|  | 3304 | 
| 3292 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, | 3305 Node* AstGraphBuilder::BuildThrowIfStaticPrototype(Node* name, | 
| 3293                                                    BailoutId bailout_id) { | 3306                                                    BailoutId bailout_id) { | 
| 3294   IfBuilder prototype_check(this); | 3307   IfBuilder prototype_check(this); | 
| 3295   Node* prototype_string = | 3308   Node* prototype_string = | 
| 3296       jsgraph()->Constant(isolate()->factory()->prototype_string()); | 3309       jsgraph()->Constant(isolate()->factory()->prototype_string()); | 
| 3297   Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string); | 3310   Node* check = NewNode(javascript()->StrictEqual(), name, prototype_string); | 
| 3298   prototype_check.If(check); | 3311   prototype_check.If(check); | 
| 3299   prototype_check.Then(); | 3312   prototype_check.Then(); | 
| 3300   Node* error = BuildThrowStaticPrototypeError(bailout_id); | 3313   Node* error = BuildThrowStaticPrototypeError(bailout_id); | 
| 3301   environment()->Push(error); | 3314   environment()->Push(error); | 
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3351           value = BuildHoleCheckSilent(value, undefined, value); | 3364           value = BuildHoleCheckSilent(value, undefined, value); | 
| 3352         } | 3365         } | 
| 3353       } else if (mode == LET || mode == CONST) { | 3366       } else if (mode == LET || mode == CONST) { | 
| 3354         // Perform check for uninitialized let/const variables. | 3367         // Perform check for uninitialized let/const variables. | 
| 3355         // TODO(mstarzinger): For now we cannot use the below optimization for | 3368         // TODO(mstarzinger): For now we cannot use the below optimization for | 
| 3356         // the {this} parameter, because JSConstructStubForDerived magically | 3369         // the {this} parameter, because JSConstructStubForDerived magically | 
| 3357         // passes {the_hole} as a receiver. | 3370         // passes {the_hole} as a receiver. | 
| 3358         if (value->op() == the_hole->op()) { | 3371         if (value->op() == the_hole->op()) { | 
| 3359           value = BuildThrowReferenceError(variable, bailout_id); | 3372           value = BuildThrowReferenceError(variable, bailout_id); | 
| 3360         } else if (value->opcode() == IrOpcode::kPhi || variable->is_this()) { | 3373         } else if (value->opcode() == IrOpcode::kPhi || variable->is_this()) { | 
| 3361           value = BuildHoleCheckThrow(value, variable, value, bailout_id); | 3374           value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); | 
| 3362         } | 3375         } | 
| 3363       } | 3376       } | 
| 3364       return value; | 3377       return value; | 
| 3365     } | 3378     } | 
| 3366     case VariableLocation::CONTEXT: { | 3379     case VariableLocation::CONTEXT: { | 
| 3367       // Context variable (potentially up the context chain). | 3380       // Context variable (potentially up the context chain). | 
| 3368       int depth = current_scope()->ContextChainLength(variable->scope()); | 3381       int depth = current_scope()->ContextChainLength(variable->scope()); | 
| 3369       bool immutable = variable->maybe_assigned() == kNotAssigned; | 3382       bool immutable = variable->maybe_assigned() == kNotAssigned; | 
| 3370       const Operator* op = | 3383       const Operator* op = | 
| 3371           javascript()->LoadContext(depth, variable->index(), immutable); | 3384           javascript()->LoadContext(depth, variable->index(), immutable); | 
| 3372       Node* value = NewNode(op, current_context()); | 3385       Node* value = NewNode(op, current_context()); | 
| 3373       // TODO(titzer): initialization checks are redundant for already | 3386       // TODO(titzer): initialization checks are redundant for already | 
| 3374       // initialized immutable context loads, but only specialization knows. | 3387       // initialized immutable context loads, but only specialization knows. | 
| 3375       // Maybe specializer should be a parameter to the graph builder? | 3388       // Maybe specializer should be a parameter to the graph builder? | 
| 3376       if (mode == CONST_LEGACY) { | 3389       if (mode == CONST_LEGACY) { | 
| 3377         // Perform check for uninitialized legacy const variables. | 3390         // Perform check for uninitialized legacy const variables. | 
| 3378         Node* undefined = jsgraph()->UndefinedConstant(); | 3391         Node* undefined = jsgraph()->UndefinedConstant(); | 
| 3379         value = BuildHoleCheckSilent(value, undefined, value); | 3392         value = BuildHoleCheckSilent(value, undefined, value); | 
| 3380       } else if (mode == LET || mode == CONST) { | 3393       } else if (mode == LET || mode == CONST) { | 
| 3381         // Perform check for uninitialized let/const variables. | 3394         // Perform check for uninitialized let/const variables. | 
| 3382         value = BuildHoleCheckThrow(value, variable, value, bailout_id); | 3395         value = BuildHoleCheckThenThrow(value, variable, value, bailout_id); | 
| 3383       } | 3396       } | 
| 3384       return value; | 3397       return value; | 
| 3385     } | 3398     } | 
| 3386     case VariableLocation::LOOKUP: { | 3399     case VariableLocation::LOOKUP: { | 
| 3387       // Dynamic lookup of context variable (anywhere in the chain). | 3400       // Dynamic lookup of context variable (anywhere in the chain). | 
| 3388       Node* value = jsgraph()->TheHoleConstant(); | 3401       Node* value = jsgraph()->TheHoleConstant(); | 
| 3389       Handle<String> name = variable->name(); | 3402       Handle<String> name = variable->name(); | 
| 3390       if (mode == DYNAMIC_GLOBAL) { | 3403       if (mode == DYNAMIC_GLOBAL) { | 
| 3391         uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); | 3404         uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable); | 
| 3392         const Operator* op = javascript()->LoadDynamicGlobal( | 3405         const Operator* op = javascript()->LoadDynamicGlobal( | 
| (...skipping 10 matching lines...) Expand all  Loading... | 
| 3403             name, check_bitset, depth, local->index()); | 3416             name, check_bitset, depth, local->index()); | 
| 3404         value = NewNode(op, current_context()); | 3417         value = NewNode(op, current_context()); | 
| 3405         PrepareFrameState(value, bailout_id, combine); | 3418         PrepareFrameState(value, bailout_id, combine); | 
| 3406         VariableMode local_mode = local->mode(); | 3419         VariableMode local_mode = local->mode(); | 
| 3407         if (local_mode == CONST_LEGACY) { | 3420         if (local_mode == CONST_LEGACY) { | 
| 3408           // Perform check for uninitialized legacy const variables. | 3421           // Perform check for uninitialized legacy const variables. | 
| 3409           Node* undefined = jsgraph()->UndefinedConstant(); | 3422           Node* undefined = jsgraph()->UndefinedConstant(); | 
| 3410           value = BuildHoleCheckSilent(value, undefined, value); | 3423           value = BuildHoleCheckSilent(value, undefined, value); | 
| 3411         } else if (local_mode == LET || local_mode == CONST) { | 3424         } else if (local_mode == LET || local_mode == CONST) { | 
| 3412           // Perform check for uninitialized let/const variables. | 3425           // Perform check for uninitialized let/const variables. | 
| 3413           value = BuildHoleCheckThrow(value, local, value, bailout_id); | 3426           value = BuildHoleCheckThenThrow(value, local, value, bailout_id); | 
| 3414         } | 3427         } | 
| 3415       } else if (mode == DYNAMIC) { | 3428       } else if (mode == DYNAMIC) { | 
| 3416         uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 3429         uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired; | 
| 3417         const Operator* op = javascript()->LoadDynamicGlobal( | 3430         const Operator* op = javascript()->LoadDynamicGlobal( | 
| 3418             name, check_bitset, feedback, typeof_mode); | 3431             name, check_bitset, feedback, typeof_mode); | 
| 3419         value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 3432         value = NewNode(op, BuildLoadFeedbackVector(), current_context()); | 
| 3420         states.AddToNode(value, bailout_id, combine); | 3433         states.AddToNode(value, bailout_id, combine); | 
| 3421       } | 3434       } | 
| 3422       return value; | 3435       return value; | 
| 3423     } | 3436     } | 
| (...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 3512         return value; | 3525         return value; | 
| 3513       } else if (mode == LET && op != Token::INIT_LET) { | 3526       } else if (mode == LET && op != Token::INIT_LET) { | 
| 3514         // Perform an initialization check for let declared variables. | 3527         // Perform an initialization check for let declared variables. | 
| 3515         // Also note that the dynamic hole-check is only done to ensure that | 3528         // Also note that the dynamic hole-check is only done to ensure that | 
| 3516         // this does not break in the presence of do-expressions within the | 3529         // this does not break in the presence of do-expressions within the | 
| 3517         // temporal dead zone of a let declared variable. | 3530         // temporal dead zone of a let declared variable. | 
| 3518         Node* current = environment()->Lookup(variable); | 3531         Node* current = environment()->Lookup(variable); | 
| 3519         if (current->op() == the_hole->op()) { | 3532         if (current->op() == the_hole->op()) { | 
| 3520           value = BuildThrowReferenceError(variable, bailout_id); | 3533           value = BuildThrowReferenceError(variable, bailout_id); | 
| 3521         } else if (value->opcode() == IrOpcode::kPhi) { | 3534         } else if (value->opcode() == IrOpcode::kPhi) { | 
| 3522           value = BuildHoleCheckThrow(current, variable, value, bailout_id); | 3535           value = BuildHoleCheckThenThrow(current, variable, value, bailout_id); | 
|  | 3536         } | 
|  | 3537       } else if (mode == CONST && op == Token::INIT_CONST) { | 
|  | 3538         // Perform an initialization check for const {this} variables. | 
|  | 3539         // Note that the {this} variable is the only const variable being able | 
|  | 3540         // to trigger bind operations outside the TDZ, via {super} calls. | 
|  | 3541         Node* current = environment()->Lookup(variable); | 
|  | 3542         if (current->op() != the_hole->op() && variable->is_this()) { | 
|  | 3543           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); | 
| 3523         } | 3544         } | 
| 3524       } else if (mode == CONST && op != Token::INIT_CONST) { | 3545       } else if (mode == CONST && op != Token::INIT_CONST) { | 
| 3525         // Assignment to const is exception in all modes. | 3546         // Assignment to const is exception in all modes. | 
| 3526         Node* current = environment()->Lookup(variable); | 3547         Node* current = environment()->Lookup(variable); | 
| 3527         if (current->op() == the_hole->op()) { | 3548         if (current->op() == the_hole->op()) { | 
| 3528           return BuildThrowReferenceError(variable, bailout_id); | 3549           return BuildThrowReferenceError(variable, bailout_id); | 
| 3529         } else if (value->opcode() == IrOpcode::kPhi) { | 3550         } else if (value->opcode() == IrOpcode::kPhi) { | 
| 3530           BuildHoleCheckThrow(current, variable, value, bailout_id); | 3551           BuildHoleCheckThenThrow(current, variable, value, bailout_id); | 
| 3531         } | 3552         } | 
| 3532         return BuildThrowConstAssignError(bailout_id); | 3553         return BuildThrowConstAssignError(bailout_id); | 
| 3533       } | 3554       } | 
| 3534       environment()->Bind(variable, value); | 3555       environment()->Bind(variable, value); | 
| 3535       return value; | 3556       return value; | 
| 3536     case VariableLocation::CONTEXT: { | 3557     case VariableLocation::CONTEXT: { | 
| 3537       // Context variable (potentially up the context chain). | 3558       // Context variable (potentially up the context chain). | 
| 3538       int depth = current_scope()->ContextChainLength(variable->scope()); | 3559       int depth = current_scope()->ContextChainLength(variable->scope()); | 
| 3539       if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 3560       if (mode == CONST_LEGACY && op == Token::INIT_CONST_LEGACY) { | 
| 3540         // Perform an initialization check for legacy const variables. | 3561         // Perform an initialization check for legacy const variables. | 
| 3541         const Operator* op = | 3562         const Operator* op = | 
| 3542             javascript()->LoadContext(depth, variable->index(), false); | 3563             javascript()->LoadContext(depth, variable->index(), false); | 
| 3543         Node* current = NewNode(op, current_context()); | 3564         Node* current = NewNode(op, current_context()); | 
| 3544         value = BuildHoleCheckSilent(current, value, current); | 3565         value = BuildHoleCheckSilent(current, value, current); | 
| 3545       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 3566       } else if (mode == CONST_LEGACY && op != Token::INIT_CONST_LEGACY) { | 
| 3546         // Non-initializing assignment to legacy const is | 3567         // Non-initializing assignment to legacy const is | 
| 3547         // - exception in strict mode. | 3568         // - exception in strict mode. | 
| 3548         // - ignored in sloppy mode. | 3569         // - ignored in sloppy mode. | 
| 3549         if (is_strict(language_mode())) { | 3570         if (is_strict(language_mode())) { | 
| 3550           return BuildThrowConstAssignError(bailout_id); | 3571           return BuildThrowConstAssignError(bailout_id); | 
| 3551         } | 3572         } | 
| 3552         return value; | 3573         return value; | 
| 3553       } else if (mode == LET && op != Token::INIT_LET) { | 3574       } else if (mode == LET && op != Token::INIT_LET) { | 
| 3554         // Perform an initialization check for let declared variables. | 3575         // Perform an initialization check for let declared variables. | 
| 3555         const Operator* op = | 3576         const Operator* op = | 
| 3556             javascript()->LoadContext(depth, variable->index(), false); | 3577             javascript()->LoadContext(depth, variable->index(), false); | 
| 3557         Node* current = NewNode(op, current_context()); | 3578         Node* current = NewNode(op, current_context()); | 
| 3558         value = BuildHoleCheckThrow(current, variable, value, bailout_id); | 3579         value = BuildHoleCheckThenThrow(current, variable, value, bailout_id); | 
|  | 3580       } else if (mode == CONST && op == Token::INIT_CONST) { | 
|  | 3581         // Perform an initialization check for const {this} variables. | 
|  | 3582         // Note that the {this} variable is the only const variable being able | 
|  | 3583         // to trigger bind operations outside the TDZ, via {super} calls. | 
|  | 3584         if (variable->is_this()) { | 
|  | 3585           const Operator* op = | 
|  | 3586               javascript()->LoadContext(depth, variable->index(), false); | 
|  | 3587           Node* current = NewNode(op, current_context()); | 
|  | 3588           value = BuildHoleCheckElseThrow(current, variable, value, bailout_id); | 
|  | 3589         } | 
| 3559       } else if (mode == CONST && op != Token::INIT_CONST) { | 3590       } else if (mode == CONST && op != Token::INIT_CONST) { | 
| 3560         // Assignment to const is exception in all modes. | 3591         // Assignment to const is exception in all modes. | 
| 3561         const Operator* op = | 3592         const Operator* op = | 
| 3562             javascript()->LoadContext(depth, variable->index(), false); | 3593             javascript()->LoadContext(depth, variable->index(), false); | 
| 3563         Node* current = NewNode(op, current_context()); | 3594         Node* current = NewNode(op, current_context()); | 
| 3564         BuildHoleCheckThrow(current, variable, value, bailout_id); | 3595         BuildHoleCheckThenThrow(current, variable, value, bailout_id); | 
| 3565         return BuildThrowConstAssignError(bailout_id); | 3596         return BuildThrowConstAssignError(bailout_id); | 
| 3566       } | 3597       } | 
| 3567       const Operator* op = javascript()->StoreContext(depth, variable->index()); | 3598       const Operator* op = javascript()->StoreContext(depth, variable->index()); | 
| 3568       return NewNode(op, current_context(), value); | 3599       return NewNode(op, current_context(), value); | 
| 3569     } | 3600     } | 
| 3570     case VariableLocation::LOOKUP: { | 3601     case VariableLocation::LOOKUP: { | 
| 3571       // Dynamic lookup of context variable (anywhere in the chain). | 3602       // Dynamic lookup of context variable (anywhere in the chain). | 
| 3572       Node* name = jsgraph()->Constant(variable->name()); | 3603       Node* name = jsgraph()->Constant(variable->name()); | 
| 3573       Node* language = jsgraph()->Constant(language_mode()); | 3604       Node* language = jsgraph()->Constant(language_mode()); | 
| 3574       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 3605       // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for | 
| (...skipping 714 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 4289     // Phi does not exist yet, introduce one. | 4320     // Phi does not exist yet, introduce one. | 
| 4290     value = NewPhi(inputs, value, control); | 4321     value = NewPhi(inputs, value, control); | 
| 4291     value->ReplaceInput(inputs - 1, other); | 4322     value->ReplaceInput(inputs - 1, other); | 
| 4292   } | 4323   } | 
| 4293   return value; | 4324   return value; | 
| 4294 } | 4325 } | 
| 4295 | 4326 | 
| 4296 }  // namespace compiler | 4327 }  // namespace compiler | 
| 4297 }  // namespace internal | 4328 }  // namespace internal | 
| 4298 }  // namespace v8 | 4329 }  // namespace v8 | 
| OLD | NEW | 
|---|