diff options
Diffstat (limited to 'src/lj_parse.c')
-rw-r--r-- | src/lj_parse.c | 20 |
1 files changed, 12 insertions, 8 deletions
diff --git a/src/lj_parse.c b/src/lj_parse.c index bd9d9a7a..f0bb4419 100644 --- a/src/lj_parse.c +++ b/src/lj_parse.c | |||
@@ -513,6 +513,7 @@ static void expr_toreg_nobranch(FuncState *fs, ExpDesc *e, BCReg reg) | |||
513 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); | 513 | ins = BCINS_AD(BC_KNUM, reg, const_num(fs, e)); |
514 | #if LJ_HASFFI | 514 | #if LJ_HASFFI |
515 | } else if (e->k == VKCDATA) { | 515 | } else if (e->k == VKCDATA) { |
516 | fs->flags |= PROTO_FFI; | ||
516 | ins = BCINS_AD(BC_KCDATA, reg, | 517 | ins = BCINS_AD(BC_KCDATA, reg, |
517 | const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); | 518 | const_gc(fs, obj2gco(cdataV(&e->u.nval)), LJ_TCDATA)); |
518 | #endif | 519 | #endif |
@@ -1120,7 +1121,7 @@ static void fs_fixup_bc(FuncState *fs, GCproto *pt, BCIns *bc, MSize n) | |||
1120 | BCInsLine *base = fs->bcbase; | 1121 | BCInsLine *base = fs->bcbase; |
1121 | MSize i; | 1122 | MSize i; |
1122 | pt->sizebc = n; | 1123 | pt->sizebc = n; |
1123 | bc[0] = BCINS_AD((fs->flags & PROTO_IS_VARARG) ? BC_FUNCV : BC_FUNCF, | 1124 | bc[0] = BCINS_AD((fs->flags & PROTO_VARARG) ? BC_FUNCV : BC_FUNCF, |
1124 | fs->framesize, 0); | 1125 | fs->framesize, 0); |
1125 | for (i = 1; i < n; i++) | 1126 | for (i = 1; i < n; i++) |
1126 | bc[i] = base[i].ins; | 1127 | bc[i] = base[i].ins; |
@@ -1336,7 +1337,7 @@ static void fs_fixup_ret(FuncState *fs) | |||
1336 | { | 1337 | { |
1337 | BCPos lastpc = fs->pc; | 1338 | BCPos lastpc = fs->pc; |
1338 | if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { | 1339 | if (lastpc <= fs->lasttarget || !bcopisret(bc_op(fs->bcbase[lastpc-1].ins))) { |
1339 | if (fs->flags & PROTO_HAS_FNEW) | 1340 | if (fs->flags & PROTO_CHILD) |
1340 | bcemit_AJ(fs, BC_UCLO, 0, 0); | 1341 | bcemit_AJ(fs, BC_UCLO, 0, 0); |
1341 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ | 1342 | bcemit_AD(fs, BC_RET0, 0, 1); /* Need final return. */ |
1342 | } | 1343 | } |
@@ -1615,7 +1616,7 @@ static BCReg parse_params(LexState *ls, int needself) | |||
1615 | var_new(ls, nparams++, lex_str(ls)); | 1616 | var_new(ls, nparams++, lex_str(ls)); |
1616 | } else if (ls->token == TK_dots) { | 1617 | } else if (ls->token == TK_dots) { |
1617 | lj_lex_next(ls); | 1618 | lj_lex_next(ls); |
1618 | fs->flags |= PROTO_IS_VARARG; | 1619 | fs->flags |= PROTO_VARARG; |
1619 | break; | 1620 | break; |
1620 | } else { | 1621 | } else { |
1621 | err_syntax(ls, LJ_ERR_XPARAM); | 1622 | err_syntax(ls, LJ_ERR_XPARAM); |
@@ -1652,10 +1653,13 @@ static void parse_body(LexState *ls, ExpDesc *e, int needself, BCLine line) | |||
1652 | /* Store new prototype in the constant array of the parent. */ | 1653 | /* Store new prototype in the constant array of the parent. */ |
1653 | expr_init(e, VRELOCABLE, | 1654 | expr_init(e, VRELOCABLE, |
1654 | bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); | 1655 | bcemit_AD(pfs, BC_FNEW, 0, const_gc(pfs, obj2gco(pt), LJ_TPROTO))); |
1655 | if (!(pfs->flags & PROTO_HAS_FNEW)) { | 1656 | #if LJ_HASFFI |
1657 | pfs->flags |= (fs.flags & PROTO_FFI); | ||
1658 | #endif | ||
1659 | if (!(pfs->flags & PROTO_CHILD)) { | ||
1656 | if (pfs->flags & PROTO_HAS_RETURN) | 1660 | if (pfs->flags & PROTO_HAS_RETURN) |
1657 | pfs->flags |= PROTO_FIXUP_RETURN; | 1661 | pfs->flags |= PROTO_FIXUP_RETURN; |
1658 | pfs->flags |= PROTO_HAS_FNEW; | 1662 | pfs->flags |= PROTO_CHILD; |
1659 | } | 1663 | } |
1660 | lj_lex_next(ls); | 1664 | lj_lex_next(ls); |
1661 | } | 1665 | } |
@@ -1781,7 +1785,7 @@ static void expr_simple(LexState *ls, ExpDesc *v) | |||
1781 | case TK_dots: { /* Vararg. */ | 1785 | case TK_dots: { /* Vararg. */ |
1782 | FuncState *fs = ls->fs; | 1786 | FuncState *fs = ls->fs; |
1783 | BCReg base; | 1787 | BCReg base; |
1784 | checkcond(ls, fs->flags & PROTO_IS_VARARG, LJ_ERR_XDOTS); | 1788 | checkcond(ls, fs->flags & PROTO_VARARG, LJ_ERR_XDOTS); |
1785 | bcreg_reserve(fs, 1); | 1789 | bcreg_reserve(fs, 1); |
1786 | base = fs->freereg-1; | 1790 | base = fs->freereg-1; |
1787 | expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); | 1791 | expr_init(v, VCALL, bcemit_ABC(fs, BC_VARG, base, 2, fs->numparams)); |
@@ -2018,7 +2022,7 @@ static void parse_return(LexState *ls) | |||
2018 | } | 2022 | } |
2019 | } | 2023 | } |
2020 | } | 2024 | } |
2021 | if (fs->flags & PROTO_HAS_FNEW) | 2025 | if (fs->flags & PROTO_CHILD) |
2022 | bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ | 2026 | bcemit_AJ(fs, BC_UCLO, 0, 0); /* May need to close upvalues first. */ |
2023 | bcemit_INS(fs, ins); | 2027 | bcemit_INS(fs, ins); |
2024 | } | 2028 | } |
@@ -2491,7 +2495,7 @@ GCproto *lj_parse(LexState *ls) | |||
2491 | fs.numparams = 0; | 2495 | fs.numparams = 0; |
2492 | fs.bcbase = NULL; | 2496 | fs.bcbase = NULL; |
2493 | fs.bclim = 0; | 2497 | fs.bclim = 0; |
2494 | fs.flags |= PROTO_IS_VARARG; /* Main chunk is always a vararg func. */ | 2498 | fs.flags |= PROTO_VARARG; /* Main chunk is always a vararg func. */ |
2495 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ | 2499 | bcemit_AD(&fs, BC_FUNCV, 0, 0); /* Placeholder. */ |
2496 | lj_lex_next(ls); /* Read-ahead first token. */ | 2500 | lj_lex_next(ls); /* Read-ahead first token. */ |
2497 | parse_chunk(ls); | 2501 | parse_chunk(ls); |