diff --git a/src/compiler.cpp b/src/compiler.cpp index 9baa9b4c2f..6d6d63810a 100644 --- a/src/compiler.cpp +++ b/src/compiler.cpp @@ -120,12 +120,16 @@ class State { class LogicalInstruction { public: + LogicalInstruction() { + memset(this, 0, sizeof(LogicalInstruction)); + } + Event* firstEvent; Event* lastEvent; LogicalInstruction* immediatePredecessor; Stack* stack; Value** locals; - Promise* machineOffset; + Assembler::Offset* machineOffset; int index; bool stackSaved; }; @@ -226,6 +230,7 @@ class Context { lastConstant(0), machineCode(0), firstEvent(0), + lastEvent(0), logicalIp(-1), constantCount(0), nextSequence(0), @@ -255,6 +260,7 @@ class Context { ConstantPoolNode* lastConstant; uint8_t* machineCode; Event* firstEvent; + Event* lastEvent; int logicalIp; unsigned constantCount; unsigned nextSequence; @@ -369,9 +375,14 @@ class Event { { assert(c, c->logicalIp >= 0); - if (logicalInstruction->lastEvent) { - logicalInstruction->lastEvent->next = this; + if (c->lastEvent) { + c->lastEvent->next = this; } else { + c->firstEvent = this; + } + c->lastEvent = this; + + if (logicalInstruction->firstEvent == 0) { logicalInstruction->firstEvent = this; } logicalInstruction->lastEvent = this; @@ -2475,6 +2486,10 @@ compile(Context* c) for (Event* e = c->firstEvent; e; e = e->next) { e->block = block; + if (e->logicalInstruction->machineOffset == 0) { + e->logicalInstruction->machineOffset = a->offset(); + } + Event* predecessor = static_cast(e->predecessors->value); if (e->predecessors->next) { setSites(c, e, predecessor->junctionSites); diff --git a/src/x86.cpp b/src/x86.cpp index cc833e0ab5..07737c3287 100644 --- a/src/x86.cpp +++ b/src/x86.cpp @@ -48,10 +48,19 @@ isInt32(intptr_t v) class Task; +class Block { + public: + Block(unsigned offset): offset(offset), start(~0) { } + + unsigned offset; + unsigned start; +}; + class Context { public: Context(System* s, Allocator* a, Zone* zone): - s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0) + s(s), zone(zone), client(0), code(s, a, 1024), tasks(0), result(0), + block(0) { } System* s; @@ -60,6 +69,7 @@ class Context { Vector code; Task* tasks; uint8_t* result; + Block* block; }; typedef void (*OperationType)(Context*); @@ -924,6 +934,31 @@ class MyArchitecture: public Assembler::Architecture { unsigned referenceCount; }; +class MyOffset: public Assembler::Offset { + public: + MyOffset(Context* c, Block* block, unsigned offset): + c(c), block(block), offset(offset) + { } + + virtual unsigned resolve(unsigned start) { + block->start = start; + return value(); + } + + virtual bool resolved() { + return block->start != static_cast(~0); + } + + virtual unsigned value() { + assert(c, resolved()); + return block->start + (offset - block->offset); + } + + Context* c; + Block* block; + unsigned offset; +}; + class MyAssembler: public Assembler { public: MyAssembler(System* s, Allocator* a, Zone* zone, MyArchitecture* arch): @@ -1043,12 +1078,12 @@ class MyAssembler: public Assembler { } virtual Offset* offset() { - // todo - return 0; + return new (c.zone->allocate(sizeof(MyOffset))) + MyOffset(&c, c.block, c.code.length()); } virtual void endBlock() { - // todo + c.block = new (c.zone->allocate(sizeof(Block))) Block(c.code.length()); } virtual unsigned length() {