| OLD | NEW |
| 1 // Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file | 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 | 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. | 3 // BSD-style license that can be found in the LICENSE.md file. |
| 4 | 4 |
| 5 library fletchc.compiled_function; | 5 library dartino_compiler.compiled_function; |
| 6 | 6 |
| 7 import 'package:compiler/src/constants/values.dart' show | 7 import 'package:compiler/src/constants/values.dart' show |
| 8 ConstantValue; | 8 ConstantValue; |
| 9 | 9 |
| 10 import 'package:compiler/src/elements/elements.dart'; | 10 import 'package:compiler/src/elements/elements.dart'; |
| 11 | 11 |
| 12 import 'fletch_constants.dart' show | 12 import 'dartino_constants.dart' show |
| 13 FletchFunctionConstant, | 13 DartinoFunctionConstant, |
| 14 FletchClassConstant; | 14 DartinoClassConstant; |
| 15 | 15 |
| 16 import '../bytecodes.dart' show | 16 import '../bytecodes.dart' show |
| 17 Bytecode, | 17 Bytecode, |
| 18 Opcode; | 18 Opcode; |
| 19 | 19 |
| 20 import 'fletch_context.dart'; | 20 import 'dartino_context.dart'; |
| 21 import 'bytecode_assembler.dart'; | 21 import 'bytecode_assembler.dart'; |
| 22 | 22 |
| 23 import '../fletch_system.dart'; | 23 import '../dartino_system.dart'; |
| 24 import '../vm_commands.dart'; | 24 import '../vm_commands.dart'; |
| 25 | 25 |
| 26 class FletchFunctionBuilder extends FletchFunctionBase { | 26 class DartinoFunctionBuilder extends DartinoFunctionBase { |
| 27 final BytecodeAssembler assembler; | 27 final BytecodeAssembler assembler; |
| 28 | 28 |
| 29 /** | 29 /** |
| 30 * If the functions is an instance member, [memberOf] is set to the id of the | 30 * If the functions is an instance member, [memberOf] is set to the id of the |
| 31 * class. | 31 * class. |
| 32 * | 32 * |
| 33 * If [memberOf] is set, the compiled function takes an 'this' argument in | 33 * If [memberOf] is set, the compiled function takes an 'this' argument in |
| 34 * addition to that of [signature]. | 34 * addition to that of [signature]. |
| 35 */ | 35 */ |
| 36 final Map<ConstantValue, int> constants = <ConstantValue, int>{}; | 36 final Map<ConstantValue, int> constants = <ConstantValue, int>{}; |
| 37 final Map<int, ConstantValue> functionConstantValues = <int, ConstantValue>{}; | 37 final Map<int, ConstantValue> functionConstantValues = <int, ConstantValue>{}; |
| 38 final Map<int, ConstantValue> classConstantValues = <int, ConstantValue>{}; | 38 final Map<int, ConstantValue> classConstantValues = <int, ConstantValue>{}; |
| 39 | 39 |
| 40 FletchFunctionBuilder.fromFletchFunction(FletchFunction function) | 40 DartinoFunctionBuilder.fromDartinoFunction(DartinoFunction function) |
| 41 : this( | 41 : this( |
| 42 function.functionId, | 42 function.functionId, |
| 43 function.kind, | 43 function.kind, |
| 44 function.arity, | 44 function.arity, |
| 45 name: function.name, | 45 name: function.name, |
| 46 element: function.element, | 46 element: function.element, |
| 47 memberOf: function.memberOf); | 47 memberOf: function.memberOf); |
| 48 | 48 |
| 49 FletchFunctionBuilder( | 49 DartinoFunctionBuilder( |
| 50 int functionId, | 50 int functionId, |
| 51 FletchFunctionKind kind, | 51 DartinoFunctionKind kind, |
| 52 int arity, | 52 int arity, |
| 53 {String name, | 53 {String name, |
| 54 Element element, | 54 Element element, |
| 55 FunctionSignature signature, | 55 FunctionSignature signature, |
| 56 int memberOf}) | 56 int memberOf}) |
| 57 : super(functionId, kind, arity, name, element, signature, memberOf), | 57 : super(functionId, kind, arity, name, element, signature, memberOf), |
| 58 assembler = new BytecodeAssembler(arity) { | 58 assembler = new BytecodeAssembler(arity) { |
| 59 assert(signature == null || | 59 assert(signature == null || |
| 60 arity == (signature.parameterCount + (isInstanceMember ? 1 : 0))); | 60 arity == (signature.parameterCount + (isInstanceMember ? 1 : 0))); |
| 61 } | 61 } |
| 62 | 62 |
| 63 void reuse() { | 63 void reuse() { |
| 64 assembler.reuse(); | 64 assembler.reuse(); |
| 65 constants.clear(); | 65 constants.clear(); |
| 66 functionConstantValues.clear(); | 66 functionConstantValues.clear(); |
| 67 classConstantValues.clear(); | 67 classConstantValues.clear(); |
| 68 } | 68 } |
| 69 | 69 |
| 70 int allocateConstant(ConstantValue constant) { | 70 int allocateConstant(ConstantValue constant) { |
| 71 if (constant == null) throw "bad constant"; | 71 if (constant == null) throw "bad constant"; |
| 72 return constants.putIfAbsent(constant, () => constants.length); | 72 return constants.putIfAbsent(constant, () => constants.length); |
| 73 } | 73 } |
| 74 | 74 |
| 75 int allocateConstantFromFunction(int functionId) { | 75 int allocateConstantFromFunction(int functionId) { |
| 76 FletchFunctionConstant constant = | 76 DartinoFunctionConstant constant = |
| 77 functionConstantValues.putIfAbsent( | 77 functionConstantValues.putIfAbsent( |
| 78 functionId, () => new FletchFunctionConstant(functionId)); | 78 functionId, () => new DartinoFunctionConstant(functionId)); |
| 79 return allocateConstant(constant); | 79 return allocateConstant(constant); |
| 80 } | 80 } |
| 81 | 81 |
| 82 int allocateConstantFromClass(int classId) { | 82 int allocateConstantFromClass(int classId) { |
| 83 FletchClassConstant constant = | 83 DartinoClassConstant constant = |
| 84 classConstantValues.putIfAbsent( | 84 classConstantValues.putIfAbsent( |
| 85 classId, () => new FletchClassConstant(classId)); | 85 classId, () => new DartinoClassConstant(classId)); |
| 86 return allocateConstant(constant); | 86 return allocateConstant(constant); |
| 87 } | 87 } |
| 88 | 88 |
| 89 // TODO(ajohnsen): Remove this function when usage is avoided in | 89 // TODO(ajohnsen): Remove this function when usage is avoided in |
| 90 // FletchBackend. | 90 // DartinoBackend. |
| 91 void copyFrom(FletchFunctionBuilder function) { | 91 void copyFrom(DartinoFunctionBuilder function) { |
| 92 assembler.bytecodes.addAll(function.assembler.bytecodes); | 92 assembler.bytecodes.addAll(function.assembler.bytecodes); |
| 93 assembler.catchRanges.addAll(function.assembler.catchRanges); | 93 assembler.catchRanges.addAll(function.assembler.catchRanges); |
| 94 constants.addAll(function.constants); | 94 constants.addAll(function.constants); |
| 95 functionConstantValues.addAll(function.functionConstantValues); | 95 functionConstantValues.addAll(function.functionConstantValues); |
| 96 classConstantValues.addAll(function.classConstantValues); | 96 classConstantValues.addAll(function.classConstantValues); |
| 97 } | 97 } |
| 98 | 98 |
| 99 FletchFunction finalizeFunction( | 99 DartinoFunction finalizeFunction( |
| 100 FletchContext context, | 100 DartinoContext context, |
| 101 List<VmCommand> commands) { | 101 List<VmCommand> commands) { |
| 102 int constantCount = constants.length; | 102 int constantCount = constants.length; |
| 103 for (int i = 0; i < constantCount; i++) { | 103 for (int i = 0; i < constantCount; i++) { |
| 104 commands.add(const PushNull()); | 104 commands.add(const PushNull()); |
| 105 } | 105 } |
| 106 | 106 |
| 107 assert(assembler.bytecodes.last.opcode == Opcode.MethodEnd); | 107 assert(assembler.bytecodes.last.opcode == Opcode.MethodEnd); |
| 108 | 108 |
| 109 commands.add( | 109 commands.add( |
| 110 new PushNewFunction( | 110 new PushNewFunction( |
| 111 assembler.functionArity, | 111 assembler.functionArity, |
| 112 constantCount, | 112 constantCount, |
| 113 assembler.bytecodes, | 113 assembler.bytecodes, |
| 114 assembler.catchRanges)); | 114 assembler.catchRanges)); |
| 115 | 115 |
| 116 commands.add(new PopToMap(MapId.methods, functionId)); | 116 commands.add(new PopToMap(MapId.methods, functionId)); |
| 117 | 117 |
| 118 return new FletchFunction( | 118 return new DartinoFunction( |
| 119 functionId, | 119 functionId, |
| 120 kind, | 120 kind, |
| 121 arity, | 121 arity, |
| 122 name, | 122 name, |
| 123 element, | 123 element, |
| 124 signature, | 124 signature, |
| 125 assembler.bytecodes, | 125 assembler.bytecodes, |
| 126 createFletchConstants(context), | 126 createDartinoConstants(context), |
| 127 memberOf); | 127 memberOf); |
| 128 } | 128 } |
| 129 | 129 |
| 130 List<FletchConstant> createFletchConstants(FletchContext context) { | 130 List<DartinoConstant> createDartinoConstants(DartinoContext context) { |
| 131 List<FletchConstant> fletchConstants = <FletchConstant>[]; | 131 List<DartinoConstant> dartinoConstants = <DartinoConstant>[]; |
| 132 | 132 |
| 133 constants.forEach((constant, int index) { | 133 constants.forEach((constant, int index) { |
| 134 if (constant is ConstantValue) { | 134 if (constant is ConstantValue) { |
| 135 if (constant is FletchFunctionConstant) { | 135 if (constant is DartinoFunctionConstant) { |
| 136 fletchConstants.add( | 136 dartinoConstants.add( |
| 137 new FletchConstant(constant.functionId, MapId.methods)); | 137 new DartinoConstant(constant.functionId, MapId.methods)); |
| 138 } else if (constant is FletchClassConstant) { | 138 } else if (constant is DartinoClassConstant) { |
| 139 fletchConstants.add( | 139 dartinoConstants.add( |
| 140 new FletchConstant(constant.classId, MapId.classes)); | 140 new DartinoConstant(constant.classId, MapId.classes)); |
| 141 } else { | 141 } else { |
| 142 int id = context.lookupConstantIdByValue(constant); | 142 int id = context.lookupConstantIdByValue(constant); |
| 143 if (id == null) { | 143 if (id == null) { |
| 144 throw "Unsupported constant: ${constant.toStructuredString()}"; | 144 throw "Unsupported constant: ${constant.toStructuredString()}"; |
| 145 } | 145 } |
| 146 fletchConstants.add( | 146 dartinoConstants.add( |
| 147 new FletchConstant(id, MapId.constants)); | 147 new DartinoConstant(id, MapId.constants)); |
| 148 } | 148 } |
| 149 } else { | 149 } else { |
| 150 throw "Unsupported constant: ${constant.runtimeType}"; | 150 throw "Unsupported constant: ${constant.runtimeType}"; |
| 151 } | 151 } |
| 152 }); | 152 }); |
| 153 | 153 |
| 154 return fletchConstants; | 154 return dartinoConstants; |
| 155 } | 155 } |
| 156 | 156 |
| 157 String verboseToString() { | 157 String verboseToString() { |
| 158 StringBuffer sb = new StringBuffer(); | 158 StringBuffer sb = new StringBuffer(); |
| 159 | 159 |
| 160 sb.writeln("Function $functionId, Arity=${assembler.functionArity}"); | 160 sb.writeln("Function $functionId, Arity=${assembler.functionArity}"); |
| 161 sb.writeln("Constants:"); | 161 sb.writeln("Constants:"); |
| 162 constants.forEach((constant, int index) { | 162 constants.forEach((constant, int index) { |
| 163 if (constant is ConstantValue) { | 163 if (constant is ConstantValue) { |
| 164 constant = constant.toStructuredString(); | 164 constant = constant.toStructuredString(); |
| 165 } | 165 } |
| 166 sb.writeln(" #$index: $constant"); | 166 sb.writeln(" #$index: $constant"); |
| 167 }); | 167 }); |
| 168 | 168 |
| 169 sb.writeln("Bytecodes (${assembler.byteSize} bytes):"); | 169 sb.writeln("Bytecodes (${assembler.byteSize} bytes):"); |
| 170 Bytecode.prettyPrint(sb, assembler.bytecodes); | 170 Bytecode.prettyPrint(sb, assembler.bytecodes); |
| 171 | 171 |
| 172 return '$sb'; | 172 return '$sb'; |
| 173 } | 173 } |
| 174 } | 174 } |
| OLD | NEW |