Index: runtime/vm/intermediate_language_ia32.cc |
=================================================================== |
--- runtime/vm/intermediate_language_ia32.cc (revision 8343) |
+++ runtime/vm/intermediate_language_ia32.cc (working copy) |
@@ -30,7 +30,7 @@ |
} |
-void BindInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void BindInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
computation()->EmitNativeCode(compiler); |
__ pushl(locs()->out().reg()); |
} |
@@ -46,7 +46,7 @@ |
} |
-void ReturnInstr::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void ReturnInstr::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register result = locs()->in(0).reg(); |
Register temp = locs()->temp(0).reg(); |
ASSERT(result == EAX); |
@@ -112,7 +112,7 @@ |
} |
-void LoadLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void LoadLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register result = locs()->out().reg(); |
__ movl(result, Address(EBP, local().index() * kWordSize)); |
} |
@@ -123,7 +123,7 @@ |
} |
-void StoreLocalComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void StoreLocalComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register value = locs()->in(0).reg(); |
Register result = locs()->out().reg(); |
ASSERT(result == value); // Assert that register assignment is correct. |
@@ -136,7 +136,7 @@ |
} |
-void ConstantVal::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void ConstantVal::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register result = locs()->out().reg(); |
if (value().IsSmi()) { |
int32_t imm = reinterpret_cast<int32_t>(value().raw()); |
@@ -157,7 +157,7 @@ |
} |
-void AssertBooleanComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void AssertBooleanComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register obj = locs()->in(0).reg(); |
Register result = locs()->out().reg(); |
@@ -192,7 +192,7 @@ |
} |
-void EqualityCompareComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void EqualityCompareComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register left = locs()->in(0).reg(); |
Register right = locs()->in(1).reg(); |
Register result = locs()->out().reg(); |
@@ -243,7 +243,7 @@ |
} |
-void NativeCallComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void NativeCallComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
ASSERT(locs()->temp(0).reg() == EAX); |
ASSERT(locs()->temp(1).reg() == ECX); |
ASSERT(locs()->temp(2).reg() == EDX); |
@@ -273,7 +273,7 @@ |
} |
-void StoreIndexedComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void StoreIndexedComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register receiver = locs()->in(0).reg(); |
Register index = locs()->in(1).reg(); |
Register value = locs()->in(2).reg(); |
@@ -299,11 +299,10 @@ |
LocationSummary* InstanceSetterComp::MakeLocationSummary() const { |
const intptr_t kNumInputs = 2; |
return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
- return NULL; |
} |
-void InstanceSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void InstanceSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register receiver = locs()->in(0).reg(); |
Register value = locs()->in(1).reg(); |
Register result = locs()->out().reg(); |
@@ -332,22 +331,46 @@ |
LocationSummary* StaticSetterComp::MakeLocationSummary() const { |
- return NULL; |
+ const intptr_t kNumInputs = 1; |
+ return LocationSummary::Make(kNumInputs, Location::RequiresRegister()); |
} |
-void StaticSetterComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+void StaticSetterComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
+ Register value = locs()->in(0).reg(); |
+ Register result = locs()->out().reg(); |
+ |
+ // Preserve the argument as the result of the computation, |
+ // then call the setter. |
+ |
+ // Duplicate the argument. |
+ // TODO(fschneider): Avoid preserving the value if the result is not used. |
+ __ pushl(value); |
+ __ pushl(value); |
+ compiler->GenerateStaticCall(cid(), |
+ token_index(), |
+ try_index(), |
+ setter_function(), |
+ 1, |
+ Array::ZoneHandle()); |
+ __ popl(result); |
} |
LocationSummary* LoadInstanceFieldComp::MakeLocationSummary() const { |
- return NULL; |
+ // TODO(fschneider): For this instruction the input register may be |
+ // reused for the result (but is not required to) because the input |
+ // is not used after the result is defined. We should consider adding |
+ // this information to the input policy. |
+ return LocationSummary::Make(1, Location::RequiresRegister()); |
} |
-void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+void LoadInstanceFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
+ Register instance = locs()->in(0).reg(); |
+ Register result = locs()->out().reg(); |
+ |
+ __ movl(result, FieldAddress(instance, field().Offset())); |
} |
@@ -356,7 +379,7 @@ |
} |
-void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void LoadStaticFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register result = locs()->out().reg(); |
__ LoadObject(result, field()); |
__ movl(result, FieldAddress(result, Field::value_offset())); |
@@ -373,7 +396,7 @@ |
} |
-void InstanceOfComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void InstanceOfComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
ASSERT(locs()->in(0).reg() == EAX); // Value. |
ASSERT(locs()->in(1).reg() == ECX); // Instantiator. |
ASSERT(locs()->in(2).reg() == EDX); // Instantiator type arguments. |
@@ -402,7 +425,7 @@ |
} |
-void CreateArrayComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void CreateArrayComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register temp_reg = locs()->temp(0).reg(); |
Register result_reg = locs()->out().reg(); |
ASSERT(temp_reg == EDX); |
@@ -430,7 +453,7 @@ |
void AllocateObjectWithBoundsCheckComp::EmitNativeCode( |
- FlowGraphCompiler* compiler) { |
+ FlowGraphCompilerShared* compiler) { |
const Class& cls = Class::ZoneHandle(constructor().owner()); |
Register type_arguments = locs()->in(0).reg(); |
Register instantiator_type_arguments = locs()->in(1).reg(); |
@@ -457,7 +480,7 @@ |
} |
-void LoadVMFieldComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void LoadVMFieldComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register obj = locs()->in(0).reg(); |
Register result = locs()->out().reg(); |
@@ -477,7 +500,7 @@ |
void InstantiateTypeArgumentsComp::EmitNativeCode( |
- FlowGraphCompiler* compiler) { |
+ FlowGraphCompilerShared* compiler) { |
Register instantiator_reg = locs()->in(0).reg(); |
Register temp = locs()->temp(0).reg(); |
Register result_reg = locs()->out().reg(); |
@@ -537,7 +560,7 @@ |
void ExtractConstructorTypeArgumentsComp::EmitNativeCode( |
- FlowGraphCompiler* compiler) { |
+ FlowGraphCompilerShared* compiler) { |
Register instantiator_reg = locs()->in(0).reg(); |
Register result_reg = locs()->out().reg(); |
ASSERT(instantiator_reg == result_reg); |
@@ -594,7 +617,7 @@ |
void ExtractConstructorInstantiatorComp::EmitNativeCode( |
- FlowGraphCompiler* compiler) { |
+ FlowGraphCompilerShared* compiler) { |
ASSERT(instantiator()->IsUse()); |
Register instantiator_reg = locs()->in(0).reg(); |
ASSERT(locs()->out().reg() == instantiator_reg); |
@@ -658,7 +681,7 @@ |
} |
-void AllocateContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void AllocateContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
ASSERT(locs()->temp(0).reg() == EDX); |
ASSERT(locs()->out().reg() == EAX); |
@@ -677,7 +700,7 @@ |
} |
-void CloneContextComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void CloneContextComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
Register context_value = locs()->in(0).reg(); |
Register result = locs()->out().reg(); |
@@ -693,12 +716,27 @@ |
LocationSummary* CatchEntryComp::MakeLocationSummary() const { |
- return NULL; |
+ return LocationSummary::Make(0, Location::NoLocation()); |
} |
-void CatchEntryComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
- UNIMPLEMENTED(); |
+// Restore stack and initialize the two exception variables: |
+// exception and stack trace variables. |
+void CatchEntryComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
+ // Restore RSP from RBP as we are coming from a throw and the code for |
+ // popping arguments has not been run. |
+ const intptr_t locals_space_size = compiler->StackSize() * kWordSize; |
+ ASSERT(locals_space_size >= 0); |
+ const intptr_t offset_size = |
+ -locals_space_size + FlowGraphCompiler::kLocalsOffsetFromFP; |
+ __ leal(ESP, Address(EBP, offset_size)); |
+ |
+ ASSERT(!exception_var().is_captured()); |
+ ASSERT(!stacktrace_var().is_captured()); |
+ __ movl(Address(EBP, exception_var().index() * kWordSize), |
+ kExceptionObjectReg); |
+ __ movl(Address(EBP, stacktrace_var().index() * kWordSize), |
+ kStackTraceObjectReg); |
} |
@@ -713,7 +751,7 @@ |
} |
-void BinaryOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void BinaryOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
// TODO(srdjan): Remove this code once BinaryOpComp has been implemeneted |
// for all intended operations. |
Register left = locs()->in(0).reg(); |
@@ -738,7 +776,7 @@ |
} |
-void UnarySmiOpComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void UnarySmiOpComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
const ICData& ic_data = *instance_call()->ic_data(); |
ASSERT(!ic_data.IsNull()); |
ASSERT(ic_data.num_args_tested() == 1); |
@@ -789,7 +827,7 @@ |
} |
-void NumberNegateComp::EmitNativeCode(FlowGraphCompiler* compiler) { |
+void NumberNegateComp::EmitNativeCode(FlowGraphCompilerShared* compiler) { |
const ICData& ic_data = *instance_call()->ic_data(); |
ASSERT(!ic_data.IsNull()); |
ASSERT(ic_data.num_args_tested() == 1); |