OLD | NEW |
---|---|
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 556 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
567 // <global>.<variable> and perform a (regular non-contextual) property | 567 // <global>.<variable> and perform a (regular non-contextual) property |
568 // load to make sure we do not get reference errors. | 568 // load to make sure we do not get reference errors. |
569 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); | 569 Slot global(variable, Slot::CONTEXT, Context::GLOBAL_INDEX); |
570 Literal key(variable->name()); | 570 Literal key(variable->name()); |
571 Property property(&global, &key, RelocInfo::kNoPosition); | 571 Property property(&global, &key, RelocInfo::kNoPosition); |
572 Reference ref(this, &property); | 572 Reference ref(this, &property); |
573 ref.GetValue(); | 573 ref.GetValue(); |
574 } else if (variable != NULL && variable->slot() != NULL) { | 574 } else if (variable != NULL && variable->slot() != NULL) { |
575 // For a variable that rewrites to a slot, we signal it is the immediate | 575 // For a variable that rewrites to a slot, we signal it is the immediate |
576 // subexpression of a typeof. | 576 // subexpression of a typeof. |
577 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); | 577 Result result = |
578 LoadFromSlotCheckForArguments(variable->slot(), INSIDE_TYPEOF); | |
579 frame()->Push(&result); | |
578 } else { | 580 } else { |
579 // Anything else can be handled normally. | 581 // Anything else can be handled normally. |
580 Load(expr); | 582 Load(expr); |
581 } | 583 } |
582 } | 584 } |
583 | 585 |
584 | 586 |
585 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { | 587 ArgumentsAllocationMode CodeGenerator::ArgumentsMode() { |
586 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; | 588 if (scope()->arguments() == NULL) return NO_ARGUMENTS_ALLOCATION; |
587 ASSERT(scope()->arguments_shadow() != NULL); | 589 ASSERT(scope()->arguments_shadow() != NULL); |
(...skipping 28 matching lines...) Expand all Loading... | |
616 Variable* arguments = scope()->arguments()->var(); | 618 Variable* arguments = scope()->arguments()->var(); |
617 Variable* shadow = scope()->arguments_shadow()->var(); | 619 Variable* shadow = scope()->arguments_shadow()->var(); |
618 ASSERT(arguments != NULL && arguments->slot() != NULL); | 620 ASSERT(arguments != NULL && arguments->slot() != NULL); |
619 ASSERT(shadow != NULL && shadow->slot() != NULL); | 621 ASSERT(shadow != NULL && shadow->slot() != NULL); |
620 JumpTarget done; | 622 JumpTarget done; |
621 bool skip_arguments = false; | 623 bool skip_arguments = false; |
622 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { | 624 if (mode == LAZY_ARGUMENTS_ALLOCATION && !initial) { |
623 // We have to skip storing into the arguments slot if it has already | 625 // We have to skip storing into the arguments slot if it has already |
624 // been written to. This can happen if the a function has a local | 626 // been written to. This can happen if the a function has a local |
625 // variable named 'arguments'. | 627 // variable named 'arguments'. |
626 LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); | 628 Result probe = LoadFromSlot(arguments->slot(), NOT_INSIDE_TYPEOF); |
627 Result probe = frame_->Pop(); | |
628 if (probe.is_constant()) { | 629 if (probe.is_constant()) { |
629 // We have to skip updating the arguments object if it has | 630 // We have to skip updating the arguments object if it has |
630 // been assigned a proper value. | 631 // been assigned a proper value. |
631 skip_arguments = !probe.handle()->IsTheHole(); | 632 skip_arguments = !probe.handle()->IsTheHole(); |
632 } else { | 633 } else { |
633 __ cmp(Operand(probe.reg()), Immediate(Factory::the_hole_value())); | 634 __ cmp(Operand(probe.reg()), Immediate(Factory::the_hole_value())); |
634 probe.Unuse(); | 635 probe.Unuse(); |
635 done.Branch(not_equal); | 636 done.Branch(not_equal); |
636 } | 637 } |
637 } | 638 } |
(...skipping 1692 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2330 frame()->Dup(); | 2331 frame()->Dup(); |
2331 Handle<String> name = Factory::LookupAsciiSymbol("apply"); | 2332 Handle<String> name = Factory::LookupAsciiSymbol("apply"); |
2332 frame()->Push(name); | 2333 frame()->Push(name); |
2333 Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET); | 2334 Result answer = frame()->CallLoadIC(RelocInfo::CODE_TARGET); |
2334 __ nop(); | 2335 __ nop(); |
2335 frame()->Push(&answer); | 2336 frame()->Push(&answer); |
2336 | 2337 |
2337 // Load the receiver and the existing arguments object onto the | 2338 // Load the receiver and the existing arguments object onto the |
2338 // expression stack. Avoid allocating the arguments object here. | 2339 // expression stack. Avoid allocating the arguments object here. |
2339 Load(receiver); | 2340 Load(receiver); |
2340 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); | 2341 Result existing_args = |
2342 LoadFromSlot(scope()->arguments()->var()->slot(), NOT_INSIDE_TYPEOF); | |
2343 frame()->Push(&existing_args); | |
2341 | 2344 |
2342 // Emit the source position information after having loaded the | 2345 // Emit the source position information after having loaded the |
2343 // receiver and the arguments. | 2346 // receiver and the arguments. |
2344 CodeForSourcePosition(position); | 2347 CodeForSourcePosition(position); |
2345 // Contents of frame at this point: | 2348 // Contents of frame at this point: |
2346 // Frame[0]: arguments object of the current function or the hole. | 2349 // Frame[0]: arguments object of the current function or the hole. |
2347 // Frame[1]: receiver | 2350 // Frame[1]: receiver |
2348 // Frame[2]: applicand.apply | 2351 // Frame[2]: applicand.apply |
2349 // Frame[3]: applicand. | 2352 // Frame[3]: applicand. |
2350 | 2353 |
(...skipping 1632 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3983 exit.Jump(); | 3986 exit.Jump(); |
3984 else_.Bind(); | 3987 else_.Bind(); |
3985 Load(node->else_expression()); | 3988 Load(node->else_expression()); |
3986 } | 3989 } |
3987 } | 3990 } |
3988 | 3991 |
3989 exit.Bind(); | 3992 exit.Bind(); |
3990 } | 3993 } |
3991 | 3994 |
3992 | 3995 |
3993 void CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { | 3996 Result CodeGenerator::LoadFromSlot(Slot* slot, TypeofState typeof_state) { |
3997 Result result; | |
fschneider
2010/02/12 12:23:06
I'd move the declaration into the innermost necess
Kevin Millikin (Chromium)
2010/02/12 12:39:21
Ultimately it will be a field in the codegen state
| |
3994 if (slot->type() == Slot::LOOKUP) { | 3998 if (slot->type() == Slot::LOOKUP) { |
3995 ASSERT(slot->var()->is_dynamic()); | 3999 ASSERT(slot->var()->is_dynamic()); |
fschneider
2010/02/12 12:23:06
Declare result here instead.
| |
3996 | |
3997 JumpTarget slow; | 4000 JumpTarget slow; |
3998 JumpTarget done; | 4001 JumpTarget done; |
3999 Result value; | |
4000 | 4002 |
4001 // Generate fast-case code for variables that might be shadowed by | 4003 // Generate fast-case code for variables that might be shadowed by |
4002 // eval-introduced variables. Eval is used a lot without | 4004 // eval-introduced variables. Eval is used a lot without |
4003 // introducing variables. In those cases, we do not want to | 4005 // introducing variables. In those cases, we do not want to |
4004 // perform a runtime call for all variables in the scope | 4006 // perform a runtime call for all variables in the scope |
4005 // containing the eval. | 4007 // containing the eval. |
4006 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { | 4008 if (slot->var()->mode() == Variable::DYNAMIC_GLOBAL) { |
4007 value = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow); | 4009 result = LoadFromGlobalSlotCheckExtensions(slot, typeof_state, &slow); |
4008 // If there was no control flow to slow, we can exit early. | 4010 // If there was no control flow to slow, we can exit early. |
4009 if (!slow.is_linked()) { | 4011 if (!slow.is_linked()) return result; |
4010 frame_->Push(&value); | 4012 done.Jump(&result); |
4011 return; | |
4012 } | |
4013 | |
4014 done.Jump(&value); | |
4015 | 4013 |
4016 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { | 4014 } else if (slot->var()->mode() == Variable::DYNAMIC_LOCAL) { |
4017 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); | 4015 Slot* potential_slot = slot->var()->local_if_not_shadowed()->slot(); |
fschneider
2010/02/12 12:23:06
Declare result here.
| |
4018 // Only generate the fast case for locals that rewrite to slots. | 4016 // Only generate the fast case for locals that rewrite to slots. |
4019 // This rules out argument loads. | 4017 // This rules out argument loads. |
4020 if (potential_slot != NULL) { | 4018 if (potential_slot != NULL) { |
4021 // Allocate a fresh register to use as a temp in | 4019 // Allocate a fresh register to use as a temp in |
4022 // ContextSlotOperandCheckExtensions and to hold the result | 4020 // ContextSlotOperandCheckExtensions and to hold the result |
4023 // value. | 4021 // value. |
4024 value = allocator_->Allocate(); | 4022 result = allocator()->Allocate(); |
4025 ASSERT(value.is_valid()); | 4023 ASSERT(result.is_valid()); |
4026 __ mov(value.reg(), | 4024 __ mov(result.reg(), |
4027 ContextSlotOperandCheckExtensions(potential_slot, | 4025 ContextSlotOperandCheckExtensions(potential_slot, |
4028 value, | 4026 result, |
4029 &slow)); | 4027 &slow)); |
4030 if (potential_slot->var()->mode() == Variable::CONST) { | 4028 if (potential_slot->var()->mode() == Variable::CONST) { |
4031 __ cmp(value.reg(), Factory::the_hole_value()); | 4029 __ cmp(result.reg(), Factory::the_hole_value()); |
4032 done.Branch(not_equal, &value); | 4030 done.Branch(not_equal, &result); |
4033 __ mov(value.reg(), Factory::undefined_value()); | 4031 __ mov(result.reg(), Factory::undefined_value()); |
4034 } | 4032 } |
4035 // There is always control flow to slow from | 4033 // There is always control flow to slow from |
4036 // ContextSlotOperandCheckExtensions so we have to jump around | 4034 // ContextSlotOperandCheckExtensions so we have to jump around |
4037 // it. | 4035 // it. |
4038 done.Jump(&value); | 4036 done.Jump(&result); |
4039 } | 4037 } |
4040 } | 4038 } |
4041 | 4039 |
4042 slow.Bind(); | 4040 slow.Bind(); |
4043 // A runtime call is inevitable. We eagerly sync frame elements | 4041 // A runtime call is inevitable. We eagerly sync frame elements |
4044 // to memory so that we can push the arguments directly into place | 4042 // to memory so that we can push the arguments directly into place |
4045 // on top of the frame. | 4043 // on top of the frame. |
4046 frame_->SyncRange(0, frame_->element_count() - 1); | 4044 frame()->SyncRange(0, frame()->element_count() - 1); |
4047 frame_->EmitPush(esi); | 4045 frame()->EmitPush(esi); |
4048 frame_->EmitPush(Immediate(slot->var()->name())); | 4046 frame()->EmitPush(Immediate(slot->var()->name())); |
4049 if (typeof_state == INSIDE_TYPEOF) { | 4047 if (typeof_state == INSIDE_TYPEOF) { |
4050 value = | 4048 result = |
4051 frame_->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); | 4049 frame()->CallRuntime(Runtime::kLoadContextSlotNoReferenceError, 2); |
4052 } else { | 4050 } else { |
4053 value = frame_->CallRuntime(Runtime::kLoadContextSlot, 2); | 4051 result = frame()->CallRuntime(Runtime::kLoadContextSlot, 2); |
4054 } | 4052 } |
4055 | 4053 |
4056 done.Bind(&value); | 4054 done.Bind(&result); |
4057 frame_->Push(&value); | 4055 return result; |
4058 | 4056 |
4059 } else if (slot->var()->mode() == Variable::CONST) { | 4057 } else if (slot->var()->mode() == Variable::CONST) { |
4060 // Const slots may contain 'the hole' value (the constant hasn't been | 4058 // Const slots may contain 'the hole' value (the constant hasn't been |
4061 // initialized yet) which needs to be converted into the 'undefined' | 4059 // initialized yet) which needs to be converted into the 'undefined' |
4062 // value. | 4060 // value. |
4063 // | 4061 // |
4064 // We currently spill the virtual frame because constants use the | 4062 // We currently spill the virtual frame because constants use the |
4065 // potentially unsafe direct-frame access of SlotOperand. | 4063 // potentially unsafe direct-frame access of SlotOperand. |
4066 VirtualFrame::SpilledScope spilled_scope; | 4064 VirtualFrame::SpilledScope spilled_scope; |
4067 Comment cmnt(masm_, "[ Load const"); | 4065 Comment cmnt(masm_, "[ Load const"); |
4068 JumpTarget exit; | 4066 Label exit; |
4069 __ mov(ecx, SlotOperand(slot, ecx)); | 4067 __ mov(ecx, SlotOperand(slot, ecx)); |
4070 __ cmp(ecx, Factory::the_hole_value()); | 4068 __ cmp(ecx, Factory::the_hole_value()); |
4071 exit.Branch(not_equal); | 4069 __ j(not_equal, &exit); |
4072 __ mov(ecx, Factory::undefined_value()); | 4070 __ mov(ecx, Factory::undefined_value()); |
4073 exit.Bind(); | 4071 __ bind(&exit); |
4074 frame_->EmitPush(ecx); | 4072 return Result(ecx); |
4075 | 4073 |
4076 } else if (slot->type() == Slot::PARAMETER) { | 4074 } else if (slot->type() == Slot::PARAMETER) { |
4077 frame_->PushParameterAt(slot->index()); | 4075 frame()->PushParameterAt(slot->index()); |
4076 return frame()->Pop(); | |
fschneider
2010/02/12 12:23:06
Would it make sense to have a virtual frame functi
Kevin Millikin (Chromium)
2010/02/12 12:39:21
Yes, and PushParameterAt should go away. That's a
| |
4078 | 4077 |
4079 } else if (slot->type() == Slot::LOCAL) { | 4078 } else if (slot->type() == Slot::LOCAL) { |
4080 frame_->PushLocalAt(slot->index()); | 4079 frame()->PushLocalAt(slot->index()); |
4080 return frame()->Pop(); | |
4081 | 4081 |
4082 } else { | 4082 } else { |
4083 // The other remaining slot types (LOOKUP and GLOBAL) cannot reach | 4083 // The other remaining slot types (LOOKUP and GLOBAL) cannot reach |
fschneider
2010/02/12 12:23:06
Declare result here.
| |
4084 // here. | 4084 // here. |
4085 // | 4085 // |
4086 // The use of SlotOperand below is safe for an unspilled frame | 4086 // The use of SlotOperand below is safe for an unspilled frame |
4087 // because it will always be a context slot. | 4087 // because it will always be a context slot. |
4088 ASSERT(slot->type() == Slot::CONTEXT); | 4088 ASSERT(slot->type() == Slot::CONTEXT); |
4089 Result temp = allocator_->Allocate(); | 4089 result = allocator()->Allocate(); |
4090 ASSERT(temp.is_valid()); | 4090 ASSERT(result.is_valid()); |
4091 __ mov(temp.reg(), SlotOperand(slot, temp.reg())); | 4091 __ mov(result.reg(), SlotOperand(slot, result.reg())); |
4092 frame_->Push(&temp); | 4092 return result; |
4093 } | 4093 } |
4094 } | 4094 } |
4095 | 4095 |
4096 | 4096 |
4097 void CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot, | 4097 Result CodeGenerator::LoadFromSlotCheckForArguments(Slot* slot, |
4098 TypeofState state) { | 4098 TypeofState state) { |
4099 LoadFromSlot(slot, state); | 4099 Result result = LoadFromSlot(slot, state); |
4100 | 4100 |
4101 // Bail out quickly if we're not using lazy arguments allocation. | 4101 // Bail out quickly if we're not using lazy arguments allocation. |
4102 if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return; | 4102 if (ArgumentsMode() != LAZY_ARGUMENTS_ALLOCATION) return result; |
4103 | 4103 |
4104 // ... or if the slot isn't a non-parameter arguments slot. | 4104 // ... or if the slot isn't a non-parameter arguments slot. |
4105 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return; | 4105 if (slot->type() == Slot::PARAMETER || !slot->is_arguments()) return result; |
4106 | |
4107 // Pop the loaded value from the stack. | |
4108 Result value = frame_->Pop(); | |
4109 | 4106 |
4110 // If the loaded value is a constant, we know if the arguments | 4107 // If the loaded value is a constant, we know if the arguments |
4111 // object has been lazily loaded yet. | 4108 // object has been lazily loaded yet. |
4112 if (value.is_constant()) { | 4109 if (result.is_constant()) { |
4113 if (value.handle()->IsTheHole()) { | 4110 if (result.handle()->IsTheHole()) { |
4114 Result arguments = StoreArgumentsObject(false); | 4111 result.Unuse(); |
4115 frame_->Push(&arguments); | 4112 return StoreArgumentsObject(false); |
4116 } else { | 4113 } else { |
4117 frame_->Push(&value); | 4114 return result; |
4118 } | 4115 } |
4119 return; | |
4120 } | 4116 } |
4121 | 4117 |
4122 // The loaded value is in a register. If it is the sentinel that | 4118 // The loaded value is in a register. If it is the sentinel that |
4123 // indicates that we haven't loaded the arguments object yet, we | 4119 // indicates that we haven't loaded the arguments object yet, we |
4124 // need to do it now. | 4120 // need to do it now. |
4125 JumpTarget exit; | 4121 JumpTarget exit; |
4126 __ cmp(Operand(value.reg()), Immediate(Factory::the_hole_value())); | 4122 __ cmp(Operand(result.reg()), Immediate(Factory::the_hole_value())); |
4127 frame_->Push(&value); | 4123 exit.Branch(not_equal, &result); |
4128 exit.Branch(not_equal); | 4124 |
4129 Result arguments = StoreArgumentsObject(false); | 4125 result.Unuse(); |
4130 frame_->SetElementAt(0, &arguments); | 4126 result = StoreArgumentsObject(false); |
4131 exit.Bind(); | 4127 exit.Bind(&result); |
4128 return result; | |
4132 } | 4129 } |
4133 | 4130 |
4134 | 4131 |
4135 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions( | 4132 Result CodeGenerator::LoadFromGlobalSlotCheckExtensions( |
4136 Slot* slot, | 4133 Slot* slot, |
4137 TypeofState typeof_state, | 4134 TypeofState typeof_state, |
4138 JumpTarget* slow) { | 4135 JumpTarget* slow) { |
4139 // Check that no extension objects have been created by calls to | 4136 // Check that no extension objects have been created by calls to |
4140 // eval from the current scope to the global scope. | 4137 // eval from the current scope to the global scope. |
4141 Register context = esi; | 4138 Register context = esi; |
(...skipping 153 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4295 // scope. | 4292 // scope. |
4296 } | 4293 } |
4297 | 4294 |
4298 exit.Bind(); | 4295 exit.Bind(); |
4299 } | 4296 } |
4300 } | 4297 } |
4301 | 4298 |
4302 | 4299 |
4303 void CodeGenerator::VisitSlot(Slot* node) { | 4300 void CodeGenerator::VisitSlot(Slot* node) { |
4304 Comment cmnt(masm_, "[ Slot"); | 4301 Comment cmnt(masm_, "[ Slot"); |
4305 LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF); | 4302 Result result = LoadFromSlotCheckForArguments(node, NOT_INSIDE_TYPEOF); |
4303 frame()->Push(&result); | |
4306 } | 4304 } |
4307 | 4305 |
4308 | 4306 |
4309 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { | 4307 void CodeGenerator::VisitVariableProxy(VariableProxy* node) { |
4310 Comment cmnt(masm_, "[ VariableProxy"); | 4308 Comment cmnt(masm_, "[ VariableProxy"); |
4311 Variable* var = node->var(); | 4309 Variable* var = node->var(); |
4312 Expression* expr = var->rewrite(); | 4310 Expression* expr = var->rewrite(); |
4313 if (expr != NULL) { | 4311 if (expr != NULL) { |
4314 Visit(expr); | 4312 Visit(expr); |
4315 } else { | 4313 } else { |
(...skipping 2246 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6562 Property* property = expression_->AsProperty(); | 6560 Property* property = expression_->AsProperty(); |
6563 if (property != NULL) { | 6561 if (property != NULL) { |
6564 cgen_->CodeForSourcePosition(property->position()); | 6562 cgen_->CodeForSourcePosition(property->position()); |
6565 } | 6563 } |
6566 | 6564 |
6567 switch (type_) { | 6565 switch (type_) { |
6568 case SLOT: { | 6566 case SLOT: { |
6569 Comment cmnt(masm, "[ Load from Slot"); | 6567 Comment cmnt(masm, "[ Load from Slot"); |
6570 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); | 6568 Slot* slot = expression_->AsVariableProxy()->AsVariable()->slot(); |
6571 ASSERT(slot != NULL); | 6569 ASSERT(slot != NULL); |
6572 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); | 6570 Result result = |
6573 if (!persist_after_get_) { | 6571 cgen_->LoadFromSlotCheckForArguments(slot, NOT_INSIDE_TYPEOF); |
6574 cgen_->UnloadReference(this); | 6572 if (!persist_after_get_) set_unloaded(); |
6575 } | 6573 cgen_->frame()->Push(&result); |
6576 break; | 6574 break; |
6577 } | 6575 } |
6578 | 6576 |
6579 case NAMED: { | 6577 case NAMED: { |
6580 Variable* var = expression_->AsVariableProxy()->AsVariable(); | 6578 Variable* var = expression_->AsVariableProxy()->AsVariable(); |
6581 bool is_global = var != NULL; | 6579 bool is_global = var != NULL; |
6582 ASSERT(!is_global || var->is_global()); | 6580 ASSERT(!is_global || var->is_global()); |
6583 | 6581 |
6584 if (persist_after_get_) { | 6582 if (persist_after_get_) { |
6585 cgen_->frame()->Dup(); | 6583 cgen_->frame()->Dup(); |
(...skipping 3530 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10116 | 10114 |
10117 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) | 10115 // Call the runtime; it returns -1 (less), 0 (equal), or 1 (greater) |
10118 // tagged as a small integer. | 10116 // tagged as a small integer. |
10119 __ bind(&runtime); | 10117 __ bind(&runtime); |
10120 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); | 10118 __ TailCallRuntime(ExternalReference(Runtime::kStringCompare), 2, 1); |
10121 } | 10119 } |
10122 | 10120 |
10123 #undef __ | 10121 #undef __ |
10124 | 10122 |
10125 } } // namespace v8::internal | 10123 } } // namespace v8::internal |
OLD | NEW |