Try to predict whether the iterator is next() and specialize the bytecode. ** Detecting next() and pairs() by name is simplistic, but quite effective. ** The interpreter backs off if the check for the closure fails at runtime. */
| 2512 | ** The interpreter backs off if the check for the closure fails at runtime. |
| 2513 | */ |
| 2514 | static int predict_next(LexState *ls, FuncState *fs, BCPos pc) |
| 2515 | { |
| 2516 | BCIns ins = fs->bcbase[pc].ins; |
| 2517 | GCstr *name; |
| 2518 | cTValue *o; |
| 2519 | switch (bc_op(ins)) { |
| 2520 | case BC_MOV: |
| 2521 | name = gco2str(gcref(var_get(ls, fs, bc_d(ins)).name)); |
| 2522 | break; |
| 2523 | case BC_UGET: |
| 2524 | name = gco2str(gcref(ls->vstack[fs->uvmap[bc_d(ins)]].name)); |
| 2525 | break; |
| 2526 | case BC_GGET: |
| 2527 | /* There's no inverse index (yet), so lookup the strings. */ |
| 2528 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "pairs")); |
| 2529 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
| 2530 | return 1; |
| 2531 | o = lj_tab_getstr(fs->kt, lj_str_newlit(ls->L, "next")); |
| 2532 | if (o && tvhaskslot(o) && tvkslot(o) == bc_d(ins)) |
| 2533 | return 1; |
| 2534 | return 0; |
| 2535 | default: |
| 2536 | return 0; |
| 2537 | } |
| 2538 | return (name->len == 5 && !strcmp(strdata(name), "pairs")) || |
| 2539 | (name->len == 4 && !strcmp(strdata(name), "next")); |
| 2540 | } |
| 2541 | |
| 2542 | /* Parse 'for' iterator. */ |
| 2543 | static void parse_for_iter(LexState *ls, GCstr *indexname) |
no test coverage detected