[vm/bytecode] Compact encoding of bytecode instructions (part 3/3)

Corresponding VM changes:
https://dart-review.googlesource.com/c/sdk/+/101062

On a large app, size of bytecode instructions:
Before: 12115384
After: 6282376 (-48.1%)

Total size of the app:
Before: 29790240
After: 23681504 (-20.5%)

Change-Id: Idd8f97e991236c25d663d1bcf18a51a53e73a2b7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/99400
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Alexander Markov 2019-05-08 17:33:15 +00:00 committed by commit-bot@chromium.org
parent 6fe73e4544
commit 68de477535
23 changed files with 1097 additions and 706 deletions

View file

@ -4,8 +4,6 @@
library vm.bytecode.assembler;
import 'dart:typed_data';
import 'package:kernel/ast.dart' show TreeNode;
import 'dbc.dart';
@ -26,8 +24,8 @@ class Label {
if (offset <= jumpOffset && !allowsBackwardJumps) {
throw 'Backward jump to this label is not allowed';
}
// Jump instruction takes an offset in DBC words.
return (offset - jumpOffset) >> BytecodeAssembler.kLog2BytesPerBytecode;
// Jump instruction takes a relative offset.
return offset - jumpOffset;
}
_jumps.add(jumpOffset);
return 0;
@ -43,32 +41,30 @@ class Label {
}
class BytecodeAssembler {
static const int kBitsPerInt = 64;
static const int kLog2BytesPerBytecode = 2;
static const int kByteMask = 0xFF;
static const int kUint32Mask = 0xFFFFFFFF;
static const int kMinInt8 = -0x80;
static const int kMaxInt8 = 0x7F;
static const int kMinInt24 = -0x800000;
static const int kMaxInt24 = 0x7FFFFF;
static const int kMinInt32 = -0x80000000;
static const int kMaxInt32 = 0x7FFFFFFF;
// TODO(alexmarkov): figure out more efficient storage for generated bytecode.
final List<int> bytecode = new List<int>();
final Uint32List _encodeBufferIn;
final Uint8List _encodeBufferOut;
final ExceptionsTable exceptionsTable = new ExceptionsTable();
final SourcePositions sourcePositions = new SourcePositions();
bool isUnreachable = false;
int currentSourcePosition = TreeNode.noOffset;
BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut);
factory BytecodeAssembler() {
final buf = new Uint32List(1);
return new BytecodeAssembler._(buf, new Uint8List.view(buf.buffer));
}
BytecodeAssembler();
int get offset => bytecode.length;
int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode;
void bind(Label label) {
final List<int> jumps = label.bind(offset);
for (int jumpOffset in jumps) {
patchJump(jumpOffset, label.jumpOperand(jumpOffset));
_patchJump(jumpOffset, label.jumpOperand(jumpOffset));
}
if (jumps.isNotEmpty || label.allowsBackwardJumps) {
isUnreachable = false;
@ -77,360 +73,451 @@ class BytecodeAssembler {
void emitSourcePosition() {
if (currentSourcePosition != TreeNode.noOffset && !isUnreachable) {
sourcePositions.add(offsetInWords, currentSourcePosition);
sourcePositions.add(offset, currentSourcePosition);
}
}
void emitWord(int word) {
void _emitByte(int abyte) {
assert(_isUint8(abyte));
bytecode.add(abyte);
}
void _emitBytes2(int b0, int b1) {
assert(_isUint8(b0) && _isUint8(b1));
bytecode.add(b0);
bytecode.add(b1);
}
void _emitBytes3(int b0, int b1, int b2) {
assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2));
bytecode.add(b0);
bytecode.add(b1);
bytecode.add(b2);
}
void _emitBytes4(int b0, int b1, int b2, int b3) {
assert(_isUint8(b0) && _isUint8(b1) && _isUint8(b2) && _isUint8(b3));
bytecode.add(b0);
bytecode.add(b1);
bytecode.add(b2);
bytecode.add(b3);
}
void _emitBytes5(int b0, int b1, int b2, int b3, int b4) {
assert(_isUint8(b0) &&
_isUint8(b1) &&
_isUint8(b2) &&
_isUint8(b3) &&
_isUint8(b4));
bytecode.add(b0);
bytecode.add(b1);
bytecode.add(b2);
bytecode.add(b3);
bytecode.add(b4);
}
void _emitBytes6(int b0, int b1, int b2, int b3, int b4, int b5) {
assert(_isUint8(b0) &&
_isUint8(b1) &&
_isUint8(b2) &&
_isUint8(b3) &&
_isUint8(b4) &&
_isUint8(b5));
bytecode.add(b0);
bytecode.add(b1);
bytecode.add(b2);
bytecode.add(b3);
bytecode.add(b4);
bytecode.add(b5);
}
int _byteAt(int pos) {
return bytecode[pos];
}
void _setByteAt(int pos, int value) {
assert(_isUint8(value));
bytecode[pos] = value;
}
int _byte0(int v) => v & kByteMask;
int _byte1(int v) => (v >> 8) & kByteMask;
int _byte2(int v) => (v >> 16) & kByteMask;
int _byte3(int v) => (v >> 24) & kByteMask;
bool _isInt8(int v) => (kMinInt8 <= v) && (v <= kMaxInt8);
bool _isInt24(int v) => (kMinInt24 <= v) && (v <= kMaxInt24);
bool _isInt32(int v) => (kMinInt32 <= v) && (v <= kMaxInt32);
bool _isUint8(int v) => (v & kByteMask) == v;
bool _isUint32(int v) => (v & kUint32Mask) == v;
void _emitInstruction0(Opcode opcode) {
if (isUnreachable) {
return;
}
_encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
bytecode.addAll(_encodeBufferOut);
_emitByte(opcode.index);
}
int _getOpcodeAt(int pos) {
return bytecode[pos]; // TODO(alexmarkov): Take endianness into account.
}
void _setWord(int pos, int word) {
_encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use?
bytecode.setRange(pos, pos + _encodeBufferOut.length, _encodeBufferOut);
}
int _unsigned(int v, int bits) {
assert(bits < kBitsPerInt);
final int mask = (1 << bits) - 1;
if ((v & mask) != v) {
throw 'Value $v is out of unsigned $bits-bit range';
void _emitInstructionA(Opcode opcode, int ra) {
if (isUnreachable) {
return;
}
return v;
_emitBytes2(opcode.index, ra);
}
int _signed(int v, int bits) {
assert(bits < kBitsPerInt);
final int shift = kBitsPerInt - bits;
if (((v << shift) >> shift) != v) {
throw 'Value $v is out of signed $bits-bit range';
void _emitInstructionD(Opcode opcode, int rd) {
if (isUnreachable) {
return;
}
if (_isUint8(rd)) {
_emitBytes2(opcode.index, rd);
} else {
assert(_isUint32(rd));
_emitBytes5(opcode.index + kWideModifier, _byte0(rd), _byte1(rd),
_byte2(rd), _byte3(rd));
}
final int mask = (1 << bits) - 1;
return v & mask;
}
int _uint8(int v) => _unsigned(v, 8);
int _uint16(int v) => _unsigned(v, 16);
void _emitInstructionX(Opcode opcode, int rx) {
if (isUnreachable) {
return;
}
if (_isInt8(rx)) {
_emitBytes2(opcode.index, rx & kByteMask);
} else {
assert(_isInt32(rx));
_emitBytes5(opcode.index + kWideModifier, _byte0(rx), _byte1(rx),
_byte2(rx), _byte3(rx));
}
}
// int _int8(int v) => _signed(v, 8);
int _int16(int v) => _signed(v, 16);
int _int24(int v) => _signed(v, 24);
void _emitInstructionAE(Opcode opcode, int ra, int re) {
if (isUnreachable) {
return;
}
if (_isUint8(re)) {
_emitBytes3(opcode.index, ra, re);
} else {
assert(_isUint32(re));
_emitBytes6(opcode.index + kWideModifier, ra, _byte0(re), _byte1(re),
_byte2(re), _byte3(re));
}
}
int _encode0(Opcode opcode) => _uint8(opcode.index);
void _emitInstructionAY(Opcode opcode, int ra, int ry) {
if (isUnreachable) {
return;
}
if (_isInt8(ry)) {
_emitBytes3(opcode.index, ra, ry & kByteMask);
} else {
assert(_isInt32(ry));
_emitBytes6(opcode.index + kWideModifier, ra, _byte0(ry), _byte1(ry),
_byte2(ry), _byte3(ry));
}
}
int _encodeA(Opcode opcode, int ra) =>
_uint8(opcode.index) | (_uint8(ra) << 8);
void _emitInstructionDF(Opcode opcode, int rd, int rf) {
if (isUnreachable) {
return;
}
if (_isUint8(rd)) {
_emitBytes3(opcode.index, rd, rf);
} else {
assert(_isUint32(rd));
_emitBytes6(opcode.index + kWideModifier, _byte0(rd), _byte1(rd),
_byte2(rd), _byte3(rd), rf);
}
}
int _encodeAD(Opcode opcode, int ra, int rd) =>
_uint8(opcode.index) | (_uint8(ra) << 8) | (_uint16(rd) << 16);
void _emitInstructionABC(Opcode opcode, int ra, int rb, int rc) {
if (isUnreachable) {
return;
}
_emitBytes4(opcode.index, ra, rb, rc);
}
int _encodeAX(Opcode opcode, int ra, int rx) =>
_uint8(opcode.index) | (_uint8(ra) << 8) | (_int16(rx) << 16);
int _encodeD(Opcode opcode, int rd) =>
_uint8(opcode.index) | (_uint16(rd) << 16);
int _encodeX(Opcode opcode, int rx) =>
_uint8(opcode.index) | (_int16(rx) << 16);
int _encodeABC(Opcode opcode, int ra, int rb, int rc) =>
_uint8(opcode.index) |
(_uint8(ra) << 8) |
(_uint8(rb) << 16) |
(_uint8(rc) << 24);
// TODO(alexmarkov) This format is currently unused. Restore it if needed, or
// remove it once bytecode instruction set is finalized.
//
// int _encodeABY(Opcode opcode, int ra, int rb, int ry) =>
// _uint8(opcode.index) |
// (_uint8(ra) << 8) |
// (_uint8(rb) << 16) |
// (_int8(ry) << 24);
int _encodeT(Opcode opcode, int rt) =>
_uint8(opcode.index) | (_int24(rt) << 8);
void emitBytecode0(Opcode opcode) {
void emitSpecializedBytecode(Opcode opcode) {
assert(BytecodeFormats[opcode].encoding == Encoding.k0);
emitSourcePosition();
emitWord(_encode0(opcode));
_emitInstruction0(opcode);
}
void _emitJumpBytecode(Opcode opcode, Label label) {
void _emitJumpInstruction(Opcode opcode, Label label) {
assert(isJump(opcode));
if (!isUnreachable) {
// Do not use label if not generating instruction.
emitWord(_encodeT(opcode, label.jumpOperand(offset)));
if (isUnreachable) {
return;
}
final int target = label.jumpOperand(offset);
// Use compact representation only for backwards jumps.
// TODO(alexmarkov): generate compact forward jumps as well.
if (label.isBound && _isInt8(target)) {
_emitBytes2(opcode.index, target & kByteMask);
} else {
assert(_isInt24(target));
_emitBytes4(opcode.index + kWideModifier, _byte0(target), _byte1(target),
_byte2(target));
}
}
void _patchJump(int pos, int rt) {
final Opcode opcode = Opcode.values[_byteAt(pos) - kWideModifier];
assert(hasWideVariant(opcode));
assert(isJump(opcode));
assert(_isInt24(rt));
_setByteAt(pos + 1, _byte0(rt));
_setByteAt(pos + 2, _byte1(rt));
_setByteAt(pos + 3, _byte2(rt));
}
void emitTrap() {
emitWord(_encode0(Opcode.kTrap));
_emitInstruction0(Opcode.kTrap);
isUnreachable = true;
}
void emitDrop1() {
emitWord(_encode0(Opcode.kDrop1));
_emitInstruction0(Opcode.kDrop1);
}
void emitJump(Label label) {
_emitJumpBytecode(Opcode.kJump, label);
_emitJumpInstruction(Opcode.kJump, label);
isUnreachable = true;
}
void emitJumpIfNoAsserts(Label label) {
_emitJumpBytecode(Opcode.kJumpIfNoAsserts, label);
_emitJumpInstruction(Opcode.kJumpIfNoAsserts, label);
}
void emitJumpIfNotZeroTypeArgs(Label label) {
_emitJumpBytecode(Opcode.kJumpIfNotZeroTypeArgs, label);
_emitJumpInstruction(Opcode.kJumpIfNotZeroTypeArgs, label);
}
void emitJumpIfEqStrict(Label label) {
_emitJumpBytecode(Opcode.kJumpIfEqStrict, label);
_emitJumpInstruction(Opcode.kJumpIfEqStrict, label);
}
void emitJumpIfNeStrict(Label label) {
_emitJumpBytecode(Opcode.kJumpIfNeStrict, label);
_emitJumpInstruction(Opcode.kJumpIfNeStrict, label);
}
void emitJumpIfTrue(Label label) {
_emitJumpBytecode(Opcode.kJumpIfTrue, label);
_emitJumpInstruction(Opcode.kJumpIfTrue, label);
}
void emitJumpIfFalse(Label label) {
_emitJumpBytecode(Opcode.kJumpIfFalse, label);
_emitJumpInstruction(Opcode.kJumpIfFalse, label);
}
void emitJumpIfNull(Label label) {
_emitJumpBytecode(Opcode.kJumpIfNull, label);
_emitJumpInstruction(Opcode.kJumpIfNull, label);
}
void emitJumpIfNotNull(Label label) {
_emitJumpBytecode(Opcode.kJumpIfNotNull, label);
}
void patchJump(int pos, int rt) {
final Opcode opcode = Opcode.values[_getOpcodeAt(pos)];
assert(isJump(opcode));
_setWord(pos, _encodeT(opcode, rt));
_emitJumpInstruction(Opcode.kJumpIfNotNull, label);
}
void emitReturnTOS() {
emitWord(_encode0(Opcode.kReturnTOS));
_emitInstruction0(Opcode.kReturnTOS);
isUnreachable = true;
}
void emitPush(int rx) {
emitWord(_encodeX(Opcode.kPush, rx));
_emitInstructionX(Opcode.kPush, rx);
}
void emitLoadConstant(int ra, int rd) {
emitWord(_encodeAD(Opcode.kLoadConstant, ra, rd));
void emitLoadConstant(int ra, int re) {
_emitInstructionAE(Opcode.kLoadConstant, ra, re);
}
void emitPushConstant(int rd) {
emitWord(_encodeD(Opcode.kPushConstant, rd));
_emitInstructionD(Opcode.kPushConstant, rd);
}
void emitPushNull() {
emitWord(_encode0(Opcode.kPushNull));
_emitInstruction0(Opcode.kPushNull);
}
void emitPushTrue() {
emitWord(_encode0(Opcode.kPushTrue));
_emitInstruction0(Opcode.kPushTrue);
}
void emitPushFalse() {
emitWord(_encode0(Opcode.kPushFalse));
_emitInstruction0(Opcode.kPushFalse);
}
void emitPushInt(int rx) {
emitWord(_encodeX(Opcode.kPushInt, rx));
_emitInstructionX(Opcode.kPushInt, rx);
}
void emitStoreLocal(int rx) {
emitWord(_encodeX(Opcode.kStoreLocal, rx));
_emitInstructionX(Opcode.kStoreLocal, rx);
}
void emitPopLocal(int rx) {
emitWord(_encodeX(Opcode.kPopLocal, rx));
_emitInstructionX(Opcode.kPopLocal, rx);
}
void emitIndirectStaticCall(int ra, int rd) {
// TODO(alexmarkov): swap operands.
void emitDirectCall(int rf, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd));
_emitInstructionDF(Opcode.kDirectCall, rd, rf);
}
void emitDirectCall(int ra, int rd) {
void emitInterfaceCall(int rf, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kDirectCall, ra, rd));
_emitInstructionDF(Opcode.kInterfaceCall, rd, rf);
}
void emitInterfaceCall(int ra, int rd) {
void emitUncheckedInterfaceCall(int rf, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kInterfaceCall, ra, rd));
_emitInstructionDF(Opcode.kUncheckedInterfaceCall, rd, rf);
}
void emitUncheckedInterfaceCall(int ra, int rd) {
void emitDynamicCall(int rf, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kUncheckedInterfaceCall, ra, rd));
}
void emitDynamicCall(int ra, int rd) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kDynamicCall, ra, rd));
_emitInstructionDF(Opcode.kDynamicCall, rd, rf);
}
void emitNativeCall(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kNativeCall, rd));
_emitInstructionD(Opcode.kNativeCall, rd);
}
void emitStoreStaticTOS(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kStoreStaticTOS, rd));
_emitInstructionD(Opcode.kStoreStaticTOS, rd);
}
void emitPushStatic(int rd) {
emitWord(_encodeD(Opcode.kPushStatic, rd));
_emitInstructionD(Opcode.kPushStatic, rd);
}
void emitCreateArrayTOS() {
emitWord(_encode0(Opcode.kCreateArrayTOS));
_emitInstruction0(Opcode.kCreateArrayTOS);
}
void emitAllocate(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kAllocate, rd));
_emitInstructionD(Opcode.kAllocate, rd);
}
void emitAllocateT() {
emitSourcePosition();
emitWord(_encode0(Opcode.kAllocateT));
_emitInstruction0(Opcode.kAllocateT);
}
void emitStoreIndexedTOS() {
emitWord(_encode0(Opcode.kStoreIndexedTOS));
_emitInstruction0(Opcode.kStoreIndexedTOS);
}
void emitStoreFieldTOS(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kStoreFieldTOS, rd));
_emitInstructionD(Opcode.kStoreFieldTOS, rd);
}
void emitStoreContextParent() {
emitWord(_encode0(Opcode.kStoreContextParent));
_emitInstruction0(Opcode.kStoreContextParent);
}
void emitStoreContextVar(int ra, int rd) {
emitWord(_encodeAD(Opcode.kStoreContextVar, ra, rd));
void emitStoreContextVar(int ra, int re) {
_emitInstructionAE(Opcode.kStoreContextVar, ra, re);
}
void emitLoadFieldTOS(int rd) {
emitWord(_encodeD(Opcode.kLoadFieldTOS, rd));
_emitInstructionD(Opcode.kLoadFieldTOS, rd);
}
void emitLoadTypeArgumentsField(int rd) {
emitWord(_encodeD(Opcode.kLoadTypeArgumentsField, rd));
_emitInstructionD(Opcode.kLoadTypeArgumentsField, rd);
}
void emitLoadContextParent() {
emitWord(_encode0(Opcode.kLoadContextParent));
_emitInstruction0(Opcode.kLoadContextParent);
}
void emitLoadContextVar(int ra, int rd) {
emitWord(_encodeAD(Opcode.kLoadContextVar, ra, rd));
void emitLoadContextVar(int ra, int re) {
_emitInstructionAE(Opcode.kLoadContextVar, ra, re);
}
void emitBooleanNegateTOS() {
emitWord(_encode0(Opcode.kBooleanNegateTOS));
_emitInstruction0(Opcode.kBooleanNegateTOS);
}
void emitThrow(int ra) {
emitSourcePosition();
emitWord(_encodeA(Opcode.kThrow, ra));
_emitInstructionA(Opcode.kThrow, ra);
isUnreachable = true;
}
void emitEntry(int rd) {
emitWord(_encodeD(Opcode.kEntry, rd));
_emitInstructionD(Opcode.kEntry, rd);
}
void emitFrame(int rd) {
emitWord(_encodeD(Opcode.kFrame, rd));
_emitInstructionD(Opcode.kFrame, rd);
}
void emitSetFrame(int ra) {
emitWord(_encodeA(Opcode.kSetFrame, ra));
_emitInstructionA(Opcode.kSetFrame, ra);
}
void emitAllocateContext(int ra, int rd) {
emitWord(_encodeAD(Opcode.kAllocateContext, ra, rd));
void emitAllocateContext(int ra, int re) {
_emitInstructionAE(Opcode.kAllocateContext, ra, re);
}
void emitCloneContext(int ra, int rd) {
emitWord(_encodeAD(Opcode.kCloneContext, ra, rd));
void emitCloneContext(int ra, int re) {
_emitInstructionAE(Opcode.kCloneContext, ra, re);
}
void emitMoveSpecial(SpecialIndex ra, int rx) {
emitWord(_encodeAX(Opcode.kMoveSpecial, ra.index, rx));
void emitMoveSpecial(SpecialIndex ra, int ry) {
_emitInstructionAY(Opcode.kMoveSpecial, ra.index, ry);
}
void emitInstantiateType(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kInstantiateType, rd));
_emitInstructionD(Opcode.kInstantiateType, rd);
}
void emitInstantiateTypeArgumentsTOS(int ra, int rd) {
void emitInstantiateTypeArgumentsTOS(int ra, int re) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kInstantiateTypeArgumentsTOS, ra, rd));
_emitInstructionAE(Opcode.kInstantiateTypeArgumentsTOS, ra, re);
}
void emitAssertAssignable(int ra, int rd) {
void emitAssertAssignable(int ra, int re) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kAssertAssignable, ra, rd));
_emitInstructionAE(Opcode.kAssertAssignable, ra, re);
}
void emitAssertSubtype() {
emitSourcePosition();
emitWord(_encode0(Opcode.kAssertSubtype));
_emitInstruction0(Opcode.kAssertSubtype);
}
void emitAssertBoolean(int ra) {
emitSourcePosition();
emitWord(_encodeA(Opcode.kAssertBoolean, ra));
_emitInstructionA(Opcode.kAssertBoolean, ra);
}
void emitCheckStack(int ra) {
emitSourcePosition();
emitWord(_encodeA(Opcode.kCheckStack, ra));
_emitInstructionA(Opcode.kCheckStack, ra);
}
void emitCheckFunctionTypeArgs(int ra, int rd) {
void emitCheckFunctionTypeArgs(int ra, int re) {
emitSourcePosition();
emitWord(_encodeAD(Opcode.kCheckFunctionTypeArgs, ra, rd));
_emitInstructionAE(Opcode.kCheckFunctionTypeArgs, ra, re);
}
void emitEntryFixed(int ra, int rd) {
emitWord(_encodeAD(Opcode.kEntryFixed, ra, rd));
void emitEntryFixed(int ra, int re) {
_emitInstructionAE(Opcode.kEntryFixed, ra, re);
}
void emitEntryOptional(int ra, int rb, int rc) {
emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc));
_emitInstructionABC(Opcode.kEntryOptional, ra, rb, rc);
}
void emitAllocateClosure(int rd) {
emitSourcePosition();
emitWord(_encodeD(Opcode.kAllocateClosure, rd));
_emitInstructionD(Opcode.kAllocateClosure, rd);
}
}

