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 2402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2413 if (possibly_eval && args->length() > 0) { | 2413 if (possibly_eval && args->length() > 0) { |
2414 int arg_count = args->length(); | 2414 int arg_count = args->length(); |
2415 | 2415 |
2416 // Extract callee and source string from the environment. | 2416 // Extract callee and source string from the environment. |
2417 Node* callee = environment()->Peek(arg_count + 1); | 2417 Node* callee = environment()->Peek(arg_count + 1); |
2418 Node* source = environment()->Peek(arg_count - 1); | 2418 Node* source = environment()->Peek(arg_count - 1); |
2419 | 2419 |
2420 // Create node to ask for help resolving potential eval call. This will | 2420 // Create node to ask for help resolving potential eval call. This will |
2421 // provide a fully resolved callee and the corresponding receiver. | 2421 // provide a fully resolved callee and the corresponding receiver. |
2422 Node* function = GetFunctionClosure(); | 2422 Node* function = GetFunctionClosure(); |
| 2423 // TODO(wingo): ResolvePossibleDirectEval doesn't really need a receiver, |
| 2424 // now that eval scopes don't have "this" declarations. Remove this hack |
| 2425 // once ResolvePossibleDirectEval changes. |
| 2426 Node* receiver; |
| 2427 { |
| 2428 Variable* variable = info()->scope()->LookupThis(); |
| 2429 if (variable->IsStackAllocated()) { |
| 2430 receiver = environment()->Lookup(variable); |
| 2431 } else { |
| 2432 DCHECK(variable->IsContextSlot()); |
| 2433 int depth = current_scope()->ContextChainLength(variable->scope()); |
| 2434 bool immutable = variable->maybe_assigned() == kNotAssigned; |
| 2435 const Operator* op = |
| 2436 javascript()->LoadContext(depth, variable->index(), immutable); |
| 2437 receiver = NewNode(op, current_context()); |
| 2438 } |
| 2439 } |
2423 Node* language = jsgraph()->Constant(language_mode()); | 2440 Node* language = jsgraph()->Constant(language_mode()); |
2424 Node* position = jsgraph()->Constant(current_scope()->start_position()); | 2441 Node* position = jsgraph()->Constant(current_scope()->start_position()); |
2425 const Operator* op = | 2442 const Operator* op = |
2426 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5); | 2443 javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6); |
2427 Node* new_callee = | 2444 Node* pair = |
2428 NewNode(op, callee, source, function, language, position); | 2445 NewNode(op, callee, source, function, receiver, language, position); |
2429 PrepareFrameState(new_callee, expr->EvalOrLookupId(), | 2446 PrepareFrameState(pair, expr->EvalOrLookupId(), |
2430 OutputFrameStateCombine::PokeAt(arg_count + 1)); | 2447 OutputFrameStateCombine::PokeAt(arg_count + 1)); |
| 2448 Node* new_callee = NewNode(common()->Projection(0), pair); |
| 2449 Node* new_receiver = NewNode(common()->Projection(1), pair); |
2431 | 2450 |
2432 // Patch callee on the environment. | 2451 // Patch callee and receiver on the environment. |
2433 environment()->Poke(arg_count + 1, new_callee); | 2452 environment()->Poke(arg_count + 1, new_callee); |
| 2453 environment()->Poke(arg_count + 0, new_receiver); |
2434 } | 2454 } |
2435 | 2455 |
2436 // Create node to perform the function call. | 2456 // Create node to perform the function call. |
2437 const Operator* call = | 2457 const Operator* call = |
2438 javascript()->CallFunction(args->length() + 2, flags, language_mode()); | 2458 javascript()->CallFunction(args->length() + 2, flags, language_mode()); |
2439 Node* value = ProcessArguments(call, args->length() + 2); | 2459 Node* value = ProcessArguments(call, args->length() + 2); |
2440 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2460 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
2441 ast_context()->ProduceValue(value); | 2461 ast_context()->ProduceValue(value); |
2442 } | 2462 } |
2443 | 2463 |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2846 Visit(stmt->body()); | 2866 Visit(stmt->body()); |
2847 } | 2867 } |
2848 | 2868 |
2849 | 2869 |
2850 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { | 2870 void AstGraphBuilder::VisitDelete(UnaryOperation* expr) { |
2851 Node* value; | 2871 Node* value; |
2852 if (expr->expression()->IsVariableProxy()) { | 2872 if (expr->expression()->IsVariableProxy()) { |
2853 // Delete of an unqualified identifier is only allowed in classic mode but | 2873 // Delete of an unqualified identifier is only allowed in classic mode but |
2854 // deleting "this" is allowed in all language modes. | 2874 // deleting "this" is allowed in all language modes. |
2855 Variable* variable = expr->expression()->AsVariableProxy()->var(); | 2875 Variable* variable = expr->expression()->AsVariableProxy()->var(); |
2856 // Delete of an unqualified identifier is disallowed in strict mode but | 2876 DCHECK(is_sloppy(language_mode()) || variable->is_this()); |
2857 // "delete this" is allowed. | |
2858 DCHECK(is_sloppy(language_mode()) || variable->HasThisName(isolate())); | |
2859 value = BuildVariableDelete(variable, expr->id(), | 2877 value = BuildVariableDelete(variable, expr->id(), |
2860 ast_context()->GetStateCombine()); | 2878 ast_context()->GetStateCombine()); |
2861 } else if (expr->expression()->IsProperty()) { | 2879 } else if (expr->expression()->IsProperty()) { |
2862 Property* property = expr->expression()->AsProperty(); | 2880 Property* property = expr->expression()->AsProperty(); |
2863 VisitForValue(property->obj()); | 2881 VisitForValue(property->obj()); |
2864 VisitForValue(property->key()); | 2882 VisitForValue(property->key()); |
2865 Node* key = environment()->Pop(); | 2883 Node* key = environment()->Pop(); |
2866 Node* object = environment()->Pop(); | 2884 Node* object = environment()->Pop(); |
2867 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); | 2885 value = NewNode(javascript()->DeleteProperty(language_mode()), object, key); |
2868 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); | 2886 PrepareFrameState(value, expr->id(), ast_context()->GetStateCombine()); |
(...skipping 427 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3296 // Global var, const, or let variable. | 3314 // Global var, const, or let variable. |
3297 Node* global = BuildLoadGlobalObject(); | 3315 Node* global = BuildLoadGlobalObject(); |
3298 Node* name = jsgraph()->Constant(variable->name()); | 3316 Node* name = jsgraph()->Constant(variable->name()); |
3299 const Operator* op = javascript()->DeleteProperty(language_mode()); | 3317 const Operator* op = javascript()->DeleteProperty(language_mode()); |
3300 Node* result = NewNode(op, global, name); | 3318 Node* result = NewNode(op, global, name); |
3301 PrepareFrameState(result, bailout_id, combine); | 3319 PrepareFrameState(result, bailout_id, combine); |
3302 return result; | 3320 return result; |
3303 } | 3321 } |
3304 case Variable::PARAMETER: | 3322 case Variable::PARAMETER: |
3305 case Variable::LOCAL: | 3323 case Variable::LOCAL: |
3306 case Variable::CONTEXT: { | 3324 case Variable::CONTEXT: |
3307 // Local var, const, or let variable or context variable. | 3325 // Local var, const, or let variable or context variable. |
3308 return jsgraph()->BooleanConstant(variable->HasThisName(isolate())); | 3326 return jsgraph()->BooleanConstant(variable->is_this()); |
3309 } | |
3310 case Variable::LOOKUP: { | 3327 case Variable::LOOKUP: { |
3311 // Dynamic lookup of context variable (anywhere in the chain). | 3328 // Dynamic lookup of context variable (anywhere in the chain). |
3312 Node* name = jsgraph()->Constant(variable->name()); | 3329 Node* name = jsgraph()->Constant(variable->name()); |
3313 const Operator* op = | 3330 const Operator* op = |
3314 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); | 3331 javascript()->CallRuntime(Runtime::kDeleteLookupSlot, 2); |
3315 Node* result = NewNode(op, current_context(), name); | 3332 Node* result = NewNode(op, current_context(), name); |
3316 PrepareFrameState(result, bailout_id, combine); | 3333 PrepareFrameState(result, bailout_id, combine); |
3317 return result; | 3334 return result; |
3318 } | 3335 } |
3319 } | 3336 } |
(...skipping 741 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4061 // Phi does not exist yet, introduce one. | 4078 // Phi does not exist yet, introduce one. |
4062 value = NewPhi(inputs, value, control); | 4079 value = NewPhi(inputs, value, control); |
4063 value->ReplaceInput(inputs - 1, other); | 4080 value->ReplaceInput(inputs - 1, other); |
4064 } | 4081 } |
4065 return value; | 4082 return value; |
4066 } | 4083 } |
4067 | 4084 |
4068 } // namespace compiler | 4085 } // namespace compiler |
4069 } // namespace internal | 4086 } // namespace internal |
4070 } // namespace v8 | 4087 } // namespace v8 |
OLD | NEW |