squirrel icon indicating copy to clipboard operation
squirrel copied to clipboard

Squirrel opcode description ?

Open mingodad opened this issue 9 years ago • 3 comments

Hello ! Is it possible to have a description of squirrel opcodes ?

I'm trying to dump the compiled code to be manipulated by a script but I'm having some trouble to understand it by looking at the compiler/sqmv files.

Cheers !

For example in lua lopcodes.h, it's also a bit crypt but better than nothing:

typedef enum {
/*----------------------------------------------------------------------
name        args    description
------------------------------------------------------------------------*/
OP_MOVE,/*  A B R(A) := R(B)                    */
OP_LOADK,/* A Bx    R(A) := Kst(Bx)                 */
OP_LOADBOOL,/*  A B C   R(A) := (Bool)B; if (C) pc++            */
OP_LOADNIL,/*   A B R(A) := ... := R(B) := nil          */
OP_GETUPVAL,/*  A B R(A) := UpValue[B]              */

OP_GETGLOBAL,/* A Bx    R(A) := Gbl[Kst(Bx)]                */
OP_GETTABLE,/*  A B C   R(A) := R(B)[RK(C)]             */

OP_SETGLOBAL,/* A Bx    Gbl[Kst(Bx)] := R(A)                */
OP_SETUPVAL,/*  A B UpValue[B] := R(A)              */
OP_SETTABLE,/*  A B C   R(A)[RK(B)] := RK(C)                */

OP_NEWTABLE,/*  A B C   R(A) := {} (size = B,C)             */

OP_SELF,/*  A B C   R(A+1) := R(B); R(A) := R(B)[RK(C)]     */

OP_ADD,/*   A B C   R(A) := RK(B) + RK(C)               */
OP_SUB,/*   A B C   R(A) := RK(B) - RK(C)               */
OP_MUL,/*   A B C   R(A) := RK(B) * RK(C)               */
OP_DIV,/*   A B C   R(A) := RK(B) / RK(C)               */
OP_MOD,/*   A B C   R(A) := RK(B) % RK(C)               */
OP_POW,/*   A B C   R(A) := RK(B) ^ RK(C)               */
OP_UNM,/*   A B R(A) := -R(B)                   */
OP_NOT,/*   A B R(A) := not R(B)                */
OP_LEN,/*   A B R(A) := length of R(B)              */

OP_CONCAT,/*    A B C   R(A) := R(B).. ... ..R(C)           */

OP_JMP,/*   sBx pc+=sBx                 */

OP_EQ,/*    A B C   if ((RK(B) == RK(C)) ~= A) then pc++        */
OP_LT,/*    A B C   if ((RK(B) <  RK(C)) ~= A) then pc++        */
OP_LE,/*    A B C   if ((RK(B) <= RK(C)) ~= A) then pc++        */

OP_TEST,/*  A C if not (R(A) <=> C) then pc++           */ 
OP_TESTSET,/*   A B C   if (R(B) <=> C) then R(A) := R(B) else pc++ */ 

OP_CALL,/*  A B C   R(A), ... ,R(A+C-2) := R(A)(R(A+1), ... ,R(A+B-1)) */
OP_TAILCALL,/*  A B C   return R(A)(R(A+1), ... ,R(A+B-1))      */
OP_RETURN,/*    A B return R(A), ... ,R(A+B-2)  (see note)  */

OP_FORLOOP,/*   A sBx   R(A)+=R(A+2);
            if R(A) <?= R(A+1) then { pc+=sBx; R(A+3)=R(A) }*/
OP_FORPREP,/*   A sBx   R(A)-=R(A+2); pc+=sBx               */

OP_TFORLOOP,/*  A C R(A+3), ... ,R(A+2+C) := R(A)(R(A+1), R(A+2)); 
                        if R(A+3) ~= nil then R(A+2)=R(A+3) else pc++   */ 
OP_SETLIST,/*   A B C   R(A)[(C-1)*FPF+i] := R(A+i), 1 <= i <= B    */

OP_CLOSE,/* A   close all variables in the stack up to (>=) R(A)*/
OP_CLOSURE,/*   A Bx    R(A) := closure(KPROTO[Bx], R(A), ... ,R(A+n))  */

OP_VARARG/* A B R(A), R(A+1), ..., R(A+B-1) = vararg        */
} OpCode;


