| 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 |