Fix Berry compiler bug #117

This commit is contained in:
Stephan Hadinger 2021-08-16 12:11:28 +02:00
parent 1ab2b2c865
commit 660698dc10
5 changed files with 243 additions and 297 deletions

View File

@ -973,115 +973,61 @@ be_local_closure(set_timer, /* name */
); );
/*******************************************************************/ /*******************************************************************/
/********************************************************************
// run every 50ms tick
"def run_deferred() "
"if self._timers "
"var i=0 "
"while i<self._timers.size() "
"if self.time_reached(self._timers[i][0]) "
"f=self._timers[i][1] "
"self._timers.remove(i) "
"f() "
"else "
"i=i+1 "
"end "
"end "
"end "
"end "
********************************************************************/
/******************************************************************** /********************************************************************
** Solidified function: run_deferred ** Solidified function: run_deferred
********************************************************************/ ********************************************************************/
be_local_closure(run_deferred, /* name */
be_define_local_const_str(run_deferred_str_name, "run_deferred", 371594696, 12); be_nested_proto(
be_define_local_const_str(run_deferred_str_source, "string", 398550328, 6); 6, /* nstack */
be_define_local_const_str(run_deferred_str_0, "_timers", -1694866380, 7); 1, /* argc */
be_define_local_const_str(run_deferred_str_2, "size", 597743964, 4); 0, /* has upvals */
be_define_local_const_str(run_deferred_str_3, "time_reached", 2075136773, 12); NULL, /* no upvals */
be_define_local_const_str(run_deferred_str_5, "remove", -611183107, 6); 0, /* has sup protos */
NULL, /* no sub protos */
static const bvalue run_deferred_ktab[6] = { 1, /* has constants */
{ { .s=be_local_const_str(run_deferred_str_0) }, BE_STRING}, ( &(const bvalue[ 6]) { /* constants */
{ { .i=0 }, BE_INT}, be_nested_string("_timers", -1694866380, 7), /* R256 - K0 */
{ { .s=be_local_const_str(run_deferred_str_2) }, BE_STRING}, be_const_int(0), /* R257 - K1 */
{ { .s=be_local_const_str(run_deferred_str_3) }, BE_STRING}, be_nested_string("size", 597743964, 4), /* R258 - K2 */
{ { .i=1 }, BE_INT}, be_nested_string("time_reached", 2075136773, 12), /* R259 - K3 */
{ { .s=be_local_const_str(run_deferred_str_5) }, BE_STRING}, be_const_int(1), /* R260 - K4 */
}; be_nested_string("remove", -611183107, 6), /* R261 - K5 */
}),
static const uint32_t run_deferred_code[27] = { (be_nested_const_str("run_deferred", 371594696, 12)),
0x88040100, // 0000 GETMBR R1 R0 R256 (be_nested_const_str("string", 398550328, 6)),
0x78060017, // 0001 JMPF R1 #001A ( &(const binstruction[27]) { /* code */
0x58040001, // 0002 LDCONST R1 K1 0x88040100, // 0000 GETMBR R1 R0 R256
0x88080100, // 0003 GETMBR R2 R0 R256 0x78060017, // 0001 JMPF R1 #001A
0x8C080502, // 0004 GETMET R2 R2 R258 0x58040001, // 0002 LDCONST R1 K1
0x7C080200, // 0005 CALL R2 1 0x88080100, // 0003 GETMBR R2 R0 R256
0x14080202, // 0006 LT R2 R1 R2 0x8C080502, // 0004 GETMET R2 R2 R258
0x780A0011, // 0007 JMPF R2 #001A 0x7C080200, // 0005 CALL R2 1
0x8C080103, // 0008 GETMET R2 R0 R259 0x14080202, // 0006 LT R2 R1 R2
0x88100100, // 0009 GETMBR R4 R0 R256 0x780A0011, // 0007 JMPF R2 #001A
0x94100801, // 000A GETIDX R4 R4 R1 0x8C080103, // 0008 GETMET R2 R0 R259
0x94100901, // 000B GETIDX R4 R4 R257 0x88100100, // 0009 GETMBR R4 R0 R256
0x7C080400, // 000C CALL R2 2 0x94100801, // 000A GETIDX R4 R4 R1
0x780A0009, // 000D JMPF R2 #0018 0x94100901, // 000B GETIDX R4 R4 R257
0x88080100, // 000E GETMBR R2 R0 R256 0x7C080400, // 000C CALL R2 2
0x94080401, // 000F GETIDX R2 R2 R1 0x780A0009, // 000D JMPF R2 #0018
0x94080504, // 0010 GETIDX R2 R2 R260 0x88080100, // 000E GETMBR R2 R0 R256
0x880C0100, // 0011 GETMBR R3 R0 R256 0x94080401, // 000F GETIDX R2 R2 R1
0x8C0C0705, // 0012 GETMET R3 R3 R261 0x94080504, // 0010 GETIDX R2 R2 R260
0x5C140200, // 0013 MOVE R5 R1 0x880C0100, // 0011 GETMBR R3 R0 R256
0x7C0C0400, // 0014 CALL R3 2 0x8C0C0705, // 0012 GETMET R3 R3 R261
0x5C0C0400, // 0015 MOVE R3 R2 0x5C140200, // 0013 MOVE R5 R1
0x7C0C0000, // 0016 CALL R3 0 0x7C0C0400, // 0014 CALL R3 2
0x70020000, // 0017 JMP #0019 0x5C0C0400, // 0015 MOVE R3 R2
0x40304, // 0018 ADD R1 R1 R260 0x7C0C0000, // 0016 CALL R3 0
0x7001FFE8, // 0019 JMP #0003 0x70020000, // 0017 JMP #0019
0x80000000, // 001A RET 0 R0 0x00040304, // 0018 ADD R1 R1 R260
}; 0x7001FFE8, // 0019 JMP #0003
0x80000000, // 001A RET 0 R0
static const bproto run_deferred_proto = { })
NULL, // bgcobject *next )
8, // type );
0x08, // marked
6, // nstack
0, // nupvals
1, // argc
0, // varg
NULL, // bgcobject *gray
NULL, // bupvaldesc *upvals
(bvalue*) &run_deferred_ktab, // ktab
NULL, // bproto **ptab
(binstruction*) &run_deferred_code, // code
be_local_const_str(run_deferred_str_name), // name
27, // codesize
6, // nconst
0, // nproto
be_local_const_str(run_deferred_str_source), // source
#if BE_DEBUG_RUNTIME_INFO /* debug information */
NULL, // lineinfo
0, // nlineinfo
#endif
#if BE_DEBUG_VAR_INFO
NULL, // varinfo
0, // nvarinfo
#endif
};
const bclosure run_deferred_closure = {
NULL, // bgcobject *next
36, // type
0x08, // marked
0, // nupvals
NULL, // bgcobject *gray
(bproto*) &run_deferred_proto, // proto
{ NULL } // upvals
};
/*******************************************************************/ /*******************************************************************/
/******************************************************************** /********************************************************************
// Add command to list // Add command to list
"def add_cmd(c,f) " "def add_cmd(c,f) "
@ -1212,113 +1158,60 @@ be_local_closure(remove_cmd, /* name */
); );
/*******************************************************************/ /*******************************************************************/
/********************************************************************
// Execute custom command
"def exec_cmd(cmd, idx, payload) "
"if self._ccmd "
"import json "
"var payload_json = json.load(payload) "
"var cmd_found = self.find_key_i(self._ccmd, cmd) "
"if cmd_found != nil "
"self.resolvecmnd(cmd_found) " // set the command name in XdrvMailbox.command
"self._ccmd[cmd_found](cmd_found, idx, payload, payload_json) "
"return true "
"end "
"end "
"return false "
"end "
********************************************************************/
/******************************************************************** /********************************************************************
** Solidified function: exec_cmd ** Solidified function: exec_cmd
********************************************************************/ ********************************************************************/
be_local_closure(exec_cmd, /* name */
be_define_local_const_str(exec_cmd_str_name, "exec_cmd", 493567399, 8); be_nested_proto(
be_define_local_const_str(exec_cmd_str_source, "string", 398550328, 6); 12, /* nstack */
be_define_local_const_str(exec_cmd_str_0, "_ccmd", -2131545883, 5); 4, /* argc */
be_define_local_const_str(exec_cmd_str_1, "json", 916562499, 4); 0, /* has upvals */
be_define_local_const_str(exec_cmd_str_2, "load", -435725847, 4); NULL, /* no upvals */
be_define_local_const_str(exec_cmd_str_3, "find_key_i", 850136726, 10); 0, /* has sup protos */
be_define_local_const_str(exec_cmd_str_4, "resolvecmnd", 993361485, 11); NULL, /* no sub protos */
1, /* has constants */
static const bvalue exec_cmd_ktab[5] = { ( &(const bvalue[ 5]) { /* constants */
{ { .s=be_local_const_str(exec_cmd_str_0) }, BE_STRING}, be_nested_string("_ccmd", -2131545883, 5), /* R256 - K0 */
{ { .s=be_local_const_str(exec_cmd_str_1) }, BE_STRING}, be_nested_string("json", 916562499, 4), /* R257 - K1 */
{ { .s=be_local_const_str(exec_cmd_str_2) }, BE_STRING}, be_nested_string("load", -435725847, 4), /* R258 - K2 */
{ { .s=be_local_const_str(exec_cmd_str_3) }, BE_STRING}, be_nested_string("find_key_i", 850136726, 10), /* R259 - K3 */
{ { .s=be_local_const_str(exec_cmd_str_4) }, BE_STRING}, be_nested_string("resolvecmnd", 993361485, 11), /* R260 - K4 */
}; }),
(be_nested_const_str("exec_cmd", 493567399, 8)),
static const uint32_t exec_cmd_code[27] = { (be_nested_const_str("string", 398550328, 6)),
0x88100100, // 0000 GETMBR R4 R0 R256 ( &(const binstruction[27]) { /* code */
0x78120016, // 0001 JMPF R4 #0019 0x88100100, // 0000 GETMBR R4 R0 R256
0xA4120200, // 0002 IMPORT R4 R257 0x78120016, // 0001 JMPF R4 #0019
0x8C140902, // 0003 GETMET R5 R4 R258 0xA4120200, // 0002 IMPORT R4 R257
0x5C1C0600, // 0004 MOVE R7 R3 0x8C140902, // 0003 GETMET R5 R4 R258
0x7C140400, // 0005 CALL R5 2 0x5C1C0600, // 0004 MOVE R7 R3
0x8C180103, // 0006 GETMET R6 R0 R259 0x7C140400, // 0005 CALL R5 2
0x88200100, // 0007 GETMBR R8 R0 R256 0x8C180103, // 0006 GETMET R6 R0 R259
0x5C240200, // 0008 MOVE R9 R1 0x88200100, // 0007 GETMBR R8 R0 R256
0x7C180600, // 0009 CALL R6 3 0x5C240200, // 0008 MOVE R9 R1
0x4C1C0000, // 000A LDNIL 7 0x7C180600, // 0009 CALL R6 3
0x201C0C07, // 000B NE R7 R6 R7 0x4C1C0000, // 000A LDNIL 7
0x781E000B, // 000C JMPF R7 #0019 0x201C0C07, // 000B NE R7 R6 R7
0x8C1C0104, // 000D GETMET R7 R0 R260 0x781E000B, // 000C JMPF R7 #0019
0x5C240C00, // 000E MOVE R9 R6 0x8C1C0104, // 000D GETMET R7 R0 R260
0x7C1C0400, // 000F CALL R7 2 0x5C240C00, // 000E MOVE R9 R6
0x881C0100, // 0010 GETMBR R7 R0 R256 0x7C1C0400, // 000F CALL R7 2
0x941C0E06, // 0011 GETIDX R7 R7 R6 0x881C0100, // 0010 GETMBR R7 R0 R256
0x5C200C00, // 0012 MOVE R8 R6 0x941C0E06, // 0011 GETIDX R7 R7 R6
0x5C240400, // 0013 MOVE R9 R2 0x5C200C00, // 0012 MOVE R8 R6
0x5C280600, // 0014 MOVE R10 R3 0x5C240400, // 0013 MOVE R9 R2
0x5C2C0A00, // 0015 MOVE R11 R5 0x5C280600, // 0014 MOVE R10 R3
0x7C1C0800, // 0016 CALL R7 4 0x5C2C0A00, // 0015 MOVE R11 R5
0x501C0200, // 0017 LDBOOL R7 1 0 0x7C1C0800, // 0016 CALL R7 4
0x80040E00, // 0018 RET 1 R7 0x501C0200, // 0017 LDBOOL R7 1 0
0x50100000, // 0019 LDBOOL R4 0 0 0x80040E00, // 0018 RET 1 R7
0x80040800, // 001A RET 1 R4 0x50100000, // 0019 LDBOOL R4 0 0
}; 0x80040800, // 001A RET 1 R4
})
static const bproto exec_cmd_proto = { )
NULL, // bgcobject *next );
8, // type
0x08, // marked
12, // nstack
0, // nupvals
4, // argc
0, // varg
NULL, // bgcobject *gray
NULL, // bupvaldesc *upvals
(bvalue*) &exec_cmd_ktab, // ktab
NULL, // bproto **ptab
(binstruction*) &exec_cmd_code, // code
be_local_const_str(exec_cmd_str_name), // name
27, // codesize
5, // nconst
0, // nproto
be_local_const_str(exec_cmd_str_source), // source
#if BE_DEBUG_RUNTIME_INFO /* debug information */
NULL, // lineinfo
0, // nlineinfo
#endif
#if BE_DEBUG_VAR_INFO
NULL, // varinfo
0, // nvarinfo
#endif
};
static const bclosure exec_cmd_closure = {
NULL, // bgcobject *next
36, // type
0x08, // marked
0, // nupvals
NULL, // bgcobject *gray
(bproto*) &exec_cmd_proto, // proto
{ NULL } // upvals
};
/*******************************************************************/ /*******************************************************************/
/******************************************************************** /********************************************************************
// Force gc and return allocated memory // Force gc and return allocated memory
"def gc() " "def gc() "
@ -1478,70 +1371,37 @@ be_local_closure(event, /* name */
/******************************************************************** /********************************************************************
** Solidified function: add_driver ** Solidified function: add_driver
********************************************************************/ ********************************************************************/
be_local_closure(add_driver, /* name */
be_define_local_const_str(add_driver_str_name, "add_driver", 1654458371, 10); be_nested_proto(
be_define_local_const_str(add_driver_str_source, "string", 398550328, 6); 5, /* nstack */
be_define_local_const_str(add_driver_str_0, "_drivers", -1034638311, 8); 2, /* argc */
be_define_local_const_str(add_driver_str_1, "push", -2022703139, 4); 0, /* has upvals */
NULL, /* no upvals */
static const bvalue add_driver_ktab[2] = { 0, /* has sup protos */
{ { .s=be_local_const_str(add_driver_str_0) }, BE_STRING}, NULL, /* no sub protos */
{ { .s=be_local_const_str(add_driver_str_1) }, BE_STRING}, 1, /* has constants */
}; ( &(const bvalue[ 2]) { /* constants */
be_nested_string("_drivers", -1034638311, 8), /* R256 - K0 */
static const uint32_t add_driver_code[12] = { be_nested_string("push", -2022703139, 4), /* R257 - K1 */
0x88080100, // 0000 GETMBR R2 R0 R256 }),
0x780A0004, // 0001 JMPF R2 #0007 (be_nested_const_str("add_driver", 1654458371, 10)),
0x88080100, // 0002 GETMBR R2 R0 R256 (be_nested_const_str("string", 398550328, 6)),
0x8C080501, // 0003 GETMET R2 R2 R257 ( &(const binstruction[12]) { /* code */
0x5C100200, // 0004 MOVE R4 R1 0x88080100, // 0000 GETMBR R2 R0 R256
0x7C080400, // 0005 CALL R2 2 0x780A0004, // 0001 JMPF R2 #0007
0x70020003, // 0006 JMP #000B 0x88080100, // 0002 GETMBR R2 R0 R256
0x6008000A, // 0007 GETGBL R2 G10 0x8C080501, // 0003 GETMET R2 R2 R257
0x7C080000, // 0008 CALL R2 0 0x5C100200, // 0004 MOVE R4 R1
0x400C0401, // 0009 CONNECT R3 R2 R1 0x7C080400, // 0005 CALL R2 2
0x90020002, // 000A SETMBR R0 R256 R2 0x70020003, // 0006 JMP #000B
0x80000000, // 000B RET 0 R0 0x6008000A, // 0007 GETGBL R2 G10
}; 0x7C080000, // 0008 CALL R2 0
0x400C0401, // 0009 CONNECT R3 R2 R1
static const bproto add_driver_proto = { 0x90020002, // 000A SETMBR R0 R256 R2
NULL, // bgcobject *next 0x80000000, // 000B RET 0 R0
8, // type })
0x08, // marked )
5, // nstack );
0, // nupvals
2, // argc
0, // varg
NULL, // bgcobject *gray
NULL, // bupvaldesc *upvals
(bvalue*) &add_driver_ktab, // ktab
NULL, // bproto **ptab
(binstruction*) &add_driver_code, // code
be_local_const_str(add_driver_str_name), // name
12, // codesize
2, // nconst
0, // nproto
be_local_const_str(add_driver_str_source), // source
#if BE_DEBUG_RUNTIME_INFO /* debug information */
NULL, // lineinfo
0, // nlineinfo
#endif
#if BE_DEBUG_VAR_INFO
NULL, // varinfo
0, // nvarinfo
#endif
};
const bclosure add_driver_closure = {
NULL, // bgcobject *next
36, // type
0x08, // marked
0, // nupvals
NULL, // bgcobject *gray
(bproto*) &add_driver_proto, // proto
{ NULL } // upvals
};
/*******************************************************************/ /*******************************************************************/
/******************************************************************** /********************************************************************

View File

@ -265,6 +265,47 @@ class Tasmota
end end
end end
def add_driver(d)
if self._drivers
self._drivers.push(d)
else
self._drivers = [d]
end
end
# cmd high-level function
def cmd(command)
import json
var ret = self._cmd(command)
var j = json.load(ret)
if type(j) == 'instance'
return j
else
return {'response':j}
end
end
# set_light and get_light deprecetaion
def get_light(l)
print('tasmota.get_light() is deprecated, use light.get()')
import light
if l != nil
return light.get(l)
else
return light.get()
end
end
def set_light(v,l)
print('tasmota.set_light() is deprecated, use light.set()')
import light
if l != nil
return light.set(v,l)
else
return light.set(v)
end
end
#- dispatch callback number n, with parameters v0,v1,v2,v3 -# #- dispatch callback number n, with parameters v0,v1,v2,v3 -#
def cb_dispatch(n,v0,v1,v2,v3) def cb_dispatch(n,v0,v1,v2,v3)
if self._cb == nil return 0 end if self._cb == nil return 0 end

View File

@ -23,8 +23,8 @@
#define min(a, b) ((a) < (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b))
#define notexpr(e) isset((e)->not, NOT_EXPR) #define notexpr(e) isset((e)->not, NOT_EXPR)
#define notmask(e) isset((e)->not, NOT_MASK) #define notmask(e) isset((e)->not, NOT_MASK)
#define exp2anyreg(f, e) exp2reg(f, e, (f)->freereg) #define exp2anyreg(f, e) exp2reg(f, e, -1) /* -1 means allocate a new register if needed */
#define var2anyreg(f, e) var2reg(f, e, (f)->freereg) #define var2anyreg(f, e) var2reg(f, e, -1) /* -1 means allocate a new register if needed */
#define hasjump(e) ((e)->t != (e)->f || notexpr(e)) #define hasjump(e) ((e)->t != (e)->f || notexpr(e))
#define code_bool(f, r, b, j) codeABC(f, OP_LDBOOL, r, b, j) #define code_bool(f, r, b, j) codeABC(f, OP_LDBOOL, r, b, j)
#define code_call(f, a, b) codeABC(f, OP_CALL, a, b, 0) #define code_call(f, a, b) codeABC(f, OP_CALL, a, b, 0)
@ -321,9 +321,38 @@ static void free_suffix(bfuncinfo *finfo, bexpdesc *e)
} }
} }
static int suffix_destreg(bfuncinfo *finfo, bexpdesc *e1, int dst)
{
int cand_dst = dst; /* candidate for new dst */
int nlocal = be_list_count(finfo->local);
int reg1 = (e1->v.ss.tt == ETREG) ? e1->v.ss.obj : -1; /* check if obj is ETREG or -1 */
int reg2 = (!isK(e1->v.ss.idx) && e1->v.ss.idx >= nlocal) ? e1->v.ss.idx : -1; /* check if idx is ETREG or -1 */
if (reg1 >= 0 && reg2 >= 0) {
/* both are ETREG, we keep the lowest and discard the other */
if (reg1 != reg2) {
cand_dst = min(reg1, reg2);
be_code_freeregs(finfo, 1); /* and free the other one */
} else {
cand_dst = reg1; /* both ETREG are equal, we return its value */
}
} else if (reg1 >= 0) {
cand_dst = reg1;
} else if (reg2 >= 0) {
cand_dst = reg2;
} else {
// dst unchanged
}
if (dst >= finfo->freereg) {
dst = cand_dst; /* if dst was allocating a new register, use the more precise candidate */
}
return dst;
}
static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst) static int code_suffix(bfuncinfo *finfo, bopcode op, bexpdesc *e, int dst)
{ {
free_suffix(finfo, e); /* free temporary registers */ dst = suffix_destreg(finfo, e, dst);
if (dst > finfo->freereg) { if (dst > finfo->freereg) {
dst = finfo->freereg; dst = finfo->freereg;
} }
@ -351,6 +380,9 @@ static bbool constint(bfuncinfo *finfo, bint i)
static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst) static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
{ {
if (dst < 0) { /* if unspecified, allocate a new register if needed */
dst = finfo->freereg;
}
be_assert(e != NULL); be_assert(e != NULL);
switch (e->type) { switch (e->type) {
case ETINT: case ETINT:
@ -376,7 +408,7 @@ static int var2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
codeABx(finfo, OP_GETGBL, dst, e->v.idx); codeABx(finfo, OP_GETGBL, dst, e->v.idx);
break; break;
case ETNGLOBAL: case ETNGLOBAL:
codeABC(finfo, OP_GETNGBL, dst, e->v.ss.idx, 0); codeABC(finfo, OP_GETNGBL, dst, e->v.ss.obj, e->v.ss.idx);
break; break;
case ETUPVAL: case ETUPVAL:
codeABx(finfo, OP_GETUPV, dst, e->v.idx); codeABx(finfo, OP_GETUPV, dst, e->v.idx);
@ -420,28 +452,37 @@ static int exp2reg(bfuncinfo *finfo, bexpdesc *e, int dst)
return reg; return reg;
} }
static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2) static int codedestreg(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2, int dst)
{ {
int dst, con1 = e1->type == ETREG, con2 = e2->type == ETREG; int cand_dst = dst;
int con1 = e1->type == ETREG, con2 = e2->type == ETREG;
if (con1 && con2) { if (con1 && con2) {
dst = min(e1->v.idx, e2->v.idx); cand_dst = min(e1->v.idx, e2->v.idx);
be_code_freeregs(finfo, 1); be_code_freeregs(finfo, 1);
} else if (con1) { } else if (con1) {
dst = e1->v.idx; cand_dst = e1->v.idx;
} else if (con2) { } else if (con2) {
dst = e2->v.idx; cand_dst = e2->v.idx;
} else { } else {
dst = be_code_allocregs(finfo, 1); if (dst >= finfo->freereg) {
cand_dst = be_code_allocregs(finfo, 1);
return cand_dst;
}
}
if (dst >= finfo->freereg) {
return cand_dst;
} else {
return dst;
} }
return dst;
} }
static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2) static void binaryexp(bfuncinfo *finfo, bopcode op, bexpdesc *e1, bexpdesc *e2, int dst)
{ {
int src1 = exp2anyreg(finfo, e1); if (dst < 0) { dst = finfo->freereg; }
int src1 = exp2reg(finfo, e1, dst); /* potentially force the target for src1 reg */
int src2 = exp2anyreg(finfo, e2); int src2 = exp2anyreg(finfo, e2);
int dst = codedestreg(finfo, e1, e2); dst = codedestreg(finfo, e1, e2, dst);
codeABC(finfo, op, dst, src1, src2); codeABC(finfo, op, dst, src1, src2);
e1->type = ETREG; e1->type = ETREG;
e1->v.idx = dst; e1->v.idx = dst;
@ -462,7 +503,7 @@ void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e)
} }
} }
void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2) void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst)
{ {
switch (op) { switch (op) {
case OptAnd: case OptAnd:
@ -480,7 +521,7 @@ void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2)
case OptNE: case OptGT: case OptGE: case OptConnect: case OptNE: case OptGT: case OptGE: case OptConnect:
case OptBitAnd: case OptBitOr: case OptBitXor: case OptBitAnd: case OptBitOr: case OptBitXor:
case OptShiftL: case OptShiftR: case OptShiftL: case OptShiftR:
binaryexp(finfo, (bopcode)(op - OptAdd), e1, e2); binaryexp(finfo, (bopcode)(op - OptAdd), e1, e2, dst);
break; break;
default: break; default: break;
} }
@ -560,7 +601,7 @@ static void setbgblvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
code_move(finfo, finfo->freereg, src); code_move(finfo, finfo->freereg, src);
src = finfo->freereg; src = finfo->freereg;
} }
codeABC(finfo, op, src, e1->v.idx, 0); codeABC(finfo, op, src, 0, e1->v.idx);
} }
static void setsupvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src) static void setsupvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
@ -586,7 +627,7 @@ static void setsfxvar(bfuncinfo *finfo, bopcode op, bexpdesc *e1, int src)
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2) int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2)
{ {
int src = exp2reg(finfo, e2, int src = exp2reg(finfo, e2,
e1->type == ETLOCAL ? e1->v.idx : finfo->freereg); e1->type == ETLOCAL ? e1->v.idx : -1);
if (e1->type != ETLOCAL || e1->v.idx != src) { if (e1->type != ETLOCAL || e1->v.idx != src) {
free_expreg(finfo, e2); /* free source (only ETREG) */ free_expreg(finfo, e2); /* free source (only ETREG) */

View File

@ -14,7 +14,7 @@
int be_code_allocregs(bfuncinfo *finfo, int count); int be_code_allocregs(bfuncinfo *finfo, int count);
void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e); void be_code_prebinop(bfuncinfo *finfo, int op, bexpdesc *e);
void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2); void be_code_binop(bfuncinfo *finfo, int op, bexpdesc *e1, bexpdesc *e2, int dst);
int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e); int be_code_unop(bfuncinfo *finfo, int op, bexpdesc *e);
int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2); int be_code_setvar(bfuncinfo *finfo, bexpdesc *e1, bexpdesc *e2);
int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e); int be_code_nextreg(bfuncinfo *finfo, bexpdesc *e);

