emit/__emit: Fix incorrect code generation

This commit is contained in:
Daniel_Cortez 2017-12-04 18:18:06 +07:00
parent fab8c53db0
commit e922e48aa6
2 changed files with 29 additions and 8 deletions

View File

@ -5871,12 +5871,11 @@ static void emit_invalid_token(int expected_token,int found_token)
static void emit_param_any(ucell *p,int size) static void emit_param_any(ucell *p,int size)
{ {
char *str; char *str;
cell val; cell val,cidx;
symbol *sym; symbol *sym;
int tok;
extern char *sc_tokens[]; extern char *sc_tokens[];
int curp=0; int curp=0;
int neg; int tok,neg,ident,index;
assert(size>0); assert(size>0);
do { do {
@ -5908,9 +5907,19 @@ static void emit_param_any(ucell *p,int size)
p[curp]=(neg!=0) ? -sym->addr : sym->addr; p[curp]=(neg!=0) ? -sym->addr : sym->addr;
break; break;
case '(': 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(')'); needtoken(')');
p[curp]=val; p[curp]=(neg==0) ? val : -val;
break; break;
case '-': case '-':
if (neg==0) { if (neg==0) {

View File

@ -1452,13 +1452,25 @@ static int hier2(value *lval)
case t__EMIT: { case t__EMIT: {
cell val; cell val;
char* st; char* st;
if (matchtoken('{')) int opt_bck;
error(29); /* invalid expression, assumed zero */
lval->ident=iEXPRESSION; /* 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; emit_parsing_mode |= epmEXPR;
lex(&val,&st); lex(&val,&st);
emit_parse_line(); emit_parse_line();
emit_parsing_mode &= ~epmEXPR; emit_parsing_mode &= ~epmEXPR;
lval->ident=iEXPRESSION;
/* restore the bytecode optimisation level and return */
pc_optimize=opt_bck;
return FALSE; return FALSE;
} /* case */ } /* case */
default: default: