diff options
author | Mike Pall <mike> | 2010-12-15 21:49:40 +0100 |
---|---|---|
committer | Mike Pall <mike> | 2010-12-17 16:47:14 +0100 |
commit | c4a0fb4f60e6f318d4976123b4322e61b580553b (patch) | |
tree | 5cb06c82e42727d87b295356861c96bd765dbbb3 | |
parent | 09ef7ebf561a4573e02d65f0a324bb72780297d5 (diff) | |
download | luajit-c4a0fb4f60e6f318d4976123b4322e61b580553b.tar.gz luajit-c4a0fb4f60e6f318d4976123b4322e61b580553b.tar.bz2 luajit-c4a0fb4f60e6f318d4976123b4322e61b580553b.zip |
FFI: Record copy-by-value for pointer and complex C types.
-rw-r--r-- | src/lj_crecord.c | 38 |
1 files changed, 28 insertions, 10 deletions
diff --git a/src/lj_crecord.c b/src/lj_crecord.c index 3ee39ece..2f7e0f34 100644 --- a/src/lj_crecord.c +++ b/src/lj_crecord.c | |||
@@ -244,19 +244,37 @@ static TRef crec_tv_ct(jit_State *J, CType *s, CTypeID sid, TRef sp) | |||
244 | if (ctype_isnum(sinfo)) { | 244 | if (ctype_isnum(sinfo)) { |
245 | IRType t = crec_ct2irt(s); | 245 | IRType t = crec_ct2irt(s); |
246 | if ((sinfo & CTF_BOOL)) | 246 | if ((sinfo & CTF_BOOL)) |
247 | lj_trace_err(J, LJ_TRERR_NYICONV); /* NYI: specialize to the result. */ | 247 | goto err_nyi; /* NYI: specialize to the result. */ |
248 | if (t == IRT_CDATA) goto copyval; | 248 | if (t == IRT_CDATA) |
249 | goto err_nyi; /* NYI: copyval of >64 bit integers. */ | ||
250 | if ((sinfo & CTF_BOOL) || t == IRT_CDATA) | ||
249 | if (t == IRT_U32) lj_trace_err(J, LJ_TRERR_NYICONV); | 251 | if (t == IRT_U32) lj_trace_err(J, LJ_TRERR_NYICONV); |
250 | return emitir(IRT(IR_XLOAD, t), sp, 0); | 252 | return emitir(IRT(IR_XLOAD, t), sp, 0); |
253 | } else if (ctype_isptr(sinfo)) { | ||
254 | IRType t = (LJ_64 && s->size == 8) ? IRT_P64 : IRT_P32; | ||
255 | sp = emitir(IRT(IR_XLOAD, t), sp, 0); | ||
251 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { | 256 | } else if (ctype_isrefarray(sinfo) || ctype_isstruct(sinfo)) { |
252 | /* Create reference. */ | 257 | sid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); /* Create ref. */ |
253 | CTypeID refid = lj_ctype_intern(cts, CTINFO_REF(sid), CTSIZE_PTR); | 258 | } else if (ctype_iscomplex(sinfo)) { |
254 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), sp, lj_ir_kint(J, refid)); | 259 | IRType t = s->size == 2*sizeof(double) ? IRT_NUM : IRT_CDATA; |
260 | ptrdiff_t esz = (ptrdiff_t)(s->size >> 1); | ||
261 | TRef ptr, tr1, tr2, dp; | ||
262 | if (t == IRT_CDATA) goto err_nyi; /* NYI: float IRType. */ | ||
263 | dp = emitir(IRTG(IR_CNEW, IRT_CDATA), TREF_NIL, lj_ir_kint(J, sid)); | ||
264 | tr1 = emitir(IRT(IR_XLOAD, t), sp, 0); | ||
265 | ptr = emitir(IRT(IR_ADD, IRT_PTR), sp, lj_ir_kintp(J, esz)); | ||
266 | tr2 = emitir(IRT(IR_XLOAD, t), ptr, 0); | ||
267 | ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata))); | ||
268 | emitir(IRT(IR_XSTORE, t), ptr, tr1); | ||
269 | ptr = emitir(IRT(IR_ADD, IRT_PTR), dp, lj_ir_kintp(J, sizeof(GCcdata)+esz)); | ||
270 | emitir(IRT(IR_XSTORE, t), ptr, tr2); | ||
271 | return dp; | ||
255 | } else { | 272 | } else { |
256 | copyval: /* Copy value. */ | 273 | /* NYI: copyval of vectors. */ |
274 | err_nyi: | ||
257 | lj_trace_err(J, LJ_TRERR_NYICONV); | 275 | lj_trace_err(J, LJ_TRERR_NYICONV); |
258 | return 0; | ||
259 | } | 276 | } |
277 | return emitir(IRTG(IR_CNEWI, IRT_CDATA), sp, lj_ir_kint(J, sid)); | ||
260 | } | 278 | } |
261 | 279 | ||
262 | /* -- Convert TValue to C type (store) ------------------------------------ */ | 280 | /* -- Convert TValue to C type (store) ------------------------------------ */ |
@@ -340,6 +358,7 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
340 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); | 358 | if (ctype_isref(ct->info)) ct = ctype_rawchild(cts, ct); |
341 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_INIT1); | 359 | ptr = emitir(IRT(IR_FLOAD, t), ptr, IRFL_CDATA_INIT1); |
342 | ofs = 0; | 360 | ofs = 0; |
361 | ptr = crec_reassoc_ofs(J, ptr, &ofs, 1); | ||
343 | } | 362 | } |
344 | 363 | ||
345 | idx = J->base[1]; | 364 | idx = J->base[1]; |
@@ -356,7 +375,6 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
356 | ptrdiff_t sz = (ptrdiff_t)lj_ctype_size(cts, (sid = ctype_cid(ct->info))); | 375 | ptrdiff_t sz = (ptrdiff_t)lj_ctype_size(cts, (sid = ctype_cid(ct->info))); |
357 | idx = crec_reassoc_ofs(J, idx, &ofs, sz); | 376 | idx = crec_reassoc_ofs(J, idx, &ofs, sz); |
358 | idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); | 377 | idx = emitir(IRT(IR_MUL, IRT_INTP), idx, lj_ir_kintp(J, sz)); |
359 | ptr = crec_reassoc_ofs(J, ptr, &ofs, 1); | ||
360 | ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); | 378 | ptr = emitir(IRT(IR_ADD, IRT_PTR), idx, ptr); |
361 | } | 379 | } |
362 | } else if (tref_isstr(idx)) { | 380 | } else if (tref_isstr(idx)) { |
@@ -366,8 +384,8 @@ void LJ_FASTCALL recff_cdata_index(jit_State *J, RecordFFData *rd) | |||
366 | if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ | 384 | if (ctype_isptr(ct->info)) { /* Automatically perform '->'. */ |
367 | CType *cct = ctype_rawchild(cts, ct); | 385 | CType *cct = ctype_rawchild(cts, ct); |
368 | if (ctype_isstruct(cct->info)) { | 386 | if (ctype_isstruct(cct->info)) { |
369 | ct = cct; | 387 | ct = cct; |
370 | goto index_struct; | 388 | goto index_struct; |
371 | } | 389 | } |
372 | } else if (ctype_isstruct(ct->info)) { | 390 | } else if (ctype_isstruct(ct->info)) { |
373 | CTSize fofs; | 391 | CTSize fofs; |