/* * Copyright (C) 2018 Matus Zamborsky & The ontology Authors * This file is part of The ontology library. * * The ontology is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * The ontology is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with The ontology. If not, see . */ import * as AR from './func/arithmetic'; import * as A from './func/array'; import { opEqual, opInvert } from './func/bitwise'; import { opThrow, opThrowIfNot } from './func/exceptions'; import { opCall, opJmp, opNop, opRet } from './func/flowControl'; import { opHash } from './func/hash'; import { opPushData } from './func/pushData'; import { opCat, opLeft, opRight, opSize, opSubStr } from './func/splice'; import * as S from './func/stack'; import * as V from './func/validate'; import { ExecutionEngine } from './interfaces/engine'; import * as O from './opCode'; export interface OpExec { opCode: O.OpCode; name: string; exec?: (e: ExecutionEngine) => void; validator?: (e: ExecutionEngine) => void; } export const OpExecList: Map = new Map([ // control flow [O.PUSH0, { opCode: O.PUSH0, name: 'PUSH0', exec: opPushData }], [O.PUSHBYTES1, { opCode: O.PUSHBYTES1, name: 'PUSHBYTES1', exec: opPushData }], [O.PUSHBYTES75, { opCode: O.PUSHBYTES75, name: 'PUSHBYTES75', exec: opPushData }], [O.PUSHDATA1, { opCode: O.PUSHDATA1, name: 'PUSHDATA1', exec: opPushData }], [O.PUSHDATA2, { opCode: O.PUSHDATA2, name: 'PUSHDATA2', exec: opPushData }], [O.PUSHDATA4, { opCode: O.PUSHDATA4, name: 'PUSHDATA4', exec: opPushData, validator: V.validatorPushData4 }], [O.PUSHM1, { opCode: O.PUSHM1, name: 'PUSHM1', exec: opPushData }], [O.PUSH1, { opCode: O.PUSH1, name: 'PUSH1', exec: opPushData }], [O.PUSH2, { opCode: O.PUSH2, name: 'PUSH2', exec: opPushData }], [O.PUSH3, { opCode: O.PUSH3, name: 'PUSH3', exec: opPushData }], [O.PUSH4, { opCode: O.PUSH4, name: 'PUSH4', exec: opPushData }], [O.PUSH5, { opCode: O.PUSH5, name: 'PUSH5', exec: opPushData }], [O.PUSH6, { opCode: O.PUSH6, name: 'PUSH6', exec: opPushData }], [O.PUSH7, { opCode: O.PUSH7, name: 'PUSH7', exec: opPushData }], [O.PUSH8, { opCode: O.PUSH8, name: 'PUSH8', exec: opPushData }], [O.PUSH9, { opCode: O.PUSH9, name: 'PUSH9', exec: opPushData }], [O.PUSH10, { opCode: O.PUSH10, name: 'PUSH10', exec: opPushData }], [O.PUSH11, { opCode: O.PUSH11, name: 'PUSH11', exec: opPushData }], [O.PUSH12, { opCode: O.PUSH12, name: 'PUSH12', exec: opPushData }], [O.PUSH13, { opCode: O.PUSH13, name: 'PUSH13', exec: opPushData }], [O.PUSH14, { opCode: O.PUSH14, name: 'PUSH14', exec: opPushData }], [O.PUSH15, { opCode: O.PUSH15, name: 'PUSH15', exec: opPushData }], [O.PUSH16, { opCode: O.PUSH16, name: 'PUSH16', exec: opPushData }], // Control [O.NOP, { opCode: O.NOP, name: 'NOP', exec: opNop }], [O.JMP, { opCode: O.JMP, name: 'JMP', exec: opJmp }], [O.JMPIF, { opCode: O.JMPIF, name: 'JMPIF', exec: opJmp }], [O.JMPIFNOT, { opCode: O.JMPIFNOT, name: 'JMPIFNOT', exec: opJmp }], [O.CALL, { opCode: O.CALL, name: 'CALL', exec: opCall, validator: V.validateCall }], [O.RET, { opCode: O.RET, name: 'RET', exec: opRet }], [O.APPCALL, { opCode: O.APPCALL, name: 'APPCALL' }], // [O.TAILCALL, {opCode: O.TAILCALL, name: 'TAILCALL', exec: opAppCall}, [O.SYSCALL, { opCode: O.SYSCALL, name: 'SYSCALL' }], // Stack ops [ O.DUPFROMALTSTACK, { opCode: O.DUPFROMALTSTACK, name: 'DUPFROMALTSTACK', exec: S.opToDupFromAltStack, validator: V.validateAltStackCount1 } ], [O.TOALTSTACK, { opCode: O.TOALTSTACK, name: 'TOALTSTACK', exec: S.opToAltStack, validator: V.validateCount1 }], [ O.FROMALTSTACK, { opCode: O.FROMALTSTACK, name: 'FROMALTSTACK', exec: S.opFromAltStack, validator: V.validateAltStackCount1 } ], [O.XDROP, { opCode: O.XDROP, name: 'XDROP', exec: S.opXDrop, validator: V.validateXDrop }], [O.XSWAP, { opCode: O.XSWAP, name: 'XSWAP', exec: S.opXSwap, validator: V.validateXSwap }], [O.XTUCK, { opCode: O.XTUCK, name: 'XTUCK', exec: S.opXTuck, validator: V.validateXTuck }], [O.DEPTH, { opCode: O.DEPTH, name: 'DEPTH', exec: S.opDepth }], [O.DROP, { opCode: O.DROP, name: 'DROP', exec: S.opDrop, validator: V.validateCount1 }], [O.DUP, { opCode: O.DUP, name: 'DUP', exec: S.opDup, validator: V.validateCount1 }], [O.NIP, { opCode: O.NIP, name: 'NIP', exec: S.opNip, validator: V.validateCount2 }], [O.OVER, { opCode: O.OVER, name: 'OVER', exec: S.opOver, validator: V.validateCount2 }], [O.PICK, { opCode: O.PICK, name: 'PICK', exec: S.opPick, validator: V.validatePick }], [O.ROLL, { opCode: O.ROLL, name: 'ROLL', exec: S.opRoll, validator: V.validateRoll }], [O.ROT, { opCode: O.ROT, name: 'ROT', exec: S.opRot, validator: V.validateCount3 }], [O.SWAP, { opCode: O.SWAP, name: 'SWAP', exec: S.opSwap, validator: V.validateCount2 }], [O.TUCK, { opCode: O.TUCK, name: 'TUCK', exec: S.opTuck, validator: V.validateCount2 }], // Splice [O.CAT, { opCode: O.CAT, name: 'CAT', exec: opCat, validator: V.validateCat }], [O.SUBSTR, { opCode: O.SUBSTR, name: 'SUBSTR', exec: opSubStr, validator: V.validateSubStr }], [O.LEFT, { opCode: O.LEFT, name: 'LEFT', exec: opLeft, validator: V.validateLeft }], [O.RIGHT, { opCode: O.RIGHT, name: 'RIGHT', exec: opRight, validator: V.validateRight }], [O.SIZE, { opCode: O.SIZE, name: 'SIZE', exec: opSize, validator: V.validateCount1 }], // Bitwise logic [O.INVERT, { opCode: O.INVERT, name: 'INVERT', exec: opInvert, validator: V.validateCount1 }], [O.AND, { opCode: O.AND, name: 'AND', exec: AR.opBigIntZip, validator: V.validateCount2 }], [O.OR, { opCode: O.OR, name: 'OR', exec: AR.opBigIntZip, validator: V.validateCount2 }], [O.XOR, { opCode: O.XOR, name: 'XOR', exec: AR.opBigIntZip, validator: V.validateCount2 }], [O.EQUAL, { opCode: O.EQUAL, name: 'EQUAL', exec: opEqual, validator: V.validateCount2 }], // Arithmetic [O.INC, { opCode: O.INC, name: 'INC', exec: AR.opBigInt, validator: V.validateInc }], [O.DEC, { opCode: O.DEC, name: 'DEC', exec: AR.opBigInt, validator: V.validateDec }], [O.SIGN, { opCode: O.SIGN, name: 'SIGN', exec: AR.opSign, validator: V.validateSign }], [O.NEGATE, { opCode: O.NEGATE, name: 'NEGATE', exec: AR.opBigInt, validator: V.validateCount1 }], [O.ABS, { opCode: O.ABS, name: 'ABS', exec: AR.opBigInt, validator: V.validateCount1 }], [O.NOT, { opCode: O.NOT, name: 'NOT', exec: AR.opNot, validator: V.validateCount1 }], [O.NZ, { opCode: O.NZ, name: 'NZ', exec: AR.opNz, validator: V.validateCount1 }], [O.ADD, { opCode: O.ADD, name: 'ADD', exec: AR.opBigIntZip, validator: V.validateAdd }], [O.SUB, { opCode: O.SUB, name: 'SUB', exec: AR.opBigIntZip, validator: V.validateSub }], [O.MUL, { opCode: O.MUL, name: 'MUL', exec: AR.opBigIntZip, validator: V.validateMul }], [O.DIV, { opCode: O.DIV, name: 'DIV', exec: AR.opBigIntZip, validator: V.validateDiv }], [O.MOD, { opCode: O.MOD, name: 'MOD', exec: AR.opBigIntZip, validator: V.validateMod }], [O.SHL, { opCode: O.SHL, name: 'SHL', exec: AR.opBigIntZip, validator: V.validateShiftLeft }], [O.SHR, { opCode: O.SHR, name: 'SHR', exec: AR.opBigIntZip, validator: V.validateShift }], [O.BOOLAND, { opCode: O.BOOLAND, name: 'BOOLAND', exec: AR.opBoolZip, validator: V.validateCount2 }], [O.BOOLOR, { opCode: O.BOOLOR, name: 'BOOLOR', exec: AR.opBoolZip, validator: V.validateCount2 }], [O.NUMEQUAL, { opCode: O.NUMEQUAL, name: 'NUMEQUAL', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.NUMNOTEQUAL, { opCode: O.NUMNOTEQUAL, name: 'NUMNOTEQUAL', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.LT, { opCode: O.LT, name: 'LT', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.GT, { opCode: O.GT, name: 'GT', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.LTE, { opCode: O.LTE, name: 'LTE', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.GTE, { opCode: O.GTE, name: 'GTE', exec: AR.opBigIntComp, validator: V.validateCount2 }], [O.MIN, { opCode: O.MIN, name: 'MIN', exec: AR.opBigIntZip, validator: V.validateCount2 }], [O.MAX, { opCode: O.MAX, name: 'MAX', exec: AR.opBigIntZip, validator: V.validateCount2 }], [O.WITHIN, { opCode: O.WITHIN, name: 'WITHIN', exec: AR.opWithIn, validator: V.validateCount3 }], // Crypto [O.SHA1, { opCode: O.SHA1, name: 'SHA1', exec: opHash, validator: V.validateCount1 }], [O.SHA256, { opCode: O.SHA256, name: 'SHA256', exec: opHash, validator: V.validateCount1 }], [O.HASH160, { opCode: O.HASH160, name: 'HASH160', exec: opHash, validator: V.validateCount1 }], [O.HASH256, { opCode: O.HASH256, name: 'HASH256', exec: opHash, validator: V.validateCount1 }], [O.VERIFY, { opCode: O.VERIFY, name: 'VERIFY' }], // [O.CHECKSIG, {opCode: O.CHECKSIG, name: 'CHECKSIG', exec: opCheckSig, validator: validateCount2}, // tslint:disable-next-line:max-line-length // [O.CHECKMULTISIG, {opCode: O.CHECKMULTISIG, name: 'CHECKMULTISIG', exec: opCheckMultiSig, validator: validateCount2}, // Array [O.ARRAYSIZE, { opCode: O.ARRAYSIZE, name: 'ARRAYSIZE', exec: A.opArraySize, validator: V.validateCount1 }], [O.PACK, { opCode: O.PACK, name: 'PACK', exec: A.opPack, validator: V.validatePack }], [O.UNPACK, { opCode: O.UNPACK, name: 'UNPACK', exec: A.opUnpack, validator: V.validateUnpack }], [O.PICKITEM, { opCode: O.PICKITEM, name: 'PICKITEM', exec: A.opPickItem, validator: V.validatePickItem }], [O.SETITEM, { opCode: O.SETITEM, name: 'SETITEM', exec: A.opSetItem, validator: V.validatorSetItem }], [O.NEWARRAY, { opCode: O.NEWARRAY, name: 'NEWARRAY', exec: A.opNewArray, validator: V.validateNewArray }], [O.NEWMAP, { opCode: O.NEWMAP, name: 'NEWMAP', exec: A.opNewMap }], [O.NEWSTRUCT, { opCode: O.NEWSTRUCT, name: 'NEWSTRUCT', exec: A.opNewStruct, validator: V.validateNewStruct }], [O.APPEND, { opCode: O.APPEND, name: 'APPEND', exec: A.opAppend, validator: V.validateAppend }], [O.REVERSE, { opCode: O.REVERSE, name: 'REVERSE', exec: A.opReverse, validator: V.validatorReverse }], [O.REMOVE, { opCode: O.REMOVE, name: 'REMOVE', exec: A.opRemove, validator: V.validatorRemove }], [O.HASKEY, { opCode: O.HASKEY, name: 'HASKEY', exec: A.opHasKey, validator: V.validatorHasKey }], [O.KEYS, { opCode: O.KEYS, name: 'KEYS', exec: A.opKeys, validator: V.validatorKeys }], [O.VALUES, { opCode: O.VALUES, name: 'VALUES', exec: A.opValues, validator: V.validatorValues }], // Exceptions [O.THROW, { opCode: O.THROW, name: 'THROW', exec: opThrow }], [O.THROWIFNOT, { opCode: O.THROWIFNOT, name: 'THROWIFNOT', exec: opThrowIfNot, validator: V.validatorThrowIfNot }] ]);