Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(481)

Unified Diff: pkg/fletchc/lib/src/bytecode_assembler.dart

Issue 1659163007: Rename fletch -> dartino (Closed) Base URL: https://github.com/dartino/sdk.git@master
Patch Set: address comments Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « pkg/fletchc/lib/program_info.dart ('k') | pkg/fletchc/lib/src/class_debug_info.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: pkg/fletchc/lib/src/bytecode_assembler.dart
diff --git a/pkg/fletchc/lib/src/bytecode_assembler.dart b/pkg/fletchc/lib/src/bytecode_assembler.dart
deleted file mode 100644
index ab1bef5285047f7f0c6bcfe07841fa900a4d4713..0000000000000000000000000000000000000000
--- a/pkg/fletchc/lib/src/bytecode_assembler.dart
+++ /dev/null
@@ -1,670 +0,0 @@
-// Copyright (c) 2015, the Dartino project authors. Please see the AUTHORS file
-// for details. All rights reserved. Use of this source code is governed by a
-// BSD-style license that can be found in the LICENSE.md file.
-
-library fletchc.bytecode_assembler;
-
-import '../bytecodes.dart';
-
-const int IMPLICIT_STACK_OVERFLOW_LIMIT = 32;
-const int frameDescriptorSize = 3;
-
-class BytecodeLabel {
- int position = -1;
- final List<int> usage = <int>[];
-
- void addUsage(int bytecodePosition) {
- usage.add(bytecodePosition);
- }
-
- void forEach(f(int index)) {
- usage.forEach(f);
- }
-
- int get lastIndex {
- if (usage.isEmpty) return -1;
- return usage.last;
- }
-
- void removeLastUsage() {
- usage.removeLast();
- }
-
- void bind(int value) {
- position = value;
- usage.clear();
- }
-
- bool get isBound => position != -1;
-
- bool get isUsed => usage.isNotEmpty;
-}
-
-class BytecodeAssembler {
- final List<Bytecode> bytecodes = <Bytecode>[];
- final List<int> catchRanges = <int>[];
-
- final int functionArity;
-
- int byteSize = 0;
- int stackSize = 0;
- int maxStackSize = 0;
-
- // A bind after a terminator will still look like the last bytecode
- // is a terminator, however, due to the bind it's not.
- bool hasBindAfterTerminator = false;
-
- // A bind after a pop will still look like the last bytecode is a
- // pop, however, due to the bind we cannot collapse more pops
- // together.
- bool hasBindAfterPop = false;
-
- BytecodeAssembler(this.functionArity);
-
- int computeParameterSlot(int parameter) {
- assert(parameter >= 0 && parameter < functionArity);
- return parameter - frameDescriptorSize - functionArity;
- }
-
- void reuse() {
- bytecodes.clear();
- catchRanges.clear();
- byteSize = 0;
- stackSize = 0;
- maxStackSize = 0;
- }
-
- /**
- * Apply a fix to the currently known stack size.
- */
- void applyStackSizeFix(int diff) {
- stackSize += diff;
- if (stackSize > maxStackSize) maxStackSize = stackSize;
- }
-
- void addCatchFrameRange(int start, int end) {
- catchRanges
- ..add(start)
- ..add(end)
- ..add(stackSize);
- }
-
- void loadConst(int id) {
- internalAdd(new LoadConst(id));
- }
-
- void loadLocal(int offset) {
- assert(offset < stackSize);
- loadLocalHelper(offset);
- }
-
- void loadLocalHelper(int offset) {
- assert(offset >= 0);
- Bytecode bytecode;
- switch (offset) {
- case 0:
- bytecode = const LoadLocal0();
- break;
- case 1:
- bytecode = const LoadLocal1();
- break;
- case 2:
- bytecode = const LoadLocal2();
- break;
- case 3:
- bytecode = const LoadLocal3();
- break;
- case 4:
- bytecode = const LoadLocal4();
- break;
- case 5:
- bytecode = const LoadLocal5();
- break;
- default:
- if (offset >= 256) {
- bytecode = new LoadLocalWide(offset);
- } else {
- bytecode = new LoadLocal(offset);
- }
- break;
- }
- internalAdd(bytecode);
- }
-
- void loadBoxed(int offset) {
- assert(offset < stackSize);
- loadBoxedHelper(offset);
- }
-
- void loadBoxedHelper(int offset) {
- assert(offset >= 0 && offset <= 255);
- internalAdd(new LoadBoxed(offset));
- }
-
- void dup() {
- loadLocal(0);
- }
-
- /**
- * A 'slot' is an artificial indexing, that are frame relative. That means
- * the current frame is indexed by where 0 .. frameSize-1, -1 is the return
- * address and -1 - functionArity is the first argument, -2 is the last
- * argument.
- *
- * This kind of indexing are sometimes easier to use than stack-relative,
- * as locals and parameters have a fixed value.
- */
- void loadSlot(int slot) {
- int offset = stackSize - slot - 1;
- loadLocal(offset);
- }
-
- void loadBoxedSlot(int slot) {
- int offset = stackSize - slot - 1;
- loadBoxed(offset);
- }
-
- int computeParameterOffset(int parameter) {
- return frameDescriptorSize + stackSize + functionArity - parameter - 1;
- }
-
- void loadParameter(int parameter) {
- assert(parameter >= 0 && parameter < functionArity);
- loadLocalHelper(computeParameterOffset(parameter));
- }
-
- void loadBoxedParameter(int parameter) {
- assert(parameter >= 0 && parameter < functionArity);
- loadBoxedHelper(computeParameterOffset(parameter));
- }
-
- void loadParameterSlot(int parameterSlot) {
- int offset = stackSize - parameterSlot - 1;
- loadLocalHelper(offset);
- }
-
- void loadBoxedParameterSlot(int parameterSlot) {
- int offset = stackSize - parameterSlot - 1;
- loadBoxedHelper(offset);
- }
-
- void loadStatic(int index) {
- internalAdd(new LoadStatic(index));
- }
-
- void loadStaticInit(int index) {
- internalAdd(new LoadStaticInit(index));
- }
-
- void loadField(int index) {
- if (index >= 256) {
- internalAdd(new LoadFieldWide(index));
- } else {
- internalAdd(new LoadField(index));
- }
- }
-
- void loadLiteralNull() {
- internalAdd(new LoadLiteralNull());
- }
-
- void loadLiteralTrue() {
- internalAdd(new LoadLiteralTrue());
- }
-
- void loadLiteralFalse() {
- internalAdd(new LoadLiteralFalse());
- }
-
- void loadLiteral(int value) {
- if (value == 0) {
- internalAdd(const LoadLiteral0());
- } else if (value == 1) {
- internalAdd(const LoadLiteral1());
- } else if (value < 256) {
- internalAdd(new LoadLiteral(value));
- } else {
- internalAdd(new LoadLiteralWide(value));
- }
- }
-
- void storeLocal(int offset) {
- assert(offset < stackSize);
- storeLocalHelper(offset);
- }
-
- void storeLocalHelper(int offset) {
- assert(offset >= 0 && offset <= 255);
- internalAdd(new StoreLocal(offset));
- }
-
- void storeBoxed(int offset) {
- assert(offset < stackSize);
- storeBoxedHelper(offset);
- }
-
- void storeBoxedHelper(int offset) {
- assert(offset >= 0 && offset <= 255);
- internalAdd(new StoreBoxed(offset));
- }
-
- /**
- * See loadSlot for information about 'slots'.
- */
- void storeSlot(int slot) {
- int offset = stackSize - slot - 1;
- storeLocal(offset);
- }
-
- void storeBoxedSlot(int slot) {
- int offset = stackSize - slot - 1;
- storeBoxed(offset);
- }
-
- void storeParameter(int parameter) {
- assert(parameter >= 0 && parameter < functionArity);
- storeLocalHelper(computeParameterOffset(parameter));
- }
-
- void storeBoxedParameter(int parameter) {
- assert(parameter >= 0 && parameter < functionArity);
- storeBoxedHelper(computeParameterOffset(parameter));
- }
-
- void storeParameterSlot(int parameterSlot) {
- int offset = stackSize - parameterSlot - 1;
- storeLocalHelper(offset);
- }
-
- void storeBoxedParameterSlot(int parameterSlot) {
- int offset = stackSize - parameterSlot - 1;
- storeBoxedHelper(offset);
- }
-
- void storeStatic(int index) {
- internalAdd(new StoreStatic(index));
- }
-
- void storeField(int index) {
- if (index >= 256) {
- internalAdd(new StoreFieldWide(index));
- } else {
- internalAdd(new StoreField(index));
- }
- }
-
- void invokeStatic(int id, int arity) {
- internalAddStackPointerDifference(
- new InvokeStatic(id),
- 1 - arity);
- }
-
- void invokeFactory(int id, int arity) {
- internalAddStackPointerDifference(
- new InvokeFactory(id),
- 1 - arity);
- }
-
- void invokeMethod(int selector, int arity, [String name]) {
- var bytecode;
- switch (name) {
- case '==':
- bytecode = new InvokeEqUnfold(selector);
- break;
-
- case '<':
- bytecode = new InvokeLtUnfold(selector);
- break;
-
- case '<=':
- bytecode = new InvokeLeUnfold(selector);
- break;
-
- case '>':
- bytecode = new InvokeGtUnfold(selector);
- break;
-
- case '>=':
- bytecode = new InvokeGeUnfold(selector);
- break;
-
- case '+':
- bytecode = new InvokeAddUnfold(selector);
- break;
-
- case '-':
- bytecode = new InvokeSubUnfold(selector);
- break;
-
- case '*':
- bytecode = new InvokeMulUnfold(selector);
- break;
-
- case '~/':
- bytecode = new InvokeTruncDivUnfold(selector);
- break;
-
- case '%':
- bytecode = new InvokeModUnfold(selector);
- break;
-
- case '~':
- bytecode = new InvokeBitNotUnfold(selector);
- break;
-
- case '&':
- bytecode = new InvokeBitAndUnfold(selector);
- break;
-
- case '|':
- bytecode = new InvokeBitOrUnfold(selector);
- break;
-
- case '^':
- bytecode = new InvokeBitXorUnfold(selector);
- break;
-
- case '<<':
- bytecode = new InvokeBitShlUnfold(selector);
- break;
-
- case '>>':
- bytecode = new InvokeBitShrUnfold(selector);
- break;
-
- default:
- bytecode = new InvokeMethodUnfold(selector);
- break;
- }
- internalAddStackPointerDifference(bytecode, -arity);
- }
-
- void invokeTest(int selector, int arity) {
- internalAddStackPointerDifference(new InvokeTestUnfold(selector), -arity);
- }
-
- void invokeSelector(int slot) {
- internalAddStackPointerDifference(new InvokeSelector(slot), 0);
- }
-
- void pop() {
- if (hasBindAfterPop) {
- internalAdd(new Pop());
- hasBindAfterPop = false;
- return;
- }
- Bytecode last = bytecodes.last;
- if (last.opcode == Opcode.Drop) {
- Drop drop = last;
- int amount = drop.uint8Argument0 + 1;
- if (amount <= 255) {
- bytecodes[bytecodes.length - 1] = new Drop(amount);
- applyStackSizeFix(-1);
- } else {
- internalAdd(new Pop());
- }
- } else if (last.opcode == Opcode.Pop) {
- bytecodes[bytecodes.length - 1] = new Drop(2);
- byteSize += 1;
- applyStackSizeFix(-1);
- } else {
- internalAdd(new Pop());
- }
-
- }
-
- void popMany(int count) {
- while (count > 255) {
- internalAddStackPointerDifference(new Drop(255), -255);
- count -= 255;
- }
- if (count > 1) {
- internalAddStackPointerDifference(new Drop(count), -count);
- } else if (count == 1) {
- internalAdd(new Pop());
- }
- hasBindAfterPop = false;
- }
-
- void ret() {
- hasBindAfterTerminator = false;
- if (stackSize <= 0) throw "Bad stackSize for return bytecode: $stackSize";
- internalAdd(const Return());
- }
-
- void returnNull() {
- hasBindAfterTerminator = false;
- internalAdd(const ReturnNull());
- }
-
- void identical() {
- internalAdd(const Identical());
- }
-
- void identicalNonNumeric() {
- internalAdd(const IdenticalNonNumeric());
- }
-
- void negate() {
- internalAdd(const Negate());
- }
-
- void bind(BytecodeLabel label) {
- internalBind(label, false);
- }
-
- void internalBind(BytecodeLabel label, bool isSubroutineReturn) {
- if (label.isUsed) hasBindAfterTerminator = true;
- hasBindAfterPop = true;
- assert(label.position == -1);
- // TODO(ajohnsen): If the previous bytecode is a branch to this label,
- // consider popping it - if no other binds has happened at this bytecode
- // index.
- int position = byteSize;
- label.forEach((int index) {
- var bytecode = bytecodes[index];
- switch (bytecode.opcode) {
- case Opcode.BranchIfTrueWide:
- int offset = position - bytecode.uint32Argument0;
- bytecodes[index] = new BranchIfTrueWide(offset);
- break;
-
- case Opcode.BranchIfFalseWide:
- int offset = position - bytecode.uint32Argument0;
- bytecodes[index] = new BranchIfFalseWide(offset);
- break;
-
- case Opcode.BranchWide:
- int offset = position - bytecode.uint32Argument0;
- bytecodes[index] = new BranchWide(offset);
- break;
-
- case Opcode.PopAndBranchWide:
- int offset = position - bytecode.uint32Argument1;
- bytecodes[index] = new PopAndBranchWide(
- bytecode.uint8Argument0,
- offset);
- break;
-
- case Opcode.EnterNoSuchMethod:
- int offset = position - bytecode.uint8Argument0;
- bytecodes[index] = new EnterNoSuchMethod(offset);
- break;
-
- case Opcode.SubroutineCall:
- if (isSubroutineReturn) {
- int offset = position - bytecode.uint32Argument1;
- offset -= bytecode.size;
- bytecodes[index] = new SubroutineCall(
- bytecode.uint32Argument0,
- offset);
- } else {
- int offset = position - bytecode.uint32Argument0;
- bytecodes[index] = new SubroutineCall(
- offset,
- bytecode.uint32Argument1);
- }
- break;
-
- default:
- throw "Unhandled bind bytecode: $bytecode";
- }
- });
- label.bind(position);
- }
-
- void branchIfTrue(BytecodeLabel label) {
- if (label.isBound) {
- internalBranchBack(
- label,
- (v) => new BranchBackIfTrue(v),
- (v) => new BranchBackIfTrueWide(v));
- } else {
- label.addUsage(bytecodes.length);
- internalAdd(new BranchIfTrueWide(byteSize));
- }
- }
-
- void branchIfFalse(BytecodeLabel label) {
- if (label.isBound) {
- internalBranchBack(
- label,
- (v) => new BranchBackIfFalse(v),
- (v) => new BranchBackIfFalseWide(v));
- } else {
- label.addUsage(bytecodes.length);
- internalAdd(new BranchIfFalseWide(byteSize));
- }
- }
-
- void branch(BytecodeLabel label) {
- if (label.isBound) {
- internalBranchBack(
- label,
- (v) => new BranchBack(v),
- (v) => new BranchBackWide(v));
- } else {
- label.addUsage(bytecodes.length);
- internalAdd(new BranchWide(byteSize));
- }
- }
-
- void popAndBranch(int diff, BytecodeLabel label) {
- assert(diff >= 0 && diff <= 255);
- if (label.isBound) {
- internalBranchBack(
- label,
- (v) => new PopAndBranchBackWide(diff, v),
- (v) => new PopAndBranchBackWide(diff, v));
- } else {
- label.addUsage(bytecodes.length);
- internalAdd(new PopAndBranchWide(diff, byteSize));
- }
- }
-
- void internalBranchBack(
- BytecodeLabel label,
- Bytecode short(int offset),
- Bytecode long(int offset)) {
- int offset = byteSize - label.position;
- if (offset < 255) {
- internalAdd(short(offset));
- } else {
- internalAdd(long(offset));
- }
- }
-
- void allocate(int classId, int fields, {bool immutable: false}) {
- var instruction = immutable ?
- new AllocateImmutable(classId) : new Allocate(classId);
- internalAddStackPointerDifference(instruction, 1 - fields);
- }
-
- void allocateBoxed() {
- internalAdd(const AllocateBoxed());
- }
-
- void subroutineCall(BytecodeLabel label, BytecodeLabel returnLabel) {
- assert(!label.isBound);
- assert(!returnLabel.isBound);
- label.addUsage(bytecodes.length);
- returnLabel.addUsage(bytecodes.length);
- internalAddStackPointerDifference(
- new SubroutineCall(byteSize, byteSize),
- 0);
- }
-
- void subroutineReturn(BytecodeLabel returnLabel) {
- internalBind(returnLabel, true);
- internalAdd(const SubroutineReturn());
- }
-
- bool get endsWithTerminator {
- if (bytecodes.isEmpty) return false;
- if (hasBindAfterTerminator) return false;
- Opcode opcode = bytecodes.last.opcode;
- return opcode == Opcode.Return || opcode == Opcode.Throw;
- }
-
- void enterNoSuchMethod(BytecodeLabel skipGetterLabel) {
- assert(!skipGetterLabel.isBound);
- skipGetterLabel.addUsage(bytecodes.length);
- internalAddStackPointerDifference(new EnterNoSuchMethod(byteSize), 0);
- }
-
- void exitNoSuchMethod() {
- internalAdd(const ExitNoSuchMethod());
- }
-
- void methodEnd() {
- if (maxStackSize > IMPLICIT_STACK_OVERFLOW_LIMIT) {
- var bytecode = new StackOverflowCheck(
- maxStackSize - IMPLICIT_STACK_OVERFLOW_LIMIT);
- bytecodes.insert(0, bytecode);
- byteSize += bytecode.size;
- }
- int value = (byteSize << 1) | (catchRanges.isNotEmpty ? 1 : 0);
- internalAdd(new MethodEnd(value));
- }
-
- void processYield() {
- internalAdd(const ProcessYield());
- }
-
- void coroutineChange() {
- internalAdd(const CoroutineChange());
- }
-
- void internalAdd(Bytecode bytecode) {
- internalAddStackPointerDifference(
- bytecode,
- bytecode.stackPointerDifference);
- }
-
- void internalAddStackPointerDifference(
- Bytecode bytecode,
- int stackPointerDifference) {
- assert(stackPointerDifference != VAR_DIFF);
- assert(bytecodes.isEmpty || bytecodes.last.opcode != Opcode.MethodEnd);
- bytecodes.add(bytecode);
- byteSize += bytecode.size;
- applyStackSizeFix(stackPointerDifference);
- }
-
- void invokeNative(int arity, int index) {
- internalAdd(new InvokeNative(arity, index));
- }
-
- void invokeDetachableNative(int arity, int index) {
- internalAdd(new InvokeDetachableNative(arity, index));
- }
-
- void invokeNativeYield(int arity, int index) {
- internalAdd(new InvokeNativeYield(arity, index));
- }
-
- void emitThrow() {
- hasBindAfterTerminator = false;
- internalAdd(const Throw());
- }
-}
« no previous file with comments | « pkg/fletchc/lib/program_info.dart ('k') | pkg/fletchc/lib/src/class_debug_info.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698