aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMike Pall <mike>2011-01-03 01:30:58 +0100
committerMike Pall <mike>2011-01-03 01:59:26 +0100
commit3291bb62e0052df598a7fcf4138ae3973c08982e (patch)
treeabb269e45af25ee66820a69d483e591949a9b364 /src
parentb2c74c52cc9e850d53f2f7b06ffe2b096884f77a (diff)
downloadluajit-3291bb62e0052df598a7fcf4138ae3973c08982e.tar.gz
luajit-3291bb62e0052df598a7fcf4138ae3973c08982e.tar.bz2
luajit-3291bb62e0052df598a7fcf4138ae3973c08982e.zip
FFI: Record pointer arithmetic.
Diffstat (limited to 'src')
-rw-r--r--src/lib_ffi.c14
-rw-r--r--src/lj_crecord.c106
-rw-r--r--src/lj_crecord.h1
3 files changed, 114 insertions, 7 deletions
diff --git a/src/lib_ffi.c b/src/lib_ffi.c
index 414f1d2f..44ece1e7 100644
--- a/src/lib_ffi.c
+++ b/src/lib_ffi.c
@@ -291,37 +291,37 @@ static int ffi_arith(lua_State *L)
291 return 1; 291 return 1;
292} 292}
293 293
294LJLIB_CF(ffi_meta___add) 294LJLIB_CF(ffi_meta___add) LJLIB_REC(cdata_arith MM_add)
295{ 295{
296 return ffi_arith(L); 296 return ffi_arith(L);
297} 297}
298 298
299LJLIB_CF(ffi_meta___sub) 299LJLIB_CF(ffi_meta___sub) LJLIB_REC(cdata_arith MM_sub)
300{ 300{
301 return ffi_arith(L); 301 return ffi_arith(L);
302} 302}
303 303
304LJLIB_CF(ffi_meta___mul) 304LJLIB_CF(ffi_meta___mul) LJLIB_REC(cdata_arith MM_mul)
305{ 305{
306 return ffi_arith(L); 306 return ffi_arith(L);
307} 307}
308 308
309LJLIB_CF(ffi_meta___div) 309LJLIB_CF(ffi_meta___div) LJLIB_REC(cdata_arith MM_div)
310{ 310{
311 return ffi_arith(L); 311 return ffi_arith(L);
312} 312}
313 313
314LJLIB_CF(ffi_meta___mod) 314LJLIB_CF(ffi_meta___mod) LJLIB_REC(cdata_arith MM_mod)
315{ 315{
316 return ffi_arith(L); 316 return ffi_arith(L);
317} 317}
318 318
319LJLIB_CF(ffi_meta___pow) 319LJLIB_CF(ffi_meta___pow) LJLIB_REC(cdata_arith MM_pow)
320{ 320{
321 return ffi_arith(L); 321 return ffi_arith(L);
322} 322}
323 323
324LJLIB_CF(ffi_meta___unm) 324LJLIB_CF(ffi_meta___unm) LJLIB_REC(cdata_arith MM_unm)
325{ 325{
326 return ffi_arith(L); 326 return ffi_arith(L);
327} 327}
diff --git a/src/lj_crecord.c b/src/lj_crecord.c
index b474a6b9..81d53dfc 100644
--- a/src/lj_crecord.c
+++ b/src/lj_crecord.c
@@ -562,6 +562,112 @@ void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd)
562 } /* else: Interpreter will throw. */ 562 } /* else: Interpreter will throw. */
563} 563}
564 564
565static TRef crec_arith_int64(jit_State *J, TRef *sp, CType **s, MMS mm)
566{
567 UNUSED(J); UNUSED(sp); UNUSED(s); UNUSED(mm);
568 return 0; /* NYI: 64 bit integer arithmetic. */
569}
570
571static TRef crec_arith_ptr(jit_State *J, TRef *sp, CType **s, MMS mm)
572{
573 CTState *cts = ctype_ctsG(J2G(J));
574 CType *ctp = s[0];
575 CTSize sz;
576 if (!(mm == MM_add || mm == MM_sub))
577 return 0;
578 if (ctype_ispointer(ctp->info)) {
579 sz = lj_ctype_size(cts, ctype_cid(ctp->info));
580 if (mm == MM_sub && ctype_ispointer(s[1]->info)) {
581 /* Pointer difference. */
582 TRef tr;
583 if (sz == 0 || (sz & (sz-1)) != 0)
584 return 0; /* NYI: integer division. */
585 tr = emitir(IRT(IR_SUB, IRT_PTR), sp[0], sp[1]);
586 tr = emitir(IRT(IR_BSAR, IRT_INTP), tr, lj_ir_kint(J, lj_fls(sz)));
587#if LJ_64
588 tr = emitconv(tr, IRT_NUM, IRT_INTP, 0);
589#endif
590 return tr;
591 }
592 if (!ctype_isnum(s[1]->info)) return 0;
593 } else if (mm == MM_add &&
594 ctype_isnum(ctp->info) && ctype_ispointer(s[1]->info)) {
595 TRef tr = sp[0]; sp[0] = sp[1]; sp[1] = tr; /* Swap pointer and index. */
596 ctp = s[1];
597 sz = lj_ctype_size(cts, ctype_cid(ctp->info));
598 } else {
599 return 0;
600 }
601 {
602 TRef tr = sp[1];
603 IRType t = tref_type(tr);
604 CTypeID id;
605#if LJ_64
606 if (t == IRT_NUM || t == IRT_FLOAT)
607 tr = emitconv(tr, IRT_INTP, t, IRCONV_TRUNC|IRCONV_ANY);
608 else if (!(t == IRT_I64 || t == IRT_U64))
609 tr = emitconv(tr, IRT_INTP, IRT_INT,
610 ((t - IRT_I8) & 1) ? 0 : IRCONV_SEXT);
611#else
612 if (!tref_typerange(sp[1], IRT_I8, IRT_U32))
613 tr = emitconv(tr, IRT_INTP, t,
614 (t == IRT_NUM || t == IRT_FLOAT) ?
615 IRCONV_TRUNC|IRCONV_ANY : 0);
616#endif
617 tr = emitir(IRT(IR_MUL, IRT_INTP), tr, lj_ir_kintp(J, sz));
618 tr = emitir(IRT(IR_ADD, IRT_PTR), sp[0], tr);
619 id = lj_ctype_intern(cts, CTINFO(CT_PTR, CTALIGN_PTR|ctype_cid(ctp->info)),
620 CTSIZE_PTR);
621 return emitir(IRTG(IR_CNEWP, IRT_CDATA), lj_ir_kint(J, id), tr);
622 }
623}
624
625void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd)
626{
627 CTState *cts = ctype_ctsG(J2G(J));
628 TRef sp[2];
629 CType *s[2];
630 MSize i;
631 for (i = 0; i < 2; i++) {
632 TRef tr = J->base[i];
633 CType *ct = ctype_get(cts, CTID_DOUBLE);
634 if (tref_iscdata(tr)) {
635 CTypeID id = argv2cdata(J, tr, &rd->argv[i])->typeid;
636 ct = ctype_raw(cts, id);
637 if (ctype_isptr(ct->info)) { /* Resolve pointer or reference. */
638 IRType t = (LJ_64 && ct->size == 8) ? IRT_P64 : IRT_P32;
639 if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct);
640 tr = emitir(IRT(IR_FLOAD, t), tr, IRFL_CDATA_PTR);
641 } else {
642 tr = emitir(IRT(IR_ADD, IRT_PTR), tr, lj_ir_kintp(J, sizeof(GCcdata)));
643 }
644 if (ctype_isenum(ct->info)) ct = ctype_child(cts, ct);
645 if (ctype_isnum(ct->info)) {
646 IRType t = crec_ct2irt(ct);
647 if (t == IRT_CDATA) goto err_type;
648 tr = emitir(IRT(IR_XLOAD, t), tr, 0);
649 } else if (!(ctype_isptr(ct->info) || ctype_isrefarray(ct->info))) {
650 goto err_type;
651 }
652 } else if (tref_isinteger(tr)) {
653 ct = ctype_get(cts, CTID_INT32);
654 } else if (!tref_isnum(tr)) {
655 goto err_type;
656 }
657 s[i] = ct;
658 sp[i] = tr;
659 }
660 {
661 TRef tr;
662 if (!(tr = crec_arith_int64(J, sp, s, (MMS)rd->data)) &&
663 !(tr = crec_arith_ptr(J, sp, s, (MMS)rd->data))) {
664 err_type:
665 lj_trace_err(J, LJ_TRERR_BADTYPE);
666 }
667 J->base[0] = tr;
668 }
669}
670
565/* -- FFI library functions ----------------------------------------------- */ 671/* -- FFI library functions ----------------------------------------------- */
566 672
567void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd) 673void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd)
diff --git a/src/lj_crecord.h b/src/lj_crecord.h
index 05ef6110..f0b7045b 100644
--- a/src/lj_crecord.h
+++ b/src/lj_crecord.h
@@ -13,6 +13,7 @@
13#if LJ_HASJIT && LJ_HASFFI 13#if LJ_HASJIT && LJ_HASFFI
14LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd); 14LJ_FUNC void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd);
15LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd); 15LJ_FUNC void LJ_FASTCALL recff_cdata_call(jit_State *J, RecordFFData *rd);
16LJ_FUNC void LJ_FASTCALL recff_cdata_arith(jit_State *J, RecordFFData *rd);
16LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd); 17LJ_FUNC void LJ_FASTCALL recff_ffi_new(jit_State *J, RecordFFData *rd);
17LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd); 18LJ_FUNC void LJ_FASTCALL lj_crecord_tonumber(jit_State *J, RecordFFData *rd);
18#else 19#else