From 4c8d56c51115f3f3eefbae6cff38cfd86f46df15 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 24 Nov 2018 20:08:42 +0700 Subject: [PATCH 01/21] __emit: Issue an error if the stack offset/data address is not a multiple of cell size --- source/compiler/sc1.c | 20 ++++++++++++++------ source/compiler/sc5.c | 2 +- 2 files changed, 15 insertions(+), 7 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index c40eefe..365d486 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6221,7 +6221,6 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) tok=lex(&val,&str); switch (tok) { case tNUMBER: - p->value.ucell=(ucell)val; break; case tSYMBOL: sym=findloc(str); @@ -6239,7 +6238,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) sym=findglb(str,sSTATIC); if (sym==NULL) { error(17,str); /* undefined symbol */ - break; + return; } /* if */ markusage(sym,uREAD | uWRITTEN); if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { @@ -6247,12 +6246,17 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) goto invalid_token; } /* if */ } /* if */ - p->value.ucell=(ucell)sym->addr; + val=sym->addr; break; default: invalid_token: emit_invalid_token(teDATA,tok); + return; } /* switch */ + if ((val % sizeof(cell))==0) + p->value.ucell=(ucell)val; + else + error(11); /* must be a multiple of cell size */ } static void SC_FASTCALL emit_param_local(emit_outval *p) @@ -6266,7 +6270,6 @@ static void SC_FASTCALL emit_param_local(emit_outval *p) tok=lex(&val,&str); switch (tok) { case tNUMBER: - p->value.ucell=(ucell)val; break; case tSYMBOL: sym=findloc(str); @@ -6285,18 +6288,23 @@ static void SC_FASTCALL emit_param_local(emit_outval *p) if (sym==NULL) { undefined_sym: error(17,str); /* undefined symbol */ - break; + return; } /* if */ markusage(sym,uREAD | uWRITTEN); if (sym->ident!=iCONSTEXPR) goto undefined_sym; } /* if */ - p->value.ucell=(ucell)sym->addr; + val=sym->addr; break; default: invalid_token: emit_invalid_token(tSYMBOL,tok); + return; } /* switch */ + if ((val % sizeof(cell))==0) + p->value.ucell = (ucell)val; + else + error(11); /* must be a multiple of cell size */ } static void SC_FASTCALL emit_param_label(emit_outval *p) diff --git a/source/compiler/sc5.c b/source/compiler/sc5.c index 47772a2..4ba4555 100644 --- a/source/compiler/sc5.c +++ b/source/compiler/sc5.c @@ -50,7 +50,7 @@ static char *errmsg[] = { /*008*/ "must be a constant expression; assumed zero\n", /*009*/ "invalid array size (negative, zero or out of bounds)\n", /*010*/ "invalid function or declaration\n", -/*011*/ "invalid outside functions\n", +/*011*/ "stack offset/data address must be a multiple of cell size\n", /*012*/ "invalid function call, not a valid address\n", /*013*/ "no entry point (no public functions)\n", /*014*/ "invalid statement; not in switch\n", From 00e3e00327352006b0b3b493680924d8181f18db Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 24 Nov 2018 23:19:55 +0700 Subject: [PATCH 02/21] __emit: Don't accept numeric constants for arguments of type 'data offset' --- source/compiler/sc1.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 365d486..64db1c0 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6220,8 +6220,6 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) p->type=eotNUMBER; tok=lex(&val,&str); switch (tok) { - case tNUMBER: - break; case tSYMBOL: sym=findloc(str); if (sym!=NULL) { @@ -6230,8 +6228,8 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) tok=tLABEL; goto invalid_token; } /* if */ - if (sym->vclass!=sSTATIC && sym->ident!=iCONSTEXPR) { - tok=teLOCAL; + if (sym->vclass!=sSTATIC) { + tok=(sym->ident==iCONSTEXPR) ? teNUMERIC : teLOCAL; goto invalid_token; } /* if */ } else { @@ -6245,6 +6243,10 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; goto invalid_token; } /* if */ + if (sym->ident==iCONSTEXPR) { + tok=teNUMERIC; + goto invalid_token; + } /* if */ } /* if */ val=sym->addr; break; From e93817be091fc5af663770ab92526fbda957f0c7 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 24 Nov 2018 23:35:40 +0700 Subject: [PATCH 03/21] __emit: Display proper argument type names in error messages for arguments of type 'local variable' --- source/compiler/sc1.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 64db1c0..3b4f6c8 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6288,23 +6288,27 @@ static void SC_FASTCALL emit_param_local(emit_outval *p) } else { sym=findglb(str,sSTATEVAR); if (sym==NULL) { - undefined_sym: error(17,str); /* undefined symbol */ return; } /* if */ markusage(sym,uREAD | uWRITTEN); - if (sym->ident!=iCONSTEXPR) - goto undefined_sym; + if (sym->ident!=iCONSTEXPR) { + if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) + tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; + else + tok=teDATA; + goto invalid_token; + } /* if */ } /* if */ val=sym->addr; break; default: invalid_token: - emit_invalid_token(tSYMBOL,tok); + emit_invalid_token(teLOCAL,tok); return; } /* switch */ if ((val % sizeof(cell))==0) - p->value.ucell = (ucell)val; + p->value.ucell=(ucell)val; else error(11); /* must be a multiple of cell size */ } From 4c798112bd4884d4f777f36cc9ad5990eede2957 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sun, 25 Nov 2018 01:25:05 +0700 Subject: [PATCH 04/21] __emit: Don't mark functions as uWRITTEN --- source/compiler/sc1.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 3b4f6c8..7e6b920 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6238,7 +6238,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) error(17,str); /* undefined symbol */ return; } /* if */ - markusage(sym,uREAD | uWRITTEN); + markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; goto invalid_token; @@ -6291,7 +6291,7 @@ static void SC_FASTCALL emit_param_local(emit_outval *p) error(17,str); /* undefined symbol */ return; } /* if */ - markusage(sym,uREAD | uWRITTEN); + markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); if (sym->ident!=iCONSTEXPR) { if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; From f6c9db92697efcb8bafca1812d700fb60d1c8f12 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sun, 25 Nov 2018 03:48:45 +0700 Subject: [PATCH 05/21] __emit: Properly display error messages on type mismatch for arguments of type 'label' --- source/compiler/sc1.c | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 7e6b920..0421db4 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6330,13 +6330,29 @@ static void SC_FASTCALL emit_param_label(emit_outval *p) goto invalid_token; /* fallthrough */ case tSYMBOL: - sym=fetchlab(str); + sym=findloc(str); + if (sym==NULL) + sym=findglb(str,sSTATEVAR); + if (sym!=NULL) { + markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); + if (sym->ident!=iLABEL) { + if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) + tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; + else if (sym->ident==iCONSTEXPR) + tok=teNUMERIC; + else + tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA; + goto invalid_token; + } /* if */ + } else { + sym=fetchlab(str); + } /* if */ sym->usage|=uREAD; p->value.ucell=(ucell)sym->addr; break; default: invalid_token: - emit_invalid_token(tSYMBOL,tok); + emit_invalid_token(tLABEL,tok); } } From 1ad14487a3d956b4494defa2b60b75da5e0521e5 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sun, 25 Nov 2018 19:11:43 +0700 Subject: [PATCH 06/21] __emit: Take in account local symbols for arguments of type 'function' --- source/compiler/sc1.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 0421db4..4d92d2a 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6368,18 +6368,26 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) switch (tok) { case tSYMBOL: - sym=findglb(str,sSTATEVAR); + sym=findloc(str); + if (sym==NULL) + sym=findglb(str,sSTATEVAR); if (sym==NULL) { error(17,str); /* undefined symbol */ return; } /* if */ - markusage(sym,uREAD); if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { + markusage(sym,uREAD); if (!!(sym->usage & uNATIVE)==isnative) break; tok=(isnative!=FALSE) ? teFUNCTN : teNATIVE; } else { - tok=(sym->ident==iCONSTEXPR) ? teNUMERIC : teDATA; + markusage(sym,uREAD | uWRITTEN); + if (sym->ident==iLABEL) + tok=tLABEL; + else if (sym->ident==iCONSTEXPR) + tok=teNUMERIC; + else + tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA; } /* if */ /* fallthrough */ default: From 9fb9bbb3e2700f55cc14c7b7d8dd45b263cf99ca Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sun, 25 Nov 2018 19:24:29 +0700 Subject: [PATCH 07/21] __emit: Allow expressions for arguments of type 'shift' --- source/compiler/sc1.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 4d92d2a..1f9a9e0 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6441,10 +6441,11 @@ static void SC_FASTCALL emit_parm1_nonneg(char *name) static void SC_FASTCALL emit_parm1_shift(char *name) { - static const cell valid_values[] = { 0,sizeof(cell)*8-1 }; emit_outval p[1]; - emit_param_index(&p[0],TRUE,valid_values,(sizeof valid_values / sizeof valid_values[0])); + if (emit_param_any_internal(&p[0],tNUMBER,FALSE,TRUE)) + if (p->value.ucell>=(sizeof(cell)*8)) + error(50); /* invalid range */ outinstr(name,p,(sizeof p / sizeof p[0])); } From 69a573ad9046547da3e5f400b18219d58cdf821b Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sun, 25 Nov 2018 23:27:45 +0700 Subject: [PATCH 08/21] __emit: Remove index check for opcodes 'lctrl' and 'sctrl' --- source/compiler/sc1.c | 22 ++-------------------- 1 file changed, 2 insertions(+), 20 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 1f9a9e0..c7fe923 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6512,24 +6512,6 @@ static void SC_FASTCALL emit_do_align(char *name) outinstr(name,p,(sizeof p / sizeof p[0])); } -static void SC_FASTCALL emit_do_lctrl(char *name) -{ - static const cell valid_values[] = { 0,9 }; - emit_outval p[1]; - - emit_param_index(&p[0],TRUE,valid_values,(sizeof valid_values / sizeof valid_values[0])); - outinstr(name,p,(sizeof p / sizeof p[0])); -} - -static void SC_FASTCALL emit_do_sctrl(char *name) -{ - static const cell valid_values[] = { 2,4,5,6,8,9 }; - emit_outval p[1]; - - emit_param_index(&p[0],FALSE,valid_values,(sizeof valid_values / sizeof valid_values[0])); - outinstr(name,p,(sizeof p / sizeof p[0])); -} - static void SC_FASTCALL emit_do_call(char *name) { emit_outval p[1]; @@ -6791,7 +6773,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { 51, "jump", emit_parm1_label }, {128, "jump.pri", emit_parm0 }, { 53, "jzer", emit_parm1_label }, - { 31, "lctrl", emit_do_lctrl }, + { 31, "lctrl", emit_parm1_integer }, { 98, "leq", emit_parm0 }, { 97, "less", emit_parm0 }, { 25, "lidx", emit_parm0 }, @@ -6844,7 +6826,7 @@ static EMIT_OPCODE emit_opcodelist[] = { {152, "push5.s", emit_do_pushn_s_adr }, { 47, "ret", emit_parm0 }, { 48, "retn", emit_parm0 }, - { 32, "sctrl", emit_do_sctrl }, + { 32, "sctrl", emit_parm1_integer }, { 73, "sdiv", emit_parm0 }, { 74, "sdiv.alt", emit_parm0 }, {104, "sgeq", emit_parm0 }, From 3c1ac1e91166aae6f14871d1202712a0a6f245bb Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Mon, 26 Nov 2018 14:47:03 +0700 Subject: [PATCH 09/21] __emit: Fix crash on attempt to reference a native --- source/compiler/sc1.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index c7fe923..5c78a8d 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6088,6 +6088,7 @@ fetchtok: p->type=eotLABEL; p->value.ucell=(ucell)sym->addr; } else if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { + const int ntvref=sym->usage & uREAD; markusage(sym,uREAD); if (negate) goto invalid_token_neg; @@ -6095,7 +6096,7 @@ fetchtok: tok=(sym->usage & uNATIVE) ? teNATIVE : teFUNCTN; goto invalid_token; } /* if */ - if ((sym->usage & uNATIVE)!=0 && (sym->usage & uREAD)==0 && sym->addr>=0) + if ((sym->usage & uNATIVE)!=0 && ntvref==0 && sym->addr>=0) sym->addr=ntv_funcid++; p->type=eotFUNCTION; p->value.string=str; @@ -6361,7 +6362,7 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) cell val; char *str; symbol *sym; - int tok; + int tok,ntvref; p->type=eotNUMBER; tok=lex(&val,&str); @@ -6376,6 +6377,7 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) return; } /* if */ if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { + ntvref=sym->usage & uREAD; markusage(sym,uREAD); if (!!(sym->usage & uNATIVE)==isnative) break; @@ -6396,7 +6398,7 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) } /* switch */ if (isnative!=FALSE) { - if ((sym->usage & uREAD)==0 && sym->addr>=0) + if (ntvref==0 && sym->addr>=0) sym->addr=ntv_funcid++; p->value.ucell=(ucell)sym->addr; } else { From 32528e701af19a6c834720f3bddf4196b983e7b3 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Thu, 27 Dec 2018 22:36:47 +0700 Subject: [PATCH 10/21] __emit: Code cleanup --- source/compiler/sc.h | 6 +- source/compiler/sc1.c | 326 +++++++++++++++++++++--------------------- 2 files changed, 167 insertions(+), 165 deletions(-) diff --git a/source/compiler/sc.h b/source/compiler/sc.h index a418350..b99cf27 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -920,9 +920,9 @@ SC_VDECL FILE *outf; /* file written to */ SC_VDECL jmp_buf errbuf; /* target of longjmp() on a fatal error */ /* Possible entries for "emit_flags" - * Bits: 0 (epmBLOCK) multiline ('{}' block) syntax - * 1 (epmEXPR) used within an expression - * 2 (epmGLOBAL) used outside of a function + * Bits: 0 (efBLOCK) multiline ('()' block) syntax + * 1 (efEXPR) used within an expression + * 2 (efGLOBAL) used outside of a function */ #define efBLOCK 1 #define efEXPR 2 diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 5c78a8d..cbd81b4 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -141,7 +141,6 @@ static int *readwhile(void); typedef void (SC_FASTCALL *OPCODE_PROC)(char *name); typedef struct { - cell opcode; char *name; OPCODE_PROC func; } EMIT_OPCODE; @@ -6036,8 +6035,8 @@ static symbol *fetchlab(char *name) static void SC_FASTCALL emit_invalid_token(int expected_token,int found_token) { - char s[2]; extern char *sc_tokens[]; + char s[2]; assert(expected_token>=tFIRST); if (found_tokenvalue.ucell); #elif PAWN_CELL_SIZE==32 char ival[12]; - sprintf(ival,"%ld",(long)p->value.ucell); #elif PAWN_CELL_SIZE==64 char ival[21]; - sprintf(ival,"%lld",(long long)p->value.ucell); #else #error Unsupported cell size #endif + sprintf(ival,"%"PRIdC,(cell)p->value.ucell); error(1,sc_tokens[teNONNEG-tFIRST],ival); } /* if */ } +static void SC_FASTCALL emit_param_shift(emit_outval *p) +{ + if (emit_param_any_internal(p,tNUMBER,FALSE,TRUE)) + if (p->value.ucell>=(sizeof(cell)*8)) + error(50); /* invalid range */ +} + static void SC_FASTCALL emit_param_data(emit_outval *p) { cell val; @@ -6445,9 +6449,7 @@ static void SC_FASTCALL emit_parm1_shift(char *name) { emit_outval p[1]; - if (emit_param_any_internal(&p[0],tNUMBER,FALSE,TRUE)) - if (p->value.ucell>=(sizeof(cell)*8)) - error(50); /* invalid range */ + emit_param_shift(&p[0]); outinstr(name,p,(sizeof p / sizeof p[0])); } @@ -6720,160 +6722,160 @@ static void SC_FASTCALL emit_do_pushn_s_adr(char *name) } static EMIT_OPCODE emit_opcodelist[] = { - { 0, NULL, emit_noop }, - { 78, "add", emit_parm0 }, - { 87, "add.c", emit_parm1_any }, - { 14, "addr.alt", emit_parm1_local }, - { 13, "addr.pri", emit_parm1_local }, - { 30, "align.alt", emit_do_align }, - { 29, "align.pri", emit_do_align }, - { 81, "and", emit_parm0 }, - {121, "bounds", emit_parm1_integer }, - {137, "break", emit_parm0 }, - { 49, "call", emit_do_call }, - { 50, "call.pri", emit_parm0 }, - { 0, "case", emit_do_case }, - {130, "casetbl", emit_do_casetbl }, - {118, "cmps", emit_parm1_nonneg }, - {156, "const", emit_do_const }, - { 12, "const.alt", emit_parm1_any }, - { 11, "const.pri", emit_parm1_any }, - {157, "const.s", emit_do_const_s }, - {114, "dec", emit_parm1_data }, - {113, "dec.alt", emit_parm0 }, - {116, "dec.i", emit_parm0 }, - {112, "dec.pri", emit_parm0 }, - {115, "dec.s", emit_parm1_local }, - { 95, "eq", emit_parm0 }, - {106, "eq.c.alt", emit_parm1_any }, - {105, "eq.c.pri", emit_parm1_any }, - {119, "fill", emit_parm1_nonneg }, - {100, "geq", emit_parm0 }, - { 99, "grtr", emit_parm0 }, - {120, "halt", emit_parm1_nonneg }, - { 45, "heap", emit_parm1_integer }, - { 27, "idxaddr", emit_parm0 }, - { 28, "idxaddr.b", emit_parm1_shift }, - {109, "inc", emit_parm1_data }, - {108, "inc.alt", emit_parm0 }, - {111, "inc.i", emit_parm0 }, - {107, "inc.pri", emit_parm0 }, - {110, "inc.s", emit_parm1_local }, - { 86, "invert", emit_parm0 }, - { 55, "jeq", emit_parm1_label }, - { 60, "jgeq", emit_parm1_label }, - { 59, "jgrtr", emit_parm1_label }, - { 58, "jleq", emit_parm1_label }, - { 57, "jless", emit_parm1_label }, - { 56, "jneq", emit_parm1_label }, - { 54, "jnz", emit_parm1_label }, - { 52, "jrel", emit_parm1_integer }, - { 64, "jsgeq", emit_parm1_label }, - { 63, "jsgrtr", emit_parm1_label }, - { 62, "jsleq", emit_parm1_label }, - { 61, "jsless", emit_parm1_label }, - { 51, "jump", emit_parm1_label }, - {128, "jump.pri", emit_parm0 }, - { 53, "jzer", emit_parm1_label }, - { 31, "lctrl", emit_parm1_integer }, - { 98, "leq", emit_parm0 }, - { 97, "less", emit_parm0 }, - { 25, "lidx", emit_parm0 }, - { 26, "lidx.b", emit_parm1_shift }, - { 2, "load.alt", emit_parm1_data }, - {154, "load.both", emit_do_load_both }, - { 9, "load.i", emit_parm0 }, - { 1, "load.pri", emit_parm1_data }, - { 4, "load.s.alt", emit_parm1_local }, - {155, "load.s.both",emit_do_load_s_both }, - { 3, "load.s.pri", emit_parm1_local }, - { 10, "lodb.i", emit_do_lodb_strb }, - { 6, "lref.alt", emit_parm1_data }, - { 5, "lref.pri", emit_parm1_data }, - { 8, "lref.s.alt", emit_parm1_local }, - { 7, "lref.s.pri", emit_parm1_local }, - { 34, "move.alt", emit_parm0 }, - { 33, "move.pri", emit_parm0 }, - {117, "movs", emit_parm1_nonneg }, - { 85, "neg", emit_parm0 }, - { 96, "neq", emit_parm0 }, - {134, "nop", emit_parm0 }, - { 84, "not", emit_parm0 }, - { 82, "or", emit_parm0 }, - { 43, "pop.alt", emit_parm0 }, - { 42, "pop.pri", emit_parm0 }, - { 46, "proc", emit_parm0 }, - { 40, "push", emit_parm1_data }, - {133, "push.adr", emit_parm1_local }, - { 37, "push.alt", emit_parm0 }, - { 39, "push.c", emit_parm1_any }, - { 36, "push.pri", emit_parm0 }, - { 38, "push.r", emit_parm1_integer }, - { 41, "push.s", emit_parm1_local }, - {139, "push2", emit_do_pushn }, - {141, "push2.adr", emit_do_pushn_s_adr }, - {138, "push2.c", emit_do_pushn_c }, - {140, "push2.s", emit_do_pushn_s_adr }, - {143, "push3", emit_do_pushn }, - {145, "push3.adr", emit_do_pushn_s_adr }, - {142, "push3.c", emit_do_pushn_c }, - {144, "push3.s", emit_do_pushn_s_adr }, - {147, "push4", emit_do_pushn }, - {149, "push4.adr", emit_do_pushn_s_adr }, - {146, "push4.c", emit_do_pushn_c }, - {148, "push4.s", emit_do_pushn_s_adr }, - {151, "push5", emit_do_pushn }, - {153, "push5.adr", emit_do_pushn_s_adr }, - {150, "push5.c", emit_do_pushn_c }, - {152, "push5.s", emit_do_pushn_s_adr }, - { 47, "ret", emit_parm0 }, - { 48, "retn", emit_parm0 }, - { 32, "sctrl", emit_parm1_integer }, - { 73, "sdiv", emit_parm0 }, - { 74, "sdiv.alt", emit_parm0 }, - {104, "sgeq", emit_parm0 }, - {103, "sgrtr", emit_parm0 }, - { 65, "shl", emit_parm0 }, - { 69, "shl.c.alt", emit_parm1_shift }, - { 68, "shl.c.pri", emit_parm1_shift }, - { 66, "shr", emit_parm0 }, - { 71, "shr.c.alt", emit_parm1_shift }, - { 70, "shr.c.pri", emit_parm1_shift }, - { 94, "sign.alt", emit_parm0 }, - { 93, "sign.pri", emit_parm0 }, - {102, "sleq", emit_parm0 }, - {101, "sless", emit_parm0 }, - { 72, "smul", emit_parm0 }, - { 88, "smul.c", emit_parm1_integer }, - { 20, "sref.alt", emit_parm1_data }, - { 19, "sref.pri", emit_parm1_data }, - { 22, "sref.s.alt", emit_parm1_local }, - { 21, "sref.s.pri", emit_parm1_local }, - { 67, "sshr", emit_parm0 }, - { 44, "stack", emit_parm1_integer }, - { 16, "stor.alt", emit_parm1_data }, - { 23, "stor.i", emit_parm0 }, - { 15, "stor.pri", emit_parm1_data }, - { 18, "stor.s.alt", emit_parm1_local }, - { 17, "stor.s.pri", emit_parm1_local }, - { 24, "strb.i", emit_do_lodb_strb }, - { 79, "sub", emit_parm0 }, - { 80, "sub.alt", emit_parm0 }, - {132, "swap.alt", emit_parm0 }, - {131, "swap.pri", emit_parm0 }, - {129, "switch", emit_parm1_label }, - {123, "sysreq.c", emit_do_sysreq_c }, - {135, "sysreq.n", emit_do_sysreq_n }, - {122, "sysreq.pri", emit_parm0 }, - { 76, "udiv", emit_parm0 }, - { 77, "udiv.alt", emit_parm0 }, - { 75, "umul", emit_parm0 }, - { 35, "xchg", emit_parm0 }, - { 83, "xor", emit_parm0 }, - { 91, "zero", emit_parm1_data }, - { 90, "zero.alt", emit_parm0 }, - { 89, "zero.pri", emit_parm0 }, - { 92, "zero.s", emit_parm1_local }, + { NULL, emit_noop }, + { "add", emit_parm0 }, + { "add.c", emit_parm1_any }, + { "addr.alt", emit_parm1_local }, + { "addr.pri", emit_parm1_local }, + { "align.alt", emit_do_align }, + { "align.pri", emit_do_align }, + { "and", emit_parm0 }, + { "bounds", emit_parm1_integer }, + { "break", emit_parm0 }, + { "call", emit_do_call }, + { "call.pri", emit_parm0 }, + { "case", emit_do_case }, + { "casetbl", emit_do_casetbl }, + { "cmps", emit_parm1_nonneg }, + { "const", emit_do_const }, + { "const.alt", emit_parm1_any }, + { "const.pri", emit_parm1_any }, + { "const.s", emit_do_const_s }, + { "dec", emit_parm1_data }, + { "dec.alt", emit_parm0 }, + { "dec.i", emit_parm0 }, + { "dec.pri", emit_parm0 }, + { "dec.s", emit_parm1_local }, + { "eq", emit_parm0 }, + { "eq.c.alt", emit_parm1_any }, + { "eq.c.pri", emit_parm1_any }, + { "fill", emit_parm1_nonneg }, + { "geq", emit_parm0 }, + { "grtr", emit_parm0 }, + { "halt", emit_parm1_nonneg }, + { "heap", emit_parm1_integer }, + { "idxaddr", emit_parm0 }, + { "idxaddr.b", emit_parm1_shift }, + { "inc", emit_parm1_data }, + { "inc.alt", emit_parm0 }, + { "inc.i", emit_parm0 }, + { "inc.pri", emit_parm0 }, + { "inc.s", emit_parm1_local }, + { "invert", emit_parm0 }, + { "jeq", emit_parm1_label }, + { "jgeq", emit_parm1_label }, + { "jgrtr", emit_parm1_label }, + { "jleq", emit_parm1_label }, + { "jless", emit_parm1_label }, + { "jneq", emit_parm1_label }, + { "jnz", emit_parm1_label }, + { "jrel", emit_parm1_integer }, + { "jsgeq", emit_parm1_label }, + { "jsgrtr", emit_parm1_label }, + { "jsleq", emit_parm1_label }, + { "jsless", emit_parm1_label }, + { "jump", emit_parm1_label }, + { "jump.pri", emit_parm0 }, + { "jzer", emit_parm1_label }, + { "lctrl", emit_parm1_integer }, + { "leq", emit_parm0 }, + { "less", emit_parm0 }, + { "lidx", emit_parm0 }, + { "lidx.b", emit_parm1_shift }, + { "load.alt", emit_parm1_data }, + { "load.both", emit_do_load_both }, + { "load.i", emit_parm0 }, + { "load.pri", emit_parm1_data }, + { "load.s.alt", emit_parm1_local }, + { "load.s.both",emit_do_load_s_both }, + { "load.s.pri", emit_parm1_local }, + { "lodb.i", emit_do_lodb_strb }, + { "lref.alt", emit_parm1_data }, + { "lref.pri", emit_parm1_data }, + { "lref.s.alt", emit_parm1_local }, + { "lref.s.pri", emit_parm1_local }, + { "move.alt", emit_parm0 }, + { "move.pri", emit_parm0 }, + { "movs", emit_parm1_nonneg }, + { "neg", emit_parm0 }, + { "neq", emit_parm0 }, + { "nop", emit_parm0 }, + { "not", emit_parm0 }, + { "or", emit_parm0 }, + { "pop.alt", emit_parm0 }, + { "pop.pri", emit_parm0 }, + { "proc", emit_parm0 }, + { "push", emit_parm1_data }, + { "push.adr", emit_parm1_local }, + { "push.alt", emit_parm0 }, + { "push.c", emit_parm1_any }, + { "push.pri", emit_parm0 }, + { "push.r", emit_parm1_integer }, + { "push.s", emit_parm1_local }, + { "push2", emit_do_pushn }, + { "push2.adr", emit_do_pushn_s_adr }, + { "push2.c", emit_do_pushn_c }, + { "push2.s", emit_do_pushn_s_adr }, + { "push3", emit_do_pushn }, + { "push3.adr", emit_do_pushn_s_adr }, + { "push3.c", emit_do_pushn_c }, + { "push3.s", emit_do_pushn_s_adr }, + { "push4", emit_do_pushn }, + { "push4.adr", emit_do_pushn_s_adr }, + { "push4.c", emit_do_pushn_c }, + { "push4.s", emit_do_pushn_s_adr }, + { "push5", emit_do_pushn }, + { "push5.adr", emit_do_pushn_s_adr }, + { "push5.c", emit_do_pushn_c }, + { "push5.s", emit_do_pushn_s_adr }, + { "ret", emit_parm0 }, + { "retn", emit_parm0 }, + { "sctrl", emit_parm1_integer }, + { "sdiv", emit_parm0 }, + { "sdiv.alt", emit_parm0 }, + { "sgeq", emit_parm0 }, + { "sgrtr", emit_parm0 }, + { "shl", emit_parm0 }, + { "shl.c.alt", emit_parm1_shift }, + { "shl.c.pri", emit_parm1_shift }, + { "shr", emit_parm0 }, + { "shr.c.alt", emit_parm1_shift }, + { "shr.c.pri", emit_parm1_shift }, + { "sign.alt", emit_parm0 }, + { "sign.pri", emit_parm0 }, + { "sleq", emit_parm0 }, + { "sless", emit_parm0 }, + { "smul", emit_parm0 }, + { "smul.c", emit_parm1_integer }, + { "sref.alt", emit_parm1_data }, + { "sref.pri", emit_parm1_data }, + { "sref.s.alt", emit_parm1_local }, + { "sref.s.pri", emit_parm1_local }, + { "sshr", emit_parm0 }, + { "stack", emit_parm1_integer }, + { "stor.alt", emit_parm1_data }, + { "stor.i", emit_parm0 }, + { "stor.pri", emit_parm1_data }, + { "stor.s.alt", emit_parm1_local }, + { "stor.s.pri", emit_parm1_local }, + { "strb.i", emit_do_lodb_strb }, + { "sub", emit_parm0 }, + { "sub.alt", emit_parm0 }, + { "swap.alt", emit_parm0 }, + { "swap.pri", emit_parm0 }, + { "switch", emit_parm1_label }, + { "sysreq.c", emit_do_sysreq_c }, + { "sysreq.n", emit_do_sysreq_n }, + { "sysreq.pri", emit_parm0 }, + { "udiv", emit_parm0 }, + { "udiv.alt", emit_parm0 }, + { "umul", emit_parm0 }, + { "xchg", emit_parm0 }, + { "xor", emit_parm0 }, + { "zero", emit_parm1_data }, + { "zero.alt", emit_parm0 }, + { "zero.pri", emit_parm0 }, + { "zero.s", emit_parm1_local }, }; static int emit_findopcode(const char *instr,int maxlen) From 86f2b783f8cc46c1d2a8c56b4785eb1f0f0a3c95 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 29 Dec 2018 13:07:12 +0700 Subject: [PATCH 11/21] __emit: Do not allow to pass references (passed by reference function arguments) to 'stor.s.pri/alt', 'inc.s', 'dec.s' and 'zero.s' --- source/compiler/sc.h | 7 +++-- source/compiler/sc1.c | 68 ++++++++++++++++++++++++++++++------------- source/compiler/sc2.c | 2 +- 3 files changed, 52 insertions(+), 25 deletions(-) diff --git a/source/compiler/sc.h b/source/compiler/sc.h index b99cf27..ea53507 100644 --- a/source/compiler/sc.h +++ b/source/compiler/sc.h @@ -415,13 +415,14 @@ enum { tLABEL, tSTRING, /* argument types for emit/__emit */ - teANY , /* any value */ + teANY, /* any value */ teNUMERIC, /* integer/rational number */ - teDATA , /* data (variable name or address) */ + teDATA, /* data (variable name or address) */ teLOCAL, /* local variable (name or offset) */ + teREFERENCE, /* function argument passed by reference */ teFUNCTN, /* Pawn function */ teNATIVE, /* native function */ - teNONNEG , /* nonnegative integer */ + teNONNEG, /* nonnegative integer */ /* for assigment to "lastst" only (see SC1.C) */ tEXPR, tENDLESS, /* endless loop */ diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index cbd81b4..b789f4e 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6102,7 +6102,10 @@ fetchtok: } else { markusage(sym,uREAD | uWRITTEN); if (!allow_nonint && sym->ident!=iCONSTEXPR) { - tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA; + if (sym->vclass==sLOCAL) + tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + else + tok=teDATA; goto invalid_token; } /* if */ p->value.ucell=(ucell)(negate ? -sym->addr : sym->addr); @@ -6234,7 +6237,10 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) goto invalid_token; } /* if */ if (sym->vclass!=sSTATIC) { - tok=(sym->ident==iCONSTEXPR) ? teNUMERIC : teLOCAL; + if (sym->ident==iCONSTEXPR) + tok=teNUMERIC; + else + tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; goto invalid_token; } /* if */ } else { @@ -6266,7 +6272,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) error(11); /* must be a multiple of cell size */ } -static void SC_FASTCALL emit_param_local(emit_outval *p) +static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) { cell val; char *str; @@ -6290,6 +6296,10 @@ static void SC_FASTCALL emit_param_local(emit_outval *p) tok=teDATA; goto invalid_token; } /* if */ + if (sym->ident==iREFERENCE && allow_ref==FALSE) { + tok=teREFERENCE; + goto invalid_token; + } /* if */ } else { sym=findglb(str,sSTATEVAR); if (sym==NULL) { @@ -6341,12 +6351,16 @@ static void SC_FASTCALL emit_param_label(emit_outval *p) if (sym!=NULL) { markusage(sym,(sym->ident==iFUNCTN || sym->ident==iREFFUNC) ? uREAD : (uREAD | uWRITTEN)); if (sym->ident!=iLABEL) { - if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) + if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { tok=((sym->usage & uNATIVE)!=0) ? teNATIVE : teFUNCTN; - else if (sym->ident==iCONSTEXPR) + } else if (sym->ident==iCONSTEXPR) { tok=teNUMERIC; - else - tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA; + } else { + if (sym->vclass==sLOCAL) + tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + else + tok=teDATA; + } /* if */ goto invalid_token; } /* if */ } else { @@ -6388,12 +6402,16 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) tok=(isnative!=FALSE) ? teFUNCTN : teNATIVE; } else { markusage(sym,uREAD | uWRITTEN); - if (sym->ident==iLABEL) + if (sym->ident==iLABEL) { tok=tLABEL; - else if (sym->ident==iCONSTEXPR) + } else if (sym->ident==iCONSTEXPR) { tok=teNUMERIC; - else - tok=(sym->vclass==sLOCAL) ? teLOCAL : teDATA; + } else { + if (sym->vclass==sLOCAL) + tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + else + tok=teDATA; + } /* if */ } /* if */ /* fallthrough */ default: @@ -6465,7 +6483,15 @@ static void SC_FASTCALL emit_parm1_local(char *name) { emit_outval p[1]; - emit_param_local(&p[0]); + emit_param_local(&p[0],TRUE); + outinstr(name,p,(sizeof p / sizeof p[0])); +} + +static void SC_FASTCALL emit_parm1_local_noref(char *name) +{ + emit_outval p[1]; + + emit_param_local(&p[0],FALSE); outinstr(name,p,(sizeof p / sizeof p[0])); } @@ -6594,7 +6620,7 @@ static void SC_FASTCALL emit_do_const_s(char *name) { emit_outval p[2]; - emit_param_local(&p[0]); + emit_param_local(&p[0],FALSE); emit_param_any(&p[1]); /* if macro optimisations are enabled, output a 'const.s' instruction, @@ -6638,8 +6664,8 @@ static void SC_FASTCALL emit_do_load_s_both(char *name) { emit_outval p[2]; - emit_param_local(&p[0]); - emit_param_local(&p[1]); + emit_param_local(&p[0],TRUE); + emit_param_local(&p[1],TRUE); /* if macro optimisations are enabled, output a 'load.s.both' instruction, * otherwise generate the following sequence: @@ -6707,7 +6733,7 @@ static void SC_FASTCALL emit_do_pushn_s_adr(char *name) && name[3]=='h' && '2'<=name[4] && name[4]<='5' && name[5]=='.'); numargs=name[4]-'0'; for (i=0; i.s/.adr' instruction, * otherwise generate a sequence of 'push.s/.adr' instructions @@ -6745,7 +6771,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "dec.alt", emit_parm0 }, { "dec.i", emit_parm0 }, { "dec.pri", emit_parm0 }, - { "dec.s", emit_parm1_local }, + { "dec.s", emit_parm1_local_noref }, { "eq", emit_parm0 }, { "eq.c.alt", emit_parm1_any }, { "eq.c.pri", emit_parm1_any }, @@ -6760,7 +6786,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "inc.alt", emit_parm0 }, { "inc.i", emit_parm0 }, { "inc.pri", emit_parm0 }, - { "inc.s", emit_parm1_local }, + { "inc.s", emit_parm1_local_noref }, { "invert", emit_parm0 }, { "jeq", emit_parm1_label }, { "jgeq", emit_parm1_label }, @@ -6856,8 +6882,8 @@ static EMIT_OPCODE emit_opcodelist[] = { { "stor.alt", emit_parm1_data }, { "stor.i", emit_parm0 }, { "stor.pri", emit_parm1_data }, - { "stor.s.alt", emit_parm1_local }, - { "stor.s.pri", emit_parm1_local }, + { "stor.s.alt", emit_parm1_local_noref }, + { "stor.s.pri", emit_parm1_local_noref }, { "strb.i", emit_do_lodb_strb }, { "sub", emit_parm0 }, { "sub.alt", emit_parm0 }, @@ -6875,7 +6901,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "zero", emit_parm1_data }, { "zero.alt", emit_parm0 }, { "zero.pri", emit_parm0 }, - { "zero.s", emit_parm1_local }, + { "zero.s", emit_parm1_local_noref }, }; static int emit_findopcode(const char *instr,int maxlen) diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index d30c34f..40b60ef 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -2148,7 +2148,7 @@ char *sc_tokens[] = { ";", ";", "-integer value-", "-rational value-", "-identifier-", "-label-", "-string-", "-any value-", "-numeric value-", "-data offset-", "-local variable-", - "-function-", "-native function-", "-nonnegative integer-" + "-reference-", "-function-", "-native function-", "-nonnegative integer-" }; SC_FUNC int lex(cell *lexvalue,char **lexsym) From 62779691ab22421ac18253a988cdd626c5ed14b3 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Mon, 31 Dec 2018 01:33:42 +0700 Subject: [PATCH 12/21] __emit: Display the type of passed-by-reference arrays in error messages as "-reference-" --- source/compiler/sc1.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index b789f4e..1672db0 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6103,7 +6103,7 @@ fetchtok: markusage(sym,uREAD | uWRITTEN); if (!allow_nonint && sym->ident!=iCONSTEXPR) { if (sym->vclass==sLOCAL) - tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + tok=(sym->ident==iREFERENCE || sym->ident==iREFARRAY) ? teREFERENCE : teLOCAL; else tok=teDATA; goto invalid_token; @@ -6240,7 +6240,7 @@ static void SC_FASTCALL emit_param_data(emit_outval *p) if (sym->ident==iCONSTEXPR) tok=teNUMERIC; else - tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + tok=(sym->ident==iREFERENCE || sym->ident==iREFARRAY) ? teREFERENCE : teLOCAL; goto invalid_token; } /* if */ } else { @@ -6296,7 +6296,7 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) tok=teDATA; goto invalid_token; } /* if */ - if (sym->ident==iREFERENCE && allow_ref==FALSE) { + if (allow_ref==FALSE && (sym->ident==iREFERENCE || sym->ident==iREFARRAY)) { tok=teREFERENCE; goto invalid_token; } /* if */ @@ -6357,7 +6357,7 @@ static void SC_FASTCALL emit_param_label(emit_outval *p) tok=teNUMERIC; } else { if (sym->vclass==sLOCAL) - tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + tok=(sym->ident==iREFERENCE || sym->ident==iREFARRAY) ? teREFERENCE : teLOCAL; else tok=teDATA; } /* if */ @@ -6408,7 +6408,7 @@ static void SC_FASTCALL emit_param_function(emit_outval *p,int isnative) tok=teNUMERIC; } else { if (sym->vclass==sLOCAL) - tok=(sym->ident==iREFERENCE) ? teREFERENCE : teLOCAL; + tok=(sym->ident==iREFERENCE || sym->ident==iREFARRAY) ? teREFERENCE : teLOCAL; else tok=teDATA; } /* if */ From 4b490e8ec264e444f000123df8bb38001e0f016b Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Tue, 1 Jan 2019 19:28:59 +0700 Subject: [PATCH 13/21] Fix potential buffer overrun in #emit and __emit --- source/compiler/sc1.c | 6 +++--- source/compiler/sc2.c | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 1672db0..592c1f6 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6948,13 +6948,13 @@ SC_FUNC void emit_parse_line(void) * and copy the instruction name */ lptr-=len; - for (i=0; i Date: Wed, 3 Apr 2019 20:52:38 +0700 Subject: [PATCH 14/21] __emit: Change the format of errors related to invalid use of the '-' sign Example: L1: __emit const.pri -L1; Before: error 001: expected token: "-any value-", but found "-L1" After: error 001: expected token: "-any value-", but found "-(-label-)" --- source/compiler/sc1.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 592c1f6..17d8ddb 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6078,8 +6078,10 @@ fetchtok: } /* if */ if (sym->ident==iLABEL) { sym->usage|=uREAD; - if (negate) + if (negate) { + tok=tLABEL; goto invalid_token_neg; + } /* if */ if (!allow_nonint) { tok=tLABEL; goto invalid_token; @@ -6089,8 +6091,10 @@ fetchtok: } else if (sym->ident==iFUNCTN || sym->ident==iREFFUNC) { const int ntvref=sym->usage & uREAD; markusage(sym,uREAD); - if (negate) + if (negate) { + tok=teFUNCTN; goto invalid_token_neg; + } /* if */ if (!allow_nonint) { tok=(sym->usage & uNATIVE) ? teNATIVE : teFUNCTN; goto invalid_token; @@ -6149,7 +6153,10 @@ fetchtok: extern char *sc_tokens[]; char ival[sNAMEMAX+2]; invalid_token_neg: - sprintf(ival,"-%s",str); + if (tok Date: Wed, 3 Apr 2019 21:12:08 +0700 Subject: [PATCH 15/21] __emit: Fix previously undetected error case related to invalid use of the '-' sign --- source/compiler/sc1.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 17d8ddb..983b8f7 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6135,6 +6135,8 @@ fetchtok: } /* if */ break; case ':': + if (negate) + goto invalid_token_neg; tok=lex(&val,&str); if (tok!=tSYMBOL) { emit_invalid_token(tSYMBOL,tok); From 4c260e6c60372bdfd23a94adea9ee1eb2bdf48d1 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Thu, 4 Apr 2019 21:11:53 +0700 Subject: [PATCH 16/21] __emit: Allow negative offsets for arguments of type 'local variable' --- source/compiler/sc1.c | 32 ++++++++++++++++++++++++++++---- 1 file changed, 28 insertions(+), 4 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index 983b8f7..dac670c 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6286,9 +6286,11 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) cell val; char *str; symbol *sym; - int tok; + int tok,negate; + negate=FALSE; p->type=eotNUMBER; +fetchtok: tok=lex(&val,&str); switch (tok) { case tNUMBER: @@ -6309,6 +6311,10 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) tok=teREFERENCE; goto invalid_token; } /* if */ + if (negate && sym->ident!=iCONSTEXPR) { + tok=(sym->ident==iREFERENCE || sym->ident==iREFARRAY) ? teREFERENCE : teLOCAL; + goto invalid_token_neg; + } /* if */ } else { sym=findglb(str,sSTATEVAR); if (sym==NULL) { @@ -6326,15 +6332,33 @@ static void SC_FASTCALL emit_param_local(emit_outval *p,int allow_ref) } /* if */ val=sym->addr; break; + case '-': + if (!negate) { + negate=TRUE; + goto fetchtok; + } else { + extern char *sc_tokens[]; + char ival[sNAMEMAX+2]; + invalid_token_neg: + if (tokvalue.ucell=(ucell)val; - else + if ((val % sizeof(cell))!=0) { error(11); /* must be a multiple of cell size */ + return; + } + p->value.ucell=(ucell)(negate ? -val : val); } static void SC_FASTCALL emit_param_label(emit_outval *p) From 2cfcd2130b8e43995bce7a6263b3e3ba0da2e8d5 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Wed, 29 May 2019 01:13:43 +0700 Subject: [PATCH 17/21] __emit: Implement pseudo-opcodes --- source/compiler/sc1.c | 469 ++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 469 insertions(+) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index dac670c..e4cda9c 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6047,6 +6047,254 @@ static void SC_FASTCALL emit_invalid_token(int expected_token,int found_token) } /* if */ } +static regid SC_FASTCALL emit_findreg(char *opname) +{ + const char *regname=strrchr(opname,'.'); + assert(regname!=NULL); + regname+=1; + assert(strcmp(regname,"pri")==0 || strcmp(regname,"alt")==0); + return (strcmp(regname,"pri")==0) ? sPRI : sALT; +} + +/* emit_getlval + * + * Looks for an lvalue and generates code to get cell address in PRI + * if the lvalue is an array element (iARRAYCELL or iARRAYCHAR). + */ +static int SC_FASTCALL emit_getlval(int *identptr,emit_outval *p,int *islocal, regid reg, + int allow_char, int store_pri,int store_alt,int *ispushed) +{ + int tok,index,ident,close; + cell cidx,val,length; + char *str; + symbol *sym; + + assert(identptr!=NULL); + assert(p!=NULL); + assert((!store_pri && !store_alt) || ((store_pri ^ store_alt) && (reg==sALT && ispushed!=NULL))); + + if (staging) { + assert((emit_flags & efEXPR)!=0); + stgget(&index,&cidx); + } /* if */ + + tok=lex(&val,&str); + if (tok!=tSYMBOL) { +invalid_lvalue: + error(22); /* must be lvalue */ + return FALSE; + } /* if */ + + sym=findloc(str); + if (sym==NULL) + sym=findglb(str,sSTATEVAR); + if (sym==NULL || (sym->ident!=iFUNCTN && sym->ident!=iREFFUNC && (sym->usage & uDEFINE)==0)) { + error(17,str); /* undefined symbol */ + return FALSE; + } /* if */ + markusage(sym,uREAD | uWRITTEN); + + p->type=eotNUMBER; + switch (sym->ident) + { + case iVARIABLE: + case iREFERENCE: + *identptr=sym->ident; + *islocal=((sym->vclass & sLOCAL)!=0); + p->value.ucell=*(ucell *)&sym->addr; + break; + case iARRAY: + case iREFARRAY: + /* get the index */ + if (matchtoken('[')) { + *identptr=iARRAYCELL; + close=']'; + } else if (matchtoken('{')) { + *identptr=iARRAYCHAR; + close='}'; + } else { + error(33,sym->name); /* array must be indexed */ + return FALSE; + } /* if */ + if (store_alt || store_pri) { + pushreg(store_pri ? sPRI : sALT); + *ispushed=TRUE; + } /* if */ + errorset(sEXPRMARK,0); + ident=expression(&val,NULL,NULL,TRUE); + errorset(sEXPRRELEASE,0); + needtoken(close); + + /* check if the index isn't out of bounds */ + length=sym->dim.array.length; + if (close=='}') + length *= (8*sizeof(cell))/sCHARBITS; + if (ident==iCONSTEXPR) { /* if the index is a constant value, check it at compile time */ + if (val<0 || (length!=0 && val>=length)) { + error(32,sym->name); /* array index out of bounds */ + return FALSE; + } /* if */ + } else if (length!=0) { /* otherwise generate code for a run-time boundary check */ + ffbounds(length-1); + } /* if */ + + /* calculate cell address */ + if (ident==iCONSTEXPR) { + if (staging) + stgdel(index,cidx); /* erase generated code */ + if (store_alt || store_pri) + *ispushed=FALSE; + p->value.ucell= *(ucell *)&sym->addr; + if (close==']') + val *= (cell)sizeof(cell); + else + val *= (cell)(sCHARBITS/8); + if (sym->ident==iARRAY) { + p->value.ucell += (ucell)val; + if (close==']') { + /* If we are accessing an array cell and its address is known at + * compile time, we can return it as 'iVARIABLE', + * so the calling function could generate more optimal code. + */ + *islocal=((sym->vclass & sLOCAL)!=0); + *identptr=iVARIABLE; + break; + } /* if */ + if (reg==sPRI) { + outinstr(((sym->vclass & sLOCAL)!=0) ? "addr.pri" : "const.pri",p,1); + } else { + if (store_alt) + moveto1(); + outinstr(((sym->vclass & sLOCAL)!=0) ? "addr.alt" : "const.alt",p,1); + } /* if */ + } else { /* sym->ident==iREFARRAY */ + if (close==']' && val==0) { + *identptr=iREFERENCE; + break; + } /* if */ + if (reg==sPRI) { + outinstr("load.s.pri",p,1); + if (val==1) + outinstr("inc.pri",NULL,0); + else + addconst(val); + } else { + if (val==0 || val==1) { + if (store_alt) + outinstr("move.pri",NULL,0); + outinstr("load.s.alt",p,1); + if (val==1) + outinstr("inc.alt",NULL,0); + } else { + if (store_pri) + outinstr("move.alt",NULL,0); + outinstr("load.s.pri",p,1); + addconst(val); + if (store_pri || store_alt) + outinstr("xchg",NULL,0); + else + outinstr("move.alt",NULL,0); + } /* if */ + } /* if */ + } /* if */ + if (close=='}') { + p->value.ucell=(ucell)(sCHARBITS/8); + outinstr((reg==sPRI) ? "align.pri" : "align.alt",p,1); + } /* if */ + } else { /* ident!=iCONSTEXPR */ + if (close=='}' && sym->ident==iARRAY && (sym->vclass & sLOCAL)==0) { + char2addr(); + addconst(sym->addr); + charalign(); + if (reg==sALT) + outinstr("move.alt",NULL,0); + break; + } /* if */ + p->value.ucell= *(ucell *)&sym->addr; + if (sym->ident==iARRAY) + outinstr(((sym->vclass & sLOCAL)!=0) ? "addr.alt" : "const.alt",p,1); + else /* sym->ident==iREFARRAY */ + outinstr("load.s.alt",p,1); + if (close==']') { + outinstr("idxaddr",NULL,0); + } else { + char2addr(); + ob_add(); + charalign(); + } /* if */ + if (reg==sALT) + outinstr("move.alt",NULL,0); + } /* if */ + break; + default: + goto invalid_lvalue; + } /* switch */ + + if (!staging) { /* issue an error if a pseudo-opcode is used outside of function body */ + error(10); /* invalid function or declaration */ + return FALSE; + } /* if */ + if ((sym->ident==iARRAY || sym->ident==iREFARRAY) && close=='}' && !allow_char) { + /* issue an error if array character access isn't allowed + * (currently it's only in 'push.u.adr') + */ + error(35,1); /* argument type mismatch (argument 1) */ + return FALSE; + } /* if */ + return TRUE; +} + +/* emit_getrval + * + * Looks for an rvalue and generates code to handle expressions. + */ +static int SC_FASTCALL emit_getrval(int *identptr,emit_outval *p,int *islocal) +{ + int index,result=TRUE; + cell cidx; + cell val; + symbol *sym; + + assert(identptr!=NULL); + assert(p!=NULL); + assert(islocal!=NULL); + + if (staging) { + assert((emit_flags & efEXPR)!=0); + stgget(&index,&cidx); + } else { + error(10); /* invalid function or declaration */ + result=FALSE; + } /* if */ + + errorset(sEXPRMARK,0); + *identptr=expression(&val,NULL,&sym,TRUE); + p->type=eotNUMBER; + switch (*identptr) { + case iVARIABLE: + case iREFERENCE: + *islocal=((sym->vclass & sLOCAL)!=0); + /* fallthrough */ + case iCONSTEXPR: + /* If the expression result is a constant value or a variable - erase the code + * for this expression so the caller would be able to generate more optimal + * code for it, without unnecessary register clobbering. + */ + if (staging) + stgdel(index,cidx); + p->value.ucell=*(ucell *)((*identptr==iCONSTEXPR) ? &val : &sym->addr); + break; + case iARRAY: + case iREFARRAY: + error(33,(sym!=NULL) ? sym->name : "-unknown-"); /* array must be indexed */ + result=FALSE; + break; + } /* switch */ + errorset(sEXPRRELEASE,0); + + return result; +} + static int SC_FASTCALL emit_param_any_internal(emit_outval *p,int expected_tok, int allow_nonint,int allow_expr) { @@ -6780,12 +7028,224 @@ static void SC_FASTCALL emit_do_pushn_s_adr(char *name) } /* if */ } +static void SC_FASTCALL emit_do_load_u_pri_alt(char *name) +{ + emit_outval p[1]; + regid reg; + int ident,islocal; + + if (!emit_getrval(&ident,&p[0],&islocal)) + return; + reg=emit_findreg(name); + switch (ident) { + case iCONSTEXPR: + if (p[0].value.ucell==(ucell)0) + outinstr((reg==sPRI) ? "zero.pri" : "zero.alt",NULL,0); + else + outinstr((reg==sPRI) ? "const.pri" : "const.alt",p,1); + break; + case iVARIABLE: + if (islocal) + outinstr((reg==sPRI) ? "load.s.pri" : "load.s.alt",p,1); + else + outinstr((reg==sPRI) ? "load.pri" : "load.alt",p,1); + break; + case iREFERENCE: + outinstr((reg==sPRI) ? "lref.s.pri" : "lref.s.alt",p,1); + break; + default: + if (reg==sALT) + outinstr("move.alt",NULL,0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_stor_u_pri_alt(char *name) +{ + emit_outval p[1]; + regid reg; + int ident,islocal,ispushed; + + reg=emit_findreg(name); + if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,(reg==sPRI),(reg==sALT),&ispushed)) + return; + switch (ident) { + case iVARIABLE: + if (islocal) + outinstr((reg==sPRI) ? "stor.s.pri" : "stor.s.alt",p,1); + else + outinstr((reg==sPRI) ? "stor.pri" : "stor.alt",p,1); + break; + case iREFERENCE: + outinstr((reg==sPRI) ? "sref.s.pri" : "sref.s.alt",p,1); + break; + case iARRAYCELL: + case iARRAYCHAR: + if (ispushed) + popreg(sPRI); + if (ident==iARRAYCELL) { + outinstr("stor.i",NULL,0); + } else { + p->value.ucell=sCHARBITS/8; + outinstr("strb.i",p,1); + } /* if */ + break; + default: + assert(0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_addr_u_pri_alt(char *name) +{ + emit_outval p[1]; + regid reg; + int ident,islocal; + + reg=emit_findreg(name); + if (!emit_getlval(&ident,&p[0],&islocal,reg,TRUE,FALSE,FALSE,NULL)) + return; + switch (ident) { + case iVARIABLE: + if (islocal) + outinstr((reg==sPRI) ? "addr.pri" : "addr.alt",p,1); + else if (p[0].value.ucell==(ucell)0) + outinstr((reg==sPRI) ? "zero.pri" : "zero.alt",NULL,0); + else + outinstr((reg==sPRI) ? "const.pri" : "const.alt",p,1); + break; + case iREFERENCE: + outinstr((reg==sPRI) ? "load.s.pri" : "load.s.alt",p,1); + break; + case iARRAYCELL: + case iARRAYCHAR: + break; + default: + assert(0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_push_u(char *name) +{ + emit_outval p[1]; + int ident,islocal; + + if (!emit_getrval(&ident,&p[0],&islocal)) + return; + switch (ident) { + case iCONSTEXPR: + outinstr("push.c",&p[0],1); + break; + case iVARIABLE: + outinstr(islocal ? "push.s" : "push",p,1); + break; + case iREFERENCE: + outinstr("lref.s.pri",&p[0],1); + /* fallthrough */ + default: + outinstr("push.pri",NULL,0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_push_u_adr(char *name) +{ + emit_outval p[1]; + int ident,islocal; + + if (!emit_getlval(&ident,&p[0],&islocal,sPRI,FALSE,FALSE,FALSE,NULL)) + return; + switch (ident) { + case iVARIABLE: + outinstr(islocal ? "push.adr" : "push.c",p,1); + break; + case iREFERENCE: + outinstr("push.s",p,1); + break; + case iARRAYCELL: + case iARRAYCHAR: + pushreg(sPRI); + break; + default: + assert(0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_zero_u(char *name) +{ + emit_outval p[1]; + int ident,islocal; + + if (!emit_getlval(&ident,&p[0],&islocal,sALT,TRUE,FALSE,FALSE,NULL)) + return; + switch (ident) { + case iVARIABLE: + outinstr(islocal ? "zero.s" : "zero",p,1); + break; + case iREFERENCE: + outinstr("zero.pri",NULL,0); + outinstr("sref.s.pri",&p[0],1); + break; + case iARRAYCELL: + outinstr("zero.pri",NULL,0); + outinstr("stor.i",NULL,0); + break; + case iARRAYCHAR: + outinstr("zero.pri",NULL,0); + p[0].value.ucell=(ucell)(sCHARBITS/8); + outinstr("strb.i",p,1); + break; + default: + assert(0); + break; + } /* switch */ +} + +static void SC_FASTCALL emit_do_inc_dec_u(char *name) +{ + emit_outval p[1]; + int ident,islocal; + + assert(strcmp(name,"inc.u")==0 || strcmp(name,"dec.u")==0); + + if (!emit_getlval(&ident,&p[0],&islocal,sPRI,TRUE,FALSE,FALSE,NULL)) + return; + switch (ident) { + case iVARIABLE: + if (islocal) + outinstr((name[0]=='i') ? "inc.s" : "dec.s",p,1); + else + outinstr((name[0]=='i') ? "inc" : "dec",p,1); + break; + case iREFERENCE: + outinstr("load.s.pri",&p[0],1); + /* fallthrough */ + case iARRAYCELL: + outinstr((name[0]=='i') ? "inc.i" : "dec.i",NULL,0); + break; + case iARRAYCHAR: + p[0].value.ucell=(ucell)(sCHARBITS/8); + outinstr("move.alt",NULL,0); + outinstr("lodb.i",p,1); + outinstr((name[0]=='i') ? "inc.pri" : "dec.pri",NULL,0); + outinstr("strb.i",p,1); + break; + default: + assert(0); + break; + } /* switch */ +} + static EMIT_OPCODE emit_opcodelist[] = { { NULL, emit_noop }, { "add", emit_parm0 }, { "add.c", emit_parm1_any }, { "addr.alt", emit_parm1_local }, { "addr.pri", emit_parm1_local }, + { "addr.u.alt", emit_do_addr_u_pri_alt }, + { "addr.u.pri", emit_do_addr_u_pri_alt }, { "align.alt", emit_do_align }, { "align.pri", emit_do_align }, { "and", emit_parm0 }, @@ -6805,6 +7265,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "dec.i", emit_parm0 }, { "dec.pri", emit_parm0 }, { "dec.s", emit_parm1_local_noref }, + { "dec.u", emit_do_inc_dec_u }, { "eq", emit_parm0 }, { "eq.c.alt", emit_parm1_any }, { "eq.c.pri", emit_parm1_any }, @@ -6820,6 +7281,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "inc.i", emit_parm0 }, { "inc.pri", emit_parm0 }, { "inc.s", emit_parm1_local_noref }, + { "inc.u", emit_do_inc_dec_u }, { "invert", emit_parm0 }, { "jeq", emit_parm1_label }, { "jgeq", emit_parm1_label }, @@ -6848,6 +7310,8 @@ static EMIT_OPCODE emit_opcodelist[] = { { "load.s.alt", emit_parm1_local }, { "load.s.both",emit_do_load_s_both }, { "load.s.pri", emit_parm1_local }, + { "load.u.alt", emit_do_load_u_pri_alt }, + { "load.u.pri", emit_do_load_u_pri_alt }, { "lodb.i", emit_do_lodb_strb }, { "lref.alt", emit_parm1_data }, { "lref.pri", emit_parm1_data }, @@ -6871,6 +7335,8 @@ static EMIT_OPCODE emit_opcodelist[] = { { "push.pri", emit_parm0 }, { "push.r", emit_parm1_integer }, { "push.s", emit_parm1_local }, + { "push.u", emit_do_push_u }, + { "push.u.adr", emit_do_push_u_adr }, { "push2", emit_do_pushn }, { "push2.adr", emit_do_pushn_s_adr }, { "push2.c", emit_do_pushn_c }, @@ -6917,6 +7383,8 @@ static EMIT_OPCODE emit_opcodelist[] = { { "stor.pri", emit_parm1_data }, { "stor.s.alt", emit_parm1_local_noref }, { "stor.s.pri", emit_parm1_local_noref }, + { "stor.u.alt", emit_do_stor_u_pri_alt }, + { "stor.u.pri", emit_do_stor_u_pri_alt }, { "strb.i", emit_do_lodb_strb }, { "sub", emit_parm0 }, { "sub.alt", emit_parm0 }, @@ -6935,6 +7403,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "zero.alt", emit_parm0 }, { "zero.pri", emit_parm0 }, { "zero.s", emit_parm1_local_noref }, + { "zero.u", emit_do_zero_u }, }; static int emit_findopcode(const char *instr,int maxlen) From dfefdf3b503ccbd5ca90b530e6893fcf8b24c605 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Wed, 29 May 2019 01:14:29 +0700 Subject: [PATCH 18/21] __emit: Add tests --- source/compiler/tests/__emit.inc | 7 + source/compiler/tests/__emit_p1.meta | 30 + source/compiler/tests/__emit_p1.pwn | 141 ++++ source/compiler/tests/__emit_p2.meta | 25 + source/compiler/tests/__emit_p2.pwn | 82 ++ source/compiler/tests/__emit_p3.meta | 23 + source/compiler/tests/__emit_p3.pwn | 42 ++ source/compiler/tests/__emit_p4.meta | 25 + source/compiler/tests/__emit_p4.pwn | 68 ++ source/compiler/tests/__emit_p5.meta | 29 + source/compiler/tests/__emit_p5.pwn | 79 ++ source/compiler/tests/__emit_p6.meta | 25 + source/compiler/tests/__emit_p6.pwn | 110 +++ source/compiler/tests/__emit_p7.meta | 25 + source/compiler/tests/__emit_p7.pwn | 85 +++ source/compiler/tests/__emit_pcode_check.meta | 702 ++++++++++++++++++ source/compiler/tests/__emit_pcode_check.pwn | 345 +++++++++ 17 files changed, 1843 insertions(+) create mode 100644 source/compiler/tests/__emit.inc create mode 100644 source/compiler/tests/__emit_p1.meta create mode 100644 source/compiler/tests/__emit_p1.pwn create mode 100644 source/compiler/tests/__emit_p2.meta create mode 100644 source/compiler/tests/__emit_p2.pwn create mode 100644 source/compiler/tests/__emit_p3.meta create mode 100644 source/compiler/tests/__emit_p3.pwn create mode 100644 source/compiler/tests/__emit_p4.meta create mode 100644 source/compiler/tests/__emit_p4.pwn create mode 100644 source/compiler/tests/__emit_p5.meta create mode 100644 source/compiler/tests/__emit_p5.pwn create mode 100644 source/compiler/tests/__emit_p6.meta create mode 100644 source/compiler/tests/__emit_p6.pwn create mode 100644 source/compiler/tests/__emit_p7.meta create mode 100644 source/compiler/tests/__emit_p7.pwn create mode 100644 source/compiler/tests/__emit_pcode_check.meta create mode 100644 source/compiler/tests/__emit_pcode_check.pwn diff --git a/source/compiler/tests/__emit.inc b/source/compiler/tests/__emit.inc new file mode 100644 index 0000000..834ec6d --- /dev/null +++ b/source/compiler/tests/__emit.inc @@ -0,0 +1,7 @@ +#include + +const global_const = 0; +new stock global_var = 0; +new stock global_array[2]; +forward global_func(); public global_func() { return 0; } +native global_native(const string[]) = print; diff --git a/source/compiler/tests/__emit_p1.meta b/source/compiler/tests/__emit_p1.meta new file mode 100644 index 0000000..db8936d --- /dev/null +++ b/source/compiler/tests/__emit_p1.meta @@ -0,0 +1,30 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p1.pwn(56) : error 001: expected token: "-any value-", but found "-(-function-)" +__emit_p1.pwn(57) : error 001: expected token: "-any value-", but found "-(-label-)" +__emit_p1.pwn(58) : error 001: expected token: "-any value-", but found "--" +__emit_p1.pwn(58) : warning 215: expression has no effect +__emit_p1.pwn(59) : error 017: undefined symbol "local_label2" +__emit_p1.pwn(60) : error 001: expected token: "-any value-", but found "-:" +__emit_p1.pwn(60) : error 029: invalid expression, assumed zero +__emit_p1.pwn(60) : warning 215: expression has no effect +__emit_p1.pwn(83) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p1.pwn(84) : error 001: expected token: "-integer value-", but found "-function-" +__emit_p1.pwn(85) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p1.pwn(86) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p1.pwn(87) : error 001: expected token: "-integer value-", but found "-local variable-" +__emit_p1.pwn(88) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p1.pwn(89) : error 001: expected token: "-integer value-", but found "-label-" +__emit_p1.pwn(115) : error 001: expected token: "-nonnegative integer-", but found "-data offset-" +__emit_p1.pwn(116) : error 001: expected token: "-nonnegative integer-", but found "-function-" +__emit_p1.pwn(117) : error 001: expected token: "-nonnegative integer-", but found "-reference-" +__emit_p1.pwn(118) : error 001: expected token: "-nonnegative integer-", but found "-reference-" +__emit_p1.pwn(119) : error 001: expected token: "-nonnegative integer-", but found "-local variable-" +__emit_p1.pwn(120) : error 001: expected token: "-nonnegative integer-", but found "-data offset-" +__emit_p1.pwn(121) : error 001: expected token: "-nonnegative integer-", but found "-label-" +__emit_p1.pwn(122) : error 001: expected token: "-nonnegative integer-", but found "-1" +__emit_p1.pwn(123) : error 001: expected token: "-nonnegative integer-", but found "-1" +__emit_p1.pwn(127) : error 001: expected token: "-nonnegative integer-", but found "-2147483648" + """ +} diff --git a/source/compiler/tests/__emit_p1.pwn b/source/compiler/tests/__emit_p1.pwn new file mode 100644 index 0000000..7132e02 --- /dev/null +++ b/source/compiler/tests/__emit_p1.pwn @@ -0,0 +1,141 @@ +#include "__emit.inc" + + +stock test__any(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit const.pri global_const; + emit const.pri global_var; + emit const.pri global_func; + emit const.pri local_refvar; + emit const.pri local_refarray; + emit const.pri local_const; + emit const.pri local_var; + emit const.pri local_static_var; + emit const.pri local_label; + emit const.pri :local_label; + emit const.pri :local_label2; + emit const.pri 0; + emit const.pri -0; + emit const.pri 1; + emit const.pri -1; + emit const.pri 0x0; + emit const.pri -0x0; + emit const.pri 0x1; + emit const.pri -0x1; +#if cellbits == 16 + emit const.pri 32767; + emit const.pri -32768; + emit const.pri 0x7FFF; + emit const.pri -0x7FFF; + emit const.pri 0x8000; + emit const.pri -0x8000; +#elseif cellbits == 32 + emit const.pri 2147483647; + emit const.pri -2147483648; + emit const.pri 0x7FFFFFFF; + emit const.pri -0x7FFFFFFF; + emit const.pri 0x80000000; + emit const.pri -0x80000000; +#else // cellbits == 64 + emit const.pri 9223372036854775807; + emit const.pri -9223372036854775808; + emit const.pri 0x7FFFFFFFFFFFFFFF; + emit const.pri -0x7FFFFFFFFFFFFFFF; + emit const.pri 0x8000000000000000; + emit const.pri -0x8000000000000000; +#endif + emit const.pri (cellbits / charbits * 2); + + // should trigger an error + emit const.pri -global_func; + emit const.pri -local_label; + emit const.pri --0; + emit const.pri local_label2; + emit const.pri -:local_label; + +local_label2: +} + +stock test__integer(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit jrel global_const; + emit jrel local_const; + emit jrel 0; + emit jrel 1; + emit jrel -1; + emit jrel 0x1; + emit jrel -0x1; + emit jrel (cellbits / charbits * 2); + + // should trigger an error + emit jrel global_var; + emit jrel global_func; + emit jrel local_refvar; + emit jrel local_refarray; + emit jrel local_var; + emit jrel local_static_var; + emit jrel local_label; +} + +stock test__nonneg(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit cmps global_const; + emit cmps local_const; + emit cmps 0; + emit cmps 1; + emit cmps 0x1; + emit cmps (cellbits / charbits * 2); +#if cellbits == 16 + emit cmps 0x7FFF; +#elseif cellbits == 32 + emit cmps 0x7FFFFFFF; +#else // cellbits == 64 + emit cmps 0x7FFFFFFFFFFFFFFF; +#endif + + // should trigger an error + emit cmps global_var; + emit cmps global_func; + emit cmps local_refvar; + emit cmps local_refarray; + emit cmps local_var; + emit cmps local_static_var; + emit cmps local_label; + emit cmps -1; + emit cmps -0x1; +#if cellbits == 16 + emit cmps 0x8000; +#elseif cellbits == 32 + emit cmps 0x80000000; +#else // cellbits == 64 + emit cmps 0x8000000000000000; +#endif +} + + +main() +{ + new t; + static a[1]; + test__any(t, a); // 4 + test__integer(t, a); // 7 + test__nonneg(t, a); // 10 +} diff --git a/source/compiler/tests/__emit_p2.meta b/source/compiler/tests/__emit_p2.meta new file mode 100644 index 0000000..9cee05a --- /dev/null +++ b/source/compiler/tests/__emit_p2.meta @@ -0,0 +1,25 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p2.pwn(30) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p2.pwn(31) : error 001: expected token: "-integer value-", but found "-function-" +__emit_p2.pwn(32) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p2.pwn(33) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p2.pwn(34) : error 001: expected token: "-integer value-", but found "-local variable-" +__emit_p2.pwn(35) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p2.pwn(36) : error 001: expected token: "-integer value-", but found "-label-" +__emit_p2.pwn(37) : error 050: invalid range +__emit_p2.pwn(38) : error 050: invalid range +__emit_p2.pwn(43) : error 050: invalid range +__emit_p2.pwn(44) : error 050: invalid range +__emit_p2.pwn(65) : error 001: expected token: "-label-", but found "-numeric value-" +__emit_p2.pwn(66) : error 001: expected token: "-label-", but found "-data offset-" +__emit_p2.pwn(67) : error 001: expected token: "-label-", but found "-function-" +__emit_p2.pwn(68) : error 001: expected token: "-label-", but found "-reference-" +__emit_p2.pwn(69) : error 001: expected token: "-label-", but found "-reference-" +__emit_p2.pwn(70) : error 001: expected token: "-label-", but found "-numeric value-" +__emit_p2.pwn(71) : error 001: expected token: "-label-", but found "-local variable-" +__emit_p2.pwn(72) : error 001: expected token: "-label-", but found "-data offset-" +__emit_p2.pwn(73) : error 001: expected token: "-label-", but found "-integer value-" + """ +} diff --git a/source/compiler/tests/__emit_p2.pwn b/source/compiler/tests/__emit_p2.pwn new file mode 100644 index 0000000..bb91ea9 --- /dev/null +++ b/source/compiler/tests/__emit_p2.pwn @@ -0,0 +1,82 @@ +#include "__emit.inc" + + +stock test__shift(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit shl.c.pri global_const; + emit shl.c.pri local_const; + emit shl.c.pri 0; + emit shl.c.pri 1; + emit shl.c.pri 15; + emit shl.c.pri (cellbits / charbits); +#if cellbits == 16 + emit shl.c.pri 15; + emit shl.c.pri 0xF; +#elseif cellbits == 32 + emit shl.c.pri 31; + emit shl.c.pri 0x1F; +#else // cellbits == 64 + emit shl.c.pri 63; + emit shl.c.pri 0x3F; +#endif + + // should trigger an error + emit shl.c.pri global_var; + emit shl.c.pri global_func; + emit shl.c.pri local_refvar; + emit shl.c.pri local_refarray; + emit shl.c.pri local_var; + emit shl.c.pri local_static_var; + emit shl.c.pri local_label; + emit shl.c.pri -1; + emit shl.c.pri -0x1; +#if cellbits == 16 + emit shl.c.pri 16; + emit shl.c.pri 0x10; +#elseif cellbits == 32 + emit shl.c.pri 32; + emit shl.c.pri 0x20; +#else // cellbits == 64 + emit shl.c.pri 64; + emit shl.c.pri 0x40; +#endif +} + +stock test__label(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit jump local_label; + emit jump local_label2; + emit jump :local_label2; +local_label2: + + // should trigger an error + emit jump global_const; + emit jump global_var; + emit jump global_func; + emit jump local_refvar; + emit jump local_refarray; + emit jump local_const; + emit jump local_var; + emit jump local_static_var; + emit jump 0; +} + + +main() +{ + new t, a[1]; + test__shift(t, a); // 11 + test__label(t, a); // 9 +} diff --git a/source/compiler/tests/__emit_p3.meta b/source/compiler/tests/__emit_p3.meta new file mode 100644 index 0000000..1fe3731 --- /dev/null +++ b/source/compiler/tests/__emit_p3.meta @@ -0,0 +1,23 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p3.pwn(17) : error 001: expected token: "-function-", but found "-numeric value-" +__emit_p3.pwn(18) : error 001: expected token: "-function-", but found "-data offset-" +__emit_p3.pwn(19) : error 001: expected token: "-function-", but found "-reference-" +__emit_p3.pwn(20) : error 001: expected token: "-function-", but found "-reference-" +__emit_p3.pwn(21) : error 001: expected token: "-function-", but found "-numeric value-" +__emit_p3.pwn(22) : error 001: expected token: "-function-", but found "-local variable-" +__emit_p3.pwn(23) : error 001: expected token: "-function-", but found "-data offset-" +__emit_p3.pwn(24) : error 001: expected token: "-function-", but found "-label-" +__emit_p3.pwn(25) : error 001: expected token: "-function-", but found "-integer value-" +__emit_p3.pwn(26) : error 001: expected token: "-native function-", but found "-numeric value-" +__emit_p3.pwn(27) : error 001: expected token: "-native function-", but found "-data offset-" +__emit_p3.pwn(28) : error 001: expected token: "-native function-", but found "-reference-" +__emit_p3.pwn(29) : error 001: expected token: "-native function-", but found "-reference-" +__emit_p3.pwn(30) : error 001: expected token: "-native function-", but found "-numeric value-" +__emit_p3.pwn(31) : error 001: expected token: "-native function-", but found "-local variable-" +__emit_p3.pwn(32) : error 001: expected token: "-native function-", but found "-data offset-" +__emit_p3.pwn(33) : error 001: expected token: "-native function-", but found "-label-" +__emit_p3.pwn(34) : error 001: expected token: "-native function-", but found "-integer value-" + """ +} diff --git a/source/compiler/tests/__emit_p3.pwn b/source/compiler/tests/__emit_p3.pwn new file mode 100644 index 0000000..d21dc26 --- /dev/null +++ b/source/compiler/tests/__emit_p3.pwn @@ -0,0 +1,42 @@ +#include "__emit.inc" + + +stock test__function(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit call global_func; + emit sysreq.c global_native; + emit sysreq.n global_native 0; + + // should trigger an error + emit call global_const; + emit call global_var; + emit call local_refvar; + emit call local_refarray; + emit call local_const; + emit call local_var; + emit call local_static_var; + emit call local_label; + emit call 0; + emit sysreq.c global_const; + emit sysreq.c global_var; + emit sysreq.c local_refvar; + emit sysreq.c local_refarray; + emit sysreq.c local_const; + emit sysreq.c local_var; + emit sysreq.c local_static_var; + emit sysreq.c local_label; + emit sysreq.c 0; +} + + +main() +{ + new t, a[1]; + test__function(t, a); // 18 +} diff --git a/source/compiler/tests/__emit_p4.meta b/source/compiler/tests/__emit_p4.meta new file mode 100644 index 0000000..35a7951 --- /dev/null +++ b/source/compiler/tests/__emit_p4.meta @@ -0,0 +1,25 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p4.pwn(16) : error 001: expected token: "-data offset-", but found "-numeric value-" +__emit_p4.pwn(17) : error 001: expected token: "-data offset-", but found "-function-" +__emit_p4.pwn(18) : error 001: expected token: "-data offset-", but found "-reference-" +__emit_p4.pwn(19) : error 001: expected token: "-data offset-", but found "-reference-" +__emit_p4.pwn(20) : error 001: expected token: "-data offset-", but found "-numeric value-" +__emit_p4.pwn(21) : error 001: expected token: "-data offset-", but found "-local variable-" +__emit_p4.pwn(22) : error 001: expected token: "-data offset-", but found "-label-" +__emit_p4.pwn(23) : error 001: expected token: "-data offset-", but found "-integer value-" +__emit_p4.pwn(48) : error 001: expected token: "-local variable-", but found "-data offset-" +__emit_p4.pwn(49) : error 001: expected token: "-local variable-", but found "-function-" +__emit_p4.pwn(50) : error 001: expected token: "-local variable-", but found "-data offset-" +__emit_p4.pwn(51) : error 001: expected token: "-local variable-", but found "-label-" +__emit_p4.pwn(52) : error 001: expected token: "-local variable-", but found "-reference-" +__emit_p4.pwn(53) : error 001: expected token: "-local variable-", but found "-reference-" +__emit_p4.pwn(54) : error 001: expected token: "-local variable-", but found "-(-data offset-)" +__emit_p4.pwn(55) : error 001: expected token: "-local variable-", but found "-(-function-)" +__emit_p4.pwn(56) : error 001: expected token: "-local variable-", but found "-(-data offset-)" +__emit_p4.pwn(57) : error 001: expected token: "-local variable-", but found "-(-label-)" +__emit_p4.pwn(58) : error 001: expected token: "-local variable-", but found "-(-reference-)" +__emit_p4.pwn(59) : error 001: expected token: "-local variable-", but found "-(-reference-)" + """ +} diff --git a/source/compiler/tests/__emit_p4.pwn b/source/compiler/tests/__emit_p4.pwn new file mode 100644 index 0000000..8658722 --- /dev/null +++ b/source/compiler/tests/__emit_p4.pwn @@ -0,0 +1,68 @@ +#include "__emit.inc" + + +stock test__data_offset(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit load.pri global_var; + emit load.pri local_static_var; + + // should trigger an error + emit load.pri global_const; + emit load.pri global_func; + emit load.pri local_refvar; + emit load.pri local_refarray; + emit load.pri local_const; + emit load.pri local_var; + emit load.pri local_label; + emit load.pri 0; +} + +stock test__local_var(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit load.s.pri global_const; + emit load.s.pri local_refvar; + emit load.s.pri local_refarray; + emit load.s.pri local_const; + emit load.s.pri local_var; + emit load.s.pri 20; + emit load.s.pri -20; + emit stor.s.pri global_const; + emit stor.s.pri local_const; + emit stor.s.pri local_var; + emit stor.s.pri 20; + emit stor.s.pri -20; + + // should trigger an error + emit load.s.pri global_var; + emit load.s.pri global_func; + emit load.s.pri local_static_var; + emit load.s.pri local_label; + emit stor.s.pri local_refvar; + emit stor.s.pri local_refarray; + emit load.s.pri -global_var; + emit load.s.pri -global_func; + emit load.s.pri -local_static_var; + emit load.s.pri -local_label; + emit stor.s.pri -local_refvar; + emit stor.s.pri -local_refarray; +} + + +main() +{ + new t, a[1]; + test__data_offset(t, a); // 8 + test__local_var(t, a); // 6 +} diff --git a/source/compiler/tests/__emit_p5.meta b/source/compiler/tests/__emit_p5.meta new file mode 100644 index 0000000..6652ac2 --- /dev/null +++ b/source/compiler/tests/__emit_p5.meta @@ -0,0 +1,29 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p5.pwn(25) : error 050: invalid range +__emit_p5.pwn(26) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p5.pwn(27) : error 001: expected token: "-integer value-", but found "-function-" +__emit_p5.pwn(28) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p5.pwn(29) : error 050: invalid range +__emit_p5.pwn(30) : error 001: expected token: "-integer value-", but found "-local variable-" +__emit_p5.pwn(31) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p5.pwn(32) : error 001: expected token: "-integer value-", but found "-label-" +__emit_p5.pwn(33) : error 050: invalid range +__emit_p5.pwn(34) : error 050: invalid range +__emit_p5.pwn(35) : error 050: invalid range +__emit_p5.pwn(36) : error 050: invalid range +__emit_p5.pwn(37) : error 050: invalid range +__emit_p5.pwn(38) : error 050: invalid range +__emit_p5.pwn(61) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p5.pwn(62) : error 001: expected token: "-integer value-", but found "-function-" +__emit_p5.pwn(63) : error 001: expected token: "-integer value-", but found "-reference-" +__emit_p5.pwn(64) : error 001: expected token: "-integer value-", but found "-local variable-" +__emit_p5.pwn(65) : error 001: expected token: "-integer value-", but found "-data offset-" +__emit_p5.pwn(66) : error 001: expected token: "-integer value-", but found "-label-" +__emit_p5.pwn(67) : error 050: invalid range +__emit_p5.pwn(68) : error 050: invalid range +__emit_p5.pwn(69) : error 050: invalid range +__emit_p5.pwn(70) : error 050: invalid range +""" +} diff --git a/source/compiler/tests/__emit_p5.pwn b/source/compiler/tests/__emit_p5.pwn new file mode 100644 index 0000000..a6e525a --- /dev/null +++ b/source/compiler/tests/__emit_p5.pwn @@ -0,0 +1,79 @@ +#include "__emit.inc" + +const global_const_1 = 1; + + +stock test__op_lodb_strb(&local_refvar) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + const local_const_1 = 0x1; + + // ok + emit lodb.i 1; + emit lodb.i 2; + emit lodb.i 4; + emit lodb.i 0x1; + emit lodb.i 0x2; + emit lodb.i 0x4; + emit lodb.i global_const_1; + emit lodb.i local_const_1; + + // should trigger an error + emit lodb.i global_const; + emit lodb.i global_var; + emit lodb.i global_func; + emit lodb.i local_refvar; + emit lodb.i local_const; + emit lodb.i local_var; + emit lodb.i local_static_var; + emit lodb.i local_label; + emit lodb.i -1; + emit lodb.i 3; + emit lodb.i 5; + emit lodb.i -0x1; + emit lodb.i 0x3; + emit lodb.i 0x5; +} + +stock test__op_align(&local_refvar) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; +local_label: + + // ok + emit align.pri global_const; + emit align.pri local_const; + emit align.pri 0; + emit align.pri 1; + emit align.pri 2; + emit align.pri 3; + emit align.pri 0x0; + emit align.pri 0x1; + emit align.pri 0x2; + emit align.pri 0x3; + + // should trigger an error + emit align.pri global_var; + emit align.pri global_func; + emit align.pri local_refvar; + emit align.pri local_var; + emit align.pri local_static_var; + emit align.pri local_label; + emit align.pri -1; + emit align.pri 4; + emit align.pri -0x1; + emit align.pri 0x4; +} + + +main() +{ + new t; + test__op_lodb_strb(t); // 14 + test__op_align(t); // 10 +} diff --git a/source/compiler/tests/__emit_p6.meta b/source/compiler/tests/__emit_p6.meta new file mode 100644 index 0000000..d747d6d --- /dev/null +++ b/source/compiler/tests/__emit_p6.meta @@ -0,0 +1,25 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p6.pwn(23) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(24) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(25) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(26) : error 033: array must be indexed (variable "local_refarray") +__emit_p6.pwn(45) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(46) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(47) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(48) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(49) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(50) : error 033: array must be indexed (variable "local_refarray") +__emit_p6.pwn(69) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(70) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(71) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(72) : error 022: must be lvalue (non-constant) +__emit_p6.pwn(73) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(74) : error 033: array must be indexed (variable "local_refarray") +__emit_p6.pwn(96) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(97) : error 076: syntax error in the expression, or invalid function call +__emit_p6.pwn(98) : error 033: array must be indexed (variable "local_array") +__emit_p6.pwn(99) : error 033: array must be indexed (variable "local_refarray") +""" +} diff --git a/source/compiler/tests/__emit_p6.pwn b/source/compiler/tests/__emit_p6.pwn new file mode 100644 index 0000000..0e9a543 --- /dev/null +++ b/source/compiler/tests/__emit_p6.pwn @@ -0,0 +1,110 @@ +#include "__emit.inc" + + +stock test__op_load_u_pri_alt(&local_refvar, const local_refarray[]) +{ + const local_const = 1; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit load.u.pri global_const; + emit load.u.pri global_var; + emit load.u.pri local_const; + emit load.u.pri local_var; + emit load.u.pri local_static_var; + emit load.u.pri local_refvar; + emit load.u.pri global_const + local_const; + emit load.u.pri global_var * local_var; + emit load.u.pri local_refarray[0]; + + // should trigger an error + emit load.u.pri global_func; + emit load.u.pri global_native; + emit load.u.pri local_array; + emit load.u.pri local_refarray; +} + +stock test__op_stor_u_pri_alt(&local_refvar, local_refarray[]) +{ + const local_const = 1; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit stor.u.pri global_var; + emit stor.u.pri local_var; + emit stor.u.pri local_static_var; + emit stor.u.pri local_refvar; + emit stor.u.pri local_array[1]; + emit stor.u.pri local_refarray[local_const]; + + // should trigger an error + emit stor.u.pri global_const; + emit stor.u.pri global_func; + emit stor.u.pri global_native; + emit stor.u.pri local_const; + emit stor.u.pri local_array; + emit stor.u.pri local_refarray; +} + +stock test__op_addr_u_pri_alt(&local_refvar, local_refarray[]) +{ + const local_const = 1; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit addr.u.pri global_var; + emit addr.u.pri local_var; + emit addr.u.pri local_static_var; + emit addr.u.pri local_refvar; + emit addr.u.pri local_array[1]; + emit addr.u.pri local_refarray[local_const]; + + // should trigger an error + emit addr.u.pri global_const; + emit addr.u.pri global_func; + emit addr.u.pri global_native; + emit addr.u.pri local_const; + emit addr.u.pri local_array; + emit addr.u.pri local_refarray; +} + +stock test__push_u(&local_refvar, local_refarray[]) +{ + const local_const = 1; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit push.u global_const; + emit push.u global_var; + emit push.u local_refvar; + emit push.u local_const; + emit push.u local_var; + emit push.u local_static_var; + emit push.u (global_const + local_const); + emit push.u (global_var * local_var + local_static_var + local_refvar); + emit push.u local_refarray[0]; + + // should trigger an error + emit push.u global_func; + emit push.u global_native; + emit push.u local_array; + emit push.u local_refarray; +} + + +main() +{ + new t, a[2]; + test__op_load_u_pri_alt(t, a); // 4 + test__op_stor_u_pri_alt(t, a); // 6 + test__op_addr_u_pri_alt(t, a); // 6 + test__push_u(t, a); // 4 +} diff --git a/source/compiler/tests/__emit_p7.meta b/source/compiler/tests/__emit_p7.meta new file mode 100644 index 0000000..e32da8a --- /dev/null +++ b/source/compiler/tests/__emit_p7.meta @@ -0,0 +1,25 @@ +{ + 'test_type': 'output_check', + 'errors': """ +__emit_p7.pwn(20) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(21) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(22) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(23) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(24) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(25) : error 033: array must be indexed (variable "local_refarray") +__emit_p7.pwn(26) : error 035: argument type mismatch (argument 1) +__emit_p7.pwn(27) : error 035: argument type mismatch (argument 1) +__emit_p7.pwn(46) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(47) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(48) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(49) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(50) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(51) : error 033: array must be indexed (variable "local_refarray") +__emit_p7.pwn(70) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(71) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(72) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(73) : error 022: must be lvalue (non-constant) +__emit_p7.pwn(74) : error 033: array must be indexed (variable "local_array") +__emit_p7.pwn(75) : error 033: array must be indexed (variable "local_refarray") +""" +} diff --git a/source/compiler/tests/__emit_p7.pwn b/source/compiler/tests/__emit_p7.pwn new file mode 100644 index 0000000..65e7773 --- /dev/null +++ b/source/compiler/tests/__emit_p7.pwn @@ -0,0 +1,85 @@ +#include "__emit.inc" + + +stock test__push_u_adr(&local_refvar, local_refarray[]) +{ + const local_const = 1; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit push.u.adr global_var; + emit push.u.adr local_refvar; + emit push.u.adr local_var; + emit push.u.adr local_static_var; + emit push.u.adr local_array[1]; + emit push.u.adr local_refarray[local_const]; + + // should trigger an error + emit push.u.adr global_const; + emit push.u.adr global_func; + emit push.u.adr global_native; + emit push.u.adr local_const; + emit push.u.adr local_array; + emit push.u.adr local_refarray; + emit push.u.adr local_array{1}; + emit push.u.adr local_array{local_var}; +} + +stock test__zero_u(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit zero.u global_var; + emit zero.u local_refvar; + emit zero.u local_var; + emit zero.u local_static_var; + emit zero.u local_array[1]; + emit zero.u local_refarray[local_const]; + + // should trigger an error + emit zero.u global_const; + emit zero.u global_func; + emit zero.u global_native; + emit zero.u local_const; + emit zero.u local_array; + emit zero.u local_refarray; +} + +stock test__inc_dec_u(&local_refvar, local_refarray[]) +{ + const local_const = 0; + new local_var = 0; + static local_static_var = 0; + new local_array[2]; + + // ok + emit inc.u global_var; + emit inc.u local_refvar; + emit inc.u local_var; + emit inc.u local_static_var; + emit inc.u local_array[1]; + emit inc.u local_refarray[local_const]; + + // should trigger an error + emit inc.u global_const; + emit inc.u global_func; + emit inc.u global_native; + emit inc.u local_const; + emit inc.u local_array; + emit inc.u local_refarray; +} + + +main() +{ + new t, a[2]; + test__push_u_adr(t, a); // 8 + test__zero_u(t, a); // 6 + test__inc_dec_u(t, a); // 6 +} diff --git a/source/compiler/tests/__emit_pcode_check.meta b/source/compiler/tests/__emit_pcode_check.meta new file mode 100644 index 0000000..3c1fd70 --- /dev/null +++ b/source/compiler/tests/__emit_pcode_check.meta @@ -0,0 +1,702 @@ +{ + 'test_type': 'pcode_check', + 'code_pattern': r""" +[0-9a-f]+ push.r 00000000 +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ load.pri 00000004 +[0-9a-f]+ load.pri 0000000c +[0-9a-f]+ push.r 00000001 +[0-9a-f]+ load.s.pri 00001234 +[0-9a-f]+ load.s.pri 0000000c +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ load.s.pri 00005678 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.pri 0000fedc +[0-9a-f]+ push.r 00000002 +[0-9a-f]+ call [0-9a-f]+ +[0-9a-f]+ sysreq.c 00000000 +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ sysreq.c 00000000 +[0-9a-f]+ stack 00000004 +[0-9a-f]+ push.r 00000003 +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ lodb.i 00000002 +[0-9a-f]+ lodb.i 00000004 +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ lodb.i 00000002 +[0-9a-f]+ lodb.i 00000004 +[0-9a-f]+ push.r 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ align.pri 00000000 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ align.pri 00000002 +[0-9a-f]+ align.pri 00000003 +[0-9a-f]+ align.pri 00000000 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ align.pri 00000002 +[0-9a-f]+ align.pri 00000003 +[0-9a-f]+ push.r 00000005 +[0-9a-f]+ push.c 00001234 +[0-9a-f]+ push.c 00005678 +[0-9a-f]+ push.c 00009abc +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ push.c 00000004 +[0-9a-f]+ push.c 0000000c +[0-9a-f]+ push.c 0000000c +[0-9a-f]+ push.c fffffffc +[0-9a-f]+ push.r 00000006 +[0-9a-f]+ push 00000000 +[0-9a-f]+ push 0000000c +[0-9a-f]+ push.r 00000007 +[0-9a-f]+ push.s 00001234 +[0-9a-f]+ push.s 00005678 +[0-9a-f]+ push.s 0000000c +[0-9a-f]+ push.s 00000010 +[0-9a-f]+ push.s fffffffc +[0-9a-f]+ push.r 00000008 +[0-9a-f]+ push.adr 00001234 +[0-9a-f]+ push.adr 00005678 +[0-9a-f]+ push.adr 0000000c +[0-9a-f]+ push.adr 00000010 +[0-9a-f]+ push.adr fffffffc +[0-9a-f]+ push.r 00000009 +[0-9a-f]+ push.pri +[0-9a-f]+ const.pri 00001234 +[0-9a-f]+ stor.pri 00000000 +[0-9a-f]+ pop.pri +[0-9a-f]+ push.pri +[0-9a-f]+ const.pri 00005678 +[0-9a-f]+ stor.pri 0000000c +[0-9a-f]+ pop.pri +[0-9a-f]+ push.r 0000000a +[0-9a-f]+ push.pri +[0-9a-f]+ const.pri 00005678 +[0-9a-f]+ stor.s.pri fffffffc +[0-9a-f]+ pop.pri +[0-9a-f]+ push.r 0000000b +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ load.alt 0000000c +[0-9a-f]+ push.r 0000000c +[0-9a-f]+ load.s.pri 0000000c +[0-9a-f]+ load.s.alt fffffffc +[0-9a-f]+ push.r 00000010 +[0-9a-f]+ zero.pri +[0-9a-f]+ zero.alt +[0-9a-f]+ load.s.pri 0000000c +[0-9a-f]+ load.s.alt 0000000c +[0-9a-f]+ addr.pri fffffffc +[0-9a-f]+ addr.alt fffffffc +[0-9a-f]+ const.pri 0000000c +[0-9a-f]+ const.alt 0000000c +[0-9a-f]+ push.r 00000011 +[0-9a-f]+ const.pri 00000004 +[0-9a-f]+ const.alt 00000008 +[0-9a-f]+ const.pri 00000010 +[0-9a-f]+ const.alt 00000014 +[0-9a-f]+ addr.pri fffffff4 +[0-9a-f]+ addr.alt fffffff8 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 00000012 +[0-9a-f]+ const.pri 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ const.alt 00000005 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ const.pri 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ const.alt 00000011 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ addr.pri fffffff4 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ addr.alt fffffff5 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ push.r 00000013 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ inc.pri +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ inc.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ move.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ push.r 00000014 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 00000015 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 00000016 +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ call [0-9a-f]+ +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ call [0-9a-f]+ +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 00000017 +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ call [0-9a-f]+ +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ call [0-9a-f]+ +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 00000018 +[0-9a-f]+ const.pri 00001234 +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ lref.s.pri 0000000c +[0-9a-f]+ const.pri 00005678 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.pri 0000000c +[0-9a-f]+ const.pri 00009abc +[0-9a-f]+ push.r 00000019 +[0-9a-f]+ const.pri 000068ac +[0-9a-f]+ push.r 0000001a +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ pop.alt +[0-9a-f]+ smul +[0-9a-f]+ move.alt +[0-9a-f]+ push.r 0000001b +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ load.i +[0-9a-f]+ push.r 00000020 +[0-9a-f]+ stor.pri 00000000 +[0-9a-f]+ stor.alt 00000000 +[0-9a-f]+ sref.s.pri 0000000c +[0-9a-f]+ sref.s.alt 0000000c +[0-9a-f]+ stor.s.pri fffffffc +[0-9a-f]+ stor.s.alt fffffffc +[0-9a-f]+ stor.pri 0000000c +[0-9a-f]+ stor.alt 0000000c +[0-9a-f]+ push.r 00000021 +[0-9a-f]+ stor.pri 00000004 +[0-9a-f]+ stor.alt 00000008 +[0-9a-f]+ stor.s.pri fffffff4 +[0-9a-f]+ stor.s.alt fffffff8 +[0-9a-f]+ sref.s.pri 00000010 +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ xchg +[0-9a-f]+ stor.i +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ xchg +[0-9a-f]+ stor.i +[0-9a-f]+ push.r 00000022 +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.alt 00000005 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ const.alt 00000005 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000023 +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ addr.alt fffffff5 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ addr.alt fffffff5 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000024 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ inc.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.pri +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ inc.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ xchg +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ xchg +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000025 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.r 00000026 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.alt +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ pop.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000028 +[0-9a-f]+ push.c 00001234 +[0-9a-f]+ push 00000000 +[0-9a-f]+ lref.s.pri 0000000c +[0-9a-f]+ push.pri +[0-9a-f]+ push.c 00005678 +[0-9a-f]+ push.s fffffffc +[0-9a-f]+ push 0000000c +[0-9a-f]+ push.c 00009abc +[0-9a-f]+ push.r 00000029 +[0-9a-f]+ push.c 000068ac +[0-9a-f]+ push.r 0000002a +[0-9a-f]+ load.pri 00000000 +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ pop.alt +[0-9a-f]+ smul +[0-9a-f]+ push.pri +[0-9a-f]+ push.r 0000002b +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ load.i +[0-9a-f]+ push.pri +[0-9a-f]+ push.r 00000030 +[0-9a-f]+ push.c 00000000 +[0-9a-f]+ push.c 0000000c +[0-9a-f]+ push.adr fffffffc +[0-9a-f]+ push.s 0000000c +[0-9a-f]+ push.r 00000031 +[0-9a-f]+ push.c 00000004 +[0-9a-f]+ push.c 00000008 +[0-9a-f]+ push.c 00000010 +[0-9a-f]+ push.c 00000014 +[0-9a-f]+ push.adr fffffff4 +[0-9a-f]+ push.adr fffffff8 +[0-9a-f]+ push.s 00000010 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ push.pri +[0-9a-f]+ push.r 00000032 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ push.pri +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ push.pri +[0-9a-f]+ push.r 00000038 +[0-9a-f]+ zero 00000000 +[0-9a-f]+ zero 0000000c +[0-9a-f]+ zero.s fffffffc +[0-9a-f]+ zero.pri +[0-9a-f]+ sref.s.pri 0000000c +[0-9a-f]+ push.r 00000039 +[0-9a-f]+ zero 00000004 +[0-9a-f]+ zero 00000008 +[0-9a-f]+ zero 00000010 +[0-9a-f]+ zero 00000014 +[0-9a-f]+ zero.s fffffff4 +[0-9a-f]+ zero.s fffffff8 +[0-9a-f]+ zero.pri +[0-9a-f]+ sref.s.pri 00000010 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.r 0000003a +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.alt 00000005 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.alt 00000011 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ addr.alt fffffff5 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ inc.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ move.alt +[0-9a-f]+ align.alt 00000001 +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 0000003b +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ stor.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ stor.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ stor.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ stor.i +[0-9a-f]+ push.r 0000003c +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ zero.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000040 +[0-9a-f]+ inc 00000000 +[0-9a-f]+ inc 0000000c +[0-9a-f]+ inc.s fffffffc +[0-9a-f]+ load.s.pri 0000000c +[0-9a-f]+ inc.i +[0-9a-f]+ push.r 00000041 +[0-9a-f]+ inc 00000004 +[0-9a-f]+ inc 00000008 +[0-9a-f]+ inc 00000010 +[0-9a-f]+ inc 00000014 +[0-9a-f]+ inc.s fffffff4 +[0-9a-f]+ inc.s fffffff8 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ inc.i +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ inc.i +[0-9a-f]+ push.r 00000042 +[0-9a-f]+ const.pri 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.pri 00000005 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.pri 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ const.pri 00000011 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ addr.pri fffffff4 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ addr.pri fffffff5 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ inc.pri +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri 00000010 +[0-9a-f]+ add.c 00000002 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ push.r 00000043 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000004 +[0-9a-f]+ idxaddr +[0-9a-f]+ inc.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ const.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ inc.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ idxaddr +[0-9a-f]+ inc.i +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ idxaddr +[0-9a-f]+ inc.i +[0-9a-f]+ push.r 00000044 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000004 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ add.c 00000010 +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ addr.alt fffffff4 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ load.s.pri fffffffc +[0-9a-f]+ load.s.alt 00000010 +[0-9a-f]+ add +[0-9a-f]+ align.pri 00000001 +[0-9a-f]+ move.alt +[0-9a-f]+ lodb.i 00000001 +[0-9a-f]+ inc.pri +[0-9a-f]+ strb.i 00000001 +[0-9a-f]+ nop +""" +} diff --git a/source/compiler/tests/__emit_pcode_check.pwn b/source/compiler/tests/__emit_pcode_check.pwn new file mode 100644 index 0000000..c7cf333 --- /dev/null +++ b/source/compiler/tests/__emit_pcode_check.pwn @@ -0,0 +1,345 @@ +#include "__emit.inc" + +// Use 'push.r' as a delimiter since the compiler doesn't generate this instruction +// and its argument might be used to identify the snippet in the disassembly. +#define DEF_SNIPPET(%0) emit push.r (%0) + +const global_const_1 = 1; +const global_const_1234 = 0x1234; + + +stock test__pcode(&local_refvar, local_refarray[]) +{ + const local_const_1 = 1; + const local_const_5678 = 0x5678; + static local_static_var = 0; + static local_static_array[2]; + new local_var = 0; + new local_array[2]; + + DEF_SNIPPET(0x0); + emit load.pri global_var; // load.pri 00000000 + emit load.pri global_array; // load.pri 00000004 + emit load.pri local_static_var; // load.pri 0000000c + + DEF_SNIPPET(0x1); + emit load.s.pri global_const_1234; // load.s.pri 00001234 + emit load.s.pri local_refvar; // load.s.pri 0000000c + emit load.s.pri local_refarray; // load.s.pri 00000010 + emit load.s.pri local_const_5678; // load.s.pri 00005678 + emit load.s.pri local_var; // load.s.pri fffffffc + emit load.s.pri 0xFEDC; // load.s.pri 0000fedc + + DEF_SNIPPET(0x2); + emit call global_func; // call 00000008 + emit sysreq.c global_native; // sysreq.c 00000000 + emit sysreq.n global_native 0; // push.c 00000000 \ sysreq.c 00000000 \ stack 00000004 + + DEF_SNIPPET(0x3); + emit lodb.i global_const_1; // lodb.i 00000001 + emit lodb.i local_const_1; // lodb.i 00000001 + emit lodb.i 1; // lodb.i 00000001 + emit lodb.i 2; // lodb.i 00000002 + emit lodb.i 4; // lodb.i 00000004 + emit lodb.i 0x1; // lodb.i 00000001 + emit lodb.i 0x2; // lodb.i 00000002 + emit lodb.i 0x4; // lodb.i 00000004 + + DEF_SNIPPET(0x4); + emit align.pri global_const_1; // align.pri 00000001 + emit align.pri local_const_1; // align.pri 00000001 + emit align.pri 0; // align.pri 00000000 + emit align.pri 1; // align.pri 00000001 + emit align.pri 2; // align.pri 00000002 + emit align.pri 3; // align.pri 00000003 + emit align.pri 0x0; // align.pri 00000000 + emit align.pri 0x1; // align.pri 00000001 + emit align.pri 0x2; // align.pri 00000002 + emit align.pri 0x3; // align.pri 00000003 + + DEF_SNIPPET(0x5); + // push.c 00001234 \ push.c 00005678 \ push.c 00009abc + emit push3.c global_const_1234 local_const_5678 0x9ABC; + // push.c push.c 00000000 \ push.c 00000004 \ push.c 0000000c \ push.c 0000000c \ push.c fffffffc + emit push5.c global_var global_array local_static_var local_refvar local_var; + + DEF_SNIPPET(0x6); + // push 00000000 \ push 0000000c + emit push2 global_var local_static_var; + + DEF_SNIPPET(0x7); + // push.s 00001234 \ push.s 00005678 \ push.s 0000000c \ push.s 00000010 \ push.s fffffffc + emit push5.s global_const_1234 local_const_5678 local_refvar local_refarray local_var; + + DEF_SNIPPET(0x8); + // push.adr 00001234 \ push.adr 00005678 \ push.adr 0000000c \ push.adr 00000010 \ push.adr fffffffc + emit push5.adr global_const_1234 local_const_5678 local_refvar local_refarray local_var; + + DEF_SNIPPET(0x9); + // push.pri \ const.pri 00001234 \ stor.pri 00000000 \ pop.pri + emit const global_var global_const_1234; + // push.pri \ const.pri 00005678 \ stor.pri 0000000c \ pop.pri + emit const local_static_var local_const_5678; + + DEF_SNIPPET(0xa); + // push.pri \ const.pri 00005678 \ stor.s.pri fffffffc \ pop.pri + emit const.s local_var local_const_5678; + + DEF_SNIPPET(0xb); + // load.pri 00000000 \ load.alt 0000000c + emit load.both global_var local_static_var; + + DEF_SNIPPET(0xc); + // load.pri 0000000c \ load.alt fffffffc + emit load.s.both local_refvar local_var; + + DEF_SNIPPET(0x10); + emit addr.u.pri global_var; // zero.pri + emit addr.u.alt global_var; // zero.alt + emit addr.u.pri local_refvar; // load.s.pri 0000000c + emit addr.u.alt local_refvar; // load.s.alt 0000000c + emit addr.u.pri local_var; // addr.pri fffffffc + emit addr.u.alt local_var; // addr.alt fffffffc + emit addr.u.pri local_static_var; // const.pri 0000000c + emit addr.u.alt local_static_var; // const.alt 0000000c + DEF_SNIPPET(0x11); + emit addr.u.pri global_array[0]; // const.pri 00000004 + emit addr.u.alt global_array[1]; // const.alt 00000008 + emit addr.u.pri local_static_array[0]; // const.pri 00000010 + emit addr.u.alt local_static_array[1]; // const.alt 00000014 + emit addr.u.pri local_array[0]; // addr.pri fffffff4 + emit addr.u.alt local_array[1]; // addr.alt fffffff8 + emit addr.u.pri local_refarray[0]; // load.s.pri 00000010 + emit addr.u.alt local_refarray[1]; // load.s.alt 00000014 + DEF_SNIPPET(0x12); + emit addr.u.pri global_array{0}; // const.pri 00000004 \ align.pri 00000001 + emit addr.u.alt global_array{1}; // const.alt 00000005 \ align.alt 00000001 + emit addr.u.pri local_static_array{0}; // const.pri 00000010 \ align.pri 00000001 + emit addr.u.alt local_static_array{1}; // const.alt 00000011 \ align.alt 00000001 + emit addr.u.pri local_array{0}; // addr.pri fffffff4 \ align.pri 00000001 + emit addr.u.alt local_array{1}; // addr.alt fffffff5 \ align.alt 00000001 + DEF_SNIPPET(0x13); + emit addr.u.pri local_refarray{0}; // load.s.pri 00000010 \ align.pri 00000001 + emit addr.u.alt local_refarray{0}; // load.s.alt 00000010 \ align.alt 00000001 + emit addr.u.pri local_refarray{1}; // load.s.pri fffffff4 \ inc.pri \ align.pri 00000001 + emit addr.u.alt local_refarray{1}; // load.s.alt fffffff4 \ inc.alt \ align.alt 00000001 + emit addr.u.pri local_refarray{2}; // load.s.pri fffffff5 \ add.c 00000002 \ align.pri 00000001 + emit addr.u.alt local_refarray{2}; // load.s.pri fffffff5 \ add.c 00000002 \ move.alt \ align.alt 00000001 + DEF_SNIPPET(0x14); + emit addr.u.pri global_array[local_var]; // load.s.pri fffffffc \ const.alt 00000004 \ idxaddr + emit addr.u.alt global_array[local_var]; // load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ move.alt + emit addr.u.pri local_static_array[local_var]; // load.s.pri fffffffc \ const.alt 00000010 \ idxaddr + emit addr.u.alt local_static_array[local_var]; // load.s.pri fffffffc \ const.alt 00000010 \ idxaddr \ move.alt + emit addr.u.pri local_array[local_var]; // load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr + emit addr.u.alt local_array[local_var]; // load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ move.alt + emit addr.u.pri local_refarray[local_var]; // load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr + emit addr.u.alt local_refarray[local_var]; // load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ move.alt + DEF_SNIPPET(0x15); + emit addr.u.pri global_array{local_var}; // load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 + emit addr.u.alt global_array{local_var}; // load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ move.alt + emit addr.u.pri local_static_array{local_var}; // load.s.pri fffffffc \ add.c 00000010 \ align.pri 00000001 + emit addr.u.alt local_static_array{local_var}; // load.s.pri fffffffc \ add.c 00000010 \ align.pri 00000001 \ move.alt + emit addr.u.pri local_array{local_var}; // load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 + emit addr.u.alt local_array{local_var}; // load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ move.alt + emit addr.u.pri local_refarray{local_var}; // load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 + emit addr.u.alt local_refarray{local_var}; // load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ move.alt + DEF_SNIPPET(0x16); + emit addr.u.pri global_array[global_func()]; // push.c 0 \ call global_func \ const.alt 00000004 \ idxaddr + emit addr.u.alt global_array[global_func()]; // push.c 0 \ call global_func \ const.alt 00000004 \ idxaddr \ move.alt + DEF_SNIPPET(0x17); + emit addr.u.pri global_array{global_func()}; // push.c 0 \ call global_func \ add.c 00000004 \ align.pri 00000001 + emit addr.u.alt global_array{global_func()}; // push.c 0 \ call global_func \ add.c 00000004 \ align.pri 00000001 \ move.alt + + DEF_SNIPPET(0x18); + emit load.u.pri global_const_1234; // const.pri 00001234 + emit load.u.pri global_var; // load.pri 00000000 + emit load.u.pri local_refvar; // lref.s.pri 0000000c + emit load.u.pri local_const_5678; // const.pri 00005678 + emit load.u.pri local_var; // load.s.pri fffffffc + emit load.u.pri local_static_var; // load.pri 0000000c + emit load.u.pri 0x9abc; // const.pri 00009abc + DEF_SNIPPET(0x19); + emit load.u.pri global_const_1234 + local_const_5678; // const.pri 000068ac + DEF_SNIPPET(0x1a); + emit load.u.alt global_var * local_var; // load.pri 00000000 \ push.pri \ load.s.pri fffffffc \ pop.alt \ smul \ move.alt + DEF_SNIPPET(0x1b); + emit load.u.pri local_refarray[0]; // load.s.pri 00000010 \ load.i + + DEF_SNIPPET(0x20); + emit stor.u.pri global_var; // stor.pri 00000000 + emit stor.u.alt global_var; // stor.alt 00000000 + emit stor.u.pri local_refvar; // sref.s.pri 0000000c + emit stor.u.alt local_refvar; // sref.s.alt 0000000c + emit stor.u.pri local_var; // stor.s.pri fffffffc + emit stor.u.alt local_var; // stor.s.alt fffffffc + emit stor.u.pri local_static_var; // stor.pri 0000000c + emit stor.u.alt local_static_var; // stor.alt 0000000c + DEF_SNIPPET(0x21); + emit stor.u.pri global_array[0]; // stor.pri 00000004 + emit stor.u.alt global_array[1]; // stor.alt 00000008 + emit stor.u.pri local_array[0]; // stor.s.pri fffffff4 + emit stor.u.alt local_array[1]; // stor.s.alt fffffff8 + emit stor.u.pri local_refarray[0]; // sref.s.pri 00000010 + emit stor.u.pri local_refarray[1]; // move.alt \ load.s.pri 00000010 \ add.c 00000004 \ xchg \ stor.i + emit stor.u.alt local_refarray[1]; // load.s.pri 00000010 \ add.c 00000004 \ xchg \ stor.i + DEF_SNIPPET(0x22); + emit stor.u.pri global_array{0}; // const.alt 00000004 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt global_array{0}; // move.pri \ const.alt 00000004 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.pri global_array{1}; // const.alt 00000005 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt global_array{1}; // move.pri \ const.alt 00000005 \ align.alt 00000001 \ strb.i 00000001 + DEF_SNIPPET(0x23); + emit stor.u.pri local_array{0}; // addr.alt fffffff4 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt local_array{0}; // move.pri \ addr.alt fffffff4 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.pri local_array{1}; // addr.alt fffffff5 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt local_array{1}; // move.pri \ addr.alt fffffff5 \ align.alt 00000001 \ strb.i 00000001 + DEF_SNIPPET(0x24); + emit stor.u.pri local_refarray{0}; // load.s.alt 00000010 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt local_refarray{0}; // move.pri \ load.s.alt 00000010 \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.pri local_refarray{1}; // load.s.alt 00000010 \ inc.alt \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt local_refarray{1}; // move.pri \ load.s.alt 00000010 \ inc.alt \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.pri local_refarray{2}; // move.alt \ load.s.pri 00000010 \ add.c 00000002 \ xchg \ align.alt 00000001 \ strb.i 00000001 + emit stor.u.alt local_refarray{2}; // load.s.pri 00000010 \ add.c 00000002 \ xchg \ align.alt 00000001 \ strb.i 00000001 + DEF_SNIPPET(0x25); + emit stor.u.pri global_array[local_var]; // push.pri \ load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ move.alt \ pop.pri \ stor.i + emit stor.u.alt global_array[local_var]; // push.alt \ load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ move.alt \ pop.pri \ stor.i + emit stor.u.pri local_array[local_var]; // push.pri \ load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ move.alt \ pop.pri \ stor.i + emit stor.u.alt local_array[local_var]; // push.alt \ load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ move.alt \ pop.pri \ stor.i + emit stor.u.pri local_refarray[local_var]; // push.pri \ load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ move.alt \ pop.pri \ stor.i + emit stor.u.alt local_refarray[local_var]; // push.alt \ load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ move.alt \ pop.pri \ stor.i + DEF_SNIPPET(0x26); + emit stor.u.pri global_array{local_var}; // push.pri \ load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + emit stor.u.alt global_array{local_var}; // push.alt \ load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + emit stor.u.pri local_array{local_var}; // push.pri \ load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + emit stor.u.alt local_array{local_var}; // push.alt \ load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + emit stor.u.pri local_refarray{local_var}; // push.pri \ load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + emit stor.u.alt local_refarray{local_var}; // push.alt \ load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ move.alt \ pop.pri \ strb.i 00000001 + + DEF_SNIPPET(0x28); + emit push.u global_const_1234; // push.c 00001234 + emit push.u global_var; // push 00000000 + emit push.u local_refvar; // lref.s.pri 0000000c \ push.pri + emit push.u local_const_5678; // push.c 00005678 + emit push.u local_var; // push.s fffffffc + emit push.u local_static_var; // push 0000000c + emit push.u 0x9abc; // push.c 00009abc + DEF_SNIPPET(0x29); + emit push.u global_const_1234 + local_const_5678; // push.c 000068ac + DEF_SNIPPET(0x2a); + emit push.u global_var * local_var; // load.pri 00000000 \ push.pri \ load.s.pri fffffffc \ pop.alt \ smul \ push.pri + DEF_SNIPPET(0x2b); + emit push.u local_refarray[0]; // load.s.pri 00000010 \ load.i \ push.pri + + DEF_SNIPPET(0x30); + emit push.u.adr global_var; // push.c 00000000 + emit push.u.adr local_static_var; // push.c 0000000c + emit push.u.adr local_var; // push.adr fffffffc + emit push.u.adr local_refvar; // push.s 0000000c + DEF_SNIPPET(0x31); + emit push.u.adr global_array[0]; // push.c 00000004 + emit push.u.adr global_array[1]; // push.c 00000008 + emit push.u.adr local_static_array[0]; // push.c 00000010 + emit push.u.adr local_static_array[1]; // push.c 00000014 + emit push.u.adr local_array[0]; // push.adr fffffff4 + emit push.u.adr local_array[1]; // push.adr fffffff8 + emit push.u.adr local_refarray[0]; // push.s 00000010 + emit push.u.adr local_refarray[1]; // load.s.pri 00000010 \ add.c 00000004 \ push.pri + DEF_SNIPPET(0x32); + emit push.u.adr global_array[local_var]; // load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ push.pri + emit push.u.adr local_static_array[local_var]; // load.s.pri fffffffc \ const.alt 00000010 \ idxaddr \ push.pri + emit push.u.adr local_array[local_var]; // load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ push.pri + emit push.u.adr local_refarray[local_var]; // load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ push.pri + // DEF_SNIPPET(0x33); + // emit push.u.adr global_array{0}; // const.pri 00000004 \ align.pri 00000001 \ push.pri + // emit push.u.adr global_array{1}; // const.pri 00000005 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_static_array{0}; // const.pri 00000010 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_static_array{1}; // const.pri 00000011 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_array{0}; // addr.pri fffffff4 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_array{1}; // addr.pri fffffff5 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_refarray{0}; // load.s.pri 00000010 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_refarray{1}; // load.s.pri 00000010 \ inc.pri \ align.pri 00000001 \ push.pri + // emit push.u.adr local_refarray{2}; // load.s.pri 00000010 \ add.c 00000002 \ align.pri 00000001 \ push.pri + // DEF_SNIPPET(0x34); + // emit push.u.adr global_array{local_var}; // load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_static_array{local_var}; // load.s.pri fffffffc \ add.c 00000010 \ align.pri 00000001 \ push.pri + // emit push.u.adr local_array{local_var}; // load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ push.pri + // emit push.u.adr local_refarray{local_var}; // load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ push.pri + + DEF_SNIPPET(0x38); + emit zero.u global_var; // zero 00000000 + emit zero.u local_static_var; // zero 0000000c + emit zero.u local_var; // zero.s fffffffc + emit zero.u local_refvar; // zero.pri \ sref.s.pri 0000000c + DEF_SNIPPET(0x39); + emit zero.u global_array[0]; // zero 00000004 + emit zero.u global_array[1]; // zero 00000008 + emit zero.u local_static_array[0]; // zero 00000010 + emit zero.u local_static_array[1]; // zero 00000014 + emit zero.u local_array[0]; // zero.s fffffff4 + emit zero.u local_array[1]; // zero.s fffffff8 + emit zero.u local_refarray[0]; // zero.pri \ sref.s.pri 00000010 + emit zero.u local_refarray[1]; // load.s.pri 00000010 \ add.c 00000004 \ move.alt \ zero.pri \ stor.i + DEF_SNIPPET(0x3a); + emit zero.u global_array{0}; // const.alt 00000004 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u global_array{1}; // const.alt 00000005 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_static_array{0}; // const.alt 00000010 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_static_array{1}; // const.alt 00000011 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_array{0}; // addr.alt fffffff4 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_array{1}; // addr.alt fffffff5 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_refarray{0}; // load.s.alt 00000010 \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_refarray{1}; // load.s.alt 00000010 \ inc.alt \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + emit zero.u local_refarray{2}; // load.s.pri 00000010 \ add.c 00000002 \ move.alt \ align.alt 00000001 \ zero.pri \ strb.i 00000001 + DEF_SNIPPET(0x3b); + emit zero.u global_array[local_var]; // load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ move.alt \ zero.pri \ stor.i + emit zero.u local_static_array[local_var]; // load.s.pri fffffffc \ const.alt 00000010 \ idxaddr \ move.alt \ zero.pri \ stor.i + emit zero.u local_array[local_var]; // load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ move.alt \ zero.pri \ stor.i + emit zero.u local_refarray[local_var]; // load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ move.alt \ zero.pri \ stor.i + DEF_SNIPPET(0x3c); + emit zero.u global_array{local_var}; // load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ move.alt \ zero.pri \ strb.i 00000001 + emit zero.u local_static_array{local_var}; // load.s.pri fffffffc \ add.c 00000010 \ align.pri 00000001 \ move.alt \ zero.pri \ strb.i 00000001 + emit zero.u local_array{local_var}; // load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ move.alt \ zero.pri \ strb.i 00000001 + emit zero.u local_refarray{local_var}; // load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ move.alt \ zero.pri \ strb.i 00000001 + + DEF_SNIPPET(0x40); + emit inc.u global_var; // inc 00000000 + emit inc.u local_static_var; // inc 0000000c + emit inc.u local_var; // inc.s fffffffc + emit inc.u local_refvar; // load.s.pri 0000000c \ inc.i + DEF_SNIPPET(0x41); + emit inc.u global_array[0]; // inc 00000004 + emit inc.u global_array[1]; // inc 00000008 + emit inc.u local_static_array[0]; // inc 00000010 + emit inc.u local_static_array[1]; // inc 00000014 + emit inc.u local_array[0]; // inc.s fffffff4 + emit inc.u local_array[1]; // inc.s fffffff8 + emit inc.u local_refarray[0]; // load.s.pri 00000010 \ inc.i + emit inc.u local_refarray[1]; // load.s.pri 00000010 \ add.c 00000004 \ inc.i + DEF_SNIPPET(0x42); + emit inc.u global_array{0}; // const.pri 00000004 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u global_array{1}; // const.pri 00000005 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_static_array{0}; // const.pri 00000010 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_static_array{1}; // const.pri 00000011 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_array{0}; // addr.pri fffffff4 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_array{1}; // addr.pri fffffff5 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_refarray{0}; // load.s.pri 00000010 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_refarray{1}; // load.s.pri 00000010 \ inc.pri \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_refarray{2}; // load.s.pri 00000010 \ add.c 00000002 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + DEF_SNIPPET(0x43); + emit inc.u global_array[local_var]; // load.s.pri fffffffc \ const.alt 00000004 \ idxaddr \ inc.i + emit inc.u local_static_array[local_var]; // load.s.pri fffffffc \ const.alt 00000010 \ idxaddr \ inc.i + emit inc.u local_array[local_var]; // load.s.pri fffffffc \ addr.alt fffffff4 \ idxaddr \ inc.i + emit inc.u local_refarray[local_var]; // load.s.pri fffffffc \ load.s.alt 00000010 \ idxaddr \ inc.i + DEF_SNIPPET(0x44); + emit inc.u global_array{local_var}; // load.s.pri fffffffc \ add.c 00000004 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_static_array{local_var}; // load.s.pri fffffffc \ add.c 00000010 \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_array{local_var}; // load.s.pri fffffffc \ addr.alt fffffff4 \ add \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + emit inc.u local_refarray{local_var}; // load.s.pri fffffffc \ load.s.alt 00000010 \ add \ align.pri 00000001 \ move.alt \ lodb.i 00000001 \ inc.pri \ strb.i 00000001 + + emit nop; // end marker +} + + +main() +{ + new t, a[2]; + test__pcode(t, a); +} From 8394b5a29ecc535f62d58e4938fb6cc56220e5b8 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Mon, 3 Jun 2019 17:06:31 +0700 Subject: [PATCH 19/21] __emit: Make sure the opcode table is sorted --- source/compiler/sc1.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index e4cda9c..c46fbf6 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -7406,7 +7406,7 @@ static EMIT_OPCODE emit_opcodelist[] = { { "zero.u", emit_do_zero_u }, }; -static int emit_findopcode(const char *instr,int maxlen) +static int emit_findopcode(const char *instr) { int low,high,mid,cmp; @@ -7438,6 +7438,23 @@ SC_FUNC void emit_parse_line(void) symbol *sym; char name[MAX_INSTR_LEN]; + #if !defined NDEBUG + /* verify that the opcode list is sorted (skip entry 1; it is reserved + * for a non-existant opcode) + */ + { /* local */ + static int sorted=FALSE; + if (!sorted) { + assert(emit_opcodelist[1].name!=NULL); + for (i=2; i<(sizeof emit_opcodelist / sizeof emit_opcodelist[0]); i++) { + assert(emit_opcodelist[i].name!=NULL); + assert(stricmp(emit_opcodelist[i].name,emit_opcodelist[i-1].name)>0); + } /* for */ + sorted=TRUE; + } /* if */ + } /* local */ + #endif + tok=tokeninfo(&val,&st); if (tok==tSYMBOL || (tok>tMIDDLE && tok<=tLAST)) { /* get the token length */ @@ -7455,7 +7472,7 @@ SC_FUNC void emit_parse_line(void) name[i]='\0'; /* find the corresponding argument handler and call it */ - i=emit_findopcode(name,i); + i=emit_findopcode(name); if (emit_opcodelist[i].name==NULL && name[0]!='\0') error(104,name); /* invalid assembler instruction */ emit_opcodelist[i].func(name); From 991eed93035d453c904900ebeac99b557515b340 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 8 Jun 2019 02:59:08 +0700 Subject: [PATCH 20/21] __emit: Remove excessive local block --- source/compiler/sc3.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index a31a980..f0bc8e6 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -1463,24 +1463,21 @@ static int hier2(value *lval) return FALSE; } /* case */ case tEMIT: - case t__EMIT: { - cell val; - char* st; - int block_syntax=matchtoken('('); + case t__EMIT: + paranthese=matchtoken('('); emit_flags |= efEXPR; if (emit_stgbuf_idx==-1) emit_stgbuf_idx=stgidx; do { lex(&val,&st); emit_parse_line(); - } while ((block_syntax!=0) && matchtoken(',')); - if (block_syntax!=0) + } while ((paranthese!=0) && matchtoken(',')); + if (paranthese!=0) needtoken(')'); emit_flags &= ~efEXPR; lval->ident=iEXPRESSION; pc_sideeffect=TRUE; return FALSE; - } /* case */ default: lexpush(); lvalue=hier1(lval); From 5c4e0c27a7794bcb733ba134f52db0c97db3ff34 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Sat, 8 Jun 2019 03:02:00 +0700 Subject: [PATCH 21/21] __emit: Fix undefined behavior Apparently shifting a 32-bit signed value by 31 bits is UB... --- source/compiler/sc1.c | 2 +- source/compiler/sc2.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index c46fbf6..4ec4351 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -6314,7 +6314,7 @@ fetchtok: case tRATIONAL: if (!allow_nonint) goto invalid_token; - p->value.ucell=(ucell)(negate ? (val|((cell)1 << (PAWN_CELL_SIZE-1))) : val); + p->value.ucell=(negate ? ((ucell)val|((ucell)1 << (PAWN_CELL_SIZE-1))) : (ucell)val); break; case tSYMBOL: sym=findloc(str); diff --git a/source/compiler/sc2.c b/source/compiler/sc2.c index b611086..b4c97dd 100644 --- a/source/compiler/sc2.c +++ b/source/compiler/sc2.c @@ -1405,7 +1405,7 @@ static int command(void) break; } else if (current_token==tRATIONAL) { /* change the first bit to make float negative value */ - outval(val|((cell)1 << (PAWN_CELL_SIZE-1)),FALSE); + outval(val|(cell)((ucell)1 << (PAWN_CELL_SIZE-1)),FALSE); code_idx+=opargs(1); break; } else {