Major rewrite of relocation and point systems

- Instead of two overloads for JNE and JMP, the relocation overload is
now implemented as an actual relocation (sunJumpNotEqualSite and
sunJumpSite, respectively).
- sunPoint is completely removed, replaced with simple uint.
- Relocations are now associated with a particular binary, instead of
specifying it per relocation.
- Break points and continue points are now relocations, rather than raw
offsets.
- Minor cleanup
This commit is contained in:
arookas 2016-02-12 22:58:48 -05:00
parent 5658eff03f
commit aeb22bc4ed
7 changed files with 192 additions and 171 deletions

View file

@ -38,14 +38,29 @@ namespace arookas {
class sunNode : IEnumerable<sunNode> {
List<sunNode> mChildren;
sunNode mParent;
sunSourceLocation mLocation;
public sunNode Parent { get; private set; }
public sunSourceLocation Location { get; private set; }
public sunNode Parent {
get { return mParent; }
}
public sunSourceLocation Location {
get { return mLocation; }
}
public int Count { get { return mChildren.Count; } }
public sunNode this[int index] { get { return index >= 0 && index < Count ? mChildren[index] : null; } }
public int Count {
get { return mChildren.Count; }
}
public sunNode this[int index] {
get {
if (index < 0 || index >= mChildren.Count) {
return null;
}
return mChildren[index];
}
}
public bool IsRoot { get { return Parent == null; } }
public bool IsRoot { get { return mParent == null; } }
public bool IsBranch { get { return Count > 0; } }
public bool IsLeaf { get { return Count < 1; } }
@ -86,31 +101,31 @@ namespace arookas {
public sunNode(sunSourceLocation location) {
mChildren = new List<sunNode>(5);
Location = location;
mLocation = location;
}
public void Add(sunNode node) {
if (node == null) {
throw new ArgumentNullException("node");
}
if (node.Parent != null) {
node.Parent.Remove(node);
if (node.mParent != null) {
node.mParent.Remove(node);
}
node.Parent = this;
node.mParent = this;
mChildren.Add(node);
}
public void Remove(sunNode node) {
if (node == null) {
throw new ArgumentNullException("node");
}
if (node.Parent == this) {
if (node.mParent == this) {
mChildren.Remove(node);
node.Parent = null;
node.mParent = null;
}
}
public void Clear() {
foreach (var child in this) {
child.Parent = null;
child.mParent = null;
}
mChildren.Clear();
}
@ -128,8 +143,12 @@ namespace arookas {
return true;
}
public IEnumerator<sunNode> GetEnumerator() { return mChildren.GetEnumerator(); }
IEnumerator IEnumerable.GetEnumerator() { return GetEnumerator(); }
public IEnumerator<sunNode> GetEnumerator() {
return mChildren.GetEnumerator();
}
IEnumerator IEnumerable.GetEnumerator() {
return GetEnumerator();
}
}
abstract class sunToken<TValue> : sunNode {

View file

@ -116,12 +116,12 @@ namespace arookas {
public override void Compile(sunCompiler compiler) {
Condition.Compile(compiler);
var falsePrologue = compiler.Binary.WriteJNE();
var falsePrologue = new sunJumpNotEqualSite(compiler.Binary);
TrueBody.Compile(compiler);
var trueEpilogue = compiler.Binary.WriteJMP();
compiler.Binary.ClosePoint(falsePrologue);
var trueEpilogue = new sunJumpSite(compiler.Binary);
falsePrologue.Relocate();
FalseBody.Compile(compiler);
compiler.Binary.ClosePoint(trueEpilogue);
trueEpilogue.Relocate();
}
sunExpressionFlags sunTerm.GetExpressionFlags(sunContext context) {

View file

@ -12,17 +12,17 @@ namespace arookas {
public override void Compile(sunCompiler compiler) {
Condition.Compile(compiler);
var trueBodyEpilogue = compiler.Binary.WriteJNE();
var trueBodyEpilogue = new sunJumpNotEqualSite(compiler.Binary);
TrueBody.Compile(compiler);
var falseBody = FalseBody;
if (falseBody != null) {
var falseBodyEpilogue = compiler.Binary.WriteJMP();
compiler.Binary.ClosePoint(trueBodyEpilogue);
var falseBodyEpilogue = new sunJumpSite(compiler.Binary);
trueBodyEpilogue.Relocate();
falseBody.Compile(compiler);
compiler.Binary.ClosePoint(falseBodyEpilogue);
falseBodyEpilogue.Relocate();
}
else {
compiler.Binary.ClosePoint(trueBodyEpilogue);
trueBodyEpilogue.Relocate();
}
}
}
@ -56,14 +56,14 @@ namespace arookas {
public override void Compile(sunCompiler compiler) {
var loop = PushLoop(compiler.Context);
var bodyPrologue = compiler.Binary.OpenPoint();
loop.ContinuePoint = compiler.Binary.OpenPoint();
var bodyPrologue = compiler.Binary.Offset;
loop.ContinuePoint = compiler.Binary.Offset;
Condition.Compile(compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
var bodyEpilogue = new sunJumpNotEqualSite(compiler.Binary);
Body.Compile(compiler);
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
bodyEpilogue.Relocate();
loop.BreakPoint = compiler.Binary.Offset;
compiler.Context.Loops.Pop(compiler);
}
}
@ -77,14 +77,14 @@ namespace arookas {
public override void Compile(sunCompiler compiler) {
var loop = PushLoop(compiler.Context);
var bodyPrologue = compiler.Binary.OpenPoint();
var bodyPrologue = compiler.Binary.Offset;
Body.Compile(compiler);
loop.ContinuePoint = compiler.Binary.OpenPoint();
loop.ContinuePoint = compiler.Binary.Offset;
Condition.Compile(compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
var bodyEpilogue = new sunJumpNotEqualSite(compiler.Binary);
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
bodyEpilogue.Relocate();
loop.BreakPoint = compiler.Binary.Offset;
compiler.Context.Loops.Pop(compiler);
}
}
@ -104,15 +104,15 @@ namespace arookas {
#endif
var loop = PushLoop(compiler.Context);
TryCompile(Declaration, compiler);
var bodyPrologue = compiler.Binary.OpenPoint();
var bodyPrologue = compiler.Binary.Offset;
TryCompile(Condition, compiler);
var bodyEpilogue = compiler.Binary.WriteJNE();
var bodyEpilogue = new sunJumpNotEqualSite(compiler.Binary);
Body.Compile(compiler);
loop.ContinuePoint = compiler.Binary.OpenPoint();
loop.ContinuePoint = compiler.Binary.Offset;
TryCompile(Iteration, compiler);
compiler.Binary.WriteJMP(bodyPrologue);
compiler.Binary.ClosePoint(bodyEpilogue);
loop.BreakPoint = compiler.Binary.OpenPoint();
bodyEpilogue.Relocate();
loop.BreakPoint = compiler.Binary.Offset;
compiler.Context.Loops.Pop(compiler);
#if SSC_SCOPES
compiler.Context.Scopes.Pop();
@ -158,7 +158,7 @@ namespace arookas {
: base(location) { }
public override void Compile(sunCompiler compiler) {
var point = compiler.Binary.WriteJMP();
var point = new sunJumpSite(compiler.Binary);
var success = true;
if (IsNamed) {
success = compiler.Context.Loops.AddBreak(point, NameLabel.Value);
@ -180,7 +180,7 @@ namespace arookas {
: base(location) { }
public override void Compile(sunCompiler compiler) {
var point = compiler.Binary.WriteJMP();
var point = new sunJumpSite(compiler.Binary);
var success = true;
if (IsNamed) {
success = compiler.Context.Loops.AddContinue(point, NameLabel.Value);

View file

@ -21,14 +21,6 @@ namespace arookas {
public abstract void Back();
public abstract void Goto(uint offset);
public virtual sunPoint OpenPoint() {
return new sunPoint(Offset);
}
public virtual void ClosePoint(sunPoint point) {
ClosePoint(point, Offset);
}
public abstract void ClosePoint(sunPoint point, uint offset);
public virtual void BeginText() {
// stub
}
@ -66,10 +58,8 @@ namespace arookas {
public abstract void WriteMKDS(int display);
public abstract void WriteRET();
public abstract void WriteRET0();
public abstract sunPoint WriteJNE();
public abstract void WriteJNE(sunPoint point);
public abstract sunPoint WriteJMP();
public abstract void WriteJMP(sunPoint point);
public abstract void WriteJNE(uint offset);
public abstract void WriteJMP(uint offset);
public abstract void WritePOP();
public abstract void WriteINT0();
public abstract void WriteINT1();
@ -95,25 +85,6 @@ namespace arookas {
}
}
public struct sunPoint {
readonly uint mOffset;
public uint Offset {
get { return mOffset; }
}
public sunPoint(uint offset) {
mOffset = offset;
}
public static implicit operator sunPoint(uint offset) {
return new sunPoint(offset);
}
public static implicit operator uint(sunPoint point) {
return point.mOffset;
}
}
sealed class sunSpcBinary : sunBinary {
aBinaryWriter mWriter;
sunSpcBinarySection mText, mData, mDataString, mSymbol, mSymbolString;
@ -133,13 +104,6 @@ namespace arookas {
mWriter.PushAnchor();
}
public override void ClosePoint(sunPoint point, uint offset) {
Keep();
Goto(point.Offset);
mText.Writer.Write32(offset);
Back();
}
public override void Close() {
// header
mWriter.WriteString("SPCB");
@ -396,37 +360,19 @@ namespace arookas {
#endif
mText.Writer.Write8(0x21);
}
public override sunPoint WriteJNE() {
public override void WriteJNE(uint offset) {
#if DEBUG
TraceInstruction("jne # UNFINISHED");
TraceInstruction("jne ${0:X8}", offset);
#endif
mText.Writer.Write8(0x22);
sunPoint point = OpenPoint();
mText.Writer.Write32(0); // dummy
return point;
mText.Writer.Write32(offset);
}
public override void WriteJNE(sunPoint point) {
public override void WriteJMP(uint offset) {
#if DEBUG
TraceInstruction("jne {0:X8}", point.Offset);
#endif
mText.Writer.Write8(0x22);
mText.Writer.Write32(point.Offset);
}
public override sunPoint WriteJMP() {
#if DEBUG
TraceInstruction("jmp # UNFINISHED");
TraceInstruction("jmp ${0:X8}", offset);
#endif
mText.Writer.Write8(0x23);
sunPoint point = OpenPoint();
mText.Writer.Write32(0); // dummy
return point;
}
public override void WriteJMP(sunPoint point) {
#if DEBUG
TraceInstruction("jmp {0:X8}", point.Offset);
#endif
mText.Writer.Write8(0x23);
mText.Writer.Write32(point.Offset);
mText.Writer.Write32(offset);
}
public override void WritePOP() {
#if DEBUG

View file

@ -51,21 +51,21 @@ namespace arookas {
mLoops.Clear();
}
public bool AddBreak(sunPoint point) {
public bool AddBreak(sunRelocation point) {
if (Count > 0) {
Top.AddBreak(point);
return true;
}
return false;
}
public bool AddContinue(sunPoint point) {
public bool AddContinue(sunRelocation point) {
if (Count > 0) {
Top.AddContinue(point);
return true;
}
return false;
}
public bool AddBreak(sunPoint point, string name) {
public bool AddBreak(sunRelocation point, string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
@ -78,7 +78,7 @@ namespace arookas {
}
return false;
}
public bool AddContinue(sunPoint point, string name) {
public bool AddContinue(sunRelocation point, string name) {
if (name == null) {
throw new ArgumentNullException("name");
}
@ -96,19 +96,29 @@ namespace arookas {
class sunLoop {
string mName;
List<sunPoint> mBreaks, mContinues;
List<sunRelocation> mBreaks, mContinues;
sunLoopFlags mFlags;
sunPoint mBreakPoint, mContinuePoint;
uint mBreakPoint, mContinuePoint;
public string Name { get { return mName; } }
public bool HasName { get { return Name != null; } }
public sunPoint BreakPoint { get { return mBreakPoint; } set { mBreakPoint = value; } }
public sunPoint ContinuePoint { get { return mContinuePoint; } set { mContinuePoint = value; } }
public string Name {
get { return mName; }
}
public bool HasName {
get { return Name != null; }
}
public uint BreakPoint {
get { return mBreakPoint; }
set { mBreakPoint = value; }
}
public uint ContinuePoint {
get { return mContinuePoint; }
set { mContinuePoint = value; }
}
public sunLoop() {
mName = null;
mBreaks = new List<sunPoint>(5);
mContinues = new List<sunPoint>(5);
mBreaks = new List<sunRelocation>(5);
mContinues = new List<sunRelocation>(5);
mFlags = sunLoopFlags.ConsumeBreak | sunLoopFlags.ConsumeContinue;
}
public sunLoop(sunLoopFlags flags) {
@ -126,14 +136,14 @@ namespace arookas {
return (mFlags & flags) != 0;
}
public bool AddBreak(sunPoint point) {
public bool AddBreak(sunRelocation point) {
if (!HasFlag(sunLoopFlags.ConsumeBreak)) {
return false;
}
mBreaks.Add(point);
return true;
}
public bool AddContinue(sunPoint point) {
public bool AddContinue(sunRelocation point) {
if (!HasFlag(sunLoopFlags.ConsumeContinue)) {
return false;
}
@ -143,12 +153,12 @@ namespace arookas {
public void Close(sunCompiler compiler) {
if (HasFlag(sunLoopFlags.ConsumeBreak)) {
foreach (var b in mBreaks) {
compiler.Binary.ClosePoint(b, mBreakPoint);
b.Relocate();
}
}
if (HasFlag(sunLoopFlags.ConsumeContinue)) {
foreach (var c in mContinues) {
compiler.Binary.ClosePoint(c, mContinuePoint);
c.Relocate();
}
}
}

View file

@ -2,15 +2,25 @@
namespace arookas {
abstract class sunRelocation {
protected sunPoint mPoint;
protected sunBinary mBinary;
protected uint mPoint;
public abstract void Relocate(sunCompiler compiler);
protected sunRelocation(sunBinary binary) {
if (binary == null) {
throw new ArgumentNullException("binary");
}
mBinary = binary;
mPoint = mBinary.Offset;
}
public abstract void Relocate();
}
abstract class sunSymbolRelocation<TSymbol> : sunRelocation where TSymbol : sunSymbol {
protected TSymbol mSymbol;
protected sunRelocation(TSymbol symbol) {
protected sunSymbolRelocation(sunBinary binary, TSymbol symbol)
: base(binary) {
if (symbol == null) {
throw new ArgumentNullException("symbol");
}
@ -21,84 +31,120 @@ namespace arookas {
class sunBuiltinCallSite : sunSymbolRelocation<sunBuiltinSymbol> {
int mArgCount;
public sunBuiltinCallSite(sunBuiltinSymbol symbol, sunCompiler compiler, int argCount)
: base (symbol) {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteFUNC(0, 0);
public sunBuiltinCallSite(sunBinary binary, sunBuiltinSymbol symbol, int argCount)
: base (binary, symbol) {
mArgCount = argCount;
mBinary.WriteFUNC(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteFUNC(mSymbol.Index, mArgCount);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteFUNC(mSymbol.Index, mArgCount);
mBinary.Back();
}
}
class sunFunctionCallSite : sunRelocation<sunFunctionSymbol> {
class sunFunctionCallSite : sunSymbolRelocation<sunFunctionSymbol> {
int mArgCount;
public sunFunctionCallSite(sunFunctionSymbol symbol, sunCompiler compiler, int argCount)
: base(symbol) {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteCALL(0, 0);
public sunFunctionCallSite(sunBinary binary, sunFunctionSymbol symbol, int argCount)
: base(binary, symbol) {
mArgCount = argCount;
mBinary.WriteCALL(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteCALL(mSymbol.Offset, mArgCount);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteCALL(mSymbol.Offset, mArgCount);
mBinary.Back();
}
}
public sunVariableGetSite(sunVariableSymbol symbol, sunCompiler compiler)
: base(symbol) {
class sunVariableGetSite : sunSymbolRelocation<sunVariableSymbol> {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteVAR(0, 0);
public sunVariableGetSite(sunBinary binary, sunVariableSymbol symbol)
: base(binary, symbol) {
mBinary.WriteVAR(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteVAR(mSymbol.Display, mSymbol.Index);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteVAR(mSymbol.Display, mSymbol.Index);
mBinary.Back();
}
}
public sunVariableSetSite(sunVariableSymbol symbol, sunCompiler compiler)
: base(symbol) {
class sunVariableSetSite : sunSymbolRelocation<sunVariableSymbol> {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteASS(0, 0);
public sunVariableSetSite(sunBinary binary, sunVariableSymbol symbol)
: base(binary, symbol) {
mBinary.WriteASS(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteASS(mSymbol.Display, mSymbol.Index);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteASS(mSymbol.Display, mSymbol.Index);
mBinary.Back();
}
}
public sunVariableIncSite(sunVariableSymbol symbol, sunCompiler compiler)
: base(symbol) {
class sunVariableIncSite : sunSymbolRelocation<sunVariableSymbol> {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteINC(0, 0);
public sunVariableIncSite(sunBinary binary, sunVariableSymbol symbol)
: base(binary, symbol) {
mBinary.WriteINC(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteINC(mSymbol.Display, mSymbol.Index);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteINC(mSymbol.Display, mSymbol.Index);
mBinary.Back();
}
}
public sunVariableDecSite(sunVariableSymbol symbol, sunCompiler compiler)
: base(symbol) {
class sunVariableDecSite : sunSymbolRelocation<sunVariableSymbol> {
mPoint = compiler.Binary.OpenPoint();
compiler.Binary.WriteDEC(0, 0);
public sunVariableDecSite(sunBinary binary, sunVariableSymbol symbol)
: base(binary, symbol) {
mBinary.WriteDEC(0, 0);
}
public override void Relocate(sunCompiler compiler) {
compiler.Binary.Goto(mPoint);
compiler.Binary.WriteDEC(mSymbol.Display, mSymbol.Index);
public override void Relocate() {
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteDEC(mSymbol.Display, mSymbol.Index);
mBinary.Back();
}
}
class sunJumpNotEqualSite : sunRelocation {
public sunJumpNotEqualSite(sunBinary binary)
: base(binary) {
mBinary.WriteJNE(0);
}
public override void Relocate() {
var offset = mBinary.Offset;
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteJNE(offset);
mBinary.Back();
}
}
class sunJumpSite : sunRelocation {
public sunJumpSite(sunBinary binary)
: base(binary) {
mBinary.WriteJMP(0);
}
public override void Relocate() {
var offset = mBinary.Offset;
mBinary.Keep();
mBinary.Goto(mPoint);
mBinary.WriteJMP(offset);
mBinary.Back();
}
}
}

View file

@ -93,7 +93,7 @@ namespace arookas {
public void CloseRelocations(sunCompiler compiler) {
compiler.Binary.Keep();
foreach (var relocation in mRelocations) {
relocation.Relocate(compiler);
relocation.Relocate();
}
compiler.Binary.Back();
}
@ -157,7 +157,7 @@ namespace arookas {
++mCompiles;
}
public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) {
return new sunBuiltinCallSite(this, compiler, argCount);
return new sunBuiltinCallSite(compiler.Binary, this, argCount);
}
}
@ -206,7 +206,7 @@ namespace arookas {
++mCompiles;
}
public override sunRelocation CreateCallSite(sunCompiler compiler, int argCount) {
return new sunFunctionCallSite(this, compiler, argCount);
return new sunFunctionCallSite(compiler.Binary, this, argCount);
}
}
@ -298,16 +298,16 @@ namespace arookas {
}
public override void CompileGet(sunCompiler compiler) {
OpenRelocation(new sunVariableGetSite(this, compiler));
OpenRelocation(new sunVariableGetSite(compiler.Binary, this));
}
public override void CompileSet(sunCompiler compiler) {
OpenRelocation(new sunVariableSetSite(this, compiler));
OpenRelocation(new sunVariableSetSite(compiler.Binary, this));
}
public override void CompileInc(sunCompiler compiler) {
OpenRelocation(new sunVariableIncSite(this, compiler));
OpenRelocation(new sunVariableIncSite(compiler.Binary, this));
}
public override void CompileDec(sunCompiler compiler) {
OpenRelocation(new sunVariableDecSite(this, compiler));
OpenRelocation(new sunVariableDecSite(compiler.Binary, this));
}
}