diff options
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r-- | src/lj_carith.c | 75 |
1 files changed, 75 insertions, 0 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c index c34596ca..1c050eba 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -11,10 +11,12 @@ | |||
11 | #include "lj_err.h" | 11 | #include "lj_err.h" |
12 | #include "lj_tab.h" | 12 | #include "lj_tab.h" |
13 | #include "lj_meta.h" | 13 | #include "lj_meta.h" |
14 | #include "lj_ir.h" | ||
14 | #include "lj_ctype.h" | 15 | #include "lj_ctype.h" |
15 | #include "lj_cconv.h" | 16 | #include "lj_cconv.h" |
16 | #include "lj_cdata.h" | 17 | #include "lj_cdata.h" |
17 | #include "lj_carith.h" | 18 | #include "lj_carith.h" |
19 | #include "lj_strscan.h" | ||
18 | 20 | ||
19 | /* -- C data arithmetic --------------------------------------------------- */ | 21 | /* -- C data arithmetic --------------------------------------------------- */ |
20 | 22 | ||
@@ -281,6 +283,79 @@ int lj_carith_len(lua_State *L) | |||
281 | return lj_carith_meta(L, cts, &ca, MM_len); | 283 | return lj_carith_meta(L, cts, &ca, MM_len); |
282 | } | 284 | } |
283 | 285 | ||
286 | /* -- 64 bit bit operations helpers --------------------------------------- */ | ||
287 | |||
288 | #if LJ_64 | ||
289 | #define B64DEF(name) \ | ||
290 | static LJ_AINLINE uint64_t lj_carith_##name(uint64_t x, int32_t sh) | ||
291 | #else | ||
292 | /* Not inlined on 32 bit archs, since some of these are quite lengthy. */ | ||
293 | #define B64DEF(name) \ | ||
294 | uint64_t LJ_NOINLINE lj_carith_##name(uint64_t x, int32_t sh) | ||
295 | #endif | ||
296 | |||
297 | B64DEF(shl64) { return x << (sh&63); } | ||
298 | B64DEF(shr64) { return x >> (sh&63); } | ||
299 | B64DEF(sar64) { return (uint64_t)((int64_t)x >> (sh&63)); } | ||
300 | B64DEF(rol64) { return lj_rol(x, (sh&63)); } | ||
301 | B64DEF(ror64) { return lj_ror(x, (sh&63)); } | ||
302 | |||
303 | #undef B64DEF | ||
304 | |||
305 | uint64_t lj_carith_shift64(uint64_t x, int32_t sh, int op) | ||
306 | { | ||
307 | switch (op) { | ||
308 | case IR_BSHL-IR_BSHL: x = lj_carith_shl64(x, sh); break; | ||
309 | case IR_BSHR-IR_BSHL: x = lj_carith_shr64(x, sh); break; | ||
310 | case IR_BSAR-IR_BSHL: x = lj_carith_sar64(x, sh); break; | ||
311 | case IR_BROL-IR_BSHL: x = lj_carith_rol64(x, sh); break; | ||
312 | case IR_BROR-IR_BSHL: x = lj_carith_ror64(x, sh); break; | ||
313 | default: lua_assert(0); break; | ||
314 | } | ||
315 | return x; | ||
316 | } | ||
317 | |||
318 | /* Equivalent to lj_lib_checkbit(), but handles cdata. */ | ||
319 | uint64_t lj_carith_check64(lua_State *L, int narg, CTypeID *id) | ||
320 | { | ||
321 | TValue *o = L->base + narg-1; | ||
322 | if (o >= L->top) { | ||
323 | err: | ||
324 | lj_err_argt(L, narg, LUA_TNUMBER); | ||
325 | } else if (LJ_LIKELY(tvisnumber(o))) { | ||
326 | /* Handled below. */ | ||
327 | } else if (tviscdata(o)) { | ||
328 | CTState *cts = ctype_cts(L); | ||
329 | uint8_t *sp = (uint8_t *)cdataptr(cdataV(o)); | ||
330 | CTypeID sid = cdataV(o)->ctypeid; | ||
331 | CType *s = ctype_get(cts, sid); | ||
332 | uint64_t x; | ||
333 | if (ctype_isref(s->info)) { | ||
334 | sp = *(void **)sp; | ||
335 | sid = ctype_cid(s->info); | ||
336 | } | ||
337 | s = ctype_raw(cts, sid); | ||
338 | if (ctype_isenum(s->info)) s = ctype_child(cts, s); | ||
339 | if ((s->info & (CTMASK_NUM|CTF_BOOL|CTF_FP|CTF_UNSIGNED)) == | ||
340 | CTINFO(CT_NUM, CTF_UNSIGNED) && s->size == 8) | ||
341 | *id = CTID_UINT64; /* Use uint64_t, since it has the highest rank. */ | ||
342 | else if (!*id) | ||
343 | *id = CTID_INT64; /* Use int64_t, unless already set. */ | ||
344 | lj_cconv_ct_ct(cts, ctype_get(cts, *id), s, | ||
345 | (uint8_t *)&x, sp, CCF_ARG(narg)); | ||
346 | return x; | ||
347 | } else if (!(tvisstr(o) && lj_strscan_number(strV(o), o))) { | ||
348 | goto err; | ||
349 | } | ||
350 | if (LJ_LIKELY(tvisint(o))) { | ||
351 | return (uint32_t)intV(o); | ||
352 | } else { | ||
353 | int32_t i = lj_num2bit(numV(o)); | ||
354 | if (LJ_DUALNUM) setintV(o, i); | ||
355 | return (uint32_t)i; | ||
356 | } | ||
357 | } | ||
358 | |||
284 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ | 359 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ |
285 | 360 | ||
286 | #if LJ_32 && LJ_HASJIT | 361 | #if LJ_32 && LJ_HASJIT |