/* Helper for FORI. Coercion. */ void LJ_FASTCALL lj_meta_for(lua_State *L, TValue *o) { if (!(tvisnumber(o) || (tvisstr(o) && lj_str_tonumber(strV(o), o)))) lj_err_msg(L, LJ_ERR_FORINIT); if (!(tvisnumber(o+1) || (tvisstr(o+1) && lj_str_tonumber(strV(o+1), o+1)))) lj_err_msg(L, LJ_ERR_FORLIM); if (!(tvisnumber(o+2) || (tvisstr(o+2) && lj_str_tonumber(strV(o+2), o+2)))) lj_err_msg(L, LJ_ERR_FORSTEP); if (LJ_DUALNUM) { /* Ensure all slots are integers or all slots are numbers. */ int32_t k[3]; int nint = 0; ptrdiff_t i; for (i = 0; i <= 2; i++) { if (tvisint(o+i)) { k[i] = intV(o+i); nint++; } else { k[i] = lj_num2int(numV(o+i)); nint += ((lua_Number)k[i] == numV(o+i)); } } if (nint == 3) { /* Narrow to integers. */ setintV(o, k[0]); setintV(o+1, k[1]); setintV(o+2, k[2]); } else if (nint != 0) { /* Widen to numbers. */ if (tvisint(o)) setnumV(o, (lua_Number)intV(o)); if (tvisint(o+1)) setnumV(o+1, (lua_Number)intV(o+1)); if (tvisint(o+2)) setnumV(o+2, (lua_Number)intV(o+2)); } } }
static void LJ_FASTCALL recff_tonumber(jit_State *J, RecordFFData *rd) { TRef tr = J->base[0]; TRef base = J->base[1]; if (tr && base) { base = lj_opt_narrow_toint(J, base); if (!tref_isk(base) || IR(tref_ref(base))->i != 10) recff_nyiu(J); } if (tref_isnumber_str(tr)) { if (tref_isstr(tr)) { TValue tmp; if (!lj_str_tonum(strV(&rd->argv[0]), &tmp)) recff_nyiu(J); /* Would need an inverted STRTO for this case. */ tr = emitir(IRTG(IR_STRTO, IRT_NUM), tr, 0); } #if LJ_HASFFI } else if (tref_iscdata(tr)) { lj_crecord_tonumber(J, rd); return; #endif } else { tr = TREF_NIL; } J->base[0] = tr; UNUSED(rd); }
/* Narrowing of power operator or math.pow. */ TRef lj_opt_narrow_pow(jit_State *J, TRef rb, TRef rc, TValue *vc) { lua_Number n; if (tvisstr(vc) && !lj_str_tonum(strV(vc), vc)) lj_trace_err(J, LJ_TRERR_BADTYPE); n = numV(vc); /* Limit narrowing for pow to small exponents (or for two constants). */ if ((tref_isk(rc) && tref_isint(rc) && tref_isk(rb)) || ((J->flags & JIT_F_OPT_NARROW) && (numisint(n) && n >= -65536.0 && n <= 65536.0))) { TRef tmp; if (!tref_isinteger(rc)) { if (tref_isstr(rc)) rc = emitir(IRTG(IR_STRTO, IRT_NUM), rc, 0); rc = emitir(IRTGI(IR_TOINT), rc, IRTOINT_CHECK); /* Guarded TOINT! */ } if (!tref_isk(rc)) { /* Range guard: -65536 <= i <= 65536 */ tmp = emitir(IRTI(IR_ADD), rc, lj_ir_kint(J, 65536-2147483647-1)); emitir(IRTGI(IR_LE), tmp, lj_ir_kint(J, 2*65536-2147483647-1)); } return emitir(IRTN(IR_POWI), rb, rc); } /* FOLD covers most cases, but some are easier to do here. */ if (tref_isk(rb) && tvispone(ir_knum(IR(tref_ref(rb))))) return rb; /* 1 ^ x ==> 1 */ rc = lj_ir_tonum(J, rc); if (tref_isk(rc) && ir_knum(IR(tref_ref(rc)))->n == 0.5) return emitir(IRTN(IR_FPMATH), rb, IRFPM_SQRT); /* x ^ 0.5 ==> sqrt(x) */ /* Split up b^c into exp2(c*log2(b)). Assembler may rejoin later. */ rb = emitir(IRTN(IR_FPMATH), rb, IRFPM_LOG2); rc = emitir(IRTN(IR_MUL), rb, rc); return emitir(IRTN(IR_FPMATH), rc, IRFPM_EXP2); }
static int io_file_write(lua_State *L, FILE *fp, int start) { cTValue *tv; int status = 1; for (tv = L->base+start; tv < L->top; tv++) { if (tvisstr(tv)) { MSize len = strV(tv)->len; status = status && (fwrite(strVdata(tv), 1, len, fp) == len); } else if (tvisint(tv)) { char buf[LJ_STR_INTBUF]; char *p = lj_str_bufint(buf, intV(tv)); size_t len = (size_t)(buf+LJ_STR_INTBUF-p); status = status && (fwrite(p, 1, len, fp) == len); } else if (tvisnum(tv)) { status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); } else { lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); } } if (LJ_52 && status) { L->top = L->base+1; if (start == 0) setudataV(L, L->base, IOSTDF_UD(L, GCROOT_IO_OUTPUT)); return 1; } return luaL_fileresult(L, status, NULL); }
void QPredefProfileEditDialog::on_BtnDelete_clicked() { int nIndex = ui->CBProfileList->currentIndex(); if( nIndex < 0 ) return; ui->CBProfileList->removeItem( nIndex ); QString strFilePath( QApplication::applicationDirPath() ); strFilePath += "/config/gestureprofiles.ini"; if( !QFile::exists( strFilePath ) ) return; QFile file( strFilePath ); if( !file.open( QFile::WriteOnly ) ) return; for( int i=0; i<ui->CBProfileList->count(); i++ ) { QString strV( ui->CBProfileList->itemText(i) ); strV += "=" + ui->CBProfileList->itemData(i).toString() + "\n"; file.write( strV.toUtf8().constData() ); } file.close(); }
/* Check first argument for a C type and returns its ID. */ static CTypeID ffi_checkctype(lua_State *L, CTState *cts, TValue *param) { TValue *o = L->base; if (!(o < L->top)) { err_argtype: lj_err_argtype(L, 1, "C type"); } if (tvisstr(o)) { /* Parse an abstract C type declaration. */ GCstr *s = strV(o); CPState cp; int errcode; cp.L = L; cp.cts = cts; cp.srcname = strdata(s); cp.p = strdata(s); cp.param = param; cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT; errcode = lj_cparse(&cp); if (errcode) lj_err_throw(L, errcode); /* Propagate errors. */ return cp.val.id; } else { GCcdata *cd; if (!tviscdata(o)) goto err_argtype; if (param && param < L->top) lj_err_arg(L, 1, LJ_ERR_FFI_NUMPARAM); cd = cdataV(o); return cd->ctypeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->ctypeid; } }
/* Determine mode of select() call. */ int32_t lj_ffrecord_select_mode(jit_State *J, TRef tr, TValue *tv) { if (tref_isstr(tr) && *strVdata(tv) == '#') { /* select('#', ...) */ if (strV(tv)->len == 1) { emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, strV(tv))); } else { TRef trptr = emitir(IRT(IR_STRREF, IRT_P32), tr, lj_ir_kint(J, 0)); TRef trchar = emitir(IRT(IR_XLOAD, IRT_U8), trptr, IRXLOAD_READONLY); emitir(IRTG(IR_EQ, IRT_INT), trchar, lj_ir_kint(J, '#')); } return 0; } else { /* select(n, ...) */ int32_t start = argv2int(J, tv); if (start == 0) lj_trace_err(J, LJ_TRERR_BADTYPE); /* A bit misleading. */ return start; } }
/* Helper for ordered comparisons. String compare, __lt/__le metamethods. */ TValue *lj_meta_comp(lua_State *L, cTValue *o1, cTValue *o2, int op) { if (LJ_HASFFI && (tviscdata(o1) || tviscdata(o2))) { ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt; MMS mm = (op & 2) ? MM_le : MM_lt; cTValue *mo = lj_meta_lookup(L, tviscdata(o1) ? o1 : o2, mm); if (LJ_UNLIKELY(tvisnil(mo))) goto err; return mmcall(L, cont, mo, o1, o2); } else if (LJ_52 || itype(o1) == itype(o2)) { /* Never called with two numbers. */ if (tvisstr(o1) && tvisstr(o2)) { int32_t res = lj_str_cmp(strV(o1), strV(o2)); return (TValue *)(intptr_t)(((op&2) ? res <= 0 : res < 0) ^ (op&1)); } else { trymt: while (1) { ASMFunction cont = (op & 1) ? lj_cont_condf : lj_cont_condt; MMS mm = (op & 2) ? MM_le : MM_lt; cTValue *mo = lj_meta_lookup(L, o1, mm); #if LJ_52 if (tvisnil(mo) && tvisnil((mo = lj_meta_lookup(L, o2, mm)))) #else cTValue *mo2 = lj_meta_lookup(L, o2, mm); if (tvisnil(mo) || !lj_obj_equal(mo, mo2)) #endif { if (op & 2) { /* MM_le not found: retry with MM_lt. */ cTValue *ot = o1; o1 = o2; o2 = ot; /* Swap operands. */ op ^= 3; /* Use LT and flip condition. */ continue; } goto err; } return mmcall(L, cont, mo, o1, o2); } } } else if (tvisbool(o1) && tvisbool(o2)) { goto trymt; } else { err: lj_err_comp(L, o1, o2); return NULL; } }
static cTValue *str2num(cTValue *o, TValue *n) { if (tvisnum(o)) return o; else if (tvisint(o)) return (setnumV(n, (lua_Number)intV(o)), n); else if (tvisstr(o) && lj_strscan_num(strV(o), n)) return n; else return NULL; }
/* Hash an arbitrary key and return its anchor position in the hash table. */ static Node *hashkey(const GCtab *t, cTValue *key) { if (tvisstr(key)) return hashstr(t, strV(key)); else if (tvisnum(key)) return hashnum(t, key); else if (tvisbool(key)) return hashmask(t, boolV(key)); else return hashgcref(t, key->gcr); /* Only hash 32 bits of lightuserdata on a 64 bit CPU. Good enough? */ }
static void LJ_FASTCALL recff_type(jit_State *J, RecordFFData *rd) { /* Arguments already specialized. Result is a constant string. Neat, huh? */ uint32_t t; if (tvisnumber(&rd->argv[0])) t = ~LJ_TNUMX; else if (LJ_64 && tvislightud(&rd->argv[0])) t = ~LJ_TLIGHTUD; else t = ~itype(&rd->argv[0]); J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[t])); UNUSED(rd); }
lua_Number lj_lib_checknum(lua_State *L, int narg) { TValue *o = L->base + narg-1; if (!(o < L->top && (tvisnumber(o) || (tvisstr(o) && lj_strscan_num(strV(o), o))))) lj_err_argt(L, narg, LUA_TNUMBER); if (LJ_UNLIKELY(tvisint(o))) { lua_Number n = (lua_Number)intV(o); setnumV(o, n); return n; } else { return numV(o); } }
GCstr *lj_lib_checkstr(lua_State *L, int narg) { TValue *o = L->base + narg-1; if (o < L->top) { if (LJ_LIKELY(tvisstr(o))) { return strV(o); } else if (tvisnumber(o)) { GCstr *s = lj_str_fromnumber(L, o); setstrV(L, o, s); return s; } } lj_err_argt(L, narg, LUA_TSTRING); return NULL; /* unreachable */ }
static int io_file_write(lua_State *L, FILE *fp, int start) { cTValue *tv; int status = 1; for (tv = L->base+start; tv < L->top; tv++) { if (tvisstr(tv)) { MSize len = strV(tv)->len; status = status && (fwrite(strVdata(tv), 1, len, fp) == len); } else if (tvisnum(tv)) { status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); } else { lj_err_argt(L, cast_int(tv - L->base) + 1, LUA_TSTRING); } } return io_pushresult(L, status, NULL); }
/* Get runtime value of string argument. */ static GCstr *argv2str(jit_State *J, TValue *o) { if (LJ_LIKELY(tvisstr(o))) { return strV(o); } else { GCstr *s; if (!tvisnumber(o)) lj_trace_err(J, LJ_TRERR_BADTYPE); if (tvisint(o)) s = lj_str_fromint(J->L, intV(o)); else s = lj_str_fromnum(J->L, &o->n); setstrV(J->L, o, s); return s; } }
static void LJ_FASTCALL recff_tostring(jit_State *J, RecordFFData *rd) { TRef tr = J->base[0]; if (tref_isstr(tr)) { /* Ignore __tostring in the string base metatable. */ /* Pass on result in J->base[0]. */ } else if (!recff_metacall(J, rd, MM_tostring)) { if (tref_isnumber(tr)) { J->base[0] = emitir(IRT(IR_TOSTR, IRT_STR), tr, 0); } else if (tref_ispri(tr)) { J->base[0] = lj_ir_kstr(J, strV(&J->fn->c.upvalue[tref_type(tr)])); } else { recff_nyiu(J); } } }
static int io_file_readchars(lua_State *L, FILE *fp, size_t n) { size_t rlen; /* how much to read */ size_t nr; /* number of chars actually read */ luaL_Buffer b; luaL_buffinit(L, &b); rlen = LUAL_BUFFERSIZE; /* try to read that much each time */ do { char *p = luaL_prepbuffer(&b); if (rlen > n) rlen = n; /* cannot read more than asked */ nr = fread(p, 1, rlen, fp); luaL_addsize(&b, nr); n -= nr; /* still have to read `n' chars */ } while (n > 0 && nr == rlen); /* until end of count or eof */ luaL_pushresult(&b); /* close buffer */ return (n == 0 || strV(L->top-1)->len > 0); }
static int io_file_readline(lua_State *L, FILE *fp) { luaL_Buffer b; luaL_buffinit(L, &b); for (;;) { size_t len; char *p = luaL_prepbuffer(&b); if (fgets(p, LUAL_BUFFERSIZE, fp) == NULL) { /* EOF? */ luaL_pushresult(&b); return (strV(L->top-1)->len > 0); /* Anything read? */ } len = strlen(p); if (len == 0 || p[len-1] != '\n') { /* Partial line? */ luaL_addsize(&b, len); } else { luaL_addsize(&b, len - 1); /* Don't include EOL. */ luaL_pushresult(&b); return 1; /* Got at least an EOL. */ } } }
static int io_file_write(lua_State *L, FILE *fp, int start) { cTValue *tv; int status = 1; for (tv = L->base+start; tv < L->top; tv++) { if (tvisstr(tv)) { MSize len = strV(tv)->len; status = status && (fwrite(strVdata(tv), 1, len, fp) == len); } else if (tvisint(tv)) { char buf[LJ_STR_INTBUF]; char *p = lj_str_bufint(buf, intV(tv)); size_t len = (size_t)(buf+LJ_STR_INTBUF-p); status = status && (fwrite(p, 1, len, fp) == len); } else if (tvisnum(tv)) { status = status && (fprintf(fp, LUA_NUMBER_FMT, numV(tv)) > 0); } else { lj_err_argt(L, (int)(tv - L->base) + 1, LUA_TSTRING); } } return io_pushresult(L, status, NULL); }
static CTypeID argv2ctype(jit_State *J, TRef tr, cTValue *o) { if (tref_isstr(tr)) { GCstr *s = strV(o); CPState cp; CTypeID oldtop; /* Specialize to the string containing the C type declaration. */ emitir(IRTG(IR_EQ, IRT_STR), tr, lj_ir_kstr(J, s)); cp.L = J->L; cp.cts = ctype_ctsG(J2G(J)); oldtop = cp.cts->top; cp.srcname = strdata(s); cp.p = strdata(s); cp.mode = CPARSE_MODE_ABSTRACT|CPARSE_MODE_NOIMPLICIT; if (lj_cparse(&cp) || cp.cts->top > oldtop) /* Avoid new struct defs. */ lj_trace_err(J, LJ_TRERR_BADTYPE); return cp.val.id; } else { GCcdata *cd = argv2cdata(J, tr, o); return cd->typeid == CTID_CTYPEID ? *(CTypeID *)cdataptr(cd) : cd->typeid; } }
int OTLResultSetMetaData::GetColumnType(int i) { int fieldType = COLUMN_UNKNOWN; int OTLFieldType = m_desc[i]->dbtype; wxString strV(ConvertFromUnicodeStream(m_desc[i]->name)); switch (OTLFieldType) { case extLong: case extUInt: case extNumber: case extInt: case extVarNum: case extRowId: //fixme: check fieldType = COLUMN_INTEGER; break; case extVarChar2: case extLongVarChar: case extCChar: case extVarChar: case extChar: case extCharZ: case extMslabel://fixme : Check fieldType = COLUMN_STRING; break; case extFloat: fieldType = COLUMN_DOUBLE; break; /* case SQL_BIT: fieldType = COLUMN_BOOL; break; */ case extBLOB: case extCLOB: case extVarRaw: //fixme : Check //case extRaw: //fixme : Check case extLongRaw://fixme : Check case extLongVarRaw://fixme : Check fieldType = COLUMN_BLOB; break; case extDate: #if (defined(OTL_ORA8I)||defined(OTL_ORA9I))&&defined(OTL_ORA_TIMESTAMP) case extTimestamp: case extTimestamp_TZ: case extTimestamp_LTZ: #endif fieldType = COLUMN_DATE; break; default: fieldType = COLUMN_UNKNOWN; break; }; return fieldType; }
void QTouchSettingWidget::TPDP_OnRSP(T3K_DEVICE_INFO /*devInfo*/, ResponsePart Part, unsigned short /*ticktime*/, const char */*partid*/, int /*id*/, bool /*bFinal*/, const char *cmd) { if( !isVisible() ) return; if ( strstr(cmd, cstrTimeA) == cmd ) { m_RequestSensorData.RemoveItem( cstrTimeA ); int nTime = atoi(cmd + sizeof(cstrTimeA) - 1); if( nTime < NV_DEF_TIME_A_RANGE_START ) nTime = NV_DEF_TIME_A_RANGE_START; if( nTime > NV_DEF_TIME_A_RANGE_END ) nTime = NV_DEF_TIME_A_RANGE_END; QString strV( QString("%1").arg(nTime) ); ui->EditTap->setText( strV ); ui->SldTap->setValue( NV_DEF_TIME_A_RANGE_END/100 - nTime/100 + (NV_DEF_TIME_A_RANGE_START)/100 ); } else if ( strstr(cmd, cstrTimeL) == cmd ) { m_RequestSensorData.RemoveItem( cstrTimeL ); int nTime = atoi(cmd + sizeof(cstrTimeL) - 1); if( nTime < NV_DEF_TIME_L_RANGE_START ) nTime = NV_DEF_TIME_L_RANGE_START; if( nTime > NV_DEF_TIME_L_RANGE_END ) nTime = NV_DEF_TIME_L_RANGE_END; QString strV( QString("%1").arg(nTime) ); ui->EditLongTap->setText( strV ); ui->SldLongTap->setValue( NV_DEF_TIME_L_RANGE_END/100 - nTime/100 + (NV_DEF_TIME_L_RANGE_START)/100 ); } else if ( strstr(cmd, cstrWheelSensitivity) == cmd ) { m_RequestSensorData.RemoveItem( cstrWheelSensitivity ); int nSens = atoi(cmd + sizeof(cstrWheelSensitivity) - 1); if( !(nSens >= NV_DEF_WHEEL_SENSITIVITY_RANGE_START && nSens <= NV_DEF_WHEEL_SENSITIVITY_RANGE_END) ) { nSens = NV_DEF_WHEEL_SENSITIVITY; } QString strV( QString("%1").arg(nSens) ); ui->EditWheel->setText( strV ); ui->SldWheel->setValue( nSens ); } else if ( strstr(cmd, cstrZoomSensitivity) == cmd ) { m_RequestSensorData.RemoveItem( cstrZoomSensitivity ); int nSens = atoi(cmd + sizeof(cstrZoomSensitivity) - 1); if( !(nSens >= NV_DEF_ZOOM_SENSITIVITY_RANGE_START && nSens <= NV_DEF_ZOOM_SENSITIVITY_RANGE_END) ) { nSens = NV_DEF_ZOOM_SENSITIVITY; } QString strV( QString("%1").arg(nSens) ); ui->EditZoom->setText( strV ); ui->SldZoom->setValue( nSens ); } else if( strstr(cmd, cstrDetectionThreshold) == cmd ) { if( Part != MM ) { m_RequestSensorData.RemoveItem( cstrDetectionThreshold, Part ); int nSensitivity = strtol(cmd + sizeof(cstrDetectionThreshold) - 1, NULL, 10); m_mapTouchSensitivity.insert( Part, nSensitivity ); nSensitivity = NV_DEF_CAM_TRIGGER_THRESHOLD_RANGE_END; foreach( int nV, m_mapTouchSensitivity.values() ) { if( nSensitivity > nV ) nSensitivity = nV; } ui->EditSensitivity->setText( QString::number(nSensitivity) ); } }
/* Get runtime value of int argument. */ static int32_t argv2int(jit_State *J, TValue *o) { if (!tvisnumber(o) && !(tvisstr(o) && lj_str_tonumber(strV(o), o))) lj_trace_err(J, LJ_TRERR_BADTYPE); return tvisint(o) ? intV(o) : lj_num2int(numV(o)); }
CString GetWClustVersionString() { CString strV("2.0.0.102"); return strV; }
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */ TValue *lj_meta_cat(lua_State *L, TValue *top, int left) { do { int n = 1; if (!(tvisstr(top-1) || tvisnumber(top-1)) || !tostring(L, top)) { cTValue *mo = lj_meta_lookup(L, top-1, MM_concat); if (tvisnil(mo)) { mo = lj_meta_lookup(L, top, MM_concat); if (tvisnil(mo)) { if (tvisstr(top-1) || tvisnumber(top-1)) top++; lj_err_optype(L, top-1, LJ_ERR_OPCAT); return NULL; /* unreachable */ } } /* One of the top two elements is not a string, call __cat metamethod: ** ** before: [...][CAT stack .........................] ** top-1 top top+1 top+2 ** pick two: [...][CAT stack ...] [o1] [o2] ** setup mm: [...][CAT stack ...] [cont|?] [mo|tmtype] [o1] [o2] ** in asm: [...][CAT stack ...] [cont|PC] [mo|delta] [o1] [o2] ** ^-- func base ^-- mm base ** after mm: [...][CAT stack ...] <--push-- [result] ** next step: [...][CAT stack .............] */ copyTV(L, top+2, top); /* Careful with the order of stack copies! */ copyTV(L, top+1, top-1); copyTV(L, top, mo); setcont(top-1, lj_cont_cat); return top+1; /* Trigger metamethod call. */ } else if (strV(top)->len == 0) { /* Shortcut. */ (void)tostring(L, top-1); } else { /* Pick as many strings as possible from the top and concatenate them: ** ** before: [...][CAT stack ...........................] ** pick str: [...][CAT stack ...] [...... strings ......] ** concat: [...][CAT stack ...] [result] ** next step: [...][CAT stack ............] */ MSize tlen = strV(top)->len; char *buffer; int i; for (n = 1; n <= left && tostring(L, top-n); n++) { MSize len = strV(top-n)->len; if (len >= LJ_MAX_STR - tlen) lj_err_msg(L, LJ_ERR_STROV); tlen += len; } buffer = lj_str_needbuf(L, &G(L)->tmpbuf, tlen); n--; tlen = 0; for (i = n; i >= 0; i--) { MSize len = strV(top-i)->len; memcpy(buffer + tlen, strVdata(top-i), len); tlen += len; } setstrV(L, top-n, lj_str_new(L, buffer, tlen)); } left -= n; top -= n; } while (left >= 1); lj_gc_check_fixtop(L); return NULL; }
/* Helper for CAT. Coercion, iterative concat, __concat metamethod. */ TValue *lj_meta_cat(lua_State *L, TValue *top, int left) { int fromc = 0; if (left < 0) { left = -left; fromc = 1; } do { if (!(tvisstr(top) || tvisnumber(top)) || !(tvisstr(top-1) || tvisnumber(top-1))) { cTValue *mo = lj_meta_lookup(L, top-1, MM_concat); if (tvisnil(mo)) { mo = lj_meta_lookup(L, top, MM_concat); if (tvisnil(mo)) { if (tvisstr(top-1) || tvisnumber(top-1)) top++; lj_err_optype(L, top-1, LJ_ERR_OPCAT); return NULL; /* unreachable */ } } /* One of the top two elements is not a string, call __cat metamethod: ** ** before: [...][CAT stack .........................] ** top-1 top top+1 top+2 ** pick two: [...][CAT stack ...] [o1] [o2] ** setup mm: [...][CAT stack ...] [cont|?] [mo|tmtype] [o1] [o2] ** in asm: [...][CAT stack ...] [cont|PC] [mo|delta] [o1] [o2] ** ^-- func base ^-- mm base ** after mm: [...][CAT stack ...] <--push-- [result] ** next step: [...][CAT stack .............] */ copyTV(L, top+2*LJ_FR2+2, top); /* Carefully ordered stack copies! */ copyTV(L, top+2*LJ_FR2+1, top-1); copyTV(L, top+LJ_FR2, mo); setcont(top-1, lj_cont_cat); if (LJ_FR2) { setnilV(top); setnilV(top+2); top += 2; } return top+1; /* Trigger metamethod call. */ } else { /* Pick as many strings as possible from the top and concatenate them: ** ** before: [...][CAT stack ...........................] ** pick str: [...][CAT stack ...] [...... strings ......] ** concat: [...][CAT stack ...] [result] ** next step: [...][CAT stack ............] */ TValue *e, *o = top; uint64_t tlen = tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM; char *p, *buf; do { o--; tlen += tvisstr(o) ? strV(o)->len : STRFMT_MAXBUF_NUM; } while (--left > 0 && (tvisstr(o-1) || tvisnumber(o-1))); if (tlen >= LJ_MAX_STR) lj_err_msg(L, LJ_ERR_STROV); p = buf = lj_buf_tmp(L, (MSize)tlen); for (e = top, top = o; o <= e; o++) { if (tvisstr(o)) { GCstr *s = strV(o); MSize len = s->len; p = lj_buf_wmem(p, strdata(s), len); } else if (tvisint(o)) { p = lj_strfmt_wint(p, intV(o)); } else { lua_assert(tvisnum(o)); p = lj_strfmt_wnum(p, o); } } setstrV(L, top, lj_str_new(L, buf, (size_t)(p-buf))); } } while (left >= 1); if (LJ_UNLIKELY(G(L)->gc.total >= G(L)->gc.threshold)) { if (!fromc) L->top = curr_topL(L); lj_gc_step(L); } return NULL; }
/* Array and hash load forwarding. */ static TRef fwd_ahload(jit_State *J, IRRef xref) { IRIns *xr = IR(xref); IRRef lim = xref; /* Search limit. */ IRRef ref; /* Search for conflicting stores. */ ref = J->chain[fins->o+IRDELTA_L2S]; while (ref > xref) { IRIns *store = IR(ref); switch (aa_ahref(J, xr, IR(store->op1))) { case ALIAS_NO: break; /* Continue searching. */ case ALIAS_MAY: lim = ref; goto cselim; /* Limit search for load. */ case ALIAS_MUST: return store->op2; /* Store forwarding. */ } ref = store->prev; } /* No conflicting store (yet): const-fold loads from allocations. */ { IRIns *ir = (xr->o == IR_HREFK || xr->o == IR_AREF) ? IR(xr->op1) : xr; IRRef tab = ir->op1; ir = IR(tab); if (ir->o == IR_TNEW || (ir->o == IR_TDUP && irref_isk(xr->op2))) { /* A NEWREF with a number key may end up pointing to the array part. ** But it's referenced from HSTORE and not found in the ASTORE chain. ** For now simply consider this a conflict without forwarding anything. */ if (xr->o == IR_AREF) { IRRef ref2 = J->chain[IR_NEWREF]; while (ref2 > tab) { IRIns *newref = IR(ref2); if (irt_isnum(IR(newref->op2)->t)) goto cselim; ref2 = newref->prev; } } /* NEWREF inhibits CSE for HREF, and dependent FLOADs from HREFK/AREF. ** But the above search for conflicting stores was limited by xref. ** So continue searching, limited by the TNEW/TDUP. Store forwarding ** is ok, too. A conflict does NOT limit the search for a matching load. */ while (ref > tab) { IRIns *store = IR(ref); switch (aa_ahref(J, xr, IR(store->op1))) { case ALIAS_NO: break; /* Continue searching. */ case ALIAS_MAY: goto cselim; /* Conflicting store. */ case ALIAS_MUST: return store->op2; /* Store forwarding. */ } ref = store->prev; } lua_assert(ir->o != IR_TNEW || irt_isnil(fins->t)); if (irt_ispri(fins->t)) { return TREF_PRI(irt_type(fins->t)); } else if (irt_isnum(fins->t) || (LJ_DUALNUM && irt_isint(fins->t)) || irt_isstr(fins->t)) { TValue keyv; cTValue *tv; IRIns *key = IR(xr->op2); if (key->o == IR_KSLOT) key = IR(key->op1); lj_ir_kvalue(J->L, &keyv, key); tv = lj_tab_get(J->L, ir_ktab(IR(ir->op1)), &keyv); lua_assert(itype2irt(tv) == irt_type(fins->t)); if (irt_isnum(fins->t)) return lj_ir_knum_u64(J, tv->u64); else if (LJ_DUALNUM && irt_isint(fins->t)) return lj_ir_kint(J, intV(tv)); else return lj_ir_kstr(J, strV(tv)); } /* Othwerwise: don't intern as a constant. */ } } cselim: /* Try to find a matching load. Below the conflicting store, if any. */ ref = J->chain[fins->o]; while (ref > lim) { IRIns *load = IR(ref); if (load->op1 == xref) return ref; /* Load forwarding. */ ref = load->prev; } return 0; /* Conflict or no match. */ }
void lj_lib_register(lua_State *L, const char *libname, const uint8_t *p, const lua_CFunction *cf) { GCtab *env = tabref(L->env); GCfunc *ofn = NULL; int ffid = *p++; BCIns *bcff = &L2GG(L)->bcff[*p++]; GCtab *tab = lib_create_table(L, libname, *p++); ptrdiff_t tpos = L->top - L->base; /* Avoid barriers further down. */ lj_gc_anybarriert(L, tab); tab->nomm = 0; for (;;) { uint32_t tag = *p++; MSize len = tag & LIBINIT_LENMASK; tag &= LIBINIT_TAGMASK; if (tag != LIBINIT_STRING) { const char *name; MSize nuv = (MSize)(L->top - L->base - tpos); GCfunc *fn = lj_func_newC(L, nuv, env); if (nuv) { L->top = L->base + tpos; memcpy(fn->c.upvalue, L->top, sizeof(TValue)*nuv); } fn->c.ffid = (uint8_t)(ffid++); name = (const char *)p; p += len; if (tag == LIBINIT_CF) setmref(fn->c.pc, &G(L)->bc_cfunc_int); else setmref(fn->c.pc, bcff++); if (tag == LIBINIT_ASM_) fn->c.f = ofn->c.f; /* Copy handler from previous function. */ else fn->c.f = *cf++; /* Get cf or handler from C function table. */ if (len) { /* NOBARRIER: See above for common barrier. */ setfuncV(L, lj_tab_setstr(L, tab, lj_str_new(L, name, len)), fn); } ofn = fn; } else { switch (tag | len) { case LIBINIT_SET: L->top -= 2; if (tvisstr(L->top+1) && strV(L->top+1)->len == 0) env = tabV(L->top); else /* NOBARRIER: See above for common barrier. */ copyTV(L, lj_tab_set(L, tab, L->top+1), L->top); break; case LIBINIT_NUMBER: memcpy(&L->top->n, p, sizeof(double)); L->top++; p += sizeof(double); break; case LIBINIT_COPY: copyTV(L, L->top, L->top - *p++); L->top++; break; case LIBINIT_LASTCL: setfuncV(L, L->top++, ofn); break; case LIBINIT_FFID: ffid++; break; case LIBINIT_END: return; default: setstrV(L, L->top++, lj_str_new(L, (const char *)p, len)); p += len; break; } } } }
/* Index C data by a TValue. Return CType and pointer. */ CType *lj_cdata_index(CTState *cts, GCcdata *cd, cTValue *key, uint8_t **pp, CTInfo *qual) { uint8_t *p = (uint8_t *)cdataptr(cd); CType *ct = ctype_get(cts, cd->ctypeid); ptrdiff_t idx; /* Resolve reference for cdata object. */ if (ctype_isref(ct->info)) { lua_assert(ct->size == CTSIZE_PTR); p = *(uint8_t **)p; ct = ctype_child(cts, ct); } collect_attrib: /* Skip attributes and collect qualifiers. */ while (ctype_isattrib(ct->info)) { if (ctype_attrib(ct->info) == CTA_QUAL) *qual |= ct->size; ct = ctype_child(cts, ct); } lua_assert(!ctype_isref(ct->info)); /* Interning rejects refs to refs. */ if (tvisint(key)) { idx = (ptrdiff_t)intV(key); goto integer_key; } else if (tvisnum(key)) { /* Numeric key. */ #ifdef _MSC_VER /* Workaround for MSVC bug. */ volatile #endif lua_Number n = numV(key); idx = LJ_64 ? (ptrdiff_t)n : (ptrdiff_t)lj_num2int(n); integer_key: if (ctype_ispointer(ct->info)) { CTSize sz = lj_ctype_size(cts, ctype_cid(ct->info)); /* Element size. */ if (sz == CTSIZE_INVALID) lj_err_caller(cts->L, LJ_ERR_FFI_INVSIZE); if (ctype_isptr(ct->info)) { p = (uint8_t *)cdata_getptr(p, ct->size); } else if ((ct->info & (CTF_VECTOR|CTF_COMPLEX))) { if ((ct->info & CTF_COMPLEX)) idx &= 1; *qual |= CTF_CONST; /* Valarray elements are constant. */ } *pp = p + idx*(int32_t)sz; return ct; } } else if (tviscdata(key)) { /* Integer cdata key. */ GCcdata *cdk = cdataV(key); CType *ctk = ctype_raw(cts, cdk->ctypeid); if (ctype_isenum(ctk->info)) ctk = ctype_child(cts, ctk); if (ctype_isinteger(ctk->info)) { lj_cconv_ct_ct(cts, ctype_get(cts, CTID_INT_PSZ), ctk, (uint8_t *)&idx, cdataptr(cdk), 0); goto integer_key; } } else if (tvisstr(key)) { /* String key. */ GCstr *name = strV(key); if (ctype_isstruct(ct->info)) { CTSize ofs; CType *fct = lj_ctype_getfieldq(cts, ct, name, &ofs, qual); if (fct) { *pp = p + ofs; return fct; } } else if (ctype_iscomplex(ct->info)) { if (name->len == 2) { *qual |= CTF_CONST; /* Complex fields are constant. */ if (strdata(name)[0] == 'r' && strdata(name)[1] == 'e') { *pp = p; return ct; } else if (strdata(name)[0] == 'i' && strdata(name)[1] == 'm') { *pp = p + (ct->size >> 1); return ct; } } } else if (cd->ctypeid == CTID_CTYPEID) {