diff options
| author | Mike Pall <mike> | 2011-02-05 14:09:50 +0100 |
|---|---|---|
| committer | Mike Pall <mike> | 2011-02-05 14:09:50 +0100 |
| commit | 223d85aa06a30dcf4bfdbdda38114c49e9bc6cbe (patch) | |
| tree | 6815c9210fcac4874fe686ebe16d17bc043f375e | |
| parent | c29ed4dbbf9089c6a7ba22c785e342c12862cbd8 (diff) | |
| download | luajit-223d85aa06a30dcf4bfdbdda38114c49e9bc6cbe.tar.gz luajit-223d85aa06a30dcf4bfdbdda38114c49e9bc6cbe.tar.bz2 luajit-223d85aa06a30dcf4bfdbdda38114c49e9bc6cbe.zip | |
Treat metatables of special userdata objects as immutable.
| -rw-r--r-- | src/lj_record.c | 38 |
1 files changed, 26 insertions, 12 deletions
diff --git a/src/lj_record.c b/src/lj_record.c index f1dd8e3e..e9841102 100644 --- a/src/lj_record.c +++ b/src/lj_record.c | |||
| @@ -661,7 +661,32 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) | |||
| 661 | mt = tabref(tabV(&ix->tabv)->metatable); | 661 | mt = tabref(tabV(&ix->tabv)->metatable); |
| 662 | mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META); | 662 | mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_TAB_META); |
| 663 | } else if (tref_isudata(ix->tab)) { | 663 | } else if (tref_isudata(ix->tab)) { |
| 664 | int udtype = udataV(&ix->tabv)->udtype; | ||
| 664 | mt = tabref(udataV(&ix->tabv)->metatable); | 665 | mt = tabref(udataV(&ix->tabv)->metatable); |
| 666 | /* The metatables of special userdata objects are treated as immutable. */ | ||
| 667 | if (udtype != UDTYPE_USERDATA) { | ||
| 668 | cTValue *mo; | ||
| 669 | if (LJ_HASFFI && udtype == UDTYPE_FFI_CLIB) { | ||
| 670 | /* Specialize to the C library namespace object. */ | ||
| 671 | emitir(IRTG(IR_EQ, IRT_P32), ix->tab, lj_ir_kptr(J, udataV(&ix->tabv))); | ||
| 672 | } else { | ||
| 673 | /* Specialize to the type of userdata. */ | ||
| 674 | TRef tr = emitir(IRT(IR_FLOAD, IRT_U8), ix->tab, IRFL_UDATA_UDTYPE); | ||
| 675 | emitir(IRTGI(IR_EQ), tr, lj_ir_kint(J, udtype)); | ||
| 676 | } | ||
| 677 | immutable_mt: | ||
| 678 | mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm)); | ||
| 679 | if (!mo || tvisnil(mo)) | ||
| 680 | return 0; /* No metamethod. */ | ||
| 681 | /* Treat metamethod or index table as immutable, too. */ | ||
| 682 | if (!(tvisfunc(mo) || tvistab(mo))) | ||
| 683 | lj_trace_err(J, LJ_TRERR_BADTYPE); | ||
| 684 | copyTV(J->L, &ix->mobjv, mo); | ||
| 685 | ix->mobj = lj_ir_kgc(J, gcV(mo), tvisfunc(mo) ? IRT_FUNC : IRT_TAB); | ||
| 686 | ix->mtv = mt; | ||
| 687 | ix->mt = TREF_NIL; /* Dummy value for comparison semantics. */ | ||
| 688 | return 1; /* Got metamethod or index table. */ | ||
| 689 | } | ||
| 665 | mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META); | 690 | mix.tab = emitir(IRT(IR_FLOAD, IRT_TAB), ix->tab, IRFL_UDATA_META); |
| 666 | } else { | 691 | } else { |
| 667 | /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */ | 692 | /* Specialize to base metatable. Must flush mcode in lua_setmetatable(). */ |
| @@ -670,19 +695,8 @@ int lj_record_mm_lookup(jit_State *J, RecordIndex *ix, MMS mm) | |||
| 670 | ix->mt = TREF_NIL; | 695 | ix->mt = TREF_NIL; |
| 671 | return 0; /* No metamethod. */ | 696 | return 0; /* No metamethod. */ |
| 672 | } | 697 | } |
| 673 | #if LJ_HASFFI | ||
| 674 | /* The cdata metatable is treated as immutable. */ | 698 | /* The cdata metatable is treated as immutable. */ |
| 675 | if (tref_iscdata(ix->tab)) { | 699 | if (LJ_HASFFI && tref_iscdata(ix->tab)) goto immutable_mt; |
| 676 | cTValue *mo = lj_tab_getstr(mt, mmname_str(J2G(J), mm)); | ||
| 677 | if (!mo || tvisnil(mo)) | ||
| 678 | return 0; /* No metamethod. */ | ||
| 679 | setfuncV(J->L, &ix->mobjv, funcV(mo)); | ||
| 680 | ix->mobj = lj_ir_kfunc(J, funcV(mo)); /* Immutable metamethod. */ | ||
| 681 | ix->mtv = mt; | ||
| 682 | ix->mt = TREF_NIL; /* Dummy value for comparison semantics. */ | ||
| 683 | return 1; /* Got cdata metamethod. */ | ||
| 684 | } | ||
| 685 | #endif | ||
| 686 | ix->mt = mix.tab = lj_ir_ktab(J, mt); | 700 | ix->mt = mix.tab = lj_ir_ktab(J, mt); |
| 687 | goto nocheck; | 701 | goto nocheck; |
| 688 | } | 702 | } |
