Exemple #1
0
 public static Instruction[] Assemble(List<Instruction> bytecode)
 {
     int length = 0;
     var labels = new Dictionary<string, int>();
     foreach (var instruction in bytecode)
     {
         if (instruction.Opcode == Instruction.Opcodes.Label)
         {
             var label = (string)instruction.Arguments;
             if (labels.ContainsKey(label))
             {
                 Utils.Panic();
             }
             labels[label] = length;
         }
         else
         {
             length++;
         }
     }
     var result = new Instruction[length];
     var index = 0;
     foreach (var instruction in bytecode)
     {
         if (instruction.Opcode != Instruction.Opcodes.Label)
         {
             result[index] = instruction;
             index++;
             if (instruction.Opcode == Instruction.Opcodes.Fjump
                 || instruction.Opcode == Instruction.Opcodes.Tjump
                 || instruction.Opcode == Instruction.Opcodes.Jump
                 || instruction.Opcode == Instruction.Opcodes.Block)
             {
                 instruction.Arguments = labels[(string)instruction.Arguments];
             }
             else if (instruction.Opcode == Instruction.Opcodes.Fn)
             {
                 var args = (object[])instruction.Arguments;
                 var label = (string)args[0];
                 instruction.Arguments = new int[] {
                     labels [label],
                     (int)args [1]
                 };
             }
             instruction.NumericOpcode = Utils.GetNumericOpcode(instruction.Opcode);
         }
     }
     return result;
 }
Exemple #2
0
 public static MemoryStream SerializeBytecodeToStream(Instruction[] bytecode)
 {
     return Serialization.BytecodeSerializer.SerializeBytecode (bytecode);
 }
Exemple #3
0
 public static byte[] SerializeBytecode(Instruction[] bytecode)
 {
     return Serialization.BytecodeSerializer.SerializeBytecode (bytecode).ToArray();
 }
Exemple #4
0
 public static string PrintAssembledBytecode(Instruction[] bytecode)
 {
     var labels = Utils.GetNumericLabels (bytecode);
     var sb = new StringBuilder ();
     for (var i = 0; i < bytecode.Length; i++) {
         if (labels.Contains (i)) {
             sb.AppendLine (String.Format ("{0}:", i));
         }
         sb.Append (bytecode [i].ToString ());
     }
     if (labels.Contains (bytecode.Length)) {
         sb.AppendLine (String.Format ("{0}:", bytecode.Length));
     }
     return sb.ToString ();
 }
Exemple #5
0
 internal static byte[] ComputeBytecodeMd5(Instruction[] bytecode)
 {
     var ms = Api.SerializeBytecodeToStream(bytecode);
     using (var md5 = MD5.Create()) {
         ms.Seek(0, SeekOrigin.Begin);
         return md5.ComputeHash(ms);
     }
 }
