// Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file // for details. All rights reserved. Use of this source code is governed by a // BSD-style license that can be found in the LICENSE file. library vm.bytecode.assembler; import 'dart:typed_data'; import 'package:vm/bytecode/dbc.dart'; import 'package:vm/bytecode/exceptions.dart' show ExceptionsTable; class Label { List _jumps = []; int offset = -1; Label(); bool get isBound => offset >= 0; int jumpOperand(int jumpOffset) { if (isBound) { // Jump instruction takes an offset in DBC words. return (offset - jumpOffset) >> BytecodeAssembler.kLog2BytesPerBytecode; } _jumps.add(jumpOffset); return 0; } List bind(int offset) { assert(!isBound); this.offset = offset; final jumps = _jumps; _jumps = null; return jumps; } } class BytecodeAssembler { static const int kBitsPerInt = 64; static const int kLog2BytesPerBytecode = 2; // TODO(alexmarkov): figure out more efficient storage for generated bytecode. final List bytecode = new List(); final Uint32List _encodeBufferIn; final Uint8List _encodeBufferOut; final ExceptionsTable exceptionsTable = new ExceptionsTable(); BytecodeAssembler._(this._encodeBufferIn, this._encodeBufferOut); factory BytecodeAssembler() { final buf = new Uint32List(1); return new BytecodeAssembler._(buf, new Uint8List.view(buf.buffer)); } int get offset => bytecode.length; int get offsetInWords => bytecode.length >> kLog2BytesPerBytecode; void bind(Label label) { final List jumps = label.bind(offset); for (int jumpOffset in jumps) { patchJump(jumpOffset, label.jumpOperand(jumpOffset)); } } void emitWord(int word) { _encodeBufferIn[0] = word; // TODO(alexmarkov): Which endianness to use? bytecode.addAll(_encodeBufferOut); } 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'; } return v; } 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'; } final int mask = (1 << bits) - 1; return v & mask; } int _uint8(int v) => _unsigned(v, 8); int _uint16(int v) => _unsigned(v, 16); int _int8(int v) => _signed(v, 8); int _int16(int v) => _signed(v, 16); int _int24(int v) => _signed(v, 24); int _encode0(Opcode opcode) => _uint8(opcode.index); int _encodeA(Opcode opcode, int ra) => _uint8(opcode.index) | (_uint8(ra) << 8); int _encodeAD(Opcode opcode, int ra, int rd) => _uint8(opcode.index) | (_uint8(ra) << 8) | (_uint16(rd) << 16); 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); 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 emitTrap() { emitWord(_encode0(Opcode.kTrap)); } void emitNop(int ra, int rd) { emitWord(_encodeAD(Opcode.kNop, ra, rd)); } void emitCompile() { emitWord(_encode0(Opcode.kCompile)); } void emitHotCheck(int ra, int rd) { emitWord(_encodeAD(Opcode.kHotCheck, ra, rd)); } void emitIntrinsic(int ra) { emitWord(_encodeA(Opcode.kIntrinsic, ra)); } void emitDrop1() { emitWord(_encode0(Opcode.kDrop1)); } void emitDropR(int ra) { emitWord(_encodeA(Opcode.kDropR, ra)); } void emitDrop(int ra) { emitWord(_encodeA(Opcode.kDrop, ra)); } void emitJump(Label label) { emitWord(_encodeT(Opcode.kJump, label.jumpOperand(offset))); } void patchJump(int pos, int rt) { _setWord(pos, _encodeT(Opcode.kJump, rt)); } void emitReturn(int ra) { emitWord(_encodeA(Opcode.kReturn, ra)); } void emitReturnTOS() { emitWord(_encode0(Opcode.kReturnTOS)); } void emitMove(int ra, int rx) { emitWord(_encodeAX(Opcode.kMove, ra, rx)); } void emitSwap(int ra, int rx) { emitWord(_encodeAX(Opcode.kSwap, ra, rx)); } void emitPush(int rx) { emitWord(_encodeX(Opcode.kPush, rx)); } void emitLoadConstant(int ra, int rd) { emitWord(_encodeAD(Opcode.kLoadConstant, ra, rd)); } void emitLoadClassId(int ra, int rd) { emitWord(_encodeAD(Opcode.kLoadClassId, ra, rd)); } void emitLoadClassIdTOS() { emitWord(_encode0(Opcode.kLoadClassIdTOS)); } void emitPushConstant(int rd) { emitWord(_encodeD(Opcode.kPushConstant, rd)); } void emitStoreLocal(int rx) { emitWord(_encodeX(Opcode.kStoreLocal, rx)); } void emitPopLocal(int rx) { emitWord(_encodeX(Opcode.kPopLocal, rx)); } void emitIndirectStaticCall(int ra, int rd) { emitWord(_encodeAD(Opcode.kIndirectStaticCall, ra, rd)); } void emitStaticCall(int ra, int rd) { emitWord(_encodeAD(Opcode.kStaticCall, ra, rd)); } void emitInstanceCall1(int ra, int rd) { emitWord(_encodeAD(Opcode.kInstanceCall1, ra, rd)); } void emitInstanceCall2(int ra, int rd) { emitWord(_encodeAD(Opcode.kInstanceCall2, ra, rd)); } void emitInstanceCall1Opt(int ra, int rd) { emitWord(_encodeAD(Opcode.kInstanceCall1Opt, ra, rd)); } void emitInstanceCall2Opt(int ra, int rd) { emitWord(_encodeAD(Opcode.kInstanceCall2Opt, ra, rd)); } void emitPushPolymorphicInstanceCall(int ra, int rd) { emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCall, ra, rd)); } void emitPushPolymorphicInstanceCallByRange(int ra, int rd) { emitWord(_encodeAD(Opcode.kPushPolymorphicInstanceCallByRange, ra, rd)); } void emitNativeCall(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kNativeCall, ra, rb, rc)); } void emitOneByteStringFromCharCode(int ra, int rx) { emitWord(_encodeAX(Opcode.kOneByteStringFromCharCode, ra, rx)); } void emitStringToCharCode(int ra, int rx) { emitWord(_encodeAX(Opcode.kStringToCharCode, ra, rx)); } void emitAddTOS() { emitWord(_encode0(Opcode.kAddTOS)); } void emitSubTOS() { emitWord(_encode0(Opcode.kSubTOS)); } void emitMulTOS() { emitWord(_encode0(Opcode.kMulTOS)); } void emitBitOrTOS() { emitWord(_encode0(Opcode.kBitOrTOS)); } void emitBitAndTOS() { emitWord(_encode0(Opcode.kBitAndTOS)); } void emitEqualTOS() { emitWord(_encode0(Opcode.kEqualTOS)); } void emitLessThanTOS() { emitWord(_encode0(Opcode.kLessThanTOS)); } void emitGreaterThanTOS() { emitWord(_encode0(Opcode.kGreaterThanTOS)); } void emitSmiAddTOS() { emitWord(_encode0(Opcode.kSmiAddTOS)); } void emitSmiSubTOS() { emitWord(_encode0(Opcode.kSmiSubTOS)); } void emitSmiMulTOS() { emitWord(_encode0(Opcode.kSmiMulTOS)); } void emitSmiBitAndTOS() { emitWord(_encode0(Opcode.kSmiBitAndTOS)); } void emitAdd(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kAdd, ra, rb, rc)); } void emitSub(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kSub, ra, rb, rc)); } void emitMul(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kMul, ra, rb, rc)); } void emitDiv(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDiv, ra, rb, rc)); } void emitMod(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kMod, ra, rb, rc)); } void emitShl(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kShl, ra, rb, rc)); } void emitShr(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kShr, ra, rb, rc)); } void emitShlImm(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kShlImm, ra, rb, rc)); } void emitNeg(int ra, int rd) { emitWord(_encodeAD(Opcode.kNeg, ra, rd)); } void emitBitOr(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kBitOr, ra, rb, rc)); } void emitBitAnd(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kBitAnd, ra, rb, rc)); } void emitBitXor(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kBitXor, ra, rb, rc)); } void emitBitNot(int ra, int rd) { emitWord(_encodeAD(Opcode.kBitNot, ra, rd)); } void emitMin(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kMin, ra, rb, rc)); } void emitMax(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kMax, ra, rb, rc)); } void emitWriteIntoDouble(int ra, int rd) { emitWord(_encodeAD(Opcode.kWriteIntoDouble, ra, rd)); } void emitUnboxDouble(int ra, int rd) { emitWord(_encodeAD(Opcode.kUnboxDouble, ra, rd)); } void emitCheckedUnboxDouble(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckedUnboxDouble, ra, rd)); } void emitUnboxInt32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kUnboxInt32, ra, rb, rc)); } void emitBoxInt32(int ra, int rd) { emitWord(_encodeAD(Opcode.kBoxInt32, ra, rd)); } void emitBoxUint32(int ra, int rd) { emitWord(_encodeAD(Opcode.kBoxUint32, ra, rd)); } void emitSmiToDouble(int ra, int rd) { emitWord(_encodeAD(Opcode.kSmiToDouble, ra, rd)); } void emitDoubleToSmi(int ra, int rd) { emitWord(_encodeAD(Opcode.kDoubleToSmi, ra, rd)); } void emitDAdd(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDAdd, ra, rb, rc)); } void emitDSub(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDSub, ra, rb, rc)); } void emitDMul(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDMul, ra, rb, rc)); } void emitDDiv(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDDiv, ra, rb, rc)); } void emitDNeg(int ra, int rd) { emitWord(_encodeAD(Opcode.kDNeg, ra, rd)); } void emitDSqrt(int ra, int rd) { emitWord(_encodeAD(Opcode.kDSqrt, ra, rd)); } void emitDMin(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDMin, ra, rb, rc)); } void emitDMax(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDMax, ra, rb, rc)); } void emitDCos(int ra, int rd) { emitWord(_encodeAD(Opcode.kDCos, ra, rd)); } void emitDSin(int ra, int rd) { emitWord(_encodeAD(Opcode.kDSin, ra, rd)); } void emitDPow(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDPow, ra, rb, rc)); } void emitDMod(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kDMod, ra, rb, rc)); } void emitDTruncate(int ra, int rd) { emitWord(_encodeAD(Opcode.kDTruncate, ra, rd)); } void emitDFloor(int ra, int rd) { emitWord(_encodeAD(Opcode.kDFloor, ra, rd)); } void emitDCeil(int ra, int rd) { emitWord(_encodeAD(Opcode.kDCeil, ra, rd)); } void emitDoubleToFloat(int ra, int rd) { emitWord(_encodeAD(Opcode.kDoubleToFloat, ra, rd)); } void emitFloatToDouble(int ra, int rd) { emitWord(_encodeAD(Opcode.kFloatToDouble, ra, rd)); } void emitDoubleIsNaN(int ra) { emitWord(_encodeA(Opcode.kDoubleIsNaN, ra)); } void emitDoubleIsInfinite(int ra) { emitWord(_encodeA(Opcode.kDoubleIsInfinite, ra)); } void emitStoreStaticTOS(int rd) { emitWord(_encodeD(Opcode.kStoreStaticTOS, rd)); } void emitPushStatic(int rd) { emitWord(_encodeD(Opcode.kPushStatic, rd)); } void emitInitStaticTOS() { emitWord(_encode0(Opcode.kInitStaticTOS)); } void emitIfNeStrictTOS() { emitWord(_encode0(Opcode.kIfNeStrictTOS)); } void emitIfEqStrictTOS() { emitWord(_encode0(Opcode.kIfEqStrictTOS)); } void emitIfNeStrictNumTOS() { emitWord(_encode0(Opcode.kIfNeStrictNumTOS)); } void emitIfEqStrictNumTOS() { emitWord(_encode0(Opcode.kIfEqStrictNumTOS)); } void emitIfSmiLtTOS() { emitWord(_encode0(Opcode.kIfSmiLtTOS)); } void emitIfSmiLeTOS() { emitWord(_encode0(Opcode.kIfSmiLeTOS)); } void emitIfSmiGeTOS() { emitWord(_encode0(Opcode.kIfSmiGeTOS)); } void emitIfSmiGtTOS() { emitWord(_encode0(Opcode.kIfSmiGtTOS)); } void emitIfNeStrict(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfNeStrict, ra, rd)); } void emitIfEqStrict(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfEqStrict, ra, rd)); } void emitIfLe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfLe, ra, rd)); } void emitIfLt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfLt, ra, rd)); } void emitIfGe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfGe, ra, rd)); } void emitIfGt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfGt, ra, rd)); } void emitIfULe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfULe, ra, rd)); } void emitIfULt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfULt, ra, rd)); } void emitIfUGe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfUGe, ra, rd)); } void emitIfUGt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfUGt, ra, rd)); } void emitIfDNe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDNe, ra, rd)); } void emitIfDEq(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDEq, ra, rd)); } void emitIfDLe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDLe, ra, rd)); } void emitIfDLt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDLt, ra, rd)); } void emitIfDGe(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDGe, ra, rd)); } void emitIfDGt(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfDGt, ra, rd)); } void emitIfNeStrictNum(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfNeStrictNum, ra, rd)); } void emitIfEqStrictNum(int ra, int rd) { emitWord(_encodeAD(Opcode.kIfEqStrictNum, ra, rd)); } void emitIfEqNull(int ra) { emitWord(_encodeA(Opcode.kIfEqNull, ra)); } void emitIfNeNull(int ra) { emitWord(_encodeA(Opcode.kIfNeNull, ra)); } void emitCreateArrayTOS() { emitWord(_encode0(Opcode.kCreateArrayTOS)); } void emitCreateArrayOpt(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kCreateArrayOpt, ra, rb, rc)); } void emitAllocate(int rd) { emitWord(_encodeD(Opcode.kAllocate, rd)); } void emitAllocateT() { emitWord(_encode0(Opcode.kAllocateT)); } void emitAllocateOpt(int ra, int rd) { emitWord(_encodeAD(Opcode.kAllocateOpt, ra, rd)); } void emitAllocateTOpt(int ra, int rd) { emitWord(_encodeAD(Opcode.kAllocateTOpt, ra, rd)); } void emitStoreIndexedTOS() { emitWord(_encode0(Opcode.kStoreIndexedTOS)); } void emitStoreIndexed(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexed, ra, rb, rc)); } void emitStoreIndexedUint8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedUint8, ra, rb, rc)); } void emitStoreIndexedExternalUint8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedExternalUint8, ra, rb, rc)); } void emitStoreIndexedOneByteString(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedOneByteString, ra, rb, rc)); } void emitStoreIndexedUint32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedUint32, ra, rb, rc)); } void emitStoreIndexedFloat32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedFloat32, ra, rb, rc)); } void emitStoreIndexed4Float32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexed4Float32, ra, rb, rc)); } void emitStoreIndexedFloat64(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexedFloat64, ra, rb, rc)); } void emitStoreIndexed8Float64(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreIndexed8Float64, ra, rb, rc)); } void emitNoSuchMethod() { emitWord(_encode0(Opcode.kNoSuchMethod)); } void emitTailCall() { emitWord(_encode0(Opcode.kTailCall)); } void emitTailCallOpt(int ra, int rd) { emitWord(_encodeAD(Opcode.kTailCallOpt, ra, rd)); } void emitLoadArgDescriptor() { emitWord(_encode0(Opcode.kLoadArgDescriptor)); } void emitLoadArgDescriptorOpt(int ra) { emitWord(_encodeA(Opcode.kLoadArgDescriptorOpt, ra)); } void emitLoadFpRelativeSlot(int rx) { emitWord(_encodeX(Opcode.kLoadFpRelativeSlot, rx)); } void emitLoadFpRelativeSlotOpt(int ra, int rb, int ry) { emitWord(_encodeABY(Opcode.kLoadFpRelativeSlotOpt, ra, rb, ry)); } void emitStoreFpRelativeSlot(int rx) { emitWord(_encodeX(Opcode.kStoreFpRelativeSlot, rx)); } void emitStoreFpRelativeSlotOpt(int ra, int rb, int ry) { emitWord(_encodeABY(Opcode.kStoreFpRelativeSlotOpt, ra, rb, ry)); } void emitLoadIndexedTOS() { emitWord(_encode0(Opcode.kLoadIndexedTOS)); } void emitLoadIndexed(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexed, ra, rb, rc)); } void emitLoadIndexedUint8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedUint8, ra, rb, rc)); } void emitLoadIndexedInt8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedInt8, ra, rb, rc)); } void emitLoadIndexedInt32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedInt32, ra, rb, rc)); } void emitLoadIndexedUint32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedUint32, ra, rb, rc)); } void emitLoadIndexedExternalUint8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedExternalUint8, ra, rb, rc)); } void emitLoadIndexedExternalInt8(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedExternalInt8, ra, rb, rc)); } void emitLoadIndexedFloat32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedFloat32, ra, rb, rc)); } void emitLoadIndexed4Float32(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexed4Float32, ra, rb, rc)); } void emitLoadIndexedFloat64(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedFloat64, ra, rb, rc)); } void emitLoadIndexed8Float64(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexed8Float64, ra, rb, rc)); } void emitLoadIndexedOneByteString(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedOneByteString, ra, rb, rc)); } void emitLoadIndexedTwoByteString(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadIndexedTwoByteString, ra, rb, rc)); } void emitStoreField(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kStoreField, ra, rb, rc)); } void emitStoreFieldExt(int ra, int rd) { emitWord(_encodeAD(Opcode.kStoreFieldExt, ra, rd)); } void emitStoreFieldTOS(int rd) { emitWord(_encodeD(Opcode.kStoreFieldTOS, rd)); } void emitLoadField(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadField, ra, rb, rc)); } void emitLoadFieldExt(int ra, int rd) { emitWord(_encodeAD(Opcode.kLoadFieldExt, ra, rd)); } void emitLoadUntagged(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kLoadUntagged, ra, rb, rc)); } void emitLoadFieldTOS(int rd) { emitWord(_encodeD(Opcode.kLoadFieldTOS, rd)); } void emitBooleanNegateTOS() { emitWord(_encode0(Opcode.kBooleanNegateTOS)); } void emitBooleanNegate(int ra, int rd) { emitWord(_encodeAD(Opcode.kBooleanNegate, ra, rd)); } void emitThrow(int ra) { emitWord(_encodeA(Opcode.kThrow, ra)); } void emitEntry(int rd) { emitWord(_encodeD(Opcode.kEntry, rd)); } void emitEntryOptimized(int ra, int rd) { emitWord(_encodeAD(Opcode.kEntryOptimized, ra, rd)); } void emitFrame(int rd) { emitWord(_encodeD(Opcode.kFrame, rd)); } void emitSetFrame(int ra) { emitWord(_encodeA(Opcode.kSetFrame, ra)); } void emitAllocateContext(int rd) { emitWord(_encodeD(Opcode.kAllocateContext, rd)); } void emitAllocateUninitializedContext(int ra, int rd) { emitWord(_encodeAD(Opcode.kAllocateUninitializedContext, ra, rd)); } void emitCloneContext() { emitWord(_encode0(Opcode.kCloneContext)); } void emitMoveSpecial(int ra, SpecialIndex rd) { emitWord(_encodeAD(Opcode.kMoveSpecial, ra, rd.index)); } void emitInstantiateType(int rd) { emitWord(_encodeD(Opcode.kInstantiateType, rd)); } void emitInstantiateTypeArgumentsTOS(int ra, int rd) { emitWord(_encodeAD(Opcode.kInstantiateTypeArgumentsTOS, ra, rd)); } void emitInstanceOf() { emitWord(_encode0(Opcode.kInstanceOf)); } void emitBadTypeError() { emitWord(_encode0(Opcode.kBadTypeError)); } void emitAssertAssignable(int ra, int rd) { emitWord(_encodeAD(Opcode.kAssertAssignable, ra, rd)); } void emitAssertSubtype() { emitWord(_encode0(Opcode.kAssertSubtype)); } void emitAssertBoolean(int ra) { emitWord(_encodeA(Opcode.kAssertBoolean, ra)); } void emitTestSmi(int ra, int rd) { emitWord(_encodeAD(Opcode.kTestSmi, ra, rd)); } void emitTestCids(int ra, int rd) { emitWord(_encodeAD(Opcode.kTestCids, ra, rd)); } void emitCheckSmi(int ra) { emitWord(_encodeA(Opcode.kCheckSmi, ra)); } void emitCheckEitherNonSmi(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckEitherNonSmi, ra, rd)); } void emitCheckClassId(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckClassId, ra, rd)); } void emitCheckClassIdRange(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckClassIdRange, ra, rd)); } void emitCheckBitTest(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckBitTest, ra, rd)); } void emitCheckCids(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kCheckCids, ra, rb, rc)); } void emitCheckCidsByRange(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kCheckCidsByRange, ra, rb, rc)); } void emitCheckStack() { emitWord(_encode0(Opcode.kCheckStack)); } void emitCheckStackAlwaysExit() { emitWord(_encode0(Opcode.kCheckStackAlwaysExit)); } void emitCheckFunctionTypeArgs(int ra, int rd) { emitWord(_encodeAD(Opcode.kCheckFunctionTypeArgs, ra, rd)); } void emitDebugStep() { emitWord(_encode0(Opcode.kDebugStep)); } void emitDebugBreak(int ra) { emitWord(_encodeA(Opcode.kDebugBreak, ra)); } void emitDeopt(int ra, int rd) { emitWord(_encodeAD(Opcode.kDeopt, ra, rd)); } void emitDeoptRewind() { emitWord(_encode0(Opcode.kDeoptRewind)); } void emitEntryOptional(int ra, int rb, int rc) { emitWord(_encodeABC(Opcode.kEntryOptional, ra, rb, rc)); } }