Skip to content

Commit fddf0f0

Browse files
committed
COMMON: update eval for performance
1 parent 36bca1d commit fddf0f0

File tree

4 files changed

+127
-124
lines changed

4 files changed

+127
-124
lines changed

src/common/blib.c

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@ void cmd_dim(int preserve) {
8484
code_skipnext();
8585
zaf = 0;
8686
do {
87+
v_init(&arg);
8788
eval(&arg);
8889
if (prog_error) {
8990
return;
@@ -1755,7 +1756,6 @@ void cmd_next() {
17551756
jump_ip = node.x.vfor.jump_ip;
17561757

17571758
var_p = node.x.vfor.var_ptr;
1758-
// v_init(&var_to);
17591759
var_step.const_flag = 0;
17601760
var_step.type = V_INT;
17611761
var_step.v.i = 1;
@@ -1766,6 +1766,7 @@ void cmd_next() {
17661766
//
17671767

17681768
prog_ip = node.x.vfor.to_expr_ip;
1769+
v_init(&var_to);
17691770
eval(&var_to);
17701771

17711772
if (!prog_error && (var_to.type == V_INT || var_to.type == V_NUM)) {

src/common/device.c

Lines changed: 17 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -355,24 +355,26 @@ void dev_clear_sound_queue() {
355355

356356
/**
357357
* printf
358-
*
359-
* WARNING: Win32/Unix ver is limited to 1024 bytes
360358
*/
361-
void dev_printf(const char *fmt, ...) {
362-
char *buf;
363-
va_list ap;
359+
void dev_printf(const char *format, ...) {
360+
va_list args;
361+
va_start(args, format);
362+
unsigned size = vsnprintf(NULL, 0, format, args);
363+
va_end(args);
364364

365-
va_start(ap, fmt);
366-
buf = malloc(1024);
367-
#if defined(_DOS) || defined(_Win32)
368-
vsprintf(buf, fmt, ap);
369-
#else
370-
vsnprintf(buf, 1024, fmt, ap);
371-
#endif
372-
va_end(ap);
365+
if (size) {
366+
char *buf = malloc(size + 1);
367+
buf[0] = '\0';
368+
va_start(args, format);
369+
vsnprintf(buf, size + 1, format, args);
370+
va_end(args);
373371

374-
dev_print(buf);
375-
free(buf);
372+
buf[size] = '\0';
373+
va_end(args);
374+
375+
dev_print(buf);
376+
free(buf);
377+
}
376378
}
377379

378380
/**

src/common/eval.c

Lines changed: 105 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -274,7 +274,9 @@ int v_wc_match(var_t *vwc, var_t *v) {
274274
return ri;
275275
}
276276

277-
static inline void oper_add(var_t *r, var_t *left, byte op) {
277+
static inline void oper_add(var_t *r, var_t *left) {
278+
byte op = CODE(IP);
279+
IP++;
278280
if (r->type == V_INT && v_is_type(left, V_INT)) {
279281
if (op == '+') {
280282
r->v.i += left->v.i;
@@ -338,12 +340,15 @@ static inline void oper_add(var_t *r, var_t *left, byte op) {
338340
}
339341
}
340342

341-
static inline void oper_mul(var_t *r, var_t *left, byte op) {
343+
static inline void oper_mul(var_t *r, var_t *left) {
342344
var_num_t lf;
343345
var_num_t rf;
344346
var_int_t li;
345347
var_int_t ri;
346348

349+
byte op = CODE(IP);
350+
IP++;
351+
347352
if (r->type == V_ARRAY || v_is_type(left, V_ARRAY)) {
348353
// arrays
349354
if (r->type == V_ARRAY && v_is_type(left, V_ARRAY)) {
@@ -425,10 +430,13 @@ static inline void oper_mul(var_t *r, var_t *left, byte op) {
425430
}
426431
}
427432

428-
static inline void oper_unary(var_t *r, byte op) {
433+
static inline void oper_unary(var_t *r) {
429434
var_int_t ri;
430435
var_num_t rf;
431436

437+
byte op = CODE(IP);
438+
IP++;
439+
432440
switch (op) {
433441
case '-':
434442
if (r->type == V_INT) {
@@ -463,12 +471,16 @@ static inline void oper_unary(var_t *r, byte op) {
463471
}
464472
}
465473

466-
static inline void oper_log(var_t *r, var_t *left, byte op) {
474+
static inline void oper_log(var_t *r, var_t *left) {
467475
var_int_t li;
468476
var_int_t ri;
469477
var_int_t a, b;
470478
int i, set;
471479

480+
// logical/bit
481+
byte op = CODE(IP);
482+
IP++;
483+
472484
if (op != OPLOG_IN) {
473485
li = v_igetval(left);
474486
ri = v_igetval(r);
@@ -550,9 +562,13 @@ static inline void oper_log(var_t *r, var_t *left, byte op) {
550562
r->v.i = ri;
551563
}
552564

553-
static inline void oper_cmp(var_t *r, var_t *left, byte op) {
565+
static inline void oper_cmp(var_t *r, var_t *left) {
554566
var_int_t ri;
555567

568+
// compare
569+
byte op = CODE(IP);
570+
IP++;
571+
556572
switch (op) {
557573
case OPLOG_EQ:
558574
ri = (v_compare(left, r) == 0);
@@ -623,6 +639,9 @@ static inline void oper_cmp(var_t *r, var_t *left, byte op) {
623639
static inline void oper_powr(var_t *r, var_t *left) {
624640
var_num_t rf;
625641

642+
// pow
643+
IP++;
644+
626645
rf = pow(v_getval(left), v_getval(r));
627646
V_FREE(r);
628647
r->type = V_NUM;
@@ -632,10 +651,22 @@ static inline void oper_powr(var_t *r, var_t *left) {
632651
V_FREE(left);
633652
}
634653

635-
static inline void eval_shortc(var_t *r, bcip_t addr, byte op) {
654+
static inline void eval_shortc(var_t *r) {
655+
// short-circuit evaluation
656+
// see cev_log() in ceval.c for layout details
636657
var_int_t li;
637658
var_int_t ri;
638659

660+
// skip code kwTYPE_LOGOPR
661+
IP++;
662+
663+
// read operator
664+
byte op = CODE(IP);
665+
IP++;
666+
667+
// read shortcut jump offset
668+
bcip_t addr = code_getaddr();
669+
639670
// read left side result
640671
li = v_igetval(&eval_stk[eval_sp - 1]);
641672
ri = -1;
@@ -1139,21 +1170,12 @@ static inline void eval_call_udf(var_t *r) {
11391170
* executes the expression (Code[IP]) and returns the result (r)
11401171
*/
11411172
void eval(var_t *r) {
1142-
code_t code;
1143-
byte op;
1144-
var_t *var_p;
1145-
bcip_t addr;
1146-
11471173
var_t *left = NULL;
11481174
bcip_t eval_pos = eval_sp;
11491175
byte level = 0;
11501176

1151-
r->const_flag = 0;
1152-
r->type = V_INT;
1153-
r->v.i = 0L;
1154-
11551177
do {
1156-
code = CODE(IP);
1178+
code_t code = CODE(IP);
11571179
IP++;
11581180
switch (code) {
11591181
case kwTYPE_INT:
@@ -1176,91 +1198,41 @@ void eval(var_t *r) {
11761198
v_eval_str(r);
11771199
break;
11781200

1179-
case kwTYPE_PTR:
1180-
// UDF pointer - constant
1181-
V_FREE(r);
1182-
r->type = V_PTR;
1183-
r->const_flag = 1;
1184-
r->v.ap.p = code_getaddr();
1185-
r->v.ap.v = code_getaddr();
1186-
break;
1187-
1188-
case kwTYPE_VAR:
1189-
// variable
1190-
V_FREE(r);
1191-
IP--;
1192-
var_p = code_getvarptr();
1193-
if (prog_error) {
1194-
return;
1195-
}
1196-
eval_var(r, var_p);
1197-
break;
1198-
1199-
case kwTYPE_EVPUSH:
1200-
// stack = push result
1201-
eval_push(r);
1201+
case kwTYPE_LOGOPR:
1202+
oper_log(r, left);
12021203
break;
12031204

1204-
case kwTYPE_EVPOP:
1205-
// pop left
1206-
eval_sp--;
1207-
left = &eval_stk[eval_sp];
1205+
case kwTYPE_CMPOPR:
1206+
oper_cmp(r, left);
12081207
break;
12091208

12101209
case kwTYPE_ADDOPR:
1211-
op = CODE(IP);
1212-
IP++;
1213-
oper_add(r, left, op);
1210+
oper_add(r, left);
12141211
break;
12151212

12161213
case kwTYPE_MULOPR:
1217-
op = CODE(IP);
1218-
IP++;
1219-
oper_mul(r, left, op);
1220-
break;
1221-
1222-
case kwTYPE_UNROPR:
1223-
// unary
1224-
op = CODE(IP);
1225-
IP++;
1226-
oper_unary(r, op);
1227-
break;
1228-
1229-
case kwTYPE_EVAL_SC:
1230-
// short-circuit evaluation
1231-
// see cev_log() in ceval.c for layout details
1232-
1233-
// skip code kwTYPE_LOGOPR
1234-
IP++;
1235-
1236-
// read operator
1237-
op = CODE(IP);
1238-
IP++;
1239-
1240-
// read shortcut jump offset
1241-
addr = code_getaddr();
1242-
eval_shortc(r, addr, op);
1214+
oper_mul(r, left);
12431215
break;
12441216

1245-
case kwTYPE_LOGOPR:
1246-
// logical/bit
1247-
op = CODE(IP);
1248-
IP++;
1249-
oper_log(r, left, op);
1217+
case kwTYPE_POWOPR:
1218+
oper_powr(r, left);
12501219
break;
12511220

1252-
case kwTYPE_CMPOPR:
1253-
// compare
1254-
op = CODE(IP);
1255-
IP++;
1256-
oper_cmp(r, left, op);
1221+
case kwTYPE_UNROPR:
1222+
// unary
1223+
oper_unary(r);
12571224
break;
12581225

1259-
case kwTYPE_POWOPR:
1260-
// pow
1261-
op = CODE(IP);
1262-
IP++;
1263-
oper_powr(r, left);
1226+
case kwTYPE_VAR: {
1227+
// variable
1228+
V_FREE(r);
1229+
IP--;
1230+
var_t *var_p = code_getvarptr();
1231+
if (prog_error) {
1232+
return;
1233+
}
1234+
eval_var(r, var_p);
1235+
}
12641236
break;
12651237

12661238
case kwTYPE_LEVEL_BEGIN:
@@ -1279,9 +1251,19 @@ void eval(var_t *r) {
12791251
level--;
12801252
break;
12811253

1282-
case kwTYPE_CALLEXTF:
1283-
// [lib][index] external functions
1284-
eval_extf(r);
1254+
case kwTYPE_EVPUSH:
1255+
// stack = push result
1256+
eval_push(r);
1257+
break;
1258+
1259+
case kwTYPE_EVPOP:
1260+
// pop left
1261+
eval_sp--;
1262+
left = &eval_stk[eval_sp];
1263+
break;
1264+
1265+
case kwTYPE_EVAL_SC:
1266+
eval_shortc(r);
12851267
break;
12861268

12871269
case kwTYPE_CALLF:
@@ -1293,23 +1275,41 @@ void eval(var_t *r) {
12931275
eval_call_udf(r);
12941276
break;
12951277

1296-
case kwBYREF:
1297-
// unexpected code
1298-
err_evsyntax();
1299-
break;
1300-
13011278
default:
1302-
if (code == kwTYPE_EOC || kw_check_evexit(code)) {
1303-
IP--;
1304-
// restore stack pointer
1305-
eval_sp = eval_pos;
1279+
// less used codes
1280+
switch (code) {
1281+
case kwTYPE_CALLEXTF:
1282+
// [lib][index] external functions
1283+
eval_extf(r);
1284+
break;
13061285

1307-
// normal exit
1308-
return;
1309-
}
1310-
rt_raise("UNKNOWN ERROR. IP:%d=0x%02X", IP, code);
1311-
if (!opt_quiet) {
1312-
hex_dump(prog_source, prog_length);
1286+
case kwTYPE_PTR:
1287+
// UDF pointer - constant
1288+
V_FREE(r);
1289+
r->type = V_PTR;
1290+
r->const_flag = 1;
1291+
r->v.ap.p = code_getaddr();
1292+
r->v.ap.v = code_getaddr();
1293+
break;
1294+
1295+
case kwBYREF:
1296+
// unexpected code
1297+
err_evsyntax();
1298+
break;
1299+
1300+
default:
1301+
if (code == kwTYPE_EOC || kw_check_evexit(code)) {
1302+
IP--;
1303+
// restore stack pointer
1304+
eval_sp = eval_pos;
1305+
1306+
// normal exit
1307+
return;
1308+
}
1309+
rt_raise("UNKNOWN ERROR. IP:%d=0x%02X", IP, code);
1310+
if (!opt_quiet) {
1311+
hex_dump(prog_source, prog_length);
1312+
}
13131313
}
13141314
};
13151315

0 commit comments

Comments
 (0)