| OLD | NEW | 
|---|
|  | (Empty) | 
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |  | 
| 2 // for details. All rights reserved. Use of this source code is governed by a |  | 
| 3 // BSD-style license that can be found in the LICENSE.md file. |  | 
| 4 |  | 
| 5 main() { |  | 
| 6   print(""" |  | 
| 7 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file |  | 
| 8 // for details. All rights reserved. Use of this source code is governed by a |  | 
| 9 // BSD-style license that can be found in the LICENSE.md file. |  | 
| 10 |  | 
| 11 // WARNING: Generated file, do not edit! |  | 
| 12 |  | 
| 13 part of fletch.bytecodes; |  | 
| 14 """); |  | 
| 15 |  | 
| 16   print("enum Opcode {"); |  | 
| 17   doBytecodes((String name, bool isBranching, String format, int size, |  | 
| 18                spDiff, String formatString) { |  | 
| 19     print("  $name,"); |  | 
| 20   }); |  | 
| 21   print("}"); |  | 
| 22 |  | 
| 23   doBytecodes((String name, bool isBranching, String format, int size, |  | 
| 24                spDiff, String formatString) { |  | 
| 25   List<String> fields = <String>[]; |  | 
| 26   List<String> encode = <String>[]; |  | 
| 27 |  | 
| 28   for (int i = 0; i < format.length; i++) { |  | 
| 29     String code = format[i]; |  | 
| 30     switch (code) { |  | 
| 31       case "B": |  | 
| 32         String field = "uint8Argument$i"; |  | 
| 33         fields.add(field); |  | 
| 34         encode.add("        ..addUint8($field)\n"); |  | 
| 35         break; |  | 
| 36       case "I": |  | 
| 37         String field = "uint32Argument$i"; |  | 
| 38         fields.add(field); |  | 
| 39         encode.add("        ..addUint32($field)\n"); |  | 
| 40         break; |  | 
| 41       default: |  | 
| 42         throw "Unknown format: $code"; |  | 
| 43     } |  | 
| 44   } |  | 
| 45 |  | 
| 46   String toStringExpression = formatString; |  | 
| 47   if (fields.isNotEmpty) { |  | 
| 48     List<String> parts = formatString.split("%d"); |  | 
| 49     StringBuffer buffer = new StringBuffer(); |  | 
| 50     Iterator iterator = fields.iterator; |  | 
| 51     for (String part in parts) { |  | 
| 52       buffer.write(part); |  | 
| 53       if (iterator.moveNext()) { |  | 
| 54         buffer.write(r'${'); |  | 
| 55         buffer.write(iterator.current); |  | 
| 56         buffer.write('}'); |  | 
| 57       } |  | 
| 58     } |  | 
| 59     toStringExpression = '$buffer'; |  | 
| 60   } |  | 
| 61 |  | 
| 62   String equals = ''; |  | 
| 63   if (fields.isNotEmpty) { |  | 
| 64     StringBuffer equalsBuffer = |  | 
| 65         new StringBuffer('\n\n  operator==(Bytecode other) {\n'); |  | 
| 66     equalsBuffer.writeln('    if (!(super==(other))) return false;'); |  | 
| 67     equalsBuffer.writeln('    $name rhs = other;'); |  | 
| 68     for (String field in fields) { |  | 
| 69       equalsBuffer.writeln('    if ($field != rhs.$field) return false;'); |  | 
| 70     } |  | 
| 71     equalsBuffer.writeln('    return true;'); |  | 
| 72     equalsBuffer.write('  }'); |  | 
| 73     equals = '$equalsBuffer'; |  | 
| 74   } |  | 
| 75 |  | 
| 76   String hashCode = ''; |  | 
| 77   if (fields.isNotEmpty) { |  | 
| 78     StringBuffer hashCodeBuffer = |  | 
| 79         new StringBuffer('\n\n  int get hashCode {\n'); |  | 
| 80     hashCodeBuffer.writeln('    int value = super.hashCode;'); |  | 
| 81     for (String field in fields) { |  | 
| 82       hashCodeBuffer.writeln('    value += $field;'); |  | 
| 83     } |  | 
| 84     hashCodeBuffer.writeln('    return value;'); |  | 
| 85     hashCodeBuffer.write('  }'); |  | 
| 86     hashCode = '$hashCodeBuffer'; |  | 
| 87   } |  | 
| 88 |  | 
| 89 print(""" |  | 
| 90 |  | 
| 91 class $name extends Bytecode { |  | 
| 92 ${ |  | 
| 93   fields.map((a) => '  final int $a;\n').join('') |  | 
| 94 }  const $name(${fields.map((a) => 'this.$a').join(', ')}) |  | 
| 95       : super(); |  | 
| 96 |  | 
| 97   Opcode get opcode => Opcode.$name; |  | 
| 98 |  | 
| 99   String get name => '$name'; |  | 
| 100 |  | 
| 101   bool get isBranching => $isBranching; |  | 
| 102 |  | 
| 103   String get format => '$format'; |  | 
| 104 |  | 
| 105   int get size => $size; |  | 
| 106 |  | 
| 107   int get stackPointerDifference => $spDiff; |  | 
| 108 |  | 
| 109   String get formatString => '$formatString'; |  | 
| 110 |  | 
| 111   void addTo(Sink<List<int>> sink) { |  | 
| 112     new BytecodeBuffer() |  | 
| 113         ..addUint8(opcode.index) |  | 
| 114 ${ |  | 
| 115   encode.join("") |  | 
| 116 }        ..sendOn(sink); |  | 
| 117   } |  | 
| 118 |  | 
| 119   String toString() => '$toStringExpression';$equals$hashCode |  | 
| 120 }"""); |  | 
| 121   }); |  | 
| 122 } |  | 
| 123 |  | 
| 124 void doBytecodes(V(String name, bool isBranching, String format, int size, |  | 
| 125                    spDiff, String formatString)) { |  | 
| 126   // Code below was copied from src/shared/bytecodes.h. |  | 
| 127   var kVarDiff = "VAR_DIFF"; |  | 
| 128 |  | 
| 129   void INVOKE(V, name, diff, desc, suffix, type) { |  | 
| 130     V("Invoke${name}${suffix}", true, "I", 5, diff, "invoke ${type}${desc}%d"); |  | 
| 131   } |  | 
| 132 |  | 
| 133   void INVOKES_DO(V, suffix, type) { |  | 
| 134     INVOKE(V, "Method", kVarDiff, "method ", suffix, type); |  | 
| 135     INVOKE(V, "Test", 0, "test ", suffix, type); |  | 
| 136 |  | 
| 137     INVOKE(V, "Eq", -1, "eq ", suffix, type); |  | 
| 138     INVOKE(V, "Lt", -1, "lt ", suffix, type); |  | 
| 139     INVOKE(V, "Le", -1, "le ", suffix, type); |  | 
| 140     INVOKE(V, "Gt", -1, "gt ", suffix, type); |  | 
| 141     INVOKE(V, "Ge", -1, "ge ", suffix, type); |  | 
| 142 |  | 
| 143     INVOKE(V, "Add", -1, "add ", suffix, type); |  | 
| 144     INVOKE(V, "Sub", -1, "sub ", suffix, type); |  | 
| 145     INVOKE(V, "Mod", -1, "mod ", suffix, type); |  | 
| 146     INVOKE(V, "Mul", -1, "mul ", suffix, type); |  | 
| 147     INVOKE(V, "TruncDiv", -1, "trunc div ", suffix, type); |  | 
| 148 |  | 
| 149     INVOKE(V, "BitNot",  0, "bit not ", suffix, type); |  | 
| 150     INVOKE(V, "BitAnd", -1, "bit and ", suffix, type); |  | 
| 151     INVOKE(V, "BitOr",  -1, "bit or ", suffix, type); |  | 
| 152     INVOKE(V, "BitXor", -1, "bit xor ", suffix, type); |  | 
| 153     INVOKE(V, "BitShr", -1, "bit shr ", suffix, type); |  | 
| 154     INVOKE(V, "BitShl", -1, "bit shl ", suffix, type); |  | 
| 155   } |  | 
| 156 |  | 
| 157   /* Name             Branching Format Size   SP-diff  format-string   */ |  | 
| 158   V("LoadLocal0",           false,    "",   1,        1, "load local 0"); |  | 
| 159   V("LoadLocal1",           false,    "",   1,        1, "load local 1"); |  | 
| 160   V("LoadLocal2",           false,    "",   1,        1, "load local 2"); |  | 
| 161   V("LoadLocal3",           false,    "",   1,        1, "load local 3"); |  | 
| 162   V("LoadLocal4",           false,    "",   1,        1, "load local 4"); |  | 
| 163   V("LoadLocal5",           false,    "",   1,        1, "load local 5"); |  | 
| 164   V("LoadLocal",            false,    "B",  2,        1, "load local %d"); |  | 
| 165   V("LoadLocalWide",        false,    "I",  5,        1, "load local %d"); |  | 
| 166 |  | 
| 167   V("LoadBoxed",            false,    "B",  2,        1, "load boxed %d"); |  | 
| 168   V("LoadStatic",           false,    "I",  5,        1, "load static %d"); |  | 
| 169   V("LoadStaticInit",       false,    "I",  5,        1, "load static init %d"); |  | 
| 170   V("LoadField",            false,    "B",  2,        0, "load field %d"); |  | 
| 171   V("LoadFieldWide",        false,    "I",  5,        0, "load field %d"); |  | 
| 172 |  | 
| 173   V("StoreLocal",           false,    "B",  2,        0, "store local %d"); |  | 
| 174   V("StoreBoxed",           false,    "B",  2,        0, "store boxed %d"); |  | 
| 175   V("StoreStatic",          false,    "I",  5,        0, "store static %d"); |  | 
| 176   V("StoreField",           false,    "B",  2,       -1, "store field %d"); |  | 
| 177   V("StoreFieldWide",       false,    "I",  5,       -1, "store field %d"); |  | 
| 178 |  | 
| 179   V("LoadLiteralNull",      false,    "",   1,        1, "load literal null"); |  | 
| 180   V("LoadLiteralTrue",      false,    "",   1,        1, "load literal true"); |  | 
| 181   V("LoadLiteralFalse",     false,    "",   1,        1, "load literal false"); |  | 
| 182   V("LoadLiteral0",         false,    "",   1,        1, "load literal 0"); |  | 
| 183   V("LoadLiteral1",         false,    "",   1,        1, "load literal 1"); |  | 
| 184   V("LoadLiteral",          false,    "B",  2,        1, "load literal %d"); |  | 
| 185   // TODO(ahe): The argument to LoadLiteralWide is probably signed. |  | 
| 186   V("LoadLiteralWide",      false,    "I",  5,        1, "load literal %d"); |  | 
| 187 |  | 
| 188   INVOKES_DO(V, "", ""); |  | 
| 189   INVOKE(V, "Static", kVarDiff, "static ", "", ""); |  | 
| 190   INVOKE(V, "Factory", kVarDiff, "factory ", "", ""); |  | 
| 191   V("Allocate",             false,    "I",  5, kVarDiff, "allocate %d"); |  | 
| 192   V("AllocateImmutable",    false,    "I",  5, kVarDiff, "allocateim %d"); |  | 
| 193 |  | 
| 194   V("InvokeNoSuchMethod",   true, "I", 5, kVarDiff, "invoke no such method %d"); |  | 
| 195   V("InvokeTestNoSuchMethod", true, "I", 5, 0, "invoke test no such method %d"); |  | 
| 196 |  | 
| 197   V("InvokeNative",           true,    "BB", 3,        1, "invoke native %d %d")
     ; |  | 
| 198   V("InvokeDetachableNative", true,    "BB", 3,        1, |  | 
| 199     "invoke detachable native %d %d"); |  | 
| 200   V("InvokeNativeYield",      true,    "BB", 3,   1, "invoke native yield %d %d"
     ); |  | 
| 201 |  | 
| 202   V("InvokeSelector",        true,    "I",  5, kVarDiff, "invoke selector"); |  | 
| 203 |  | 
| 204   V("Pop",                   false,   "",   1,       -1, "pop"); |  | 
| 205   V("Drop",                  false,   "B",  2, kVarDiff, "drop %d"); |  | 
| 206   V("Return",                true,    "",   1,       -1, "return"); |  | 
| 207   V("ReturnNull",            true,    "",   1,        0, "return null"); |  | 
| 208 |  | 
| 209   V("BranchWide",            true,    "I",  5,        0, "branch +%d"); |  | 
| 210   V("BranchIfTrueWide",      true,    "I",  5,       -1, "branch if true +%d"); |  | 
| 211   V("BranchIfFalseWide",     true,    "I",  5,       -1, "branch if false +%d"); |  | 
| 212 |  | 
| 213   V("BranchBack",            true,    "B",  2,        0, "branch -%d"); |  | 
| 214   V("BranchBackIfTrue",      true,    "B",  2,       -1, "branch if true -%d"); |  | 
| 215   V("BranchBackIfFalse",     true,    "B",  2,       -1, "branch if false -%d"); |  | 
| 216 |  | 
| 217   V("BranchBackWide",        true,    "I",  5,        0, "branch -%d"); |  | 
| 218   V("BranchBackIfTrueWide",  true,    "I",  5,       -1, "branch if true -%d"); |  | 
| 219   V("BranchBackIfFalseWide", true,    "I",  5,       -1, "branch if false -%d"); |  | 
| 220 |  | 
| 221   V("PopAndBranchWide",      true,    "BI", 6,        0, "pop %d and branch +%d"
     ); |  | 
| 222   V("PopAndBranchBackWide",  true,    "BI", 6,        0, "pop %d and branch -%d"
     ); |  | 
| 223 |  | 
| 224   V("AllocateBoxed",        false,    "",   1,        0, "allocate boxed"); |  | 
| 225 |  | 
| 226   V("Negate",               false,    "",   1,        0, "negate"); |  | 
| 227 |  | 
| 228   V("StackOverflowCheck",    true,   "I",   5,      0, "stack overflow check %d"
     ); |  | 
| 229 |  | 
| 230   V("Throw",                 true,    "",   1,        0, "throw"); |  | 
| 231   V("SubroutineCall",        true,  "II", 9, kVarDiff, "subroutine call +%d -%d"
     ); |  | 
| 232   V("SubroutineReturn",      true,    "",   1,       -1, "subroutine return"); |  | 
| 233 |  | 
| 234   V("ProcessYield",          true,    "",   1,        0, "process yield"); |  | 
| 235   V("CoroutineChange",       true,    "",   1,       -1, "coroutine change"); |  | 
| 236 |  | 
| 237   V("Identical",             true,    "",   1,       -1, "identical"); |  | 
| 238   V("IdenticalNonNumeric",   true,    "",   1,       -1, "identical non numeric"
     ); |  | 
| 239 |  | 
| 240   V("EnterNoSuchMethod",     true,    "B",  2, kVarDiff, "enter noSuchMethod +%d
     "); |  | 
| 241   V("ExitNoSuchMethod",      true,    "",   1,       -1, "exit noSuchMethod"); |  | 
| 242 |  | 
| 243   INVOKES_DO(V, "Unfold", "unfold "); |  | 
| 244   V("LoadConst",            false,    "I",  5,        1, "load const @%d"); |  | 
| 245 |  | 
| 246   V("MethodEnd",            false,    "I",  5,        0, "method end %d"); |  | 
| 247 } |  | 
| OLD | NEW | 
|---|