summaryrefslogtreecommitdiff
path: root/src/lj_carith.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lj_carith.c')
-rw-r--r--src/lj_carith.c42
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. */
191int lj_carith_op(lua_State *L, MMS mm) 193static 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. */
218int 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 ----------------------------------- */