View file

@ -10,99 +10,299 @@ library vm.bytecode.dbc;
/// Before bumping current bytecode version format, make sure that
/// all users have switched to a VM which is able to consume new
/// version of bytecode.
const int currentBytecodeFormatVersion = 6;
const int currentBytecodeFormatVersion = 7;
/// Version of experimental / bleeding edge bytecode format.
/// Produced by bytecode generator when --use-future-bytecode-format
/// option is enabled.
const int futureBytecodeFormatVersion = currentBytecodeFormatVersion + 1;
/// Alignment of bytecode instructions.
const int bytecodeInstructionsAlignment = 4;
enum Opcode {
// Old instructions, used before bytecode v7.
// TODO(alexmarkov): remove
kTrap_Old,
// Prologue and stack management.
kEntry_Old,
kEntryFixed_Old,
kEntryOptional_Old,
kLoadConstant_Old,
kFrame_Old,
kCheckFunctionTypeArgs_Old,
kCheckStack_Old,
// Object allocation.
kAllocate_Old,
kAllocateT_Old,
kCreateArrayTOS_Old,
// Context allocation and access.
kAllocateContext_Old,
kCloneContext_Old,
kLoadContextParent_Old,
kStoreContextParent_Old,
kLoadContextVar_Old,
kStoreContextVar_Old,
// Constants.
kPushConstant_Old,
kPushNull_Old,
kPushTrue_Old,
kPushFalse_Old,
kPushInt_Old,
// Locals and expression stack.
kDrop1_Old,
kPush_Old,
kPopLocal_Old,
kStoreLocal_Old,
// Instance fields and arrays.
kLoadFieldTOS_Old,
kStoreFieldTOS_Old,
kStoreIndexedTOS_Old,
// Static fields.
kPushStatic_Old,
kStoreStaticTOS_Old,
// Jumps.
kJump_Old,
kJumpIfNoAsserts_Old,
kJumpIfNotZeroTypeArgs_Old,
kJumpIfEqStrict_Old,
kJumpIfNeStrict_Old,
kJumpIfTrue_Old,
kJumpIfFalse_Old,
kJumpIfNull_Old,
kJumpIfNotNull_Old,
// Calls.
kUnused00_Old,
kInterfaceCall_Old,
kDynamicCall_Old,
kNativeCall_Old,
kReturnTOS_Old,
// Types and type checks.
kAssertAssignable_Old,
kAssertBoolean_Old,
kAssertSubtype_Old,
kLoadTypeArgumentsField_Old,
kInstantiateType_Old,
kInstantiateTypeArgumentsTOS_Old,
// Exception handling.
kThrow_Old,
kMoveSpecial_Old,
kSetFrame_Old,
// Bool operations.
kBooleanNegateTOS_Old,
// Null operations.
kEqualsNull_Old,
// Int operations.
kNegateInt_Old,
kAddInt_Old,
kSubInt_Old,
kMulInt_Old,
kTruncDivInt_Old,
kModInt_Old,
kBitAndInt_Old,
kBitOrInt_Old,
kBitXorInt_Old,
kShlInt_Old,
kShrInt_Old,
kCompareIntEq_Old,
kCompareIntGt_Old,
kCompareIntLt_Old,
kCompareIntGe_Old,
kCompareIntLe_Old,
kDirectCall_Old,
kAllocateClosure_Old,
kUncheckedInterfaceCall_Old,
// Double operations.
kNegateDouble_Old,
kAddDouble_Old,
kSubDouble_Old,
kMulDouble_Old,
kDivDouble_Old,
kCompareDoubleEq_Old,
kCompareDoubleGt_Old,
kCompareDoubleLt_Old,
kCompareDoubleGe_Old,
kCompareDoubleLe_Old,
// Bytecode instructions since bytecode format v7:
kTrap,
// Prologue and stack management.
kEntry,
kEntry_Wide,
kEntryFixed,
kEntryFixed_Wide,
kEntryOptional,
kUnused00, // Reserved for EntryNoLocals.
kLoadConstant,
kLoadConstant_Wide,
kFrame,
kFrame_Wide,
kCheckFunctionTypeArgs,
kCheckFunctionTypeArgs_Wide,
kCheckStack,
kUnused01,
kUnused02, // Reserved for CheckParameterTypes
kUnused03, // Reserved for CheckParameterTypes_Wide
// Object allocation.
kAllocate,
kAllocate_Wide,
kAllocateT,
kCreateArrayTOS,
kAllocateClosure,
kAllocateClosure_Wide,
// Context allocation and access.
kAllocateContext,
kAllocateContext_Wide,
kCloneContext,
kCloneContext_Wide,
kLoadContextParent,
kStoreContextParent,
kLoadContextVar,
kLoadContextVar_Wide,
kUnused04, // Reserved for LoadContextVar0
kUnused05,
kStoreContextVar,
kStoreContextVar_Wide,
// Constants.
kPushConstant,
kPushNull,
kPushConstant_Wide,
kUnused06, // Reserved for PushConstant0
kUnused07,
kPushTrue,
kPushFalse,
kPushInt,
kPushInt_Wide,
kUnused08, // Reserved for PushInt0
kUnused09, // Reserved for PushInt1
kUnused10, // Reserved for PushInt2
kUnused11,
kPushNull,
// Locals and expression stack.
kDrop1,
kPush,
kPush_Wide,
kUnused12, // Reserved for PushLocal0
kUnused13, // Reserved for PushLocal1
kUnused14, // Reserved for PushLocal2
kUnused15, // Reserved for PushLocal3
kUnused16, // Reserved for PushParamLast0
kUnused17, // Reserved for PushParamLast1
kPopLocal,
kPopLocal_Wide,
kUnused18, // Reserved for PopLocal0
kUnused19,
kStoreLocal,
kStoreLocal_Wide,
// Instance fields and arrays.
kLoadFieldTOS,
kLoadFieldTOS_Wide,
kStoreFieldTOS,
kStoreFieldTOS_Wide,
kStoreIndexedTOS,
kUnused20,
// Static fields.
kPushStatic,
kPushStatic_Wide,
kStoreStaticTOS,
kStoreStaticTOS_Wide,
// Jumps.
kJump,
kJump_Wide,
kJumpIfNoAsserts,
kJumpIfNoAsserts_Wide,
kJumpIfNotZeroTypeArgs,
kJumpIfNotZeroTypeArgs_Wide,
kJumpIfEqStrict,
kJumpIfEqStrict_Wide,
kJumpIfNeStrict,
kJumpIfNeStrict_Wide,
kJumpIfTrue,
kJumpIfTrue_Wide,
kJumpIfFalse,
kJumpIfFalse_Wide,
kJumpIfNull,
kJumpIfNull_Wide,
kJumpIfNotNull,
kJumpIfNotNull_Wide,
// Calls.
kIndirectStaticCall,
kDirectCall,
kDirectCall_Wide,
kUnused21, // Reserved for DirectCall1
kUnused22, // Reserved for DirectCall1_Wide
kInterfaceCall,
kInterfaceCall_Wide,
kUnused23, // Reserved for InterfaceCall1
kUnused24, // Reserved for InterfaceCall1_Wide
kUnused25, // Reserved for InterfaceCall2
kUnused26, // Reserved for InterfaceCall2_Wide
kUnused27, // Reserved for InterfaceCall3
kUnused28, // Reserved for InterfaceCall3_Wide
kUncheckedInterfaceCall,
kUncheckedInterfaceCall_Wide,
kDynamicCall,
kDynamicCall_Wide,
kNativeCall,
kNativeCall_Wide,
kReturnTOS,
kUnused29,
// Types and type checks.
kAssertAssignable,
kAssertAssignable_Wide,
kUnused30, // Reserved for AsSimpleType
kUnused31, // Reserved for AsSimpleType_Wide
kAssertBoolean,
kAssertSubtype,
kLoadTypeArgumentsField,
kLoadTypeArgumentsField_Wide,
kInstantiateType,
kInstantiateType_Wide,
kInstantiateTypeArgumentsTOS,
kInstantiateTypeArgumentsTOS_Wide,
kUnused32, // Reserved for IsType
kUnused33, // Reserved for IsType_Wide
kUnused34, // Reserved for IsSimpleType
kUnused35, // Reserved for IsSimpleType_Wide
// Exception handling.
kThrow,
kMoveSpecial,
kSetFrame,
kMoveSpecial,
kMoveSpecial_Wide,
// Bool operations.
kBooleanNegateTOS,
// Null operations.
kEqualsNull,
kUnused36, // Reserved for CheckNull
kUnused37, // Reserved for CheckNull_Wide
// Int operations.
kNegateInt,
@ -122,12 +322,6 @@ enum Opcode {
kCompareIntGe,
kCompareIntLe,
kDirectCall,
kAllocateClosure,
kUncheckedInterfaceCall,
// Double operations.
kNegateDouble,
kAddDouble,
@ -141,16 +335,47 @@ enum Opcode {
kCompareDoubleLe,
}
/// Compact variants of opcodes are always even.
/// Wide variant = opcode + kWideModifier.
const int kWideModifier = 1;
/// Opcode should fit into 1 byte.
const int kMaxOpcodes = 256;
enum Encoding {
k0,
kA,
kAD,
kAX,
kD,
kX,
kABC,
kABY,
kT,
k0, // No operands.
kA, // 1 operand: A = 8-bit unsigned.
kD, // 1 operand: D = 8/32-bit unsigned.
kX, // 1 operand: X = 8/32-bit signed.
kT, // 1 operand: T = 8/24-bit signed.
kAE, // 2 operands: A = 8-bit unsigned, E = 8/32-bit unsigned
kAY, // 2 operands: A = 8-bit unsigned, Y = 8/32-bit signed
kDF, // 2 operands: D = 8/32-bit unsigned, F = 8-bit unsigned
kABC, // 3 operands: A, B, C - 8-bit unsigned.
}
int instructionSize(Encoding encoding, bool isWide) {
switch (encoding) {
case Encoding.k0:
return 1;
case Encoding.kA:
return 2;
case Encoding.kD:
return isWide ? 5 : 2;
case Encoding.kX:
return isWide ? 5 : 2;
case Encoding.kT:
return isWide ? 4 : 2;
case Encoding.kAE:
return isWide ? 6 : 3;
case Encoding.kAY:
return isWide ? 6 : 3;
case Encoding.kDF:
return isWide ? 6 : 3;
case Encoding.kABC:
return 4;
}
throw 'Unexpected instruction encoding $encoding';
}
enum Operand {
@ -175,15 +400,15 @@ const Map<Opcode, Format> BytecodeFormats = const {
Opcode.kEntry: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kEntryFixed: const Format(
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kEntryOptional: const Format(
Encoding.kABC, const [Operand.imm, Operand.imm, Operand.imm]),
Opcode.kLoadConstant: const Format(
Encoding.kAD, const [Operand.reg, Operand.lit, Operand.none]),
Encoding.kAE, const [Operand.reg, Operand.lit, Operand.none]),
Opcode.kFrame: const Format(
Encoding.kD, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kCheckFunctionTypeArgs: const Format(
Encoding.kAD, const [Operand.imm, Operand.reg, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.reg, Operand.none]),
Opcode.kCheckStack: const Format(
Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kAllocate: const Format(
@ -193,17 +418,17 @@ const Map<Opcode, Format> BytecodeFormats = const {
Opcode.kCreateArrayTOS: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kAllocateContext: const Format(
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kCloneContext: const Format(
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kLoadContextParent: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kStoreContextParent: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kLoadContextVar: const Format(
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kStoreContextVar: const Format(
Encoding.kAD, const [Operand.imm, Operand.imm, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.imm, Operand.none]),
Opcode.kPushConstant: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kPushNull: const Format(
@ -250,18 +475,16 @@ const Map<Opcode, Format> BytecodeFormats = const {
Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
Opcode.kJumpIfNotNull: const Format(
Encoding.kT, const [Operand.tgt, Operand.none, Operand.none]),
Opcode.kIndirectStaticCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Opcode.kInterfaceCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
Opcode.kDynamicCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
Opcode.kNativeCall: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kReturnTOS: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kAssertAssignable: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.lit, Operand.none]),
Opcode.kAssertBoolean: const Format(
Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kAssertSubtype: const Format(
@ -271,11 +494,11 @@ const Map<Opcode, Format> BytecodeFormats = const {
Opcode.kInstantiateType: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kInstantiateTypeArgumentsTOS: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kAE, const [Operand.imm, Operand.lit, Operand.none]),
Opcode.kThrow: const Format(
Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kMoveSpecial: const Format(
Encoding.kAX, const [Operand.spe, Operand.xeg, Operand.none]),
Encoding.kAY, const [Operand.spe, Operand.xeg, Operand.none]),
Opcode.kSetFrame: const Format(
Encoding.kA, const [Operand.imm, Operand.none, Operand.none]),
Opcode.kBooleanNegateTOS: const Format(
@ -315,11 +538,11 @@ const Map<Opcode, Format> BytecodeFormats = const {
Opcode.kCompareIntLe: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kDirectCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
Opcode.kAllocateClosure: const Format(
Encoding.kD, const [Operand.lit, Operand.none, Operand.none]),
Opcode.kUncheckedInterfaceCall: const Format(
Encoding.kAD, const [Operand.imm, Operand.lit, Operand.none]),
Encoding.kDF, const [Operand.lit, Operand.imm, Operand.none]),
Opcode.kNegateDouble: const Format(
Encoding.k0, const [Operand.none, Operand.none, Operand.none]),
Opcode.kAddDouble: const Format(
@ -350,18 +573,80 @@ enum SpecialIndex {
stackTrace,
}
/// Returns [true] if there is a wide variant for the given opcode.
bool hasWideVariant(Opcode opcode) {
final encoding = BytecodeFormats[opcode].encoding;
switch (encoding) {
case Encoding.k0:
case Encoding.kA:
case Encoding.kABC:
return false;
case Encoding.kD:
case Encoding.kX:
case Encoding.kT:
case Encoding.kAE:
case Encoding.kAY:
case Encoding.kDF:
return true;
}
throw 'Unexpected instruction encoding $encoding';
}
bool isWideOpcode(Opcode opcode) {
return (BytecodeFormats[opcode] == null) &&
hasWideVariant(Opcode.values[opcode.index - kWideModifier]);
}
Opcode fromWideOpcode(Opcode opcode) {
assert(isWideOpcode(opcode));
return Opcode.values[opcode.index - kWideModifier];
}
void verifyBytecodeInstructionDeclarations() {
const String kWideSuffix = '_Wide';
for (Opcode opcode in Opcode.values) {
final format = BytecodeFormats[opcode];
if (opcode.toString().endsWith(kWideSuffix)) {
if (format != null) {
throw 'Bytecode format should not be defined for wide opcode $opcode.';
}
final Opcode compact = Opcode.values[opcode.index - kWideModifier];
if (compact.toString() + kWideSuffix != opcode.toString()) {
throw 'Wide opcode $opcode should immediately follow its compact opcode (previous opcode is $compact).';
}
if (!hasWideVariant(compact)) {
throw 'Wide opcode $opcode should not be defined for opcode $compact with encoding ${BytecodeFormats[compact].encoding}.';
}
}
if (format == null) {
continue;
}
if (hasWideVariant(opcode)) {
if (Opcode.values[opcode.index + kWideModifier].toString() !=
opcode.toString() + kWideSuffix) {
throw 'Opcode $opcode$kWideSuffix should immedialy follow $opcode.';
}
if (opcode.index.isOdd) {
throw 'Opcode $opcode (${format.encoding}) has a wide variant and should be even';
}
}
}
if (Opcode.values.length > kMaxOpcodes) {
throw 'Too many opcodes';
}
}
bool isJump(Opcode opcode) => BytecodeFormats[opcode].encoding == Encoding.kT;
bool isThrow(Opcode opcode) => opcode == Opcode.kThrow;
bool isCall(Opcode opcode) {
switch (opcode) {
case Opcode.kIndirectStaticCall:
case Opcode.kDirectCall:
case Opcode.kInterfaceCall:
case Opcode.kUncheckedInterfaceCall:
case Opcode.kDynamicCall:
case Opcode.kNativeCall:
case Opcode.kDirectCall:
return true;
default:
return false;
@ -389,14 +674,14 @@ bool isPush(Opcode opcode) {
}
// Bytecode instructions reference constant pool indices using
// unsigned 16-bit operands.
const int constantPoolIndexLimit = 1 << 16;
// unsigned 32-bit operands.
const int constantPoolIndexLimit = 1 << 32;
// Local variables are referenced using 16-bit signed operands.
const int localVariableIndexLimit = 1 << 15;
// Local variables are referenced using 32-bit signed operands.
const int localVariableIndexLimit = 1 << 31;
// Captured variables are referenced using 16-bit unsigned operands.
const int capturedVariableIndexLimit = 1 << 16;
// Captured variables are referenced using 32-bit unsigned operands.
const int capturedVariableIndexLimit = 1 << 32;
// Context IDs are referenced using 8-bit unsigned operands.
const int contextIdLimit = 1 << 8;

View file

@ -9,10 +9,7 @@ import 'bytecode_serialization.dart'
show BufferedWriter, BufferedReader, BytecodeSizeStatistics, StringTable;
import 'constant_pool.dart' show ConstantPool;
import 'dbc.dart'
show
currentBytecodeFormatVersion,
futureBytecodeFormatVersion,
bytecodeInstructionsAlignment;
show currentBytecodeFormatVersion, futureBytecodeFormatVersion;
import 'disassembler.dart' show BytecodeDisassembler;
import 'exceptions.dart' show ExceptionsTable;
import 'object_table.dart' show ObjectTable, ObjectHandle, NameAndType;
@ -1029,13 +1026,11 @@ class Component {
void _writeBytecodeInstructions(BufferedWriter writer, List<int> bytecodes) {
writer.writePackedUInt30(bytecodes.length);
writer.align(bytecodeInstructionsAlignment);
writer.writeBytes(bytecodes);
BytecodeSizeStatistics.instructionsSize += bytecodes.length;
}
List<int> _readBytecodeInstructions(BufferedReader reader) {
int len = reader.readPackedUInt30();
reader.align(bytecodeInstructionsAlignment);
return reader.readBytesAsUint8List(len);
}

View file

@ -13,8 +13,15 @@ import 'exceptions.dart';
class Instruction {
final Opcode opcode;
final bool isWide;
final List<int> operands;
Instruction(this.opcode, this.operands);
final int pc;
Instruction(this.opcode, this.isWide, this.operands, this.pc);
Format get format => BytecodeFormats[opcode];
int get length => instructionSize(format.encoding, isWide);
@override
int get hashCode => opcode.index.hashCode ^ listHashCode(operands);
@ -28,9 +35,7 @@ class Instruction {
}
class BytecodeDisassembler {
static const int kOpcodeMask = 0xFF;
static const int kBitsPerInt = 64;
Uint8List _bytecode;
List<Instruction> _instructions;
int _labelCount;
Map<int, String> _labels;
@ -47,14 +52,19 @@ class BytecodeDisassembler {
return _disasm();
}
void _init(List<int> bytecode) {
final uint8list = new Uint8List.fromList(bytecode);
// TODO(alexmarkov): endianness?
Uint32List words = uint8list.buffer.asUint32List();
List<Instruction> decode(Uint8List bytecode) {
_init(bytecode);
return _instructions;
}
_instructions = new List<Instruction>(words.length);
for (int i = 0; i < words.length; i++) {
_instructions[i] = decodeInstruction(words[i]);
void _init(List<int> bytecode) {
_bytecode = new Uint8List.fromList(bytecode);
_instructions = new List<Instruction>();
for (int pos = 0; pos < _bytecode.length;) {
final instr = decodeInstructionAt(pos);
_instructions.add(instr);
pos += instr.length;
}
_labelCount = 0;
@ -62,58 +72,73 @@ class BytecodeDisassembler {
_markers = <int, List<String>>{};
}
Instruction decodeInstruction(int word) {
final opcode = Opcode.values[word & kOpcodeMask];
Instruction decodeInstructionAt(int pos) {
Opcode opcode = Opcode.values[_bytecode[pos]];
bool isWide = isWideOpcode(opcode);
if (isWide) {
opcode = fromWideOpcode(opcode);
}
final format = BytecodeFormats[opcode];
return new Instruction(opcode, _decodeOperands(format, word));
final operands = _decodeOperands(format, pos, isWide);
return new Instruction(opcode, isWide, operands, pos);
}
List<int> _decodeOperands(Format format, int word) {
List<int> _decodeOperands(Format format, int pos, bool isWide) {
switch (format.encoding) {
case Encoding.k0:
return const [];
case Encoding.kA:
return [_unsigned(word, 8, 8)];
case Encoding.kAD:
return [_unsigned(word, 8, 8), _unsigned(word, 16, 16)];
case Encoding.kAX:
return [_unsigned(word, 8, 8), _signed(word, 16, 16)];
return [_bytecode[pos + 1]];
case Encoding.kD:
return [_unsigned(word, 16, 16)];
return isWide ? [_decodeUint32At(pos + 1)] : [_bytecode[pos + 1]];
case Encoding.kX:
return [_signed(word, 16, 16)];
case Encoding.kABC:
return [
_unsigned(word, 8, 8),
_unsigned(word, 16, 8),
_unsigned(word, 24, 8)
];
case Encoding.kABY:
return [
_unsigned(word, 8, 8),
_unsigned(word, 16, 8),
_signed(word, 24, 8)
];
return isWide
? [_decodeUint32At(pos + 1).toSigned(32)]
: [_bytecode[pos + 1].toSigned(8)];
case Encoding.kT:
return [_signed(word, 8, 24)];
return isWide
? [
(_bytecode[pos + 1] +
(_bytecode[pos + 2] << 8) +
(_bytecode[pos + 3] << 16))
.toSigned(24)
]
: [_bytecode[pos + 1].toSigned(8)];
case Encoding.kAE:
return [
_bytecode[pos + 1],
isWide ? _decodeUint32At(pos + 2) : _bytecode[pos + 2],
];
case Encoding.kAY:
return [
_bytecode[pos + 1],
isWide
? _decodeUint32At(pos + 2).toSigned(32)
: _bytecode[pos + 2].toSigned(8)
];
case Encoding.kDF:
return isWide
? [_decodeUint32At(pos + 1), _bytecode[pos + 5]]
: [_bytecode[pos + 1], _bytecode[pos + 2]];
case Encoding.kABC:
return [_bytecode[pos + 1], _bytecode[pos + 2], _bytecode[pos + 3]];
}
throw 'Unexpected format $format';
}
int _unsigned(int word, int pos, int bits) =>
(word >> pos) & ((1 << bits) - 1);
int _signed(int word, int pos, int bits) =>
_unsigned(word, pos, bits) <<
(kBitsPerInt - bits) >>
(kBitsPerInt - bits);
_decodeUint32At(int pos) =>
_bytecode[pos] +
(_bytecode[pos + 1] << 8) +
(_bytecode[pos + 2] << 16) +
(_bytecode[pos + 3] << 24);
void _scanForJumpTargets() {
for (int i = 0; i < _instructions.length; i++) {
final instr = _instructions[i];
if (isJump(instr.opcode)) {
final target = i + instr.operands[0];
assert(0 <= target && target < _instructions.length);
final target = instr.pc + instr.operands[0];
assert(0 <= target && target < _bytecode.length);
if (!_labels.containsKey(target)) {
final label = 'L${++_labelCount}';
_labels[target] = label;
@ -147,17 +172,17 @@ class BytecodeDisassembler {
String _disasm() {
StringBuffer out = new StringBuffer();
for (int i = 0; i < _instructions.length; i++) {
List<String> markers = _markers[i];
for (Instruction instr in _instructions) {
List<String> markers = _markers[instr.pc];
if (markers != null) {
markers.forEach(out.writeln);
}
writeInstruction(out, i, _instructions[i]);
writeInstruction(out, instr);
}
return out.toString();
}
void writeInstruction(StringBuffer out, int bci, Instruction instr) {
void writeInstruction(StringBuffer out, Instruction instr) {
final format = BytecodeFormats[instr.opcode];
assert(format != null);
@ -184,14 +209,14 @@ class BytecodeDisassembler {
out.write(', ');
}
final operand =
_formatOperand(bci, format.operands[i], instr.operands[i]);
_formatOperand(instr.pc, format.operands[i], instr.operands[i]);
out.write(operand);
}
out.writeln();
}
String _formatOperand(int bci, Operand fmt, int value) {
String _formatOperand(int pc, Operand fmt, int value) {
switch (fmt) {
case Operand.none:
break;
@ -206,7 +231,7 @@ class BytecodeDisassembler {
case Operand.tgt:
return (_labels == null)
? value.toString()
: _labels[bci + value] ?? (throw 'Label not found');
: _labels[pc + value] ?? (throw 'Label not found');
case Operand.spe:
return SpecialIndex.values[value]
.toString()

View file

@ -11,7 +11,7 @@ import 'bytecode_serialization.dart' show BufferedWriter, BufferedReader;
In kernel binary, try blocks are encoded in the following way
(using notation from pkg/kernel/binary.md):
// Offset of a bytecode instruction, in DBC words.
// Offset of a bytecode instruction.
type BytecodeOffset = UInt;
type TryBlock {

View file

@ -59,6 +59,7 @@ void generateBytecode(
List<Library> libraries,
ClassHierarchy hierarchy,
}) {
verifyBytecodeInstructionDeclarations();
final coreTypes = new CoreTypes(component);
void ignoreAmbiguousSupertypes(Class cls, Supertype a, Supertype b) {}
hierarchy ??= new ClassHierarchy(component,
@ -739,6 +740,9 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
}
void _genPushInt(int value) {
// TODO(alexmarkov): relax this constraint as PushInt instruction can
// hold up to 32-bit signed operand (note that interpreter assumes
// it is Smi).
if (value.bitLength + 1 <= 16) {
asm.emitPushInt(value);
} else {
@ -2290,7 +2294,7 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
throw 'Unexpected specialized bytecode $opcode';
}
asm.emitBytecode0(opcode);
asm.emitSpecializedBytecode(opcode);
}
void _genInstanceCall(
@ -3088,13 +3092,13 @@ class BytecodeGenerator extends RecursiveVisitor<Null> {
_saveContextForTryBlock(node);
return asm.exceptionsTable.enterTryBlock(asm.offsetInWords);
return asm.exceptionsTable.enterTryBlock(asm.offset);
}
/// End try block and start its handler.
void _endTryBlock(TreeNode node, TryBlock tryBlock) {
tryBlock.endPC = asm.offsetInWords;
tryBlock.handlerPC = asm.offsetInWords;
tryBlock.endPC = asm.offset;
tryBlock.handlerPC = asm.offset;
// Exception handlers are reachable although there are no labels or jumps.
asm.isUnreachable = false;

View file

@ -16,16 +16,9 @@ bool isControlFlowInstr(Instruction instr) => isControlFlow(instr.opcode);
class NGram {
List<Instruction> instrs;
List<int> _words;
BytecodeDisassembler _disassembler;
NGram(List<int> words, {bool mergePushes = false}) {
_disassembler = new BytecodeDisassembler();
_words = words;
instrs = new List<Instruction>(words.length);
for (int i = 0; i < instrs.length; i++) {
instrs[i] = _disassembler.decodeInstruction(words[i]);
}
NGram(this.instrs, {bool mergePushes = false}) {
if (mergePushes) {
_mergePushes(instrs);
}
@ -48,7 +41,7 @@ class NGram {
String toString() {
StringBuffer out = new StringBuffer();
for (var instr in instrs) {
_disassembler.writeInstruction(out, 0, instr);
_disassembler.writeInstruction(out, instr);
}
return out.toString();
}
@ -57,7 +50,7 @@ class NGram {
static void _mergePushes(List<Instruction> instrs) {
for (int i = 0; i < instrs.length; i++) {
if (isPush(instrs[i].opcode)) {
instrs[i] = new Instruction(Opcode.kPush, <int>[0]);
instrs[i] = new Instruction(Opcode.kPush, false, <int>[0], 0);
}
}
}
@ -104,14 +97,15 @@ class NGram {
}
class NGramReader {
Uint32List _words;
List<Instruction> _instructions;
Map<NGram, int> _ngramCounts = <NGram, int>{};
NGramReader(String traceFilename) {
File traceFile = File(traceFilename);
Uint8List data = traceFile.readAsBytesSync();
_words = Uint32List.view(data.buffer);
Uint8List bytecode = traceFile.readAsBytesSync();
final disassembler = new BytecodeDisassembler();
_instructions = disassembler.decode(bytecode);
}
Map<NGram, int> get ngramCounts => _ngramCounts;
@ -119,8 +113,9 @@ class NGramReader {
void readAllNGrams(int windowSize,
{bool basicBlocks: true, bool mergePushes: false}) {
int offset = 0;
while (offset + windowSize < _words.length) {
Uint32List window = _words.sublist(offset, offset + windowSize);
while (offset + windowSize < _instructions.length) {
List<Instruction> window =
_instructions.sublist(offset, offset + windowSize);
offset += 1;
NGram ngram = new NGram(window, mergePushes: mergePushes);
if (basicBlocks && ngram.controlFlowIsNotLast) {

View file

@ -26,7 +26,7 @@ Bytecode {
PushInt 0
PushInt 0
PushNull
DirectCall 3, CP#0
DirectCall CP#0, 3
Drop1
L1:
PushNull
@ -48,14 +48,14 @@ Bytecode {
CheckStack 0
JumpIfNoAsserts L1
Push FP[-6]
DynamicCall 1, CP#1
DynamicCall CP#1, 1
AssertBoolean 0
JumpIfTrue L1
PushInt 0
PushInt 0
Push FP[-5]
DynamicCall 1, CP#2
DirectCall 3, CP#3
DynamicCall CP#2, 1
DirectCall CP#3, 3
Drop1
L1:
PushNull

View file

@ -101,7 +101,7 @@ ClosureCode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#8
DirectCall CP#8, 1
Drop1
StoreContextVar 0, 1
Push r0
@ -145,27 +145,27 @@ ClosureCode {
StoreContextVar 0, 8
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#29
DirectCall CP#29, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#31
DirectCall CP#31, 1
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#33
DirectCall CP#33, 1
StoreContextVar 0, 4
Push r0
LoadContextVar 0, 1
Push r0
LoadContextVar 0, 8
DynamicCall 2, CP#36
DynamicCall CP#36, 2
Drop1
Push r0
LoadContextVar 0, 1
InterfaceCall 1, CP#37
InterfaceCall CP#37, 1
ReturnTOS
}
@ -204,7 +204,7 @@ Try #0 start:
LoadContextVar 0, 4
Push r4
LoadContextVar 0, 8
DirectCall 4, CP#12
DirectCall CP#12, 4
PopLocal r8
PushNull
ReturnTOS
@ -221,7 +221,7 @@ L2:
LoadContextVar 0, 1
Push r4
LoadContextVar 0, 2
DirectCall 2, CP#14
DirectCall CP#14, 2
Drop1
PushNull
ReturnTOS
@ -244,7 +244,7 @@ Try #0 handler:
LoadContextVar 0, 1
Push r8
Push r9
InterfaceCall 3, CP#17
InterfaceCall CP#17, 3
Drop1
Jump L3
L3:
@ -275,7 +275,7 @@ Bytecode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
StoreContextVar 0, 0
Push r0
@ -312,22 +312,22 @@ Bytecode {
StoreFieldTOS CP#6
PopLocal r6
Push r6
DirectCall 1, CP#23
DirectCall CP#23, 1
PopLocal r3
Push r6
DirectCall 1, CP#25
DirectCall CP#25, 1
PopLocal r4
Push r6
DirectCall 1, CP#27
DirectCall CP#27, 1
PopLocal r5
Push r0
LoadContextVar 0, 0
Push r6
DynamicCall 2, CP#30
DynamicCall CP#30, 2
Drop1
Push r0
LoadContextVar 0, 0
InterfaceCall 1, CP#31
InterfaceCall CP#31, 1
ReturnTOS
}
ConstantPool {
@ -393,7 +393,7 @@ L2:
LoadContextVar 0, 0
Push r4
LoadContextVar 0, 1
DirectCall 2, CP#8
DirectCall CP#8, 2
Drop1
PushNull
ReturnTOS
@ -412,7 +412,7 @@ Try #0 handler:
LoadContextVar 0, 0
Push r8
Push r9
InterfaceCall 3, CP#11
InterfaceCall CP#11, 3
Drop1
Jump L3
L3:
@ -446,7 +446,7 @@ Bytecode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
StoreContextVar 0, 2
Push r0
@ -493,27 +493,27 @@ Bytecode {
StoreContextVar 0, 10
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#27
DirectCall CP#27, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#29
DirectCall CP#29, 1
StoreContextVar 0, 4
Push r0
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#31
DirectCall CP#31, 1
StoreContextVar 0, 5
Push r0
LoadContextVar 0, 2
Push r0
LoadContextVar 0, 10
DynamicCall 2, CP#34
DynamicCall CP#34, 2
Drop1
Push r0
LoadContextVar 0, 2
InterfaceCall 1, CP#35
InterfaceCall CP#35, 1
ReturnTOS
}
ConstantPool {
@ -589,7 +589,7 @@ Try #0 start:
LoadContextVar 0, 5
Push r4
LoadContextVar 0, 10
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r8
PushNull
ReturnTOS
@ -617,7 +617,7 @@ L2:
LoadContextVar 0, 5
Push r4
LoadContextVar 0, 10
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r9
PushNull
ReturnTOS
@ -632,7 +632,7 @@ L3:
Push r4
LoadContextVar 0, 9
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 0, 3
Jump L4
L4:
@ -640,7 +640,7 @@ L4:
LoadContextVar 0, 2
Push r4
LoadContextVar 0, 3
DirectCall 2, CP#12
DirectCall CP#12, 2
Drop1
PushNull
ReturnTOS
@ -663,7 +663,7 @@ Try #0 handler:
LoadContextVar 0, 2
Push r8
Push r9
InterfaceCall 3, CP#15
InterfaceCall CP#15, 3
Drop1
Jump L5
L5:
@ -700,7 +700,7 @@ Bytecode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
StoreContextVar 0, 1
Push r0
@ -750,27 +750,27 @@ Bytecode {
StoreContextVar 0, 10
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#35
DirectCall CP#35, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#37
DirectCall CP#37, 1
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 10
DirectCall 1, CP#39
DirectCall CP#39, 1
StoreContextVar 0, 4
Push r0
LoadContextVar 0, 1
Push r0
LoadContextVar 0, 10
DynamicCall 2, CP#42
DynamicCall CP#42, 2
Drop1
Push r0
LoadContextVar 0, 1
InterfaceCall 1, CP#43
InterfaceCall CP#43, 1
ReturnTOS
}
ConstantPool {
@ -869,7 +869,7 @@ L6:
LoadContextParent
LoadContextParent
LoadContextVar 0, 0
InterfaceCall 1, CP#8
InterfaceCall CP#8, 1
PopLocal r8
Push r4
Push r8
@ -879,7 +879,7 @@ L5:
Push r4
LoadContextVar 2, 1
StoreLocal r8
InterfaceCall 1, CP#10
InterfaceCall CP#10, 1
JumpIfFalse L3
AllocateContext 3, 1
StoreLocal r5
@ -889,7 +889,7 @@ L5:
PopLocal r4
Push r4
Push r8
InterfaceCall 1, CP#12
InterfaceCall CP#12, 1
StoreContextVar 3, 0
Push r4
LoadContextParent
@ -923,7 +923,7 @@ L5:
LoadContextParent
Push r4
StoreContextVar 0, 6
DirectCall 0, CP#14
DirectCall CP#14, 0
Push r4
LoadContextParent
LoadContextParent
@ -939,7 +939,7 @@ L5:
LoadContextParent
LoadContextParent
LoadContextVar 0, 10
DirectCall 4, CP#16
DirectCall CP#16, 4
PopLocal r10
PushNull
ReturnTOS
@ -964,8 +964,8 @@ L4:
LoadContextParent
LoadContextVar 0, 8
Push r1
InterfaceCall 2, CP#18
InterfaceCall 2, CP#18
InterfaceCall CP#18, 2
InterfaceCall CP#18, 2
StoreContextVar 1, 0
Push r4
LoadContextParent
@ -1024,7 +1024,7 @@ L9:
LoadContextVar 0, 1
Push r4
LoadContextVar 0, 2
DirectCall 2, CP#20
DirectCall CP#20, 2
Drop1
PushNull
ReturnTOS
@ -1047,7 +1047,7 @@ Try #0 handler:
LoadContextVar 0, 1
Push r8
Push r9
InterfaceCall 3, CP#23
InterfaceCall CP#23, 3
Drop1
Jump L10
L10:
@ -1087,7 +1087,7 @@ Bytecode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
StoreContextVar 0, 3
Push r0
@ -1152,27 +1152,27 @@ Bytecode {
StoreContextVar 0, 17
Push r0
LoadContextVar 0, 17
DirectCall 1, CP#33
DirectCall CP#33, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 0, 17
DirectCall 1, CP#35
DirectCall CP#35, 1
StoreContextVar 0, 5
Push r0
Push r0
LoadContextVar 0, 17
DirectCall 1, CP#37
DirectCall CP#37, 1
StoreContextVar 0, 6
Push r0
LoadContextVar 0, 3
Push r0
LoadContextVar 0, 17
DynamicCall 2, CP#40
DynamicCall CP#40, 2
Drop1
Push r0
LoadContextVar 0, 3
InterfaceCall 1, CP#41
InterfaceCall CP#41, 1
ReturnTOS
}
ConstantPool {
@ -1284,7 +1284,7 @@ Try #2 start:
Push r4
LoadContextParent
LoadContextVar 0, 17
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r13
PushNull
ReturnTOS
@ -1300,7 +1300,7 @@ L2:
LoadContextParent
LoadContextVar 0, 14
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 1, 0
Jump L3
Try #2 end:
@ -1328,7 +1328,7 @@ Try #2 handler:
Push r4
LoadContextVar 1, 1
PushConstant CP#13
InterfaceCall 2, CP#14
InterfaceCall CP#14, 2
JumpIfFalse L4
Push r4
LoadContextParent
@ -1361,7 +1361,7 @@ L4:
Push r4
LoadContextParent
LoadContextVar 0, 17
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r13
PushNull
ReturnTOS
@ -1377,7 +1377,7 @@ L6:
LoadContextParent
LoadContextVar 0, 15
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 1, 0
Push r4
LoadContextParent
@ -1408,7 +1408,7 @@ Try #1 handler:
Push r9
StoreContextVar 0, 13
PushConstant CP#16
DirectCall 1, CP#17
DirectCall CP#17, 1
Drop1
Push r4
LoadContextParent
@ -1435,7 +1435,7 @@ Try #1 handler:
Push r4
LoadContextParent
LoadContextVar 0, 17
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r12
PushNull
ReturnTOS
@ -1451,7 +1451,7 @@ L8:
LoadContextParent
LoadContextVar 0, 16
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 1, 0
Push r4
LoadContextParent
@ -1470,7 +1470,7 @@ L5:
LoadContextVar 0, 10
PopLocal r4
PushConstant CP#16
DirectCall 1, CP#17
DirectCall CP#17, 1
Drop1
Push r4
LoadContextParent
@ -1497,7 +1497,7 @@ L5:
Push r4
LoadContextParent
LoadContextVar 0, 17
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r12
PushNull
ReturnTOS
@ -1513,7 +1513,7 @@ L10:
LoadContextParent
LoadContextVar 0, 16
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 1, 0
Push r4
LoadContextParent
@ -1532,7 +1532,7 @@ L7:
LoadContextVar 0, 10
PopLocal r4
PushConstant CP#16
DirectCall 1, CP#17
DirectCall CP#17, 1
Drop1
Push r4
LoadContextParent
@ -1559,7 +1559,7 @@ L7:
Push r4
LoadContextParent
LoadContextVar 0, 17
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r12
PushNull
ReturnTOS
@ -1575,7 +1575,7 @@ L11:
LoadContextParent
LoadContextVar 0, 16
Push r1
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
StoreContextVar 1, 0
Push r4
LoadContextParent
@ -1591,7 +1591,7 @@ L9:
LoadContextVar 0, 3
Push r4
LoadContextVar 0, 4
DirectCall 2, CP#19
DirectCall CP#19, 2
Drop1
PushNull
ReturnTOS
@ -1614,7 +1614,7 @@ Try #0 handler:
LoadContextVar 0, 3
Push r8
Push r9
InterfaceCall 3, CP#21
InterfaceCall CP#21, 3
Drop1
Jump L12
L12:
@ -1739,7 +1739,7 @@ ClosureCode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
StoreContextVar 1, 0
Push r0
@ -1786,27 +1786,27 @@ ClosureCode {
StoreContextVar 1, 8
Push r0
LoadContextVar 1, 8
DirectCall 1, CP#29
DirectCall CP#29, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 1, 8
DirectCall 1, CP#31
DirectCall CP#31, 1
StoreContextVar 1, 2
Push r0
Push r0
LoadContextVar 1, 8
DirectCall 1, CP#33
DirectCall CP#33, 1
StoreContextVar 1, 3
Push r0
LoadContextVar 1, 0
Push r0
LoadContextVar 1, 8
DynamicCall 2, CP#36
DynamicCall CP#36, 2
Drop1
Push r0
LoadContextVar 1, 0
InterfaceCall 1, CP#37
InterfaceCall CP#37, 1
ReturnTOS
}
@ -1871,7 +1871,7 @@ Try #1 start:
Push r4
LoadContextParent
LoadContextVar 1, 8
DirectCall 4, CP#9
DirectCall CP#9, 4
PopLocal r11
PushNull
ReturnTOS
@ -1908,7 +1908,7 @@ Try #1 handler:
MoveSpecial exception, r8
MoveSpecial stackTrace, r9
PushConstant CP#12
DirectCall 1, CP#13
DirectCall CP#13, 1
Drop1
Push r8
Push r9
@ -1921,7 +1921,7 @@ L3:
LoadContextVar 1, 7
PopLocal r4
PushConstant CP#12
DirectCall 1, CP#13
DirectCall CP#13, 1
Drop1
Push r4
LoadContextParent
@ -1932,7 +1932,7 @@ L4:
LoadContextVar 1, 0
Push r4
LoadContextVar 1, 1
DirectCall 2, CP#15
DirectCall CP#15, 2
Drop1
PushNull
ReturnTOS
@ -1955,7 +1955,7 @@ Try #0 handler:
LoadContextVar 1, 0
Push r8
Push r9
InterfaceCall 3, CP#17
InterfaceCall CP#17, 3
Drop1
Jump L5
L5:
@ -1989,7 +1989,7 @@ Bytecode {
AllocateT
StoreLocal r2
Push r2
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
StoreContextVar 0, 1
Push r0
@ -2033,27 +2033,27 @@ Bytecode {
StoreContextVar 0, 8
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#29
DirectCall CP#29, 1
PopLocal r3
Push r0
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#31
DirectCall CP#31, 1
StoreContextVar 0, 3
Push r0
Push r0
LoadContextVar 0, 8
DirectCall 1, CP#33
DirectCall CP#33, 1
StoreContextVar 0, 4
Push r0
LoadContextVar 0, 1
Push r0
LoadContextVar 0, 8
DynamicCall 2, CP#36
DynamicCall CP#36, 2
Drop1
Push r0
LoadContextVar 0, 1
InterfaceCall 1, CP#37
InterfaceCall CP#37, 1
ReturnTOS
}
ConstantPool {
@ -2132,7 +2132,7 @@ Try #0 start:
LoadContextVar 0, 4
Push r4
LoadContextVar 0, 8
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r8
PushNull
ReturnTOS
@ -2146,13 +2146,13 @@ L3:
JumpIfNoAsserts L2
Push r1
PushInt 42
InterfaceCall 2, CP#10
InterfaceCall CP#10, 2
AssertBoolean 0
JumpIfTrue L2
PushInt 0
PushInt 0
PushNull
DirectCall 3, CP#12
DirectCall CP#12, 3
Drop1
L2:
Push r4
@ -2164,7 +2164,7 @@ L4:
LoadContextVar 0, 1
Push r4
LoadContextVar 0, 2
DirectCall 2, CP#14
DirectCall CP#14, 2
Drop1
PushNull
ReturnTOS
@ -2187,7 +2187,7 @@ Try #0 handler:
LoadContextVar 0, 1
Push r8
Push r9
InterfaceCall 3, CP#17
InterfaceCall CP#17, 3
Drop1
Jump L5
L5:

View file

@ -51,8 +51,8 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
InterfaceCall 1, CP#0
DirectCall 1, CP#2
InterfaceCall CP#0, 1
DirectCall CP#2, 1
Drop1
PushNull
ReturnTOS
@ -134,13 +134,13 @@ Bytecode {
PushConstant CP#0
PushStatic CP#0
PushConstant CP#1
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AssertBoolean 0
JumpIfTrue L1
PushConstant CP#0
PushStatic CP#0
PushConstant CP#4
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AssertBoolean 0
PopLocal r1
Jump L2
@ -153,7 +153,7 @@ L2:
PushConstant CP#0
PushStatic CP#0
PushConstant CP#5
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AssertBoolean 0
PopLocal r0
Jump L4
@ -165,15 +165,15 @@ L4:
JumpIfFalse L5
PushConstant CP#0
PushStatic CP#0
DirectCall 1, CP#6
DirectCall CP#6, 1
ReturnTOS
L5:
DirectCall 0, CP#8
DirectCall CP#8, 0
PushNull
PushConstant CP#0
PushStatic CP#0
DirectCall 2, CP#10
InterfaceCall 2, CP#12
DirectCall CP#10, 2
InterfaceCall CP#12, 2
ReturnTOS
}
ConstantPool {
@ -203,7 +203,7 @@ Bytecode {
Entry 1
CheckStack 0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
@ -229,7 +229,7 @@ Bytecode {
JumpIfFalse L1
PushConstant CP#1
PushStatic CP#1
DirectCall 1, CP#2
DirectCall CP#2, 1
StoreLocal r1
Push r1
StoreStaticTOS CP#0
@ -289,7 +289,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -324,7 +324,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -397,10 +397,10 @@ Bytecode {
Allocate CP#0
StoreLocal r1
Push r1
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push FP[-5]
DirectCall 2, CP#3
DirectCall CP#3, 2
StoreStaticTOS CP#5
PushNull
ReturnTOS
@ -430,10 +430,10 @@ Bytecode {
Allocate CP#1
StoreLocal r1
Push r1
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
DirectCall 0, CP#4
DirectCall 2, CP#6
DirectCall CP#4, 0
DirectCall CP#6, 2
StoreStaticTOS CP#0
L1:
PushConstant CP#0
@ -460,8 +460,8 @@ Function 'get:_namespacePointer', getter, static, reflectable, debuggable
Bytecode {
Entry 0
CheckStack 0
DirectCall 0, CP#0
DirectCall 1, CP#2
DirectCall CP#0, 0
DirectCall CP#2, 1
ReturnTOS
}
ConstantPool {
@ -511,7 +511,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -531,7 +531,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -550,7 +550,7 @@ Function 'get:_namespace', getter, static, reflectable, debuggable
Bytecode {
Entry 0
CheckStack 0
DirectCall 0, CP#0
DirectCall CP#0, 0
ReturnTOS
}
ConstantPool {
@ -567,7 +567,7 @@ Function 'get:_namespacePointer', getter, static, reflectable, debuggable
Bytecode {
Entry 0
CheckStack 0
DirectCall 0, CP#0
DirectCall CP#0, 0
ReturnTOS
}
ConstantPool {
@ -636,7 +636,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -694,7 +694,7 @@ L2:
JumpIfFalse L3
PushConstant CP#1
PushStatic CP#1
DynamicCall 1, CP#3
DynamicCall CP#3, 1
StoreStaticTOS CP#0
L3:
PushConstant CP#0
@ -751,7 +751,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -783,7 +783,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS

View file

@ -44,7 +44,7 @@ Bytecode {
PopLocal r2
Push r2
PushInt 3
DynamicCall 2, CP#17
DynamicCall CP#17, 2
Drop1
Push r0
LoadContextVar 0, 0
@ -160,8 +160,8 @@ Bytecode {
Push r0
InstantiateType CP#8
StoreIndexedTOS
DirectCall 2, CP#9
DirectCall 1, CP#11
DirectCall CP#9, 2
DirectCall CP#11, 1
Drop1
PushNull
ReturnTOS
@ -197,9 +197,9 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
InterfaceCall 2, CP#5
InterfaceCall CP#5, 2
Drop1
PushConstant CP#7
PushConstant CP#2
@ -207,9 +207,9 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
InterfaceCall 2, CP#5
InterfaceCall CP#5, 2
Drop1
PushConstant CP#7
PushConstant CP#8
@ -217,9 +217,9 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
InterfaceCall 2, CP#5
InterfaceCall CP#5, 2
Drop1
PushNull
ReturnTOS
@ -267,7 +267,7 @@ Bytecode {
StoreLocal r3
PushConstant CP#18
StoreLocal r6
DirectCall 2, CP#19
DirectCall CP#19, 2
Drop1
Allocate CP#21
StoreLocal r5
@ -340,7 +340,7 @@ L2:
LoadFieldTOS CP#6
PushInt 0
PushInt 1
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r0
Push FP[-5]
PushConstant CP#10
@ -389,7 +389,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -421,7 +421,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -453,7 +453,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -485,7 +485,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -517,7 +517,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -549,7 +549,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -581,7 +581,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -613,7 +613,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -645,7 +645,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -692,11 +692,11 @@ Bytecode {
PopLocal r3
PushConstant CP#43
Push r3
DynamicCall 2, CP#44
DynamicCall CP#44, 2
Drop1
PushConstant CP#45
Push r3
DynamicCall 2, CP#46
DynamicCall CP#46, 2
Drop1
PushNull
ReturnTOS
@ -772,7 +772,7 @@ L2:
LoadFieldTOS CP#6
PushInt 2
PushInt 4
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r0
AllocateClosure CP#10
StoreLocal r4
@ -796,11 +796,11 @@ L2:
PopLocal r3
PushConstant CP#37
Push r3
DynamicCall 2, CP#39
DynamicCall CP#39, 2
Drop1
PushConstant CP#40
Push r3
DynamicCall 2, CP#41
DynamicCall CP#41, 2
Drop1
PushNull
ReturnTOS
@ -829,7 +829,7 @@ L2:
LoadFieldTOS CP#6
PushInt 4
PushInt 6
DirectCall 4, CP#8
DirectCall CP#8, 4
PopLocal r0
AllocateClosure CP#11
StoreLocal r4
@ -852,7 +852,7 @@ L2:
StoreFieldTOS CP#1
PopLocal r3
Push r3
DynamicCall 1, CP#35
DynamicCall CP#35, 1
Drop1
PushNull
ReturnTOS
@ -927,15 +927,15 @@ ClosureCode {
Push r0
InstantiateType CP#21
StoreIndexedTOS
DirectCall 2, CP#22
DirectCall 1, CP#24
DirectCall CP#22, 2
DirectCall CP#24, 1
Drop1
Push r1
LoadContextVar 0, 0
LoadTypeArgumentsField CP#14
Push r0
InstantiateTypeArgumentsTOS 0, CP#26
DirectCall 1, CP#27
DirectCall CP#27, 1
Drop1
PushNull
ReturnTOS
@ -981,7 +981,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -1034,22 +1034,22 @@ Bytecode {
PopLocal r3
Push r3
PushInt 10
DynamicCall 2, CP#25
DynamicCall CP#25, 2
Drop1
Push r3
PushInt 11
DynamicCall 2, CP#26
DynamicCall CP#26, 2
Drop1
Push r2
DirectCall 1, CP#21
DirectCall CP#21, 1
Drop1
Push r0
LoadContextVar 0, 2
DirectCall 1, CP#21
DirectCall CP#21, 1
Drop1
Push r0
LoadContextVar 0, 1
DirectCall 1, CP#21
DirectCall CP#21, 1
Drop1
Push r0
PushInt 42
@ -1073,7 +1073,7 @@ Bytecode {
StoreFieldTOS CP#1
PopLocal r2
Push r2
DynamicCall 1, CP#31
DynamicCall CP#31, 1
Drop1
PushNull
ReturnTOS
@ -1170,11 +1170,11 @@ ClosureCode {
StoreFieldTOS CP#1
PopLocal r3
Push r3
DynamicCall 1, CP#20
DynamicCall CP#20, 1
Drop1
Push r0
LoadContextVar 1, 1
DirectCall 1, CP#21
DirectCall CP#21, 1
Drop1
L1:
PushNull
@ -1201,7 +1201,7 @@ ClosureCode {
Push r0
LoadContextParent
LoadContextVar 0, 0
InterfaceCall 1, CP#7
InterfaceCall CP#7, 1
Push r0
LoadContextVar 1, 0
AddInt
@ -1222,7 +1222,7 @@ ClosureCode {
LoadContextVar 0, 0
Push r0
LoadContextVar 0, 3
InterfaceCall 2, CP#28
InterfaceCall CP#28, 2
Drop1
PushNull
ReturnTOS
@ -1285,7 +1285,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -1311,11 +1311,11 @@ Bytecode {
StoreContextVar 0, 0
PushConstant CP#0
PushConstant CP#1
DirectCall 2, CP#2
DirectCall CP#2, 2
PopLocal r2
PushConstant CP#0
PushConstant CP#1
DirectCall 2, CP#2
DirectCall CP#2, 2
PopLocal r4
AllocateContext 1, 1
StoreLocal r1
@ -1351,7 +1351,7 @@ L2:
Push r3
Push r0
StoreFieldTOS CP#5
InterfaceCall 2, CP#17
InterfaceCall CP#17, 2
Drop1
Push r4
AllocateClosure CP#19
@ -1371,7 +1371,7 @@ L2:
Push r3
Push r0
StoreFieldTOS CP#5
InterfaceCall 2, CP#17
InterfaceCall CP#17, 2
Drop1
Push r0
CloneContext 1, 1
@ -1475,18 +1475,18 @@ Bytecode {
Entry 5
CheckStack 0
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
PopLocal r2
L2:
CheckStack 1
Push r2
InterfaceCall 1, CP#2
InterfaceCall CP#2, 1
JumpIfFalse L1
AllocateContext 0, 1
PopLocal r0
Push r0
Push r2
InterfaceCall 1, CP#4
InterfaceCall CP#4, 1
StoreContextVar 0, 0
AllocateClosure CP#6
StoreLocal r4
@ -1507,11 +1507,11 @@ L2:
StoreFieldTOS CP#7
PopLocal r3
Push r3
DynamicCall 1, CP#20
DynamicCall CP#20, 1
Drop1
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#21
DirectCall CP#21, 1
Drop1
Push r0
LoadContextParent
@ -1606,7 +1606,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -1773,7 +1773,7 @@ ClosureCode {
StoreFieldTOS CP#1
PopLocal r2
Push r2
DynamicCall 1, CP#16
DynamicCall CP#16, 1
Drop1
PushNull
ReturnTOS

View file

@ -20,9 +20,9 @@ Bytecode {
Entry 1
CheckStack 0
PushNull
DirectCall 1, CP#0
DirectCall CP#0, 1
PopLocal r0
DirectCall 0, CP#2
DirectCall CP#2, 0
ReturnTOS
}
ConstantPool {
@ -42,7 +42,7 @@ Bytecode {
Entry 0
CheckStack 0
PushNull
DirectCall 1, CP#0
DirectCall CP#0, 1
ReturnTOS
}
ConstantPool {

View file

@ -70,7 +70,7 @@ Bytecode {
PushInt 44
StoreFieldTOS CP#2
Push FP[-6]
DirectCall 1, CP#6
DirectCall CP#6, 1
Drop1
PushNull
ReturnTOS
@ -111,7 +111,7 @@ Bytecode {
AddInt
StoreFieldTOS CP#2
Push FP[-7]
DirectCall 1, CP#6
DirectCall CP#6, 1
Drop1
PushNull
ReturnTOS
@ -139,7 +139,7 @@ Bytecode {
CheckStack 0
Push FP[-5]
PushInt 45
DirectCall 2, CP#0
DirectCall CP#0, 2
Drop1
PushNull
ReturnTOS
@ -163,7 +163,7 @@ Bytecode {
Push FP[-6]
Push FP[-5]
MulInt
DirectCall 3, CP#0
DirectCall CP#0, 3
Drop1
PushNull
ReturnTOS
@ -221,7 +221,7 @@ Bytecode {
StoreFieldTOS CP#0
Push FP[-5]
PushInt 49
DirectCall 2, CP#2
DirectCall CP#2, 2
Drop1
PushNull
ReturnTOS
@ -252,7 +252,7 @@ Bytecode {
Push FP[-6]
Push FP[-5]
PushInt 51
DirectCall 4, CP#2
DirectCall CP#2, 4
Drop1
PushNull
ReturnTOS

View file

@ -20,7 +20,7 @@ Bytecode {
Entry 0
CheckStack 0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS

View file

@ -23,7 +23,7 @@ Bytecode {
StoreLocal r0
Push r0
PushConstant CP#1
DirectCall 2, CP#2
DirectCall CP#2, 2
Drop1
ReturnTOS
}
@ -49,7 +49,7 @@ Bytecode {
StoreLocal r0
Push r0
PushConstant CP#2
DirectCall 2, CP#3
DirectCall CP#3, 2
Drop1
Drop1
PushConstant CP#6
@ -57,7 +57,7 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#7
DirectCall CP#7, 1
Drop1
Drop1
PushNull
@ -93,7 +93,7 @@ Bytecode {
AllocateT
StoreLocal r1
Push r1
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
Drop1
PushNull
@ -116,7 +116,7 @@ Bytecode {
Entry 0
CheckStack 0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
@ -137,11 +137,11 @@ Bytecode {
Entry 0
CheckStack 0
PushNull
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
PushInt 42
DirectCall 2, CP#2
DirectCall CP#2, 2
Drop1
PushNull
ReturnTOS
@ -164,7 +164,7 @@ Bytecode {
CheckStack 0
PushConstant CP#0
PushInt 0
DirectCall 2, CP#1
DirectCall CP#1, 2
ReturnTOS
}
ConstantPool {
@ -184,7 +184,7 @@ Bytecode {
CheckStack 0
PushConstant CP#0
Push FP[-5]
DirectCall 2, CP#1
DirectCall CP#1, 2
ReturnTOS
}
ConstantPool {
@ -202,12 +202,12 @@ Function 'main', static, reflectable, debuggable
Bytecode {
Entry 0
CheckStack 0
DirectCall 0, CP#0
DirectCall CP#0, 0
Drop1
DirectCall 0, CP#2
DirectCall CP#2, 0
Drop1
PushConstant CP#4
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
PushNull
ReturnTOS
@ -246,7 +246,7 @@ Bytecode {
Entry 1
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
PushInt 4
@ -274,8 +274,8 @@ Bytecode {
PushNull
InstantiateType CP#6
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
ReturnTOS
@ -320,7 +320,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-6]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -352,7 +352,7 @@ Bytecode {
Entry 1
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
PushInt 2
@ -369,8 +369,8 @@ Bytecode {
PushNull
InstantiateType CP#3
StoreIndexedTOS
DirectCall 1, CP#5
DirectCall 1, CP#7
DirectCall CP#5, 1
DirectCall CP#7, 1
Drop1
PushNull
ReturnTOS
@ -410,7 +410,7 @@ Bytecode {
Entry 1
CheckStack 0
Push FP[-6]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
PushInt 2
@ -424,8 +424,8 @@ Bytecode {
PushInt 1
Push FP[-5]
StoreIndexedTOS
DirectCall 1, CP#3
DirectCall 1, CP#5
DirectCall CP#3, 1
DirectCall CP#5, 1
Drop1
PushNull
ReturnTOS
@ -463,7 +463,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -484,7 +484,7 @@ Bytecode {
CheckStack 0
Push FP[-5]
LoadTypeArgumentsField CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
ReturnTOS
}
ConstantPool {
@ -517,7 +517,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -538,7 +538,7 @@ Bytecode {
CheckStack 0
Push FP[-5]
LoadTypeArgumentsField CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
ReturnTOS
}
ConstantPool {
@ -571,7 +571,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -598,7 +598,7 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
ReturnTOS
}
@ -633,7 +633,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -665,7 +665,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-6]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -691,7 +691,7 @@ Bytecode {
StoreLocal r2
Push r2
Push r1
DirectCall 2, CP#3
DirectCall CP#3, 2
Drop1
ReturnTOS
}
@ -760,7 +760,7 @@ Bytecode {
AllocateT
StoreLocal r0
Push r0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
ReturnTOS
}
@ -791,7 +791,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS

View file

@ -67,19 +67,19 @@ Bytecode {
Entry 0
CheckStack 0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushConstant CP#3
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushInt 6
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushConstant CP#4
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushConstant CP#5
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
@ -103,22 +103,22 @@ Bytecode {
Entry 0
CheckStack 0
PushInt 42
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushConstant CP#2
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushConstant CP#3
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushConstant CP#4
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushConstant CP#5
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushConstant CP#6
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -160,8 +160,8 @@ Bytecode {
PushInt 2
PushInt 3
StoreIndexedTOS
DirectCall 2, CP#1
DirectCall 1, CP#3
DirectCall CP#1, 2
DirectCall CP#3, 1
Drop1
PushConstant CP#5
StoreLocal r0
@ -176,14 +176,14 @@ Bytecode {
Push r0
PushInt 1
Push FP[-5]
InterfaceCall 1, CP#7
InterfaceCall CP#7, 1
StoreIndexedTOS
Push r0
PushInt 2
PushConstant CP#9
StoreIndexedTOS
DirectCall 2, CP#1
DirectCall 1, CP#3
DirectCall CP#1, 2
DirectCall CP#3, 1
Drop1
PushNull
ReturnTOS
@ -233,8 +233,8 @@ Bytecode {
PushInt 3
PushInt 2
StoreIndexedTOS
DirectCall 2, CP#2
DirectCall 1, CP#4
DirectCall CP#2, 2
DirectCall CP#4, 1
Drop1
PushConstant CP#6
PushConstant CP#1
@ -252,21 +252,21 @@ Bytecode {
Push r1
PushInt 2
Push FP[-6]
InterfaceCall 1, CP#8
InterfaceCall CP#8, 1
StoreIndexedTOS
Push r1
PushInt 3
PushInt 3
StoreIndexedTOS
DirectCall 2, CP#2
DirectCall 1, CP#4
DirectCall CP#2, 2
DirectCall CP#4, 1
Drop1
PushNull
Push r0
InstantiateTypeArgumentsTOS 0, CP#10
PushConstant CP#11
DirectCall 2, CP#2
DirectCall 1, CP#4
DirectCall CP#2, 2
DirectCall CP#4, 1
Drop1
PushNull
Push r0
@ -283,8 +283,8 @@ Bytecode {
PushInt 1
PushInt 4
StoreIndexedTOS
DirectCall 2, CP#2
DirectCall 1, CP#4
DirectCall CP#2, 2
DirectCall CP#4, 1
Drop1
PushNull
ReturnTOS
@ -315,10 +315,10 @@ Bytecode {
Entry 0
CheckStack 0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushConstant CP#3
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
@ -342,12 +342,12 @@ Bytecode {
CheckStack 0
CheckFunctionTypeArgs 1, r0
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
Push r0
InstantiateType CP#3
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
@ -519,7 +519,7 @@ Bytecode {
Push FP[-5]
StoreFieldTOS CP#2
Push FP[-7]
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
PushNull
ReturnTOS
@ -543,7 +543,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
ReturnTOS
}
ConstantPool {
@ -587,7 +587,7 @@ Bytecode {
Push FP[-5]
StoreFieldTOS CP#0
Push FP[-6]
DirectCall 1, CP#2
DirectCall CP#2, 1
Drop1
PushNull
ReturnTOS
@ -632,7 +632,7 @@ Bytecode {
Push FP[-5]
PushInt 5
MulInt
DirectCall 2, CP#2
DirectCall CP#2, 2
Drop1
PushNull
ReturnTOS
@ -680,7 +680,7 @@ Bytecode {
Push r2
StoreFieldTOS CP#3
Push r0
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
PushNull
ReturnTOS
@ -719,7 +719,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -751,7 +751,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS

View file

@ -27,13 +27,13 @@ L2:
CheckStack 1
Push r1
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
CompareIntLt
JumpIfFalse L1
Push r0
Push FP[-5]
Push r1
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AddInt
PopLocal r0
Push r1
@ -74,7 +74,7 @@ L3:
JumpIfFalse L1
Push r1
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
CompareIntGe
JumpIfFalse L2
Jump L1
@ -82,7 +82,7 @@ L2:
Push r0
Push FP[-5]
Push r1
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AddInt
PopLocal r0
Push r1
@ -120,7 +120,7 @@ L4:
CheckStack 1
Push r1
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
CompareIntLt
JumpIfFalse L1
Push r1
@ -132,7 +132,7 @@ L2:
Push r0
Push FP[-5]
Push r1
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AddInt
PopLocal r0
L3:
@ -170,7 +170,7 @@ L2:
CheckStack 1
Push r1
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
CompareIntLt
JumpIfFalse L1
Push r0
@ -183,7 +183,7 @@ L2:
StoreLocal r1
PopLocal r3
Push r2
InterfaceCall 2, CP#2
InterfaceCall CP#2, 2
AddInt
PopLocal r0
Jump L2
@ -216,7 +216,7 @@ L1:
Push r0
Push FP[-5]
Push r1
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
AddInt
PopLocal r0
Push r1
@ -225,7 +225,7 @@ L1:
PopLocal r1
Push r1
Push FP[-5]
InterfaceCall 1, CP#2
InterfaceCall CP#2, 1
CompareIntLt
JumpIfTrue L1
Push r0
@ -250,15 +250,15 @@ Bytecode {
PushInt 0
PopLocal r0
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
PopLocal r1
L2:
CheckStack 1
Push r1
InterfaceCall 1, CP#2
InterfaceCall CP#2, 1
JumpIfFalse L1
Push r1
InterfaceCall 1, CP#4
InterfaceCall CP#4, 1
PopLocal r2
Push r0
Push r2
@ -292,15 +292,15 @@ Bytecode {
PushInt 42
PopLocal r1
Push FP[-5]
InterfaceCall 1, CP#0
InterfaceCall CP#0, 1
PopLocal r2
L2:
CheckStack 1
Push r2
InterfaceCall 1, CP#2
InterfaceCall CP#2, 1
JumpIfFalse L1
Push r2
InterfaceCall 1, CP#4
InterfaceCall CP#4, 1
PopLocal r3
Push r3
PopLocal r1

View file

@ -34,8 +34,8 @@ Bytecode {
PushInt 1
Push r0
StoreIndexedTOS
DirectCall 1, CP#3
DirectCall 1, CP#5
DirectCall CP#3, 1
DirectCall CP#5, 1
Drop1
PushNull
PushInt 2
@ -49,8 +49,8 @@ Bytecode {
PushInt 1
Push r1
StoreIndexedTOS
DirectCall 1, CP#3
DirectCall 1, CP#5
DirectCall CP#3, 1
DirectCall CP#5, 1
Drop1
PushNull
PushInt 2
@ -64,8 +64,8 @@ Bytecode {
PushInt 1
Push r2
StoreIndexedTOS
DirectCall 1, CP#3
DirectCall 1, CP#5
DirectCall CP#3, 1
DirectCall CP#5, 1
Drop1
PushNull
ReturnTOS
@ -110,8 +110,8 @@ Bytecode {
PushInt 1
Push r0
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
PushInt 2
@ -125,8 +125,8 @@ Bytecode {
PushInt 1
Push r1
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
PushInt 2
@ -140,8 +140,8 @@ Bytecode {
PushInt 1
Push r2
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
PushInt 2
@ -155,8 +155,8 @@ Bytecode {
PushInt 1
Push r3
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
PushInt 2
@ -170,8 +170,8 @@ Bytecode {
PushInt 1
Push r4
StoreIndexedTOS
DirectCall 1, CP#7
DirectCall 1, CP#9
DirectCall CP#7, 1
DirectCall CP#9, 1
Drop1
PushNull
ReturnTOS
@ -213,13 +213,13 @@ Bytecode {
PushNull
Push r4
InstantiateType CP#4
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
Push r1
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
Push r3
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
PushNull
ReturnTOS
@ -245,12 +245,12 @@ Bytecode {
CheckStack 0
PushConstant CP#0
PushConstant CP#1
DirectCall 2, CP#2
DirectCall CP#2, 2
Drop1
PushConstant CP#4
PushConstant CP#5
PushConstant CP#1
DirectCall 3, CP#6
DirectCall CP#6, 3
Drop1
PushNull
ReturnTOS

View file

@ -44,7 +44,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -127,7 +127,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -150,7 +150,7 @@ Bytecode {
Push FP[-6]
PushConstant CP#1
PushInt 2
DirectCall 4, CP#2
DirectCall CP#2, 4
ReturnTOS
}
ConstantPool {
@ -170,7 +170,7 @@ Bytecode {
Entry 1
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
ReturnTOS
}
ConstantPool {
@ -188,7 +188,7 @@ Bytecode {
Entry 1
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
ReturnTOS
}
ConstantPool {
@ -207,9 +207,9 @@ Bytecode {
CheckStack 0
PushConstant CP#0
Push FP[-5]
DirectCall 1, CP#1
DirectCall CP#1, 1
PushConstant CP#3
DynamicCall 3, CP#5
DynamicCall CP#5, 3
ReturnTOS
}
ConstantPool {
@ -232,7 +232,7 @@ Bytecode {
CheckStack 0
Push FP[-5]
PushInt 3
DirectCall 2, CP#0
DirectCall CP#0, 2
Drop1
PushNull
ReturnTOS
@ -275,7 +275,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -323,7 +323,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -370,8 +370,8 @@ Bytecode {
PushInt 5
StoreIndexedTOS
PushTrue
DirectCall 4, CP#6
DirectCall 2, CP#8
DirectCall CP#6, 4
DirectCall CP#8, 2
ReturnTOS
}
ConstantPool {
@ -408,8 +408,8 @@ Bytecode {
Push FP[-5]
StoreIndexedTOS
PushTrue
DirectCall 4, CP#3
DirectCall 2, CP#5
DirectCall CP#3, 4
DirectCall CP#5, 2
ReturnTOS
}
ConstantPool {
@ -443,8 +443,8 @@ Bytecode {
Push FP[-5]
StoreIndexedTOS
PushTrue
DirectCall 4, CP#3
DirectCall 2, CP#5
DirectCall CP#3, 4
DirectCall CP#5, 2
ReturnTOS
}
ConstantPool {
@ -479,10 +479,10 @@ Bytecode {
Push FP[-5]
StoreIndexedTOS
PushTrue
DirectCall 4, CP#4
DirectCall 2, CP#6
DirectCall CP#4, 4
DirectCall CP#6, 2
PushConstant CP#8
DynamicCall 3, CP#10
DynamicCall CP#10, 3
ReturnTOS
}
ConstantPool {
@ -524,8 +524,8 @@ Bytecode {
PushInt 3
StoreIndexedTOS
PushTrue
DirectCall 4, CP#3
DirectCall 2, CP#5
DirectCall CP#3, 4
DirectCall CP#5, 2
Drop1
PushNull
ReturnTOS

View file

@ -25,15 +25,15 @@ Bytecode {
PopLocal r1
Push r1
PushInt 1
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 2
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Push r1
PushInt 3
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L3
Jump L4
L1:
@ -72,27 +72,27 @@ Bytecode {
PopLocal r1
Push r1
PushInt 1
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 2
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 3
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 4
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Push r1
PushInt 5
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Push r1
PushInt 6
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Jump L3
L1:
@ -130,27 +130,27 @@ Bytecode {
PopLocal r1
Push r1
PushInt 1
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 2
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 3
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r1
PushInt 4
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Push r1
PushInt 5
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Push r1
PushInt 6
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Jump L3
L1:

View file

@ -21,7 +21,7 @@ Bytecode {
CheckStack 0
Try #0 start:
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
Try #0 end:
@ -43,8 +43,8 @@ Try #0 handler:
PushInt 1
Push r2
StoreIndexedTOS
DirectCall 1, CP#5
DirectCall 1, CP#1
DirectCall CP#5, 1
DirectCall CP#1, 1
Drop1
Jump L1
L1:
@ -52,7 +52,7 @@ L1:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 2, end 6, handler 6, types [CP#3]
try-index 0, outer -1, start 4, end 14, handler 14, types [CP#3]
}
ConstantPool {
[0] = ObjectRef 'danger!'
@ -75,7 +75,7 @@ Bytecode {
CheckStack 0
Try #0 start:
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
Try #0 end:
@ -85,16 +85,16 @@ Try #0 handler:
MoveSpecial stackTrace, r1
Push r0
PushConstant CP#3
InterfaceCall 2, CP#4
InterfaceCall CP#4, 2
JumpIfFalse L2
PushConstant CP#6
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
L2:
Push r0
PushConstant CP#7
InterfaceCall 2, CP#4
InterfaceCall CP#4, 2
JumpIfFalse L3
Push r0
PopLocal r2
@ -110,14 +110,14 @@ L2:
PushInt 1
Push r2
StoreIndexedTOS
DirectCall 1, CP#9
DirectCall 1, CP#1
DirectCall CP#9, 1
DirectCall CP#1, 1
Drop1
Jump L1
L3:
Push r0
PushConstant CP#11
InterfaceCall 2, CP#4
InterfaceCall CP#4, 2
JumpIfFalse L4
Push r0
PopLocal r2
@ -143,8 +143,8 @@ L3:
PushInt 3
Push r3
StoreIndexedTOS
DirectCall 1, CP#9
DirectCall 1, CP#1
DirectCall CP#9, 1
DirectCall CP#1, 1
Drop1
Jump L1
L4:
@ -172,8 +172,8 @@ L4:
PushInt 3
Push r3
StoreIndexedTOS
DirectCall 1, CP#9
DirectCall 1, CP#1
DirectCall CP#9, 1
DirectCall CP#1, 1
Drop1
Jump L1
L1:
@ -181,7 +181,7 @@ L1:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 2, end 6, handler 6, needs-stack-trace, types [CP#3, CP#7, CP#11, CP#14]
try-index 0, outer -1, start 4, end 14, handler 14, needs-stack-trace, types [CP#3, CP#7, CP#11, CP#14]
}
ConstantPool {
[0] = ObjectRef 'danger!'
@ -241,11 +241,11 @@ Try #0 start:
StoreFieldTOS CP#1
PopLocal r4
Push r4
DynamicCall 1, CP#18
DynamicCall CP#18, 1
Drop1
Push r0
LoadContextVar 0, 1
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
Jump L1
Try #0 end:
@ -281,8 +281,8 @@ Try #0 handler:
Push r0
LoadContextVar 0, 2
StoreIndexedTOS
DirectCall 1, CP#21
DirectCall 1, CP#4
DirectCall CP#21, 1
DirectCall CP#4, 1
Drop1
AllocateClosure CP#23
StoreLocal r5
@ -312,7 +312,7 @@ L1:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 9, end 38, handler 38, needs-stack-trace, types [CP#6]
try-index 0, outer -1, start 20, end 80, handler 80, needs-stack-trace, types [CP#6]
}
ConstantPool {
[0] = ClosureFunction 0
@ -358,7 +358,7 @@ ClosureCode {
PopLocal r2
Try #0 start:
PushConstant CP#3
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
Jump L1
Try #0 end:
@ -372,7 +372,7 @@ Try #0 handler:
PopLocal r4
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
Push r0
PushInt 3
@ -395,7 +395,7 @@ ClosureCode {
PopLocal r2
Try #0 start:
PushConstant CP#24
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
Jump L1
Try #0 end:
@ -407,7 +407,7 @@ Try #0 handler:
MoveSpecial stackTrace, r3
Push r2
PushConstant CP#25
InterfaceCall 2, CP#26
InterfaceCall CP#26, 2
JumpIfFalse L2
Push r2
PopLocal r4
@ -432,8 +432,8 @@ Try #0 handler:
Push r0
LoadContextVar 0, 2
StoreIndexedTOS
DirectCall 1, CP#21
DirectCall 1, CP#4
DirectCall CP#21, 1
DirectCall CP#4, 1
Drop1
Jump L1
L2:
@ -458,7 +458,7 @@ Bytecode {
Try #0 start:
Try #1 start:
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
Try #1 end:
@ -470,7 +470,7 @@ Try #1 handler:
PopLocal r4
Try #2 start:
PushConstant CP#4
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push FP[-5]
AssertBoolean 0
@ -488,7 +488,7 @@ Try #2 handler:
Push r5
PopLocal r7
PushConstant CP#5
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L3
L3:
@ -505,10 +505,10 @@ Try #0 handler:
Push r1
PopLocal r3
PushConstant CP#6
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push r3
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L4
L4:
@ -516,9 +516,9 @@ L4:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 2, end 32, handler 32, needs-stack-trace, types [CP#3]
try-index 1, outer 0, start 2, end 6, handler 6, needs-stack-trace, types [CP#3]
try-index 2, outer 0, start 11, end 21, handler 21, types [CP#3]
try-index 0, outer -1, start 4, end 80, handler 80, needs-stack-trace, types [CP#3]
try-index 1, outer 0, start 4, end 14, handler 14, needs-stack-trace, types [CP#3]
try-index 2, outer 0, start 26, end 50, handler 50, types [CP#3]
}
ConstantPool {
[0] = ObjectRef 'try 1 > try 2'
@ -561,19 +561,19 @@ Try #0 handler:
MoveSpecial exception, r1
MoveSpecial stackTrace, r2
Push r0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push r1
Push r2
Throw 1
L3:
Push r0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
L4:
Push r0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push r0
PushInt 1
@ -586,7 +586,7 @@ L1:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 9, end 15, handler 15, needs-stack-trace, types [CP#0]
try-index 0, outer -1, start 19, end 36, handler 36, needs-stack-trace, types [CP#0]
}
ConstantPool {
[0] = Type dynamic
@ -613,11 +613,11 @@ Bytecode {
PopLocal r2
Push r2
PushInt 1
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L1
Push r2
PushInt 2
InterfaceCall 2, CP#0
InterfaceCall CP#0, 2
JumpIfTrue L2
Jump L3
L1:
@ -625,7 +625,7 @@ L1:
PopLocal r3
Try #0 start:
PushConstant CP#2
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r0
PushInt 3
@ -634,7 +634,7 @@ Try #0 start:
PopLocal r5
Try #1 start:
PushConstant CP#5
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
AllocateClosure CP#6
StoreLocal r8
@ -655,7 +655,7 @@ Try #1 start:
StoreFieldTOS CP#7
PopLocal r7
Push r7
DynamicCall 1, CP#20
DynamicCall CP#20, 1
Drop1
Jump L4
Try #1 end:
@ -666,7 +666,7 @@ Try #1 handler:
MoveSpecial exception, r5
MoveSpecial stackTrace, r6
PushConstant CP#22
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r5
Push r6
@ -675,7 +675,7 @@ L4:
Push r5
PopLocal r0
PushConstant CP#22
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L5
Try #0 end:
@ -686,7 +686,7 @@ Try #0 handler:
MoveSpecial exception, r3
MoveSpecial stackTrace, r4
PushConstant CP#24
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r3
Push r4
@ -695,12 +695,12 @@ L5:
Push r3
PopLocal r0
PushConstant CP#24
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L2
L2:
PushConstant CP#25
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L3
L3:
@ -708,8 +708,8 @@ L3:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 21, end 71, handler 71, needs-stack-trace, types [CP#21]
try-index 1, outer 0, start 29, end 54, handler 54, needs-stack-trace, types [CP#21]
try-index 0, outer -1, start 53, end 158, handler 158, needs-stack-trace, types [CP#21]
try-index 1, outer 0, start 70, end 120, handler 120, needs-stack-trace, types [CP#21]
}
ConstantPool {
[0] = InterfaceCall 'dart:core::Object::==', ArgDesc num-args 2, num-type-args 0, names []
@ -748,11 +748,11 @@ ClosureCode {
PopLocal r0
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r0
LoadContextVar 0, 1
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
PushNull
ReturnTOS
@ -806,10 +806,10 @@ Try #0 handler:
MoveSpecial stackTrace, r4
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r2
DynamicCall 1, CP#19
DynamicCall CP#19, 1
Drop1
Push r3
Push r4
@ -819,10 +819,10 @@ L1:
PopLocal r0
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r2
DynamicCall 1, CP#20
DynamicCall CP#20, 1
Drop1
Push r0
LoadContextParent
@ -831,7 +831,7 @@ L1:
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 11, end 30, handler 30, needs-stack-trace, types [CP#6]
try-index 0, outer -1, start 23, end 61, handler 61, needs-stack-trace, types [CP#6]
}
ConstantPool {
[0] = ClosureFunction 0
@ -865,13 +865,13 @@ ClosureCode {
PopLocal r0
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r0
PopLocal r2
Try #0 start:
PushConstant CP#5
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L1
Try #0 end:
@ -885,7 +885,7 @@ Try #0 handler:
PopLocal r4
Try #1 start:
PushConstant CP#7
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L2
Try #1 end:
@ -897,7 +897,7 @@ Try #1 handler:
MoveSpecial stackTrace, r5
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r4
Push r5
@ -907,7 +907,7 @@ L2:
PopLocal r0
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
PushInt 43
ReturnTOS
@ -918,7 +918,7 @@ L1:
PopLocal r4
Try #2 start:
PushConstant CP#7
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Jump L3
Try #2 end:
@ -930,7 +930,7 @@ Try #2 handler:
MoveSpecial stackTrace, r5
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
Push r4
Push r5
@ -940,7 +940,7 @@ L3:
PopLocal r0
Push r0
LoadContextVar 0, 0
DirectCall 1, CP#3
DirectCall CP#3, 1
Drop1
PushInt 43
ReturnTOS
@ -959,7 +959,7 @@ Bytecode {
Try #0 start:
Try #1 start:
PushConstant CP#0
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
Try #1 end:
@ -970,7 +970,7 @@ Try #1 handler:
Push r2
PopLocal r4
PushConstant CP#4
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Jump L1
L1:
@ -981,21 +981,21 @@ Try #0 handler:
MoveSpecial exception, r0
MoveSpecial stackTrace, r1
PushConstant CP#5
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
Push r0
Push r1
Throw 1
L2:
PushConstant CP#5
DirectCall 1, CP#1
DirectCall CP#1, 1
Drop1
PushNull
ReturnTOS
}
ExceptionsTable {
try-index 0, outer -1, start 2, end 16, handler 16, needs-stack-trace, types [CP#3]
try-index 1, outer 0, start 2, end 6, handler 6, types [CP#3]
try-index 0, outer -1, start 4, end 40, handler 40, needs-stack-trace, types [CP#3]
try-index 1, outer 0, start 4, end 14, handler 14, types [CP#3]
}
ConstantPool {
[0] = ObjectRef 'try'

View file

@ -23,20 +23,20 @@ Bytecode {
CheckStack 0
Push FP[-5]
PushConstant CP#0
InterfaceCall 2, CP#1
InterfaceCall CP#1, 2
JumpIfFalse L1
PushConstant CP#3
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
L1:
Push FP[-5]
PushNull
PushNull
PushConstant CP#6
InterfaceCall 4, CP#7
InterfaceCall CP#7, 4
JumpIfFalse L2
PushConstant CP#9
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
L2:
Push FP[-5]
@ -123,7 +123,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -155,7 +155,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -187,7 +187,7 @@ Bytecode {
Entry 0
CheckStack 0
Push FP[-5]
DirectCall 1, CP#0
DirectCall CP#0, 1
Drop1
PushNull
ReturnTOS
@ -230,7 +230,7 @@ Bytecode {
AssertAssignable 0, CP#3
StoreFieldTOS CP#4
Push FP[-6]
DirectCall 1, CP#6
DirectCall CP#6, 1
Drop1
PushNull
ReturnTOS
@ -260,10 +260,10 @@ Bytecode {
LoadTypeArgumentsField CP#0
PushNull
PushConstant CP#1
InterfaceCall 4, CP#2
InterfaceCall CP#2, 4
JumpIfFalse L1
PushConstant CP#4
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
L1:
Push FP[-5]
@ -271,10 +271,10 @@ L1:
LoadTypeArgumentsField CP#0
PushNull
PushConstant CP#7
InterfaceCall 4, CP#2
InterfaceCall CP#2, 4
JumpIfFalse L2
PushConstant CP#8
DirectCall 1, CP#5
DirectCall CP#5, 1
Drop1
L2:
Push FP[-6]
@ -285,7 +285,7 @@ L2:
PushNull
PushConstant CP#10
AssertAssignable 0, CP#11
UncheckedInterfaceCall 2, CP#12
UncheckedInterfaceCall CP#12, 2
Drop1
PushNull
ReturnTOS
@ -322,10 +322,10 @@ Bytecode {
PushNull
Push r0
PushConstant CP#0
InterfaceCall 4, CP#1
InterfaceCall CP#1, 4
JumpIfFalse L1
PushConstant CP#3
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
L1:
Push FP[-5]
@ -333,10 +333,10 @@ L1:
LoadTypeArgumentsField CP#6
Push r0
PushConstant CP#7
InterfaceCall 4, CP#1
InterfaceCall CP#1, 4
JumpIfFalse L2
PushConstant CP#8
DirectCall 1, CP#4
DirectCall CP#4, 1
Drop1
L2:
Push FP[-5]
@ -346,7 +346,7 @@ L2:
Push r0
PushConstant CP#10
AssertAssignable 0, CP#11
InterfaceCall 1, CP#12
InterfaceCall CP#12, 1
ReturnTOS
}
ConstantPool {
@ -394,7 +394,7 @@ Bytecode {
PushConstant CP#3
AssertAssignable 0, CP#4
StoreIndexedTOS
DirectCall 2, CP#5
DirectCall CP#5, 2
PopLocal r0
Push FP[-5]
PushConstant CP#2

View file

@ -35,5 +35,5 @@ MINOR 3
PATCH 0
PRERELEASE 0
PRERELEASE_PATCH 0
ABI_VERSION 4
ABI_VERSION 5
OLDEST_SUPPORTED_ABI_VERSION 3