Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(597)

Side by Side Diff: src/compiler/ast-graph-builder.cc

Issue 1683103002: [compiler] Sanitize entry points to LookupSlot access. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: REBASE. Fixes. Comments. Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/bytecode-graph-builder.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/compiler/ast-loop-assignment-analyzer.h" 9 #include "src/compiler/ast-loop-assignment-analyzer.h"
10 #include "src/compiler/control-builders.h" 10 #include "src/compiler/control-builders.h"
(...skipping 2320 matching lines...) Expand 10 before | Expand all | Expand 10 after
2331 BuildVariableLoad(proxy->var(), expr->expression()->id(), states, 2331 BuildVariableLoad(proxy->var(), expr->expression()->id(), states,
2332 pair, OutputFrameStateCombine::Push()); 2332 pair, OutputFrameStateCombine::Push());
2333 receiver_hint = ConvertReceiverMode::kNullOrUndefined; 2333 receiver_hint = ConvertReceiverMode::kNullOrUndefined;
2334 receiver_value = jsgraph()->UndefinedConstant(); 2334 receiver_value = jsgraph()->UndefinedConstant();
2335 break; 2335 break;
2336 } 2336 }
2337 case Call::LOOKUP_SLOT_CALL: { 2337 case Call::LOOKUP_SLOT_CALL: {
2338 Variable* variable = callee->AsVariableProxy()->var(); 2338 Variable* variable = callee->AsVariableProxy()->var();
2339 DCHECK(variable->location() == VariableLocation::LOOKUP); 2339 DCHECK(variable->location() == VariableLocation::LOOKUP);
2340 Node* name = jsgraph()->Constant(variable->name()); 2340 Node* name = jsgraph()->Constant(variable->name());
2341 const Operator* op = javascript()->CallRuntime(Runtime::kLoadLookupSlot); 2341 const Operator* op =
2342 Node* pair = NewNode(op, current_context(), name); 2342 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
2343 Node* pair = NewNode(op, name);
2343 callee_value = NewNode(common()->Projection(0), pair); 2344 callee_value = NewNode(common()->Projection(0), pair);
2344 receiver_value = NewNode(common()->Projection(1), pair); 2345 receiver_value = NewNode(common()->Projection(1), pair);
2345 PrepareFrameState(pair, expr->LookupId(), 2346 PrepareFrameState(pair, expr->LookupId(),
2346 OutputFrameStateCombine::Push(2)); 2347 OutputFrameStateCombine::Push(2));
2347 break; 2348 break;
2348 } 2349 }
2349 case Call::NAMED_PROPERTY_CALL: { 2350 case Call::NAMED_PROPERTY_CALL: {
2350 Property* property = callee->AsProperty(); 2351 Property* property = callee->AsProperty();
2351 VectorSlotPair feedback = 2352 VectorSlotPair feedback =
2352 CreateVectorSlotPair(property->PropertyFeedbackSlot()); 2353 CreateVectorSlotPair(property->PropertyFeedbackSlot());
(...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 break; 2428 break;
2428 } 2429 }
2429 case Call::SUPER_CALL: 2430 case Call::SUPER_CALL:
2430 return VisitCallSuper(expr); 2431 return VisitCallSuper(expr);
2431 case Call::POSSIBLY_EVAL_CALL: 2432 case Call::POSSIBLY_EVAL_CALL:
2432 possibly_eval = true; 2433 possibly_eval = true;
2433 if (callee->AsVariableProxy()->var()->IsLookupSlot()) { 2434 if (callee->AsVariableProxy()->var()->IsLookupSlot()) {
2434 Variable* variable = callee->AsVariableProxy()->var(); 2435 Variable* variable = callee->AsVariableProxy()->var();
2435 Node* name = jsgraph()->Constant(variable->name()); 2436 Node* name = jsgraph()->Constant(variable->name());
2436 const Operator* op = 2437 const Operator* op =
2437 javascript()->CallRuntime(Runtime::kLoadLookupSlot); 2438 javascript()->CallRuntime(Runtime::kLoadLookupSlotForCall);
2438 Node* pair = NewNode(op, current_context(), name); 2439 Node* pair = NewNode(op, name);
2439 callee_value = NewNode(common()->Projection(0), pair); 2440 callee_value = NewNode(common()->Projection(0), pair);
2440 receiver_value = NewNode(common()->Projection(1), pair); 2441 receiver_value = NewNode(common()->Projection(1), pair);
2441 PrepareFrameState(pair, expr->LookupId(), 2442 PrepareFrameState(pair, expr->LookupId(),
2442 OutputFrameStateCombine::Push(2)); 2443 OutputFrameStateCombine::Push(2));
2443 break; 2444 break;
2444 } 2445 }
2445 // Fall through. 2446 // Fall through.
2446 case Call::OTHER_CALL: 2447 case Call::OTHER_CALL:
2447 VisitForValue(callee); 2448 VisitForValue(callee);
2448 callee_value = environment()->Pop(); 2449 callee_value = environment()->Pop();
(...skipping 946 matching lines...) Expand 10 before | Expand all | Expand 10 after
3395 return value; 3396 return value;
3396 } 3397 }
3397 case VariableLocation::LOOKUP: { 3398 case VariableLocation::LOOKUP: {
3398 // Dynamic lookup of context variable (anywhere in the chain). 3399 // Dynamic lookup of context variable (anywhere in the chain).
3399 Handle<String> name = variable->name(); 3400 Handle<String> name = variable->name();
3400 if (Node* node = 3401 if (Node* node =
3401 TryLoadDynamicVariable(variable, name, bailout_id, states, 3402 TryLoadDynamicVariable(variable, name, bailout_id, states,
3402 feedback, combine, typeof_mode)) { 3403 feedback, combine, typeof_mode)) {
3403 return node; 3404 return node;
3404 } 3405 }
3405 const Operator* op = javascript()->LoadDynamic(name, typeof_mode); 3406 Node* value = BuildDynamicLoad(name, typeof_mode);
3406 Node* value = NewNode(op, BuildLoadFeedbackVector(), current_context());
3407 states.AddToNode(value, bailout_id, combine); 3407 states.AddToNode(value, bailout_id, combine);
3408 return value; 3408 return value;
3409 } 3409 }
3410 } 3410 }
3411 UNREACHABLE(); 3411 UNREACHABLE();
3412 return nullptr; 3412 return nullptr;
3413 } 3413 }
3414 3414
3415 3415
3416 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable, 3416 Node* AstGraphBuilder::BuildVariableDelete(Variable* variable,
(...skipping 14 matching lines...) Expand all
3431 case VariableLocation::LOCAL: 3431 case VariableLocation::LOCAL:
3432 case VariableLocation::CONTEXT: { 3432 case VariableLocation::CONTEXT: {
3433 // Local var, const, or let variable or context variable. 3433 // Local var, const, or let variable or context variable.
3434 return jsgraph()->BooleanConstant(variable->HasThisName(isolate())); 3434 return jsgraph()->BooleanConstant(variable->HasThisName(isolate()));
3435 } 3435 }
3436 case VariableLocation::LOOKUP: { 3436 case VariableLocation::LOOKUP: {
3437 // Dynamic lookup of context variable (anywhere in the chain). 3437 // Dynamic lookup of context variable (anywhere in the chain).
3438 Node* name = jsgraph()->Constant(variable->name()); 3438 Node* name = jsgraph()->Constant(variable->name());
3439 const Operator* op = 3439 const Operator* op =
3440 javascript()->CallRuntime(Runtime::kDeleteLookupSlot); 3440 javascript()->CallRuntime(Runtime::kDeleteLookupSlot);
3441 Node* result = NewNode(op, current_context(), name); 3441 Node* result = NewNode(op, name);
3442 PrepareFrameState(result, bailout_id, combine); 3442 PrepareFrameState(result, bailout_id, combine);
3443 return result; 3443 return result;
3444 } 3444 }
3445 } 3445 }
3446 UNREACHABLE(); 3446 UNREACHABLE();
3447 return nullptr; 3447 return nullptr;
3448 } 3448 }
3449 3449
3450 3450
3451 Node* AstGraphBuilder::BuildVariableAssignment( 3451 Node* AstGraphBuilder::BuildVariableAssignment(
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
3553 javascript()->LoadContext(depth, variable->index(), false); 3553 javascript()->LoadContext(depth, variable->index(), false);
3554 Node* current = NewNode(op, current_context()); 3554 Node* current = NewNode(op, current_context());
3555 BuildHoleCheckThenThrow(current, variable, value, bailout_id); 3555 BuildHoleCheckThenThrow(current, variable, value, bailout_id);
3556 return BuildThrowConstAssignError(bailout_id); 3556 return BuildThrowConstAssignError(bailout_id);
3557 } 3557 }
3558 const Operator* op = javascript()->StoreContext(depth, variable->index()); 3558 const Operator* op = javascript()->StoreContext(depth, variable->index());
3559 return NewNode(op, current_context(), value); 3559 return NewNode(op, current_context(), value);
3560 } 3560 }
3561 case VariableLocation::LOOKUP: { 3561 case VariableLocation::LOOKUP: {
3562 // Dynamic lookup of context variable (anywhere in the chain). 3562 // Dynamic lookup of context variable (anywhere in the chain).
3563 Node* name = jsgraph()->Constant(variable->name()); 3563 Handle<Name> name = variable->name();
3564 Node* language = jsgraph()->Constant(language_mode());
3565 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for 3564 // TODO(mstarzinger): Use Runtime::kInitializeLegacyConstLookupSlot for
3566 // initializations of const declarations. 3565 // initializations of const declarations.
3567 const Operator* op = javascript()->CallRuntime(Runtime::kStoreLookupSlot); 3566 Node* store = BuildDynamicStore(name, value);
3568 Node* store = NewNode(op, value, current_context(), name, language);
3569 PrepareFrameState(store, bailout_id, combine); 3567 PrepareFrameState(store, bailout_id, combine);
3570 return store; 3568 return store;
3571 } 3569 }
3572 } 3570 }
3573 UNREACHABLE(); 3571 UNREACHABLE();
3574 return nullptr; 3572 return nullptr;
3575 } 3573 }
3576 3574
3577 3575
3578 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key, 3576 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after
3664 3662
3665 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value, 3663 Node* AstGraphBuilder::BuildGlobalStore(Handle<Name> name, Node* value,
3666 const VectorSlotPair& feedback) { 3664 const VectorSlotPair& feedback) {
3667 const Operator* op = 3665 const Operator* op =
3668 javascript()->StoreGlobal(language_mode(), name, feedback); 3666 javascript()->StoreGlobal(language_mode(), name, feedback);
3669 Node* node = NewNode(op, value, GetFunctionClosure()); 3667 Node* node = NewNode(op, value, GetFunctionClosure());
3670 return node; 3668 return node;
3671 } 3669 }
3672 3670
3673 3671
3674 Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) { 3672 Node* AstGraphBuilder::BuildDynamicLoad(Handle<Name> name,
3675 return graph()->NewNode(jsgraph()->machine()->Load(MachineType::AnyTagged()), 3673 TypeofMode typeof_mode) {
3676 object, 3674 Node* name_node = jsgraph()->Constant(name);
3677 jsgraph()->IntPtrConstant(offset - kHeapObjectTag), 3675 const Operator* op =
3678 graph()->start(), graph()->start()); 3676 javascript()->CallRuntime(typeof_mode == TypeofMode::NOT_INSIDE_TYPEOF
3677 ? Runtime::kLoadLookupSlot
3678 : Runtime::kLoadLookupSlotInsideTypeof);
3679 Node* node = NewNode(op, name_node);
3680 return node;
3679 } 3681 }
3680 3682
3681 3683
3684 Node* AstGraphBuilder::BuildDynamicStore(Handle<Name> name, Node* value) {
3685 Node* name_node = jsgraph()->Constant(name);
3686 const Operator* op = javascript()->CallRuntime(
3687 is_strict(language_mode()) ? Runtime::kStoreLookupSlot_Strict
3688 : Runtime::kStoreLookupSlot_Sloppy);
3689 Node* node = NewNode(op, name_node, value);
3690 return node;
3691 }
3692
3693
3682 Node* AstGraphBuilder::BuildLoadGlobalObject() { 3694 Node* AstGraphBuilder::BuildLoadGlobalObject() {
3683 return BuildLoadNativeContextField(Context::EXTENSION_INDEX); 3695 return BuildLoadNativeContextField(Context::EXTENSION_INDEX);
3684 } 3696 }
3685 3697
3686 3698
3687 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) { 3699 Node* AstGraphBuilder::BuildLoadNativeContextField(int index) {
3688 const Operator* op = 3700 const Operator* op =
3689 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true); 3701 javascript()->LoadContext(0, Context::NATIVE_CONTEXT_INDEX, true);
3690 Node* native_context = NewNode(op, current_context()); 3702 Node* native_context = NewNode(op, current_context());
3691 return NewNode(javascript()->LoadContext(0, index, true), native_context); 3703 return NewNode(javascript()->LoadContext(0, index, true), native_context);
3692 } 3704 }
3693 3705
3694 3706
3695 Node* AstGraphBuilder::BuildLoadFeedbackVector() {
3696 if (!feedback_vector_.is_set()) {
3697 Node* closure = GetFunctionClosure();
3698 Node* shared = BuildLoadImmutableObjectField(
3699 closure, JSFunction::kSharedFunctionInfoOffset);
3700 Node* vector = BuildLoadImmutableObjectField(
3701 shared, SharedFunctionInfo::kFeedbackVectorOffset);
3702 feedback_vector_.set(vector);
3703 }
3704 return feedback_vector_.get();
3705 }
3706
3707
3708 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) { 3707 Node* AstGraphBuilder::BuildToBoolean(Node* input, TypeFeedbackId feedback_id) {
3709 if (Node* node = TryFastToBoolean(input)) return node; 3708 if (Node* node = TryFastToBoolean(input)) return node;
3710 ToBooleanHints hints; 3709 ToBooleanHints hints;
3711 if (!type_hint_analysis_ || 3710 if (!type_hint_analysis_ ||
3712 !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) { 3711 !type_hint_analysis_->GetToBooleanHints(feedback_id, &hints)) {
3713 hints = ToBooleanHint::kAny; 3712 hints = ToBooleanHint::kAny;
3714 } 3713 }
3715 return NewNode(javascript()->ToBoolean(hints), input); 3714 return NewNode(javascript()->ToBoolean(hints), input);
3716 } 3715 }
3717 3716
(...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after
3916 // Perform global slot load. 3915 // Perform global slot load.
3917 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode); 3916 Node* fast = BuildGlobalLoad(name, feedback, typeof_mode);
3918 states.AddToNode(fast, bailout_id, combine); 3917 states.AddToNode(fast, bailout_id, combine);
3919 environment()->Push(fast); 3918 environment()->Push(fast);
3920 } 3919 }
3921 slow_block.Break(); 3920 slow_block.Break();
3922 environment()->Pop(); 3921 environment()->Pop();
3923 fast_block.EndBlock(); 3922 fast_block.EndBlock();
3924 3923
3925 // Slow case, because variable potentially shadowed. Perform dynamic lookup. 3924 // Slow case, because variable potentially shadowed. Perform dynamic lookup.
3926 const Operator* op = javascript()->LoadDynamic(name, typeof_mode); 3925 Node* slow = BuildDynamicLoad(name, typeof_mode);
3927 Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
3928 states.AddToNode(slow, bailout_id, combine); 3926 states.AddToNode(slow, bailout_id, combine);
3929 environment()->Push(slow); 3927 environment()->Push(slow);
3930 slow_block.EndBlock(); 3928 slow_block.EndBlock();
3931 3929
3932 return environment()->Pop(); 3930 return environment()->Pop();
3933 } 3931 }
3934 3932
3935 if (mode == DYNAMIC_LOCAL) { 3933 if (mode == DYNAMIC_LOCAL) {
3936 uint32_t bitset = ComputeBitsetForDynamicContext(variable); 3934 uint32_t bitset = ComputeBitsetForDynamicContext(variable);
3937 if (bitset == kFullCheckRequired) return nullptr; 3935 if (bitset == kFullCheckRequired) return nullptr;
(...skipping 22 matching lines...) Expand all
3960 Variable* local = variable->local_if_not_shadowed(); 3958 Variable* local = variable->local_if_not_shadowed();
3961 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context. 3959 DCHECK(local->location() == VariableLocation::CONTEXT); // Must be context.
3962 Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine, 3960 Node* fast = BuildVariableLoad(local, bailout_id, states, feedback, combine,
3963 typeof_mode); 3961 typeof_mode);
3964 environment()->Push(fast); 3962 environment()->Push(fast);
3965 slow_block.Break(); 3963 slow_block.Break();
3966 environment()->Pop(); 3964 environment()->Pop();
3967 fast_block.EndBlock(); 3965 fast_block.EndBlock();
3968 3966
3969 // Slow case, because variable potentially shadowed. Perform dynamic lookup. 3967 // Slow case, because variable potentially shadowed. Perform dynamic lookup.
3970 const Operator* op = javascript()->LoadDynamic(name, typeof_mode); 3968 Node* slow = BuildDynamicLoad(name, typeof_mode);
3971 Node* slow = NewNode(op, BuildLoadFeedbackVector(), current_context());
3972 states.AddToNode(slow, bailout_id, combine); 3969 states.AddToNode(slow, bailout_id, combine);
3973 environment()->Push(slow); 3970 environment()->Push(slow);
3974 slow_block.EndBlock(); 3971 slow_block.EndBlock();
3975 3972
3976 return environment()->Pop(); 3973 return environment()->Pop();
3977 } 3974 }
3978 3975
3979 return nullptr; 3976 return nullptr;
3980 } 3977 }
3981 3978
(...skipping 373 matching lines...) Expand 10 before | Expand all | Expand 10 after
4355 // Phi does not exist yet, introduce one. 4352 // Phi does not exist yet, introduce one.
4356 value = NewPhi(inputs, value, control); 4353 value = NewPhi(inputs, value, control);
4357 value->ReplaceInput(inputs - 1, other); 4354 value->ReplaceInput(inputs - 1, other);
4358 } 4355 }
4359 return value; 4356 return value;
4360 } 4357 }
4361 4358
4362 } // namespace compiler 4359 } // namespace compiler
4363 } // namespace internal 4360 } // namespace internal
4364 } // namespace v8 4361 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/ast-graph-builder.h ('k') | src/compiler/bytecode-graph-builder.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698