Exemple #6
0
 static byte GetNumericOpcode(Instruction.Opcodes opcode)
 {
     switch (opcode)
     {
         case Instruction.Opcodes.Jump:
             return 0;
         case Instruction.Opcodes.Const:
             return 1;
         case Instruction.Opcodes.Prim0:
             return 2;
         case Instruction.Opcodes.Prim:
             return 3;
         case Instruction.Opcodes.Call:
             return 4;
         case Instruction.Opcodes.CallJ:
             return 5;
         case Instruction.Opcodes.Fjump:
             return 6;
         case Instruction.Opcodes.Lset:
             return 7;
         case Instruction.Opcodes.Pop:
             return 8;
         case Instruction.Opcodes.Lget:
             return 9;
         case Instruction.Opcodes.Fn:
             return 10;
         case Instruction.Opcodes.NewFrame:
             return 11;
         case Instruction.Opcodes.DropFrame:
             return 12;
         case Instruction.Opcodes.Args:
             return 13;
         case Instruction.Opcodes.Return:
             return 14;
         case Instruction.Opcodes.Block:
             return 15;
         case Instruction.Opcodes.PopBlock:
             return 16;
         case Instruction.Opcodes.BlockReturn:
             return 17;
         case Instruction.Opcodes.Context:
             return 18;
         case Instruction.Opcodes.Tjump:
             return 19;
         case Instruction.Opcodes.FileName:
             return 20;
         case Instruction.Opcodes.VmVersion:
             return 20;
         case Instruction.Opcodes.VmSourcesMd5:
             return 20;
         case Instruction.Opcodes.VmBytecodeMd5:
             return 20;
         case Instruction.Opcodes.Div:
             return 21;
         case Instruction.Opcodes.Mod:
             return 22;
         case Instruction.Opcodes.Neq:
             return 23;
         case Instruction.Opcodes.Lt:
             return 24;
         case Instruction.Opcodes.Add:
             return 25;
         case Instruction.Opcodes.Gref:
             return 26;
         case Instruction.Opcodes.Eq:
             return 27;
         case Instruction.Opcodes.Apush:
             return 28;
         case Instruction.Opcodes.GrefDot:
             return 29;
         case Instruction.Opcodes.Sub:
             return 30;
         case Instruction.Opcodes.Neg:
             return 31;
         case Instruction.Opcodes.Mul:
             return 32;
         case Instruction.Opcodes.Shl:
             return 33;
         case Instruction.Opcodes.Shr:
             return 34;
         case Instruction.Opcodes.Pow:
             return 35;
         case Instruction.Opcodes.Floor:
             return 36;
         case Instruction.Opcodes.Lte:
             return 37;
         case Instruction.Opcodes.Gt:
             return 38;
         case Instruction.Opcodes.Gte:
             return 39;
         case Instruction.Opcodes.Not:
             return 40;
         case Instruction.Opcodes.And:
             return 41;
         case Instruction.Opcodes.Ior:
             return 42;
         case Instruction.Opcodes.Xor:
             return 43;
         case Instruction.Opcodes.Keys:
             return 44;
         case Instruction.Opcodes.HasKey:
             return 45;
         case Instruction.Opcodes.Apop:
             return 46;
         case Instruction.Opcodes.SetIndexed:
             return 47;
         case Instruction.Opcodes.Len:
             return 48;
         case Instruction.Opcodes.IsString:
             return 49;
         case Instruction.Opcodes.IsHash:
             return 50;
         case Instruction.Opcodes.IsBool:
             return 51;
         case Instruction.Opcodes.IsArray:
             return 52;
         case Instruction.Opcodes.IsNumber:
             return 53;
         case Instruction.Opcodes.IsInteger:
             return 54;
         case Instruction.Opcodes.IsCallable:
             return 55;
         default:
             Utils.Panic();
             return 0;
     }
 }
Exemple #7
0
 internal static void SetBytecodeMd5(Instruction[] bytecode, string md5)
 {
     foreach (var instruction in bytecode) {
         if (instruction.Opcode == Instruction.Opcodes.VmBytecodeMd5) {
             instruction.Arguments = md5;
             return;
         }
     }
 }
Exemple #8
0
 internal static string GetSourcesMd5(Instruction[] bytecode)
 {
     foreach (var instruction in bytecode) {
         if (instruction.Opcode == Instruction.Opcodes.VmSourcesMd5) {
             return (string)instruction.Arguments;
         }
     }
     Utils.Panic();
     return null;
 }
Exemple #9
0
 internal static HashSet<int> GetNumericLabels(Instruction[] bytecode)
 {
     var result = new HashSet<int>();
     foreach (var instruction in bytecode) {
         switch (instruction.Opcode) {
         case Instruction.Opcodes.Jump:
             result.Add((int)instruction.Arguments);
             break;
         case Instruction.Opcodes.Fjump:
             result.Add((int)instruction.Arguments);
             break;
         case Instruction.Opcodes.Fn:
             result.Add (((int[])instruction.Arguments)[0]);
             break;
         case Instruction.Opcodes.Block:
             result.Add((int)instruction.Arguments);
             break;
         case Instruction.Opcodes.Tjump:
             result.Add((int)instruction.Arguments);
             break;
         }
     }
     return result;
 }