#define NUM_OPCODES (cast(int, OP_VARARG) + 1)



/*===========================================================================
  Notes:
  (*) In OP_CALL, if (B == 0) then B = top. C is the number of returns - 1,
      and can be 0: OP_CALL then sets `top' to last_result+1, so
      next open instruction (OP_CALL, OP_RETURN, OP_SETLIST) may use `top'.

  (*) In OP_VARARG, if (B == 0) then use actual number of varargs and
      set top (like in OP_CALL with C == 0).

  (*) In OP_RETURN, if (B == 0) then return up to `top'

  (*) In OP_SETLIST, if (B == 0) then B = `top';
      if (C == 0) then next `instruction' is real C

  (*) For comparisons, A specifies what condition the test should accept
      (true or false).

  (*) All `skips' (pc++) assume that next instruction is a jump
===========================================================================*/


/*
** masks for instruction properties. The format is:
** bits 0-1: op mode
** bits 2-3: C arg mode
** bits 4-5: B arg mode
** bit 6: instruction set register A
** bit 7: operator is a test
*/  

enum OpArgMask {
  OpArgN,  /* argument is not used */
  OpArgU,  /* argument is used */
  OpArgR,  /* argument is a register or a jump offset */
  OpArgK   /* argument is a constant or register/constant */
};

mingodad avatar Mar 11 '16 08:03 mingodad

I'll try to write something about it, asap.

albertodemichelis avatar Mar 28 '16 16:03 albertodemichelis

Did anything ever get written up for this? I'm trying to understand the opcode format as well and having some documentation would be helpful.

mattnewport avatar Sep 18 '24 23:09 mattnewport

I've tried to make sense of it by adding an extra option -s to my fork here https://github.com/mingodad/squilu:

squilu -h
usage: sq <options> <scriptpath [args]>.
Available options are:
   -s              compiles the file to bytecode(default output 'out.cnut')
   -o              specifies output file for the -c option
   -c              compiles only
   -d              generates debug infos
   -v              displays version infos
   -p              preload given script file
   -i              set the include_path
   -D              define a preprocesor named constant
   -h              prints help
SquiLu based on Squirrel 3.1 stable and Lua 5.1.5 Copyright (C) 2003-2017 Alberto Demichelis, Domingo Alvarez Duarte (64 bits)

Sample:

//squilu _fix-non-terminal.nut srcML-dad.g
if(vargv.len() < 2) {
	print("usage:", vargv[0], " grammar_file");
	os.exit(1);
}

auto cmd = "./parsertl-playground " + vargv[1] + " test.empty 2>&1";
print(cmd);

auto txt = popen(cmd, "r").read_all();
//print(txt);

txt = txt.gsub("Warning: Token \"[^\n]-\" is not used in the grammar.\n", "");
txt = txt.replace("Non-terminal '", "%token ");
txt = txt.replace("' does not have any productions.", "");

txt = txt.gsub("Warning: Token \"([^\n]-)\" does not have a lexer definiton%.", function(m) {
	if(m[0] == '\'') return format("\"%s\"\t%s", m.slice(1,-1), m);
	return format("%s\t%s", m, m);
	});
txt = txt.gsub("Unknown token \"([^\n]-)\"%.", "%%token %1");

auto lines = txt.split('\n');
lines.sort(@(a,b) a<=>b);

auto prevLine;
foreach(line in lines) {
	if(line == prevLine) continue;
	prevLine = line;
	print(line);
}

Output:

