From e922e48aa67c0748f1623efeda90760cef051d65 Mon Sep 17 00:00:00 2001 From: Daniel_Cortez Date: Mon, 4 Dec 2017 18:18:06 +0700 Subject: [PATCH] emit/__emit: Fix incorrect code generation --- source/compiler/sc1.c | 19 ++++++++++++++----- source/compiler/sc3.c | 18 +++++++++++++++--- 2 files changed, 29 insertions(+), 8 deletions(-) diff --git a/source/compiler/sc1.c b/source/compiler/sc1.c index c6dd67a..dad2fb4 100644 --- a/source/compiler/sc1.c +++ b/source/compiler/sc1.c @@ -5871,12 +5871,11 @@ static void emit_invalid_token(int expected_token,int found_token) static void emit_param_any(ucell *p,int size) { char *str; - cell val; + cell val,cidx; symbol *sym; - int tok; extern char *sc_tokens[]; int curp=0; - int neg; + int tok,neg,ident,index; assert(size>0); do { @@ -5908,9 +5907,19 @@ static void emit_param_any(ucell *p,int size) p[curp]=(neg!=0) ? -sym->addr : sym->addr; break; case '(': - constexpr(&val,NULL,NULL); + if ((emit_parsing_mode & epmEXPR)==0) + stgset(TRUE); + stgget(&index,&cidx); + errorset(sEXPRMARK,0); + ident=expression(&val,NULL,NULL,FALSE); + if (ident!=iCONSTEXPR) + error(8); /* must be constant expression */ + errorset(sEXPRRELEASE,0); + stgdel(index,cidx); + if ((emit_parsing_mode & epmEXPR)==0) + stgset(FALSE); needtoken(')'); - p[curp]=val; + p[curp]=(neg==0) ? val : -val; break; case '-': if (neg==0) { diff --git a/source/compiler/sc3.c b/source/compiler/sc3.c index cb8ae85..c516a0b 100644 --- a/source/compiler/sc3.c +++ b/source/compiler/sc3.c @@ -1452,13 +1452,25 @@ static int hier2(value *lval) case t__EMIT: { cell val; char* st; - if (matchtoken('{')) - error(29); /* invalid expression, assumed zero */ - lval->ident=iEXPRESSION; + int opt_bck; + + /* write the staging buffer to the output file and temporarily disable + * bytecode optimisation so instructions generated by the `emit`/`__emit` + * operator won't get altered by the optimizer + */ + stgout(0); + opt_bck=pc_optimize; + pc_optimize=sOPTIMIZE_NONE; + + /* parse the `emit`/`__emit` expression */ emit_parsing_mode |= epmEXPR; lex(&val,&st); emit_parse_line(); emit_parsing_mode &= ~epmEXPR; + lval->ident=iEXPRESSION; + + /* restore the bytecode optimisation level and return */ + pc_optimize=opt_bck; return FALSE; } /* case */ default: