UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

113 lines (111 loc) 5.34 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.TryStatementCompiler = void 0; const tslib_1 = require("tslib"); const ts_utils_1 = require("@neo-one/ts-utils"); const utils_1 = require("@neo-one/utils"); const typescript_1 = tslib_1.__importDefault(require("typescript")); const constants = tslib_1.__importStar(require("../../constants")); const NodeCompiler_1 = require("../NodeCompiler"); class TryStatementCompiler extends NodeCompiler_1.NodeCompiler { constructor() { super(...arguments); this.kind = typescript_1.default.SyntaxKind.TryStatement; } visitNode(sb, node, options) { const catchClause = ts_utils_1.tsUtils.statement.getCatchClause(node); const finallyBlock = ts_utils_1.tsUtils.statement.getFinallyBlock(node); const pushFinally = () => { if (finallyBlock !== undefined) { sb.emitPushInt(node, constants.FINALLY_COMPLETION); sb.emitPushInt(node, constants.FINALLY_COMPLETION); sb.emitPushInt(node, constants.FINALLY_COMPLETION); } }; sb.withProgramCounter((finallyPC) => { sb.withProgramCounter((catchPC) => { let pcOptions = catchClause === undefined ? sb.noCatchPCOptions(options) : sb.catchPCOptions(options, catchPC.getLast()); pcOptions = finallyBlock === undefined ? pcOptions : sb.finallyPCOptions(pcOptions, finallyPC.getLast()); sb.visit(ts_utils_1.tsUtils.statement.getTryBlock(node), pcOptions); pushFinally(); sb.emitJmp(node, 'JMP', finallyPC.getLast()); }); const finallyOptions = finallyBlock === undefined ? options : sb.finallyPCOptions(options, finallyPC.getLast()); if (catchClause !== undefined) { const variable = ts_utils_1.tsUtils.statement.getOnlyVariableDeclaration(catchClause); sb.emitOp(node, 'DROP'); if (variable === undefined) { sb.emitOp(node, 'DROP'); sb.visit(ts_utils_1.tsUtils.statement.getBlock(catchClause), finallyOptions); } else { sb.withScope(node, finallyOptions, (innerOptions) => { sb.visit(variable, sb.setValueOptions(innerOptions)); sb.visit(ts_utils_1.tsUtils.statement.getBlock(catchClause), innerOptions); }); } pushFinally(); } }); if (finallyBlock !== undefined) { const completion = sb.scope.addUnique(); const val = sb.scope.addUnique(); sb.emitOp(finallyBlock, 'DROP'); sb.scope.set(sb, finallyBlock, options, completion); sb.scope.set(sb, finallyBlock, options, val); sb.visit(finallyBlock, options); sb.scope.get(sb, finallyBlock, options, completion); const condition = (value) => () => { sb.emitOp(finallyBlock, 'DUP'); sb.emitPushInt(finallyBlock, value); sb.emitOp(finallyBlock, 'NUMEQUAL'); }; sb.emitHelper(finallyBlock, options, sb.helpers.case([ { condition: condition(constants.FINALLY_COMPLETION), whenTrue: () => { sb.emitOp(finallyBlock, 'DROP'); }, }, { condition: condition(constants.THROW_COMPLETION), whenTrue: () => { sb.emitOp(finallyBlock, 'DROP'); sb.scope.get(sb, finallyBlock, options, val); sb.emitHelper(finallyBlock, options, sb.helpers.throwCompletionBase); }, }, { condition: condition(constants.NORMAL_COMPLETION), whenTrue: () => { sb.emitOp(finallyBlock, 'DROP'); sb.scope.get(sb, finallyBlock, options, val); sb.emitHelper(finallyBlock, options, sb.helpers.return); }, }, options.breakPC === undefined ? undefined : { condition: condition(constants.BREAK_COMPLETION), whenTrue: () => { sb.emitOp(finallyBlock, 'DROP'); sb.emitHelper(finallyBlock, options, sb.helpers.break); }, }, options.continuePC === undefined ? undefined : { condition: condition(constants.CONTINUE_COMPLETION), whenTrue: () => { sb.emitOp(finallyBlock, 'DROP'); sb.emitHelper(finallyBlock, options, sb.helpers.continue); }, }, ].filter(utils_1.utils.notNull), () => { sb.emitOp(finallyBlock, 'DROP'); })); } } } exports.TryStatementCompiler = TryStatementCompiler; //# sourceMappingURL=TryStatementCompiler.js.map