View File

@ -467,7 +467,6 @@ static int singlevaraux(bvm *vm, bfuncinfo *finfo, bstring *s, bexpdesc *var)
static void singlevar(bparser *parser, bexpdesc *var) static void singlevar(bparser *parser, bexpdesc *var)
{ {
bexpdesc key;
bstring *varname = next_token(parser).u.s; bstring *varname = next_token(parser).u.s;
int type = singlevaraux(parser->vm, parser->finfo, varname, var); int type = singlevaraux(parser->vm, parser->finfo, varname, var);
switch (type) { switch (type) {
@ -480,10 +479,13 @@ static void singlevar(bparser *parser, bexpdesc *var)
var->v.idx = be_global_find(parser->vm, varname); var->v.idx = be_global_find(parser->vm, varname);
break; break;
case ETNGLOBAL: case ETNGLOBAL:
init_exp(&key, ETSTRING, 0); {
key.v.s = varname; bexpdesc key;
init_exp(var, ETNGLOBAL, 0); init_exp(&key, ETSTRING, 0);
var->v.idx = be_code_nglobal(parser->finfo, &key); key.v.s = varname;
init_exp(var, ETNGLOBAL, 0);
var->v.idx = be_code_nglobal(parser->finfo, &key);
}
break; break;
default: default:
break; break;
@ -610,7 +612,7 @@ static void list_nextmember(bparser *parser, bexpdesc *l)
bfuncinfo *finfo = parser->finfo; bfuncinfo *finfo = parser->finfo;
expr(parser, &e); /* value */ expr(parser, &e); /* value */
check_var(parser, &e); check_var(parser, &e);
be_code_binop(finfo, OptConnect, &v, &e); be_code_binop(finfo, OptConnect, &v, &e, -1);
be_code_freeregs(finfo, 1); be_code_freeregs(finfo, 1);
} }
@ -823,9 +825,11 @@ static void suffix_alloc_reg(bparser *parser, bexpdesc *l)
/* compound assignment */ /* compound assignment */
static void compound_assign(bparser *parser, int op, bexpdesc *l, bexpdesc *r) static void compound_assign(bparser *parser, int op, bexpdesc *l, bexpdesc *r)
{ {
int dst = -1; /* destination register in case of compound assignment */
if (op != OptAssign) { /* check left variable */ if (op != OptAssign) { /* check left variable */
check_var(parser, l); check_var(parser, l);
/* cache the register of the object when continuously assigning */ /* cache the register of the object when continuously assigning */
dst = parser->finfo->freereg;
suffix_alloc_reg(parser, l); suffix_alloc_reg(parser, l);
} }
expr(parser, r); /* right expression */ expr(parser, r); /* right expression */
@ -834,7 +838,7 @@ static void compound_assign(bparser *parser, int op, bexpdesc *l, bexpdesc *r)
bexpdesc e = *l; bexpdesc e = *l;
op = op < OptAndAssign ? op - OptAddAssign + OptAdd op = op < OptAndAssign ? op - OptAddAssign + OptAdd
: op - OptAndAssign + OptBitAnd; : op - OptAndAssign + OptBitAnd;
be_code_binop(parser->finfo, op, &e, r); /* coding operation */ be_code_binop(parser->finfo, op, &e, r, dst); /* coding operation */
*r = e; *r = e;
} }
} }
@ -938,7 +942,7 @@ static void sub_expr(bparser *parser, bexpdesc *e, int prio)
init_exp(&e2, ETVOID, 0); init_exp(&e2, ETVOID, 0);
sub_expr(parser, &e2, binary_op_prio(op)); sub_expr(parser, &e2, binary_op_prio(op));
check_var(parser, &e2); check_var(parser, &e2);
be_code_binop(finfo, op, e, &e2); /* encode binary op */ be_code_binop(finfo, op, e, &e2, -1); /* encode binary op */
op = get_binop(parser); op = get_binop(parser);
} }
if (prio == ASSIGN_OP_PRIO) { if (prio == ASSIGN_OP_PRIO) {