diff options
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r-- | src/lj_carith.c | 42 |
1 files changed, 27 insertions, 15 deletions
diff --git a/src/lj_carith.c b/src/lj_carith.c index a59665d8..8f644d83 100644 --- a/src/lj_carith.c +++ b/src/lj_carith.c | |||
@@ -9,6 +9,8 @@ | |||
9 | 9 | ||
10 | #include "lj_gc.h" | 10 | #include "lj_gc.h" |
11 | #include "lj_err.h" | 11 | #include "lj_err.h" |
12 | #include "lj_tab.h" | ||
13 | #include "lj_meta.h" | ||
12 | #include "lj_ctype.h" | 14 | #include "lj_ctype.h" |
13 | #include "lj_cconv.h" | 15 | #include "lj_cconv.h" |
14 | #include "lj_cdata.h" | 16 | #include "lj_cdata.h" |
@@ -187,24 +189,20 @@ static int carith_int64(lua_State *L, CTState *cts, CDArith *ca, MMS mm) | |||
187 | return 0; | 189 | return 0; |
188 | } | 190 | } |
189 | 191 | ||
190 | /* Arithmetic operators for cdata. */ | 192 | /* Handle ctype arithmetic metamethods. */ |
191 | int lj_carith_op(lua_State *L, MMS mm) | 193 | static int lj_carith_meta(lua_State *L, CTState *cts, CDArith *ca, MMS mm) |
192 | { | 194 | { |
193 | CTState *cts = ctype_cts(L); | 195 | cTValue *tv = NULL; |
194 | CDArith ca; | 196 | if (tviscdata(L->base)) |
195 | if (carith_checkarg(L, cts, &ca)) { | 197 | tv = lj_ctype_meta(cts, cdataV(L->base)->typeid, mm); |
196 | if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) { | 198 | if (!tv && L->base+1 < L->top && tviscdata(L->base+1)) |
197 | copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */ | 199 | tv = lj_ctype_meta(cts, cdataV(L->base+1)->typeid, mm); |
198 | return 1; | 200 | if (!tv) { |
199 | } | ||
200 | } | ||
201 | /* NYI: per-cdata metamethods. */ | ||
202 | { | ||
203 | const char *repr[2]; | 201 | const char *repr[2]; |
204 | int i; | 202 | int i; |
205 | for (i = 0; i < 2; i++) { | 203 | for (i = 0; i < 2; i++) { |
206 | if (ca.ct[i]) | 204 | if (ca->ct[i]) |
207 | repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca.ct[i]), NULL)); | 205 | repr[i] = strdata(lj_ctype_repr(L, ctype_typeid(cts, ca->ct[i]), NULL)); |
208 | else | 206 | else |
209 | repr[i] = typename(&L->base[i]); | 207 | repr[i] = typename(&L->base[i]); |
210 | } | 208 | } |
@@ -213,7 +211,21 @@ int lj_carith_op(lua_State *L, MMS mm) | |||
213 | mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH, | 211 | mm < MM_add ? LJ_ERR_FFI_BADCOMP : LJ_ERR_FFI_BADARITH, |
214 | repr[0], repr[1]); | 212 | repr[0], repr[1]); |
215 | } | 213 | } |
216 | return 0; /* unreachable */ | 214 | return lj_meta_tailcall(L, tv); |
215 | } | ||
216 | |||
217 | /* Arithmetic operators for cdata. */ | ||
218 | int lj_carith_op(lua_State *L, MMS mm) | ||
219 | { | ||
220 | CTState *cts = ctype_cts(L); | ||
221 | CDArith ca; | ||
222 | if (carith_checkarg(L, cts, &ca)) { | ||
223 | if (carith_int64(L, cts, &ca, mm) || carith_ptr(L, cts, &ca, mm)) { | ||
224 | copyTV(L, &G(L)->tmptv2, L->top-1); /* Remember for trace recorder. */ | ||
225 | return 1; | ||
226 | } | ||
227 | } | ||
228 | return lj_carith_meta(L, cts, &ca, mm); | ||
217 | } | 229 | } |
218 | 230 | ||
219 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ | 231 | /* -- 64 bit integer arithmetic helpers ----------------------------------- */ |