local bytecode = {
	source_name = "_fix-non-terminal.nut",
	function_name = "main",
	function_return_type = null,
	literals = [
		/*0*/ "len",
		/*1*/ "print",
		/*2*/ "usage:",
		/*3*/ " grammar_file",
		/*4*/ "os",
		/*5*/ "exit",
		/*6*/ "./parsertl-playground ",
		/*7*/ " test.empty 2>&1",
		/*8*/ "popen",
		/*9*/ "r",
		/*10*/ "read_all",
		/*11*/ "gsub",
		/*12*/ [==[Warning: Token "[^
]-" is not used in the grammar.
]==],
		/*13*/ null,
		/*14*/ "replace",
		/*15*/ "Non-terminal '",
		/*16*/ "%token ",
		/*17*/ "' does not have any productions.",
		/*18*/ [==[Warning: Token "([^
]-)" does not have a lexer definiton%.]==],
		/*19*/ [==[Unknown token "([^
]-)"%.]==],
		/*20*/ "%%token %1",
		/*21*/ "split",
		/*22*/ "sort",
	],
	parameters = [
		/*0*/ "this",
		/*1*/ "vargv",
	],
	outervalues = [
		//[type, src, name],
	],
	localvarinfos = [
		//[pos, name, start_op, end_op, scope, type, type_name, dtype_name],
		/*0*/ [0, "this", 0, 68, 1, 1, "ANY", ""],
		/*1*/ [1, "vargv", 0, 68, 1, 1, "ANY", ""],
		/*2*/ [2, "cmd", 20, 67, 0, 1, "ANY", "TK_LOCAL"],
		/*3*/ [3, "txt", 29, 67, 0, 1, "ANY", "TK_LOCAL"],
		/*4*/ [4, "lines", 53, 67, 0, 1, "ANY", "TK_LOCAL"],
		/*5*/ [5, "prevLine", 57, 67, 0, 1, "ANY", "TK_LOCAL"],
		/*6*/ [6, "@INDEX@", 57, 67, 1, 1, "ANY", ""],
		/*7*/ [7, "line", 58, 67, 1, 1, "ANY", ""],
		/*8*/ [8, "@ITERATOR@", 58, 67, 1, 1, "ANY", ""],
	],
	lineinfos = [
		//[op, line],
		/*0*/ [0, 2], /*_OP_PREPCALLK*/
		/*1*/ [4, 3], /*_OP_PREPCALLK*/
		/*2*/ [10, 4], /*_OP_GETK*/
		/*3*/ [14, 7], /*_OP_LOAD*/
		/*4*/ [20, 8], /*_OP_PREPCALLK*/
		/*5*/ [23, 10], /*_OP_PREPCALLK*/
		/*6*/ [29, 13], /*_OP_PREPCALLK*/
		/*7*/ [33, 14], /*_OP_PREPCALLK*/
		/*8*/ [37, 15], /*_OP_PREPCALLK*/
		/*9*/ [41, 17], /*_OP_PREPCALLK*/
		/*10*/ [46, 21], /*_OP_PREPCALLK*/
		/*11*/ [50, 23], /*_OP_PREPCALLK*/
		/*12*/ [53, 24], /*_OP_PREPCALLK*/
		/*13*/ [56, 26], /*_OP_LOADNULLS*/
		/*14*/ [57, 27], /*_OP_LOADNULLS*/
		/*15*/ [60, 28], /*_OP_EQ*/
		/*16*/ [63, 29], /*_OP_MOVE*/
		/*17*/ [64, 30], /*_OP_PREPCALLK*/
		/*18*/ [68, 33], /*_OP_RETURN*/
	],
	defaultparams = [],
	instructions = [ /*stack*/
		//[op_str, op, arg0, arg1, arg2, arg3],
		/*0*/ ["_OP_PREPCALLK", 8, 2, 0, 1, 3],	/* closure_at_stk[2], stk[1].get(literals[0]) -> stk[3] */
		/*1*/ ["_OP_CALL", 6, 2, 2, 3, 1],		/* target[2], lvi[2]("cmd"), stackbase(3), nargs(1) */
		/*2*/ ["_OP_LOADINT", 2, 3, 2, 0, 0],	/* stk[3] <- arg1(2) */
		/*3*/ ["_OP_JCMP", 29, 3, 10, 2, 3],		/* IsFalse(STK(2) CMP_L STK(3)) (ci->_ip+=(10) -> goto[14]) */
		/*4*/ ["_OP_PREPCALLK", 8, 2, 1, 0, 3],	/* closure_at_stk[2], stk[0].get(literals[1]) -> stk[3] */
		/*5*/ ["_OP_LOAD", 1, 4, 2, 0, 0],		/* stk[4] <- literals[2]("usage:") */
		/*6*/ ["_OP_LOADINT", 2, 5, 0, 0, 0],	/* stk[5] <- arg1(0) */
		/*7*/ ["_OP_GET", 14, 5, 1, 5, 0],	/* stk_at_arg0[5] = stk_at_arg1[1].get(stk_at_arg2(5)) */
		/*8*/ ["_OP_LOAD", 1, 6, 3, 0, 0],		/* stk[6] <- literals[3](" grammar_file") */
		/*9*/ ["_OP_CALL", 6, 255, 2, 3, 4],		/* target[255], lvi[2]("cmd"), stackbase(3), nargs(4) */
		/*10*/ ["_OP_GETK", 9, 2, 4, 0, 0],		/* stk[2] <- literals[4]("os") */
		/*11*/ ["_OP_PREPCALLK", 8, 2, 5, 2, 3],	/* closure_at_stk[2], stk[2].get(literals[5]) -> stk[3] */
		/*12*/ ["_OP_LOADINT", 2, 4, 1, 0, 0],	/* stk[4] <- arg1(1) */
		/*13*/ ["_OP_CALL", 6, 255, 2, 3, 2],		/* target[255], lvi[2]("cmd"), stackbase(3), nargs(2) */
		/*14*/ ["_OP_LOAD", 1, 2, 6, 0, 0],		/* stk[2] <- literals[6]("./parsertl-playground ") */
		/*15*/ ["_OP_LOADINT", 2, 3, 1, 0, 0],	/* stk[3] <- arg1(1) */
		/*16*/ ["_OP_GET", 14, 3, 1, 3, 0],	/* stk_at_arg0[3] = stk_at_arg1[1].get(stk_at_arg2(3)) */
		/*17*/ ["_OP_ADD", 17, 2, 3, 2, 0],		/* stk[2] = stk[2]("cmd") + stk[3]("txt") */
		/*18*/ ["_OP_LOAD", 1, 3, 7, 0, 0],		/* stk[3] <- literals[7](" test.empty 2>&1") */
		/*19*/ ["_OP_ADD", 17, 2, 3, 2, 0],		/* stk[2] = stk[2]("cmd") + stk[3]("txt") */
		/*20*/ ["_OP_PREPCALLK", 8, 3, 1, 0, 4],	/* closure_at_stk[3], stk[0].get(literals[1]) -> stk[4] */
		/*21*/ ["_OP_MOVE", 10, 5, 2, 0, 0],		/* stk[5] <- lvi[2]("cmd") */
		/*22*/ ["_OP_CALL", 6, 255, 3, 4, 2],		/* target[255], lvi[3]("txt"), stackbase(4), nargs(2) */
		/*23*/ ["_OP_PREPCALLK", 8, 3, 8, 0, 4],	/* closure_at_stk[3], stk[0].get(literals[8]) -> stk[4] */
		/*24*/ ["_OP_MOVE", 10, 5, 2, 0, 0],		/* stk[5] <- lvi[2]("cmd") */
		/*25*/ ["_OP_LOAD", 1, 6, 9, 0, 0],		/* stk[6] <- literals[9]("r") */
		/*26*/ ["_OP_CALL", 6, 3, 3, 4, 3],		/* target[3], lvi[3]("txt"), stackbase(4), nargs(3) */
		/*27*/ ["_OP_PREPCALLK", 8, 3, 10, 3, 4],	/* closure_at_stk[3], stk[3].get(literals[10]) -> stk[4] */
		/*28*/ ["_OP_CALL", 6, 3, 3, 4, 1],		/* target[3], lvi[3]("txt"), stackbase(4), nargs(1) */
		/*29*/ ["_OP_PREPCALLK", 8, 4, 11, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[11]) -> stk[5] */
		/*30*/ ["_OP_DLOAD", 4, 6, 12, 7, 13],		/* stk[6] <- literals[12]("Warning: Token "[^
]-" is not used in the grammar.
") */ /* stk[7] <- literals[13] null */
		/*31*/ ["_OP_CALL", 6, 4, 4, 5, 3],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(3) */
		/*32*/ ["_OP_MOVE", 10, 3, 4, 0, 0],		/* stk[3] <- lvi[4]("lines") */
		/*33*/ ["_OP_PREPCALLK", 8, 4, 14, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[14]) -> stk[5] */
		/*34*/ ["_OP_DLOAD", 4, 6, 15, 7, 16],		/* stk[6] <- literals[15]("Non-terminal '") */ /* stk[7] <- literals[16] "%token " */
		/*35*/ ["_OP_CALL", 6, 4, 4, 5, 3],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(3) */
		/*36*/ ["_OP_MOVE", 10, 3, 4, 0, 0],		/* stk[3] <- lvi[4]("lines") */
		/*37*/ ["_OP_PREPCALLK", 8, 4, 14, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[14]) -> stk[5] */
		/*38*/ ["_OP_DLOAD", 4, 6, 17, 7, 13],		/* stk[6] <- literals[17]("' does not have any productions.") */ /* stk[7] <- literals[13] null */
		/*39*/ ["_OP_CALL", 6, 4, 4, 5, 3],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(3) */
		/*40*/ ["_OP_MOVE", 10, 3, 4, 0, 0],		/* stk[3] <- lvi[4]("lines") */
		/*41*/ ["_OP_PREPCALLK", 8, 4, 11, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[11]) -> stk[5] */
		/*42*/ ["_OP_LOAD", 1, 6, 18, 0, 0],		/* stk[6] <- literals[18]("Warning: Token "([^
]-)" does not have a lexer definiton%.") */
		/*43*/ ["_OP_CLOSURE", 48, 7, 0, 0, 0],	/* stk_at_arg0[7] <- functions[0](null), isLanbda(0) */
		/*44*/ ["_OP_CALL", 6, 4, 4, 5, 3],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(3) */
		/*45*/ ["_OP_MOVE", 10, 3, 4, 0, 0],		/* stk[3] <- lvi[4]("lines") */
		/*46*/ ["_OP_PREPCALLK", 8, 4, 11, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[11]) -> stk[5] */
		/*47*/ ["_OP_DLOAD", 4, 6, 19, 7, 20],		/* stk[6] <- literals[19]("Unknown token "([^
]-)"%.") */ /* stk[7] <- literals[20] "%%token %1" */
		/*48*/ ["_OP_CALL", 6, 4, 4, 5, 3],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(3) */
		/*49*/ ["_OP_MOVE", 10, 3, 4, 0, 0],		/* stk[3] <- lvi[4]("lines") */
		/*50*/ ["_OP_PREPCALLK", 8, 4, 21, 3, 5],	/* closure_at_stk[4], stk[3].get(literals[21]) -> stk[5] */
		/*51*/ ["_OP_LOADINT", 2, 6, 10, 0, 0],	/* stk[6] <- arg1(10) */
		/*52*/ ["_OP_CALL", 6, 4, 4, 5, 2],		/* target[4], lvi[4]("lines"), stackbase(5), nargs(2) */
		/*53*/ ["_OP_PREPCALLK", 8, 5, 22, 4, 6],	/* closure_at_stk[5], stk[4].get(literals[22]) -> stk[6] */
		/*54*/ ["_OP_CLOSURE", 48, 7, 1, 1, 0],	/* stk_at_arg0[7] <- functions[1](null), isLanbda(1) */
		/*55*/ ["_OP_CALL", 6, 255, 5, 6, 2],		/* target[255], lvi[5]("prevLine"), stackbase(6), nargs(2) */
		/*56*/ ["_OP_LOADNULLS", 24, 5, 1, 0, 0],	/* stk_at_arg0[5.. (arg0 + arg1(1))] = null */
		/*57*/ ["_OP_LOADNULLS", 24, 6, 3, 0, 0],	/* stk_at_arg0[6.. (arg0 + arg1(3))] = null */
		/*58*/ ["_OP_FOREACH", 51, 4, 9, 6, 0],
		/*59*/ ["_OP_POSTFOREACH", 52, 4, 9, 6, 0],
		/*60*/ ["_OP_EQ", 15, 9, 5, 7, 0],		/* stk_at_arg0[9] = stk_at_arg2[7] == (arg3(0) !=0 ? literals_at_arg1[5] : stk_at_arg1[5]) */
		/*61*/ ["_OP_JZ", 30, 9, 1, 0, 0],		/* IsFalse(STK(9) (ci->_ip+=(1) -> goto[63]) */
		/*62*/ ["_OP_JMP", 28, 0, -5, 0, 0],		/* (ci->_ip+=(-5)) -> goto[58] */
		/*63*/ ["_OP_MOVE", 10, 5, 7, 0, 0],		/* stk[5] <- lvi[7]("line") */
		/*64*/ ["_OP_PREPCALLK", 8, 9, 1, 0, 10],	/* closure_at_stk[9], stk[0].get(literals[1]) -> stk[10] */
		/*65*/ ["_OP_MOVE", 10, 11, 7, 0, 0],		/* stk[11] <- lvi[7]("line") */
		/*66*/ ["_OP_CALL", 6, 255, 9, 10, 2],		/* target[255], lvi[9]("?"), stackbase(10), nargs(2) */
		/*67*/ ["_OP_JMP", 28, 0, -10, 0, 0],		/* (ci->_ip+=(-10)) -> goto[58] */
		/*68*/ ["_OP_RETURN", 23, 255, 0, 0, 0],	/* _arg0(255) != 255 ? stk[0] : null */
	],
	functions = [
/*function 0*/{
	source_name = "_fix-non-terminal.nut",
	function_name = null,
	function_return_type = null,
	literals = [
		/*0*/ "format",
		/*1*/ [==["%s"	%s]==],
		/*2*/ "slice",
		/*3*/ -1,
		/*4*/ "%s	%s",
	],
	parameters = [
		/*0*/ "this",
		/*1*/ "m",
	],
	outervalues = [
		//[type, src, name],
	],
	localvarinfos = [
		//[pos, name, start_op, end_op, scope, type, type_name, dtype_name],
		/*0*/ [0, "this", 0, 19, 1, 1, "ANY", ""],
		/*1*/ [1, "m", 0, 19, 1, 1, "ANY", ""],
	],
	lineinfos = [
		//[op, line],
		/*0*/ [0, 17], /*_OP_LOADINT*/
		/*1*/ [0, 18], /*_OP_LOADINT*/
		/*2*/ [14, 19], /*_OP_PREPCALLK*/
		/*3*/ [19, 20], /*_OP_RETURN*/
	],
	defaultparams = [],
	instructions = [ /*stack*/
		//[op_str, op, arg0, arg1, arg2, arg3],
		/*0*/ ["_OP_LOADINT", 2, 2, 0, 0, 0],	/* stk[2] <- arg1(0) */
		/*1*/ ["_OP_GET", 14, 2, 1, 2, 0],	/* stk_at_arg0[2] = stk_at_arg1[1].get(stk_at_arg2(2)) */
		/*2*/ ["_OP_LOADINT", 2, 3, 39, 0, 0],	/* stk[3] <- arg1(39) */
		/*3*/ ["_OP_EQ", 15, 2, 3, 2, 0],		/* stk_at_arg0[2] = stk_at_arg2[2] == (arg3(0) !=0 ? literals_at_arg1[3] : stk_at_arg1[3]) */
		/*4*/ ["_OP_JZ", 30, 2, 9, 0, 0],		/* IsFalse(STK(2) (ci->_ip+=(9) -> goto[14]) */
		/*5*/ ["_OP_PREPCALLK", 8, 2, 0, 0, 3],	/* closure_at_stk[2], stk[0].get(literals[0]) -> stk[3] */
		/*6*/ ["_OP_DLOAD", 4, 4, 1, 5, 2],		/* stk[4] <- literals[1](""%s"	%s") */ /* stk[5] <- literals[2] "slice" */
		/*7*/ ["_OP_PREPCALL", 7, 5, 5, 1, 6],	/* closure_at_stk[5], stk[1].get(stk[5]) -> stk[6] */
		/*8*/ ["_OP_LOADINT", 2, 7, 1, 0, 0],	/* stk[7] <- arg1(1) */
		/*9*/ ["_OP_LOAD", 1, 8, 3, 0, 0],		/* stk[8] <- literals[3]("?") */
		/*10*/ ["_OP_CALL", 6, 5, 5, 6, 3],		/* target[5], lvi[5]("?"), stackbase(6), nargs(3) */
		/*11*/ ["_OP_MOVE", 10, 6, 1, 0, 0],		/* stk[6] <- lvi[1]("m") */
		/*12*/ ["_OP_TAILCALL", 5, 2, 2, 3, 4],
		/*13*/ ["_OP_RETURN", 23, 1, 2, 3, 0],	/* _arg0(1) != 255 ? stk[2] : null */
		/*14*/ ["_OP_PREPCALLK", 8, 2, 0, 0, 3],	/* closure_at_stk[2], stk[0].get(literals[0]) -> stk[3] */
		/*15*/ ["_OP_LOAD", 1, 4, 4, 0, 0],		/* stk[4] <- literals[4]("%s	%s") */
		/*16*/ ["_OP_DMOVE", 27, 5, 1, 6, 1],	/* stk[5] <- lvi[1]("m"), stk[6] <- lvi[1]("m") */
		/*17*/ ["_OP_TAILCALL", 5, 2, 2, 3, 4],
		/*18*/ ["_OP_RETURN", 23, 1, 2, 3, 0],	/* _arg0(1) != 255 ? stk[2] : null */
		/*19*/ ["_OP_RETURN", 23, 255, 0, 0, 0],	/* _arg0(255) != 255 ? stk[0] : null */
	],
	functions = [
	],
	stacksize = 9,
	bgenerator = 0,
	varparams = 0,
},
/*function 1*/{
	source_name = "_fix-non-terminal.nut",
	function_name = null,
	function_return_type = null,
	literals = [
	],
	parameters = [
		/*0*/ "this",
		/*1*/ "a",
		/*2*/ "b",
	],
	outervalues = [
		//[type, src, name],
	],
	localvarinfos = [
		//[pos, name, start_op, end_op, scope, type, type_name, dtype_name],
		/*0*/ [0, "this", 0, 2, 1, 1, "ANY", ""],
		/*1*/ [1, "a", 0, 2, 1, 1, "ANY", ""],
		/*2*/ [2, "b", 0, 2, 1, 1, "ANY", ""],
	],
	lineinfos = [
		//[op, line],
		/*0*/ [2, 24], /*_OP_RETURN*/
	],
	defaultparams = [],
	instructions = [ /*stack*/
		//[op_str, op, arg0, arg1, arg2, arg3],
		/*0*/ ["_OP_CMP", 40, 3, 2, 1, 5],
		/*1*/ ["_OP_RETURN", 23, 1, 3, 0, 0],	/* _arg0(1) != 255 ? stk[3] : null */
		/*2*/ ["_OP_RETURN", 23, 255, 0, 0, 0],	/* _arg0(255) != 255 ? stk[0] : null */
	],
	functions = [
	],
	stacksize = 4,
	bgenerator = 0,
	varparams = 0,
},
	],
	stacksize = 12,
	bgenerator = 0,
	varparams = 1,
}

mingodad avatar Sep 19 '24 07:09 mingodad