diff options
Diffstat (limited to 'src/lib_base.c')
-rw-r--r-- | src/lib_base.c | 156 |
1 files changed, 83 insertions, 73 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index 6c96e8d5..98ec67c7 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -19,10 +19,12 @@ | |||
19 | #include "lj_gc.h" | 19 | #include "lj_gc.h" |
20 | #include "lj_err.h" | 20 | #include "lj_err.h" |
21 | #include "lj_debug.h" | 21 | #include "lj_debug.h" |
22 | #include "lj_buf.h" | ||
22 | #include "lj_str.h" | 23 | #include "lj_str.h" |
23 | #include "lj_tab.h" | 24 | #include "lj_tab.h" |
24 | #include "lj_meta.h" | 25 | #include "lj_meta.h" |
25 | #include "lj_state.h" | 26 | #include "lj_state.h" |
27 | #include "lj_frame.h" | ||
26 | #if LJ_HASFFI | 28 | #if LJ_HASFFI |
27 | #include "lj_ctype.h" | 29 | #include "lj_ctype.h" |
28 | #include "lj_cconv.h" | 30 | #include "lj_cconv.h" |
@@ -32,6 +34,7 @@ | |||
32 | #include "lj_dispatch.h" | 34 | #include "lj_dispatch.h" |
33 | #include "lj_char.h" | 35 | #include "lj_char.h" |
34 | #include "lj_strscan.h" | 36 | #include "lj_strscan.h" |
37 | #include "lj_strfmt.h" | ||
35 | #include "lj_lib.h" | 38 | #include "lj_lib.h" |
36 | 39 | ||
37 | /* -- Base library: checks ------------------------------------------------ */ | 40 | /* -- Base library: checks ------------------------------------------------ */ |
@@ -40,13 +43,13 @@ | |||
40 | 43 | ||
41 | LJLIB_ASM(assert) LJLIB_REC(.) | 44 | LJLIB_ASM(assert) LJLIB_REC(.) |
42 | { | 45 | { |
43 | GCstr *s; | ||
44 | lj_lib_checkany(L, 1); | 46 | lj_lib_checkany(L, 1); |
45 | s = lj_lib_optstr(L, 2); | 47 | if (L->top == L->base+1) |
46 | if (s) | ||
47 | lj_err_callermsg(L, strdata(s)); | ||
48 | else | ||
49 | lj_err_caller(L, LJ_ERR_ASSERT); | 48 | lj_err_caller(L, LJ_ERR_ASSERT); |
49 | else if (tvisstr(L->base+1) || tvisnumber(L->base+1)) | ||
50 | lj_err_callermsg(L, strdata(lj_lib_checkstr(L, 2))); | ||
51 | else | ||
52 | lj_err_run(L); | ||
50 | return FFH_UNREACHABLE; | 53 | return FFH_UNREACHABLE; |
51 | } | 54 | } |
52 | 55 | ||
@@ -73,9 +76,10 @@ LJLIB_ASM_(type) LJLIB_REC(.) | |||
73 | /* This solves a circular dependency problem -- change FF_next_N as needed. */ | 76 | /* This solves a circular dependency problem -- change FF_next_N as needed. */ |
74 | LJ_STATIC_ASSERT((int)FF_next == FF_next_N); | 77 | LJ_STATIC_ASSERT((int)FF_next == FF_next_N); |
75 | 78 | ||
76 | LJLIB_ASM(next) | 79 | LJLIB_ASM(next) LJLIB_REC(.) |
77 | { | 80 | { |
78 | lj_lib_checktab(L, 1); | 81 | lj_lib_checktab(L, 1); |
82 | lj_err_msg(L, LJ_ERR_NEXTIDX); | ||
79 | return FFH_UNREACHABLE; | 83 | return FFH_UNREACHABLE; |
80 | } | 84 | } |
81 | 85 | ||
@@ -86,10 +90,11 @@ static int ffh_pairs(lua_State *L, MMS mm) | |||
86 | cTValue *mo = lj_meta_lookup(L, o, mm); | 90 | cTValue *mo = lj_meta_lookup(L, o, mm); |
87 | if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) { | 91 | if ((LJ_52 || tviscdata(o)) && !tvisnil(mo)) { |
88 | L->top = o+1; /* Only keep one argument. */ | 92 | L->top = o+1; /* Only keep one argument. */ |
89 | copyTV(L, L->base-1, mo); /* Replace callable. */ | 93 | copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */ |
90 | return FFH_TAILCALL; | 94 | return FFH_TAILCALL; |
91 | } else { | 95 | } else { |
92 | if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); | 96 | if (!tvistab(o)) lj_err_argt(L, 1, LUA_TTABLE); |
97 | if (LJ_FR2) { copyTV(L, o-1, o); o--; } | ||
93 | setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); | 98 | setfuncV(L, o-1, funcV(lj_lib_upvalue(L, 1))); |
94 | if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); | 99 | if (mm == MM_pairs) setnilV(o+1); else setintV(o+1, 0); |
95 | return FFH_RES(3); | 100 | return FFH_RES(3); |
@@ -100,7 +105,7 @@ static int ffh_pairs(lua_State *L, MMS mm) | |||
100 | #endif | 105 | #endif |
101 | 106 | ||
102 | LJLIB_PUSH(lastcl) | 107 | LJLIB_PUSH(lastcl) |
103 | LJLIB_ASM(pairs) | 108 | LJLIB_ASM(pairs) LJLIB_REC(xpairs 0) |
104 | { | 109 | { |
105 | return ffh_pairs(L, MM_pairs); | 110 | return ffh_pairs(L, MM_pairs); |
106 | } | 111 | } |
@@ -113,7 +118,7 @@ LJLIB_NOREGUV LJLIB_ASM(ipairs_aux) LJLIB_REC(.) | |||
113 | } | 118 | } |
114 | 119 | ||
115 | LJLIB_PUSH(lastcl) | 120 | LJLIB_PUSH(lastcl) |
116 | LJLIB_ASM(ipairs) LJLIB_REC(.) | 121 | LJLIB_ASM(ipairs) LJLIB_REC(xpairs 1) |
117 | { | 122 | { |
118 | return ffh_pairs(L, MM_ipairs); | 123 | return ffh_pairs(L, MM_ipairs); |
119 | } | 124 | } |
@@ -131,11 +136,11 @@ LJLIB_ASM(setmetatable) LJLIB_REC(.) | |||
131 | lj_err_caller(L, LJ_ERR_PROTMT); | 136 | lj_err_caller(L, LJ_ERR_PROTMT); |
132 | setgcref(t->metatable, obj2gco(mt)); | 137 | setgcref(t->metatable, obj2gco(mt)); |
133 | if (mt) { lj_gc_objbarriert(L, t, mt); } | 138 | if (mt) { lj_gc_objbarriert(L, t, mt); } |
134 | settabV(L, L->base-1, t); | 139 | settabV(L, L->base-1-LJ_FR2, t); |
135 | return FFH_RES(1); | 140 | return FFH_RES(1); |
136 | } | 141 | } |
137 | 142 | ||
138 | LJLIB_CF(getfenv) | 143 | LJLIB_CF(getfenv) LJLIB_REC(.) |
139 | { | 144 | { |
140 | GCfunc *fn; | 145 | GCfunc *fn; |
141 | cTValue *o = L->base; | 146 | cTValue *o = L->base; |
@@ -144,6 +149,7 @@ LJLIB_CF(getfenv) | |||
144 | o = lj_debug_frame(L, level, &level); | 149 | o = lj_debug_frame(L, level, &level); |
145 | if (o == NULL) | 150 | if (o == NULL) |
146 | lj_err_arg(L, 1, LJ_ERR_INVLVL); | 151 | lj_err_arg(L, 1, LJ_ERR_INVLVL); |
152 | if (LJ_FR2) o--; | ||
147 | } | 153 | } |
148 | fn = &gcval(o)->fn; | 154 | fn = &gcval(o)->fn; |
149 | settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env)); | 155 | settabV(L, L->top++, isluafunc(fn) ? tabref(fn->l.env) : tabref(L->env)); |
@@ -165,6 +171,7 @@ LJLIB_CF(setfenv) | |||
165 | o = lj_debug_frame(L, level, &level); | 171 | o = lj_debug_frame(L, level, &level); |
166 | if (o == NULL) | 172 | if (o == NULL) |
167 | lj_err_arg(L, 1, LJ_ERR_INVLVL); | 173 | lj_err_arg(L, 1, LJ_ERR_INVLVL); |
174 | if (LJ_FR2) o--; | ||
168 | } | 175 | } |
169 | fn = &gcval(o)->fn; | 176 | fn = &gcval(o)->fn; |
170 | if (!isluafunc(fn)) | 177 | if (!isluafunc(fn)) |
@@ -259,7 +266,7 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
259 | if (base == 10) { | 266 | if (base == 10) { |
260 | TValue *o = lj_lib_checkany(L, 1); | 267 | TValue *o = lj_lib_checkany(L, 1); |
261 | if (lj_strscan_numberobj(o)) { | 268 | if (lj_strscan_numberobj(o)) { |
262 | copyTV(L, L->base-1, o); | 269 | copyTV(L, L->base-1-LJ_FR2, o); |
263 | return FFH_RES(1); | 270 | return FFH_RES(1); |
264 | } | 271 | } |
265 | #if LJ_HASFFI | 272 | #if LJ_HASFFI |
@@ -272,11 +279,11 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
272 | ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) { | 279 | ct->size <= 4 && !(ct->size == 4 && (ct->info & CTF_UNSIGNED))) { |
273 | int32_t i; | 280 | int32_t i; |
274 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); | 281 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_INT32), (uint8_t *)&i, o, 0); |
275 | setintV(L->base-1, i); | 282 | setintV(L->base-1-LJ_FR2, i); |
276 | return FFH_RES(1); | 283 | return FFH_RES(1); |
277 | } | 284 | } |
278 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE), | 285 | lj_cconv_ct_tv(cts, ctype_get(cts, CTID_DOUBLE), |
279 | (uint8_t *)&(L->base-1)->n, o, 0); | 286 | (uint8_t *)&(L->base-1-LJ_FR2)->n, o, 0); |
280 | return FFH_RES(1); | 287 | return FFH_RES(1); |
281 | } | 288 | } |
282 | } | 289 | } |
@@ -284,53 +291,46 @@ LJLIB_ASM(tonumber) LJLIB_REC(.) | |||
284 | } else { | 291 | } else { |
285 | const char *p = strdata(lj_lib_checkstr(L, 1)); | 292 | const char *p = strdata(lj_lib_checkstr(L, 1)); |
286 | char *ep; | 293 | char *ep; |
294 | unsigned int neg = 0; | ||
287 | unsigned long ul; | 295 | unsigned long ul; |
288 | if (base < 2 || base > 36) | 296 | if (base < 2 || base > 36) |
289 | lj_err_arg(L, 2, LJ_ERR_BASERNG); | 297 | lj_err_arg(L, 2, LJ_ERR_BASERNG); |
290 | ul = strtoul(p, &ep, base); | 298 | while (lj_char_isspace((unsigned char)(*p))) p++; |
291 | if (p != ep) { | 299 | if (*p == '-') { p++; neg = 1; } else if (*p == '+') { p++; } |
292 | while (lj_char_isspace((unsigned char)(*ep))) ep++; | 300 | if (lj_char_isalnum((unsigned char)(*p))) { |
293 | if (*ep == '\0') { | 301 | ul = strtoul(p, &ep, base); |
294 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u)) | 302 | if (p != ep) { |
295 | setintV(L->base-1, (int32_t)ul); | 303 | while (lj_char_isspace((unsigned char)(*ep))) ep++; |
296 | else | 304 | if (*ep == '\0') { |
297 | setnumV(L->base-1, (lua_Number)ul); | 305 | if (LJ_DUALNUM && LJ_LIKELY(ul < 0x80000000u+neg)) { |
298 | return FFH_RES(1); | 306 | if (neg) ul = (unsigned long)-(long)ul; |
307 | setintV(L->base-1-LJ_FR2, (int32_t)ul); | ||
308 | } else { | ||
309 | lua_Number n = (lua_Number)ul; | ||
310 | if (neg) n = -n; | ||
311 | setnumV(L->base-1-LJ_FR2, n); | ||
312 | } | ||
313 | return FFH_RES(1); | ||
314 | } | ||
299 | } | 315 | } |
300 | } | 316 | } |
301 | } | 317 | } |
302 | setnilV(L->base-1); | 318 | setnilV(L->base-1-LJ_FR2); |
303 | return FFH_RES(1); | 319 | return FFH_RES(1); |
304 | } | 320 | } |
305 | 321 | ||
306 | LJLIB_PUSH("nil") | ||
307 | LJLIB_PUSH("false") | ||
308 | LJLIB_PUSH("true") | ||
309 | LJLIB_ASM(tostring) LJLIB_REC(.) | 322 | LJLIB_ASM(tostring) LJLIB_REC(.) |
310 | { | 323 | { |
311 | TValue *o = lj_lib_checkany(L, 1); | 324 | TValue *o = lj_lib_checkany(L, 1); |
312 | cTValue *mo; | 325 | cTValue *mo; |
313 | L->top = o+1; /* Only keep one argument. */ | 326 | L->top = o+1; /* Only keep one argument. */ |
314 | if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { | 327 | if (!tvisnil(mo = lj_meta_lookup(L, o, MM_tostring))) { |
315 | copyTV(L, L->base-1, mo); /* Replace callable. */ | 328 | copyTV(L, L->base-1-LJ_FR2, mo); /* Replace callable. */ |
316 | return FFH_TAILCALL; | 329 | return FFH_TAILCALL; |
317 | } else { | ||
318 | GCstr *s; | ||
319 | if (tvisnumber(o)) { | ||
320 | s = lj_str_fromnumber(L, o); | ||
321 | } else if (tvispri(o)) { | ||
322 | s = strV(lj_lib_upvalue(L, -(int32_t)itype(o))); | ||
323 | } else { | ||
324 | if (tvisfunc(o) && isffunc(funcV(o))) | ||
325 | lua_pushfstring(L, "function: builtin#%d", funcV(o)->c.ffid); | ||
326 | else | ||
327 | lua_pushfstring(L, "%s: %p", lj_typename(o), lua_topointer(L, 1)); | ||
328 | /* Note: lua_pushfstring calls the GC which may invalidate o. */ | ||
329 | s = strV(L->top-1); | ||
330 | } | ||
331 | setstrV(L, L->base-1, s); | ||
332 | return FFH_RES(1); | ||
333 | } | 330 | } |
331 | lj_gc_check(L); | ||
332 | setstrV(L, L->base-1-LJ_FR2, lj_strfmt_obj(L, L->base)); | ||
333 | return FFH_RES(1); | ||
334 | } | 334 | } |
335 | 335 | ||
336 | /* -- Base library: throw and catch errors -------------------------------- */ | 336 | /* -- Base library: throw and catch errors -------------------------------- */ |
@@ -359,7 +359,7 @@ LJLIB_ASM_(xpcall) LJLIB_REC(.) | |||
359 | 359 | ||
360 | static int load_aux(lua_State *L, int status, int envarg) | 360 | static int load_aux(lua_State *L, int status, int envarg) |
361 | { | 361 | { |
362 | if (status == 0) { | 362 | if (status == LUA_OK) { |
363 | if (tvistab(L->base+envarg-1)) { | 363 | if (tvistab(L->base+envarg-1)) { |
364 | GCfunc *fn = funcV(L->top-1); | 364 | GCfunc *fn = funcV(L->top-1); |
365 | GCtab *t = tabV(L->base+envarg-1); | 365 | GCtab *t = tabV(L->base+envarg-1); |
@@ -408,10 +408,22 @@ LJLIB_CF(load) | |||
408 | GCstr *name = lj_lib_optstr(L, 2); | 408 | GCstr *name = lj_lib_optstr(L, 2); |
409 | GCstr *mode = lj_lib_optstr(L, 3); | 409 | GCstr *mode = lj_lib_optstr(L, 3); |
410 | int status; | 410 | int status; |
411 | if (L->base < L->top && (tvisstr(L->base) || tvisnumber(L->base))) { | 411 | if (L->base < L->top && |
412 | GCstr *s = lj_lib_checkstr(L, 1); | 412 | (tvisstr(L->base) || tvisnumber(L->base) || tvisbuf(L->base))) { |
413 | const char *s; | ||
414 | MSize len; | ||
415 | if (tvisbuf(L->base)) { | ||
416 | SBufExt *sbx = bufV(L->base); | ||
417 | s = sbx->r; | ||
418 | len = sbufxlen(sbx); | ||
419 | if (!name) name = &G(L)->strempty; /* Buffers are not NUL-terminated. */ | ||
420 | } else { | ||
421 | GCstr *str = lj_lib_checkstr(L, 1); | ||
422 | s = strdata(str); | ||
423 | len = str->len; | ||
424 | } | ||
413 | lua_settop(L, 4); /* Ensure env arg exists. */ | 425 | lua_settop(L, 4); /* Ensure env arg exists. */ |
414 | status = luaL_loadbufferx(L, strdata(s), s->len, strdata(name ? name : s), | 426 | status = luaL_loadbufferx(L, s, len, name ? strdata(name) : s, |
415 | mode ? strdata(mode) : NULL); | 427 | mode ? strdata(mode) : NULL); |
416 | } else { | 428 | } else { |
417 | lj_lib_checkfunc(L, 1); | 429 | lj_lib_checkfunc(L, 1); |
@@ -432,7 +444,7 @@ LJLIB_CF(dofile) | |||
432 | GCstr *fname = lj_lib_optstr(L, 1); | 444 | GCstr *fname = lj_lib_optstr(L, 1); |
433 | setnilV(L->top); | 445 | setnilV(L->top); |
434 | L->top = L->base+1; | 446 | L->top = L->base+1; |
435 | if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != 0) | 447 | if (luaL_loadfile(L, fname ? strdata(fname) : NULL) != LUA_OK) |
436 | lua_error(L); | 448 | lua_error(L); |
437 | lua_call(L, 0, LUA_MULTRET); | 449 | lua_call(L, 0, LUA_MULTRET); |
438 | return (int)(L->top - L->base) - 1; | 450 | return (int)(L->top - L->base) - 1; |
@@ -442,20 +454,20 @@ LJLIB_CF(dofile) | |||
442 | 454 | ||
443 | LJLIB_CF(gcinfo) | 455 | LJLIB_CF(gcinfo) |
444 | { | 456 | { |
445 | setintV(L->top++, (G(L)->gc.total >> 10)); | 457 | setintV(L->top++, (int32_t)(G(L)->gc.total >> 10)); |
446 | return 1; | 458 | return 1; |
447 | } | 459 | } |
448 | 460 | ||
449 | LJLIB_CF(collectgarbage) | 461 | LJLIB_CF(collectgarbage) |
450 | { | 462 | { |
451 | int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */ | 463 | int opt = lj_lib_checkopt(L, 1, LUA_GCCOLLECT, /* ORDER LUA_GC* */ |
452 | "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul"); | 464 | "\4stop\7restart\7collect\5count\1\377\4step\10setpause\12setstepmul\1\377\11isrunning"); |
453 | int32_t data = lj_lib_optint(L, 2, 0); | 465 | int32_t data = lj_lib_optint(L, 2, 0); |
454 | if (opt == LUA_GCCOUNT) { | 466 | if (opt == LUA_GCCOUNT) { |
455 | setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0); | 467 | setnumV(L->top, (lua_Number)G(L)->gc.total/1024.0); |
456 | } else { | 468 | } else { |
457 | int res = lua_gc(L, opt, data); | 469 | int res = lua_gc(L, opt, data); |
458 | if (opt == LUA_GCSTEP) | 470 | if (opt == LUA_GCSTEP || opt == LUA_GCISRUNNING) |
459 | setboolV(L->top, res); | 471 | setboolV(L->top, res); |
460 | else | 472 | else |
461 | setintV(L->top, res); | 473 | setintV(L->top, res); |
@@ -507,23 +519,14 @@ LJLIB_CF(print) | |||
507 | tv = L->top-1; | 519 | tv = L->top-1; |
508 | } | 520 | } |
509 | shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring) && | 521 | shortcut = (tvisfunc(tv) && funcV(tv)->c.ffid == FF_tostring) && |
510 | !gcrefu(basemt_it(G(L), LJ_TNUMX)); | 522 | !gcrefu(basemt_it(G(L), LJ_TNUMX)); |
511 | for (i = 0; i < nargs; i++) { | 523 | for (i = 0; i < nargs; i++) { |
524 | cTValue *o = &L->base[i]; | ||
512 | const char *str; | 525 | const char *str; |
513 | size_t size; | 526 | size_t size; |
514 | cTValue *o = &L->base[i]; | 527 | MSize len; |
515 | if (shortcut && tvisstr(o)) { | 528 | if (shortcut && (str = lj_strfmt_wstrnum(L, o, &len)) != NULL) { |
516 | str = strVdata(o); | 529 | size = len; |
517 | size = strV(o)->len; | ||
518 | } else if (shortcut && tvisint(o)) { | ||
519 | char buf[LJ_STR_INTBUF]; | ||
520 | char *p = lj_str_bufint(buf, intV(o)); | ||
521 | size = (size_t)(buf+LJ_STR_INTBUF-p); | ||
522 | str = p; | ||
523 | } else if (shortcut && tvisnum(o)) { | ||
524 | char buf[LJ_STR_NUMBUF]; | ||
525 | size = lj_str_bufnum(buf, o); | ||
526 | str = buf; | ||
527 | } else { | 530 | } else { |
528 | copyTV(L, L->top+1, o); | 531 | copyTV(L, L->top+1, o); |
529 | copyTV(L, L->top, L->top-1); | 532 | copyTV(L, L->top, L->top-1); |
@@ -560,8 +563,8 @@ LJLIB_CF(coroutine_status) | |||
560 | co = threadV(L->base); | 563 | co = threadV(L->base); |
561 | if (co == L) s = "running"; | 564 | if (co == L) s = "running"; |
562 | else if (co->status == LUA_YIELD) s = "suspended"; | 565 | else if (co->status == LUA_YIELD) s = "suspended"; |
563 | else if (co->status != 0) s = "dead"; | 566 | else if (co->status != LUA_OK) s = "dead"; |
564 | else if (co->base > tvref(co->stack)+1) s = "normal"; | 567 | else if (co->base > tvref(co->stack)+1+LJ_FR2) s = "normal"; |
565 | else if (co->top == co->base) s = "dead"; | 568 | else if (co->top == co->base) s = "dead"; |
566 | else s = "suspended"; | 569 | else s = "suspended"; |
567 | lua_pushstring(L, s); | 570 | lua_pushstring(L, s); |
@@ -581,6 +584,12 @@ LJLIB_CF(coroutine_running) | |||
581 | #endif | 584 | #endif |
582 | } | 585 | } |
583 | 586 | ||
587 | LJLIB_CF(coroutine_isyieldable) | ||
588 | { | ||
589 | setboolV(L->top++, cframe_canyield(L->cframe)); | ||
590 | return 1; | ||
591 | } | ||
592 | |||
584 | LJLIB_CF(coroutine_create) | 593 | LJLIB_CF(coroutine_create) |
585 | { | 594 | { |
586 | lua_State *L1; | 595 | lua_State *L1; |
@@ -600,11 +609,11 @@ LJLIB_ASM(coroutine_yield) | |||
600 | static int ffh_resume(lua_State *L, lua_State *co, int wrap) | 609 | static int ffh_resume(lua_State *L, lua_State *co, int wrap) |
601 | { | 610 | { |
602 | if (co->cframe != NULL || co->status > LUA_YIELD || | 611 | if (co->cframe != NULL || co->status > LUA_YIELD || |
603 | (co->status == 0 && co->top == co->base)) { | 612 | (co->status == LUA_OK && co->top == co->base)) { |
604 | ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; | 613 | ErrMsg em = co->cframe ? LJ_ERR_CORUN : LJ_ERR_CODEAD; |
605 | if (wrap) lj_err_caller(L, em); | 614 | if (wrap) lj_err_caller(L, em); |
606 | setboolV(L->base-1, 0); | 615 | setboolV(L->base-1-LJ_FR2, 0); |
607 | setstrV(L, L->base, lj_err_str(L, em)); | 616 | setstrV(L, L->base-LJ_FR2, lj_err_str(L, em)); |
608 | return FFH_RES(2); | 617 | return FFH_RES(2); |
609 | } | 618 | } |
610 | lj_state_growstack(co, (MSize)(L->top - L->base)); | 619 | lj_state_growstack(co, (MSize)(L->top - L->base)); |
@@ -645,9 +654,10 @@ static void setpc_wrap_aux(lua_State *L, GCfunc *fn); | |||
645 | 654 | ||
646 | LJLIB_CF(coroutine_wrap) | 655 | LJLIB_CF(coroutine_wrap) |
647 | { | 656 | { |
657 | GCfunc *fn; | ||
648 | lj_cf_coroutine_create(L); | 658 | lj_cf_coroutine_create(L); |
649 | lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1); | 659 | fn = lj_lib_pushcc(L, lj_ffh_coroutine_wrap_aux, FF_coroutine_wrap_aux, 1); |
650 | setpc_wrap_aux(L, funcV(L->top-1)); | 660 | setpc_wrap_aux(L, fn); |
651 | return 1; | 661 | return 1; |
652 | } | 662 | } |
653 | 663 | ||