11 Commits
6 changed files with 86 additions and 110 deletions
+8
View File
@@ -1,6 +1,14 @@
RABCDAsm Changelog
==================
RABCDAsm v1.5 (2011.04.14)
--------------------------
* Fixed v1.4 constant pool regression
* Added support for memory-access and sign-extend opcodes
* Speed optimizations
* Documentation updates
RABCDAsm v1.4 (2011.03.07)
--------------------------
+6 -6
View File
@@ -55,12 +55,12 @@ straight-forward as:
git clone git://github.com/CyberShadow/RABCDAsm.git
cd RABCDAsm
dmd rabcdasm abcfile asprogram disassembler autodata murmurhash2a
dmd rabcasm abcfile asprogram assembler autodata murmurhash2a
dmd abcexport swffile zlibx
dmd abcreplace swffile zlibx
dmd swfdecompress swffile zlibx
dmd swf7zcompress swffile zlibx
dmd -O -inline rabcdasm abcfile asprogram disassembler autodata murmurhash2a
dmd -O -inline rabcasm abcfile asprogram assembler autodata murmurhash2a
dmd -O -inline abcexport swffile zlibx
dmd -O -inline abcreplace swffile zlibx
dmd -O -inline swfdecompress swffile zlibx
dmd -O -inline swf7zcompress swffile zlibx
[d2]: http://www.digitalmars.com/d/2.0/
[dmd]: http://www.digitalmars.com/d/download.html
+20 -19
View File
@@ -709,16 +709,16 @@ const OpcodeInfo[256] opcodeInfo = [
/* 0x32 */ {"hasnext2", [OpcodeArgumentType.UIntLiteral, OpcodeArgumentType.UIntLiteral]},
/* 0x33 */ {"pushdecimal", [OpcodeArgumentType.Unknown]},
/* 0x34 */ {"pushdnan", [OpcodeArgumentType.Unknown]},
/* 0x35 */ {"li8", [OpcodeArgumentType.Unknown]},
/* 0x36 */ {"li16", [OpcodeArgumentType.Unknown]},
/* 0x37 */ {"li32", [OpcodeArgumentType.Unknown]},
/* 0x38 */ {"lf32", [OpcodeArgumentType.Unknown]},
/* 0x39 */ {"lf64", [OpcodeArgumentType.Unknown]},
/* 0x3A */ {"si8", [OpcodeArgumentType.Unknown]},
/* 0x3B */ {"si16", [OpcodeArgumentType.Unknown]},
/* 0x3C */ {"si32", [OpcodeArgumentType.Unknown]},
/* 0x3D */ {"sf32", [OpcodeArgumentType.Unknown]},
/* 0x3E */ {"sf64", [OpcodeArgumentType.Unknown]},
/* 0x35 */ {"li8", []},
/* 0x36 */ {"li16", []},
/* 0x37 */ {"li32", []},
/* 0x38 */ {"lf32", []},
/* 0x39 */ {"lf64", []},
/* 0x3A */ {"si8", []},
/* 0x3B */ {"si16", []},
/* 0x3C */ {"si32", []},
/* 0x3D */ {"sf32", []},
/* 0x3E */ {"sf64", []},
/* 0x3F */ {"0x3F", [OpcodeArgumentType.Unknown]},
/* 0x40 */ {"newfunction", [OpcodeArgumentType.Method]},
/* 0x41 */ {"call", [OpcodeArgumentType.UIntLiteral]},
@@ -736,9 +736,9 @@ const OpcodeInfo[256] opcodeInfo = [
/* 0x4D */ {"callinterface", [OpcodeArgumentType.Unknown]},
/* 0x4E */ {"callsupervoid", [OpcodeArgumentType.Multiname, OpcodeArgumentType.UIntLiteral]},
/* 0x4F */ {"callpropvoid", [OpcodeArgumentType.Multiname, OpcodeArgumentType.UIntLiteral]},
/* 0x50 */ {"sxi1", [OpcodeArgumentType.Unknown]},
/* 0x51 */ {"sxi8", [OpcodeArgumentType.Unknown]},
/* 0x52 */ {"sxi16", [OpcodeArgumentType.Unknown]},
/* 0x50 */ {"sxi1", []},
/* 0x51 */ {"sxi8", []},
/* 0x52 */ {"sxi16", []},
/* 0x53 */ {"applytype", [OpcodeArgumentType.UIntLiteral]},
/* 0x54 */ {"0x54", [OpcodeArgumentType.Unknown]},
/* 0x55 */ {"newobject", [OpcodeArgumentType.UIntLiteral]},
@@ -994,12 +994,12 @@ private final class ABCReader
value = readMethodBody();
}
catch (Exception e)
throw new Exception(format("Error at %d (0x%X): %s", pos, pos, e), e);
throw new Exception(format("Error at %d (0x%X):", pos, pos), e);
}
ubyte readU8()
{
assert(pos < buf.length);
enforce(pos < buf.length, "End of file reached");
return buf[pos++];
}
@@ -1047,7 +1047,7 @@ private final class ABCReader
void readExact(void* ptr, size_t len)
{
assert(pos+len <= buf.length);
enforce(pos+len <= buf.length, "End of file reached");
(cast(ubyte*)ptr)[0..len] = buf[pos..pos+len];
pos += len;
}
@@ -1473,7 +1473,7 @@ private final class ABCWriter
foreach (ref value; abc.instances)
writeInstance(value);
assert(abc.classes.length == abc.instances.length);
assert(abc.classes.length == abc.instances.length, "Number of classes and instances differs");
foreach (ref value; abc.classes)
writeClass(value);
@@ -1645,7 +1645,7 @@ private final class ABCWriter
}
if (v.flags & MethodFlags.HAS_PARAM_NAMES)
{
assert(v.paramNames.length == v.paramTypes.length);
assert(v.paramNames.length == v.paramTypes.length, "Mismatching number of parameter names and types");
foreach (value; v.paramNames)
writeU30(value);
}
@@ -1755,7 +1755,8 @@ private final class ABCWriter
// we don't know the length before writing all the instructions - swap buffer with a temporary one
auto globalBuf = buf;
auto globalPos = pos;
buf = new ubyte[1024];
static ubyte[1024*16] methodBuf;
buf = methodBuf[];
pos = 0;
struct Fixup { ABCFile.Label target; uint pos, base; }
+40 -58
View File
@@ -18,6 +18,8 @@
module asprogram;
import std.algorithm;
import core.stdc.string;
import abcfile;
import autodata;
@@ -723,6 +725,19 @@ private final class AStoABC
return value == T.init;
}
static void move(T)(T[] array, size_t from, size_t to)
{
assert(from<array.length && to<array.length);
if (from == to)
return;
T t = array[from];
if (from < to)
memmove(array.ptr+from, array.ptr+from+1, (to-from)*T.sizeof);
else
memmove(array.ptr+to+1, array.ptr+to, (from-to)*T.sizeof);
array[to] = t;
}
/// Maintain an unordered set of values; sort/index by usage count
struct ConstantPool(T, bool haveNull = true)
{
@@ -807,17 +822,8 @@ private final class AStoABC
uint addIndex, index;
void*[] parents;
int opCmp(Entry* o)
{
if (this.parents.contains(o.object))
return 1;
if (o.parents.contains(this.object))
return -1;
if (o.hits==hits)
return addIndex-o.addIndex;
else
return o.hits-hits;
}
mixin AutoToString;
mixin ProcessAllData;
}
Entry[void*] pool;
@@ -867,61 +873,37 @@ private final class AStoABC
void finalize()
{
// assign unique index
// create array
auto all = new Entry*[pool.length];
int i=0;
foreach (ref e; pool)
e.index = i++;
// topographical sort
bool done;
while (!done)
{
done = true;
foreach (ref a; pool)
foreach (parent; a.parents)
{
auto pb = parent in pool;
assert(pb !is null, "Can't find referenced object");
if (pb.index > a.index)
{
auto t = pb.index;
pb.index = a.index;
a.index = t;
done = false;
break;
}
}
}
// copy to array
auto all = new Entry[i];
foreach (ref e; pool)
all[e.index] = e;
all[i++] = &e;
// sort
//all.sort; // sort preserving topological integrity demands compared items to always be adjacent
done = false;
while (!done)
{
done = true;
sort!q{a.hits > b.hits || (a.hits == b.hits && a.addIndex < b.addIndex)}(all);
for (int j=0; j<all.length-1; j++)
if (all[j] > &all[j+1])
// topographical sort
topSort:
// update indices
foreach (j, e; all)
e.index = j;
foreach (ref a; pool)
foreach (parent; a.parents)
{
auto pb = parent in pool;
assert(pb !is null, "Can't find referenced object");
if (pb.index > a.index)
{
auto t = all[j];
all[j] = all[j+1];
all[j+1] = t;
done = false;
move(all, pb.index, a.index);
goto topSort;
}
}
}
objects.length = i;
foreach (j, ref e; all)
{
pool[e.object].index = j;
foreach (j, e; all)
objects[j] = cast(T)e.object;
}
}
uint get(T obj)
@@ -992,7 +974,7 @@ private final class AStoABC
throw new .Exception("Unknown Multiname kind");
}
bool r = multinames.add(multiname);
assert(r);
assert(r, "Recursive multiname reference");
}
}
@@ -1091,7 +1073,7 @@ private final class AStoABC
visitInstance(vclass.instance);
bool r = classes.add(vclass);
assert(r);
assert(r, "Recursive class reference");
}
}
+9 -24
View File
@@ -212,7 +212,7 @@ final class Assembler
static bool isWordChar(char c)
{
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.'; // TODO: use lookup table?
return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9') || c == '_' || c == '-' || c == '+' || c == '.';
}
string readWord()
@@ -1074,24 +1074,14 @@ final class Assembler
foreach (ref f; jumpFixups)
{
try
instructions[f.ii].arguments[f.ai].jumpTarget = parseLabel(f.name, labels);
catch (Exception e)
{
setFile(f.where.load);
throw e;
}
scope(failure) setFile(f.where.load);
instructions[f.ii].arguments[f.ai].jumpTarget = parseLabel(f.name, labels);
}
foreach (ref f; switchFixups)
{
try
instructions[f.ii].arguments[f.ai].switchTargets[f.si] = parseLabel(f.name, labels);
catch (Exception e)
{
setFile(f.where.load);
throw e;
}
scope(failure) setFile(f.where.load);
instructions[f.ii].arguments[f.ai].switchTargets[f.si] = parseLabel(f.name, labels);
}
foreach (ref f; localClassFixups)
@@ -1108,13 +1098,8 @@ final class Assembler
ABCFile.Label readLabel()
{
auto word = readWord();
try
return parseLabel(word, labels);
catch (Exception e)
{
backpedal(word.length);
throw e;
}
scope(failure) backpedal(word.length);
return parseLabel(word, labels);
}
ASProgram.Exception e;
@@ -1216,13 +1201,13 @@ final class Assembler
}
catch (Exception e)
{
string s = files[0].positionStr ~ ": " ~ e.msg;
string s = files[0].positionStr ~ ": ";
if (fileCount == -1)
s ~= "\n\t(inclusion context unavailable)";
else
foreach (ref f; files[1..fileCount])
s ~= "\n\t(included from " ~ f.positionStr ~ ")";
throw new Exception(s);
throw new Exception(s, e);
}
classFixups = null;
+3 -3
View File
@@ -107,9 +107,6 @@ template RawDataHandlerWrapper()
template getMixinRecursive(T, string name, string loopDepth)
{
static if (!hasAliasing!(T))
enum getMixinRecursive = getRawMixin!("&" ~ name, name ~ ".sizeof");
else
static if (is(T U : U[]))
enum getMixinRecursive =
"{ bool _AutoDataNullTest = " ~ name ~ " is null; " ~ getRawMixin!("&_AutoDataNullTest", "bool.sizeof") ~ "}" ~
@@ -119,6 +116,9 @@ template RawDataHandlerWrapper()
"foreach (ref _AutoDataArrayItem" ~ loopDepth ~ "; " ~ name ~ ") {" ~ getMixinRecursive!(U, "_AutoDataArrayItem" ~ loopDepth, loopDepth~"Item") ~ "}"
);
else
static if (!hasAliasing!(T))
enum getMixinRecursive = getRawMixin!("&" ~ name, name ~ ".sizeof");
else
static if (is(typeof((new T).toHash())))
enum getMixinRecursive = name ~ ".processData!(void, ``, ``)(handler);";
else