neo-decompiler 0.11.0

Neo N3 NEF decompiler: parse, disassemble, lift bytecode to high-level pseudocode and C# skeletons, with a CLI, JSON reports, and optional WebAssembly bindings.
Documentation
import { stripOuterParens } from "./high-level-stack-shared.js";
import { warnStackUnderflow } from "./high-level-state.js";

export function tryControlStatement(state, instruction) {
  switch (instruction.opcode.mnemonic) {
    case "ASSERT": {
      if (!ensureStack(state, instruction, 1)) return true;
      const condition = stripOuterParens(state.stack.pop());
      state.statements.push(`assert(${condition});`);
      return true;
    }
    case "ASSERTMSG": {
      if (!ensureStack(state, instruction, 2)) return true;
      const message = stripOuterParens(state.stack.pop());
      const condition = stripOuterParens(state.stack.pop());
      state.statements.push(`assert(${condition}, ${message});`);
      return true;
    }
    case "THROW": {
      if (!ensureStack(state, instruction, 1)) {
        state.stack.length = 0;
        return true;
      }
      const value = stripOuterParens(state.stack.pop());
      state.statements.push(`throw(${value});`);
      state.stack.length = 0;
      return true;
    }
    case "ABORT":
      state.statements.push("abort();");
      state.stack.length = 0;
      return true;
    case "ABORTMSG": {
      if (!ensureStack(state, instruction, 1)) {
        state.stack.length = 0;
        return true;
      }
      const msg = stripOuterParens(state.stack.pop());
      state.statements.push(`abort(${msg});`);
      state.stack.length = 0;
      return true;
    }
    default:
      return false;
  }
}

function ensureStack(state, instruction, needed) {
  if (state.stack.length >= needed) return true;
  warnStackUnderflow(state, instruction, needed);
  return false;
}