diff options
author | Mike Pall <mike> | 2010-09-13 01:21:44 +0200 |
---|---|---|
committer | Mike Pall <mike> | 2010-09-13 01:21:44 +0200 |
commit | 4ba0eb5f8083e95852e15777bfc0da63653f4e19 (patch) | |
tree | 25ffd219b88dee948000be8e112517a9f4b43648 | |
parent | 847b9cf2534233198e0229c209ab4c4040f5166e (diff) | |
download | luajit-4ba0eb5f8083e95852e15777bfc0da63653f4e19.tar.gz luajit-4ba0eb5f8083e95852e15777bfc0da63653f4e19.tar.bz2 luajit-4ba0eb5f8083e95852e15777bfc0da63653f4e19.zip |
Record select().
-rw-r--r-- | src/lib_base.c | 2 | ||||
-rw-r--r-- | src/lj_record.c | 42 |
2 files changed, 43 insertions, 1 deletions
diff --git a/src/lib_base.c b/src/lib_base.c index e5f71d9c..0717ea86 100644 --- a/src/lib_base.c +++ b/src/lib_base.c | |||
@@ -163,7 +163,7 @@ LJLIB_CF(unpack) | |||
163 | return n; | 163 | return n; |
164 | } | 164 | } |
165 | 165 | ||
166 | LJLIB_CF(select) | 166 | LJLIB_CF(select) LJLIB_REC(.) |
167 | { | 167 | { |
168 | int32_t n = (int32_t)(L->top - L->base); | 168 | int32_t n = (int32_t)(L->top - L->base); |
169 | if (n >= 1 && tvisstr(L->base) && *strVdata(L->base) == '#') { | 169 | if (n >= 1 && tvisstr(L->base) && *strVdata(L->base) == '#') { |
diff --git a/src/lj_record.c b/src/lj_record.c index 739279ad..5c998adf 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
@@ -1293,6 +1293,48 @@ static void LJ_FASTCALL recff_rawequal(jit_State *J, RecordFFData *rd) | |||
1293 | } /* else: Interpreter will throw. */ | 1293 | } /* else: Interpreter will throw. */ |
1294 | } | 1294 | } |
1295 | 1295 | ||
1296 | /* Determine mode of select() call. */ | ||
1297 | static int32_t select_mode(jit_State *J, TRef tr, TValue *tv) | ||
1298 | { | ||
1299 | if (tref_isstr(tr) && *strVdata(tv) == '#') { /* select('#', ...) */ | ||
1300 | if (strV(tv)->len == 1) { | ||
1301 | emitir(IRT(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv))); | ||
1302 | } else { | ||
1303 | TRef trptr = emitir(IRT(IR_STRREF, IRT_PTR), tr, 0); | ||
1304 | TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY); | ||
1305 | emitir(IRT(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#')); | ||
1306 | } | ||
1307 | return 0; | ||
1308 | } else { /* select(n, ...) */ | ||
1309 | int32_t start = argv2int(J, tv); | ||
1310 | if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE); /* A bit misleading. */ | ||
1311 | return start; | ||
1312 | } | ||
1313 | } | ||
1314 | |||
1315 | static void LJ_FASTCALL recff_select(jit_State *J, RecordFFData *rd) | ||
1316 | { | ||
1317 | TRef tr = J->base[0]; | ||
1318 | if (tr) { | ||
1319 | ptrdiff_t start = select_mode(J, tr, &rd->argv[0]); | ||
1320 | if (start == 0) { /* select('#', ...) */ | ||
1321 | J->base[0] = lj_ir_kint(J, J->maxslot - 1); | ||
1322 | } else if (tref_isk(tr)) { /* select(k, ...) */ | ||
1323 | ptrdiff_t n = (ptrdiff_t)J->maxslot; | ||
1324 | if (start < 0) start += n; | ||
1325 | else if (start > n) start = n; | ||
1326 | rd->nres = n - start; | ||
1327 | if (start >= 1) { | ||
1328 | ptrdiff_t i; | ||
1329 | for (i = 0; i < n - start; i++) | ||
1330 | J->base[i] = J->base[start+i]; | ||
1331 | } /* else: Interpreter will throw. */ | ||
1332 | } else { | ||
1333 | recff_nyiu(J); | ||
1334 | } | ||
1335 | } /* else: Interpreter will throw. */ | ||
1336 | } | ||
1337 | |||
1296 | static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd) | 1338 | static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd) |
1297 | { | 1339 | { |
1298 | TRef tr = J->base[0]; | 1340 | TRef tr = J->base[0]; |