| Index: runtime/vm/flow_graph_compiler_x64.cc
|
| ===================================================================
|
| --- runtime/vm/flow_graph_compiler_x64.cc (revision 5792)
|
| +++ runtime/vm/flow_graph_compiler_x64.cc (working copy)
|
| @@ -192,6 +192,11 @@
|
| }
|
|
|
|
|
| +void FlowGraphCompiler::VisitStoreContext(StoreContextComp* comp) {
|
| + LoadValue(CTX, comp->value());
|
| +}
|
| +
|
| +
|
| void FlowGraphCompiler::VisitClosureCall(ClosureCallComp* comp) {
|
| ASSERT(comp->context()->IsTemp());
|
| ASSERT(VerifyCallComputation(comp));
|
| @@ -254,18 +259,46 @@
|
|
|
| void FlowGraphCompiler::VisitLoadLocal(LoadLocalComp* comp) {
|
| if (comp->local().is_captured()) {
|
| - Bailout("load of context variable");
|
| + // The variable lives in the context.
|
| + intptr_t delta = comp->context_level() -
|
| + comp->local().owner()->context_level();
|
| + ASSERT(delta >= 0);
|
| + Register base = CTX;
|
| + while (delta-- > 0) {
|
| + __ movq(RAX, FieldAddress(base, Context::parent_offset()));
|
| + base = RAX;
|
| + }
|
| + __ movq(RAX,
|
| + FieldAddress(base,
|
| + Context::variable_offset(comp->local().index())));
|
| + } else {
|
| + // The variable lives in the current stack frame.
|
| + __ movq(RAX, Address(RBP, comp->local().index() * kWordSize));
|
| }
|
| - __ movq(RAX, Address(RBP, comp->local().index() * kWordSize));
|
| }
|
|
|
|
|
| void FlowGraphCompiler::VisitStoreLocal(StoreLocalComp* comp) {
|
| + LoadValue(RAX, comp->value());
|
| if (comp->local().is_captured()) {
|
| - Bailout("store to context variable");
|
| + // The variable lives in the context.
|
| + Register scratch = R10;
|
| + intptr_t delta = comp->context_level() -
|
| + comp->local().owner()->context_level();
|
| + ASSERT(delta >= 0);
|
| + Register base = CTX;
|
| + while (delta-- > 0) {
|
| + __ movq(scratch, FieldAddress(base, Context::parent_offset()));
|
| + base = scratch;
|
| + }
|
| + __ StoreIntoObject(
|
| + base,
|
| + FieldAddress(base, Context::variable_offset(comp->local().index())),
|
| + RAX);
|
| + } else {
|
| + // The variable lives in the current stack frame.
|
| + __ movq(Address(RBP, comp->local().index() * kWordSize), RAX);
|
| }
|
| - LoadValue(RAX, comp->value());
|
| - __ movq(Address(RBP, comp->local().index() * kWordSize), RAX);
|
| }
|
|
|
|
|
| @@ -751,6 +784,25 @@
|
| }
|
|
|
|
|
| +void FlowGraphCompiler::VisitAllocateContext(AllocateContextComp* comp) {
|
| + __ movq(R10, Immediate(comp->num_context_variables()));
|
| + const ExternalLabel label("alloc_context",
|
| + StubCode::AllocateContextEntryPoint());
|
| + GenerateCall(comp->token_index(), &label, PcDescriptors::kOther);
|
| +}
|
| +
|
| +
|
| +void FlowGraphCompiler::VisitChainContext(ChainContextComp* comp) {
|
| + __ popq(RAX);
|
| + // Chain the new context in RAX to its parent in CTX.
|
| + __ StoreIntoObject(RAX,
|
| + FieldAddress(RAX, Context::parent_offset()),
|
| + CTX);
|
| + // Set new context as current context.
|
| + __ movq(CTX, RAX);
|
| +}
|
| +
|
| +
|
| void FlowGraphCompiler::VisitBlocks() {
|
| for (intptr_t i = 0; i < block_order_.length(); ++i) {
|
| // Compile the block entry.
|
|
|