⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ljit_x86_inline.dash

📁 采用C语言写的Lua的解释器的代码!Lua不用介绍了吧
💻 DASH
📖 第 1 页 / 共 2 页
字号:
  case JIT_IH_TABLE_REMOVE:    jit_assert(ii->nargs == 1);    |  lea TVALUE:eax, BASE[arg]    |  lea TVALUE:ecx, BASE[res]    |  call &jit_table_remove, L, TVALUE:eax, TVALUE:ecx    if (ii->nresults == -1) {      ii->xnresults = -1;      |  mov TOP, TVALUE:eax    }    break;  case JIT_IH_TABLE_GETN:    |  mov TABLE:eax, BASE[arg].value    |  call &luaH_getn, TABLE:eax    |  mov TMP1, eax    |  fild dword TMP1    |  fstp qword BASE[res].value    |  settt BASE[res], LUA_TNUMBER    break;  default:    jit_assert(0);    break;  }}/* ------------------------------------------------------------------------ *//* This typedef must match the libm function signature. *//* Serves as a check against wrong lua_Number or wrong calling conventions. */typedef lua_Number (*mathfunc_11)(lua_Number);/* Partially inlined math functions. *//* CHECK: must match with jit_hints.h and jit.opt_lib. */static const mathfunc_11 jit_mathfuncs_11[JIT_IH_MATH_SIN] = {  log, log10, exp,	sinh, cosh, tanh,	asin, acos, atan};/* FPU control words for ceil and floor (exceptions masked, full precision). */static const unsigned short jit_fpucw[2] = { 0x0b7f, 0x077f };static void jit_inline_math(jit_State *J, jit_InlineInfo *ii){  int arg = ii->func+1;  int res = ii->res;  int idx = JIT_IH_IDX(ii->hidx);  if (idx < JIT_IH_MATH__21) {    |  isnumber arg; jne L_DEOPTIMIZE    |  fld qword BASE[arg].value  } else {    jit_assert(idx < JIT_IH_MATH__LAST);    |  isnumber2 arg, arg+1; jne L_DEOPTIMIZE  }  switch (idx) {  /* We ignore sin/cos/tan range overflows (2^63 rad) just like -ffast-math. */  case JIT_IH_MATH_SIN:    |  fsin    break;  case JIT_IH_MATH_COS:    |  fcos    break;  case JIT_IH_MATH_TAN:    |  fptan; fpop    break;  case JIT_IH_MATH_CEIL:  case JIT_IH_MATH_FLOOR:    |  fnstcw word TMP1    |  fldcw word [(ptrdiff_t)&jit_fpucw[idx-JIT_IH_MATH_CEIL]]    |  frndint    |  fldcw word TMP1    break;  case JIT_IH_MATH_ABS:    |  fabs    break;  case JIT_IH_MATH_SQRT:    |  fsqrt    break;  case JIT_IH_MATH_FMOD:    |  fld qword BASE[arg+1].value    |  fld qword BASE[arg].value    |1: ; fprem; fnstsw ax; sahf; jp <1    |  fstp st1    break;  case JIT_IH_MATH_ATAN2:    |// Inlining is easier than calling atan2().    |  fld qword BASE[arg].value    |  fld qword BASE[arg+1].value    |  fpatan    break;  default:    |// Partially inlined. Just call the libm function (__cdecl!).    |  fstp FPARG1    |  call &jit_mathfuncs_11[idx]    break;  }  |  settt BASE[res], LUA_TNUMBER  |  fstp qword BASE[res].value}/* ------------------------------------------------------------------------ *//* Try to inline a CALL or TAILCALL instruction. */static int jit_inline_call(jit_State *J, int func, int nargs, int nresults){  const TValue *callable = hint_get(J, TYPE);  /* TYPE hint = callable. */  int cltype = ttype(callable);  const TValue *oidx;  jit_InlineInfo ii;  int idx;  if (cltype != LUA_TFUNCTION) goto fail;  if (J->flags & JIT_F_DEBUG) goto fail;  /* DWIM. */  oidx = hint_get(J, INLINE);  /* INLINE hint = library/function index. */  if (!ttisnumber(oidx)) goto fail;  ii.hidx = (int)nvalue(oidx);  idx = JIT_IH_IDX(ii.hidx);  if (nresults == -2) {  /* Tailcall. */    /* Tailcalls from vararg functions don't work with BASE[-1]. */    if (J->pt->is_vararg) goto fail;  /* So forget about this rare case. */    ii.res = -1;  /* Careful: 2nd result overlaps 1st stack slot. */    ii.nresults = -1;  } else {    ii.res = func;    ii.nresults = nresults;  }  ii.func = func;  ii.nargs = nargs;  ii.xnargs = ii.xnresults = 1;  /* Default: 1 arg, 1 result. */  /* Check for the currently supported cases. */  switch (JIT_IH_LIB(ii.hidx)) {  case JIT_IHLIB_BASE:    switch (idx) {    case JIT_IH_BASE_PAIRS:    case JIT_IH_BASE_IPAIRS:      if (nresults == -2) goto fail;  /* Not useful for tailcalls. */      ii.xnresults = 3;      goto check;    }    break;#ifndef COCO_DISABLE  case JIT_IHLIB_COROUTINE:    switch (idx) {    case JIT_IH_COROUTINE_YIELD:      /* Only support common cases: no tailcalls, low number of results. */      if (nresults < 0 || nresults > EXTRA_STACK) goto fail;      ii.xnargs = ii.xnresults = -1;      goto ok;  /* Anything else is ok. */    case JIT_IH_COROUTINE_RESUME:      /* Only support common cases: no tailcalls, not with 0 args (error). */      if (nresults == -2 || nargs == 0) goto fail;      ii.xnargs = ii.xnresults = -1;      goto ok;  /* Anything else is ok. */    }    break;#endif  case JIT_IHLIB_STRING:    switch (idx) {    case JIT_IH_STRING_LEN:      goto check;    case JIT_IH_STRING_SUB:      if (nargs < 2) goto fail;  /* No support for open calls, too. */      goto ok;  /* 2 or more args are ok. */    case JIT_IH_STRING_CHAR:      goto check;  /* Only single arg supported. */    }    break;  case JIT_IHLIB_TABLE:    switch (idx) {    case JIT_IH_TABLE_INSERT:      ii.xnargs = 2;      goto check;  /* Only push (append) supported. */    case JIT_IH_TABLE_REMOVE:      goto check;  /* Only pop supported. */    case JIT_IH_TABLE_GETN:      goto check;    }    break;  case JIT_IHLIB_MATH:    if (idx >= JIT_IH_MATH__LAST) goto fail;    if (idx >= JIT_IH_MATH__21) ii.xnargs = 2;    goto check;  }fail:  return cltype;  /* Call could not be inlined. Return type of callable. */check:  if (nargs != ii.xnargs && nargs != -1) goto fail;  /* The optimizer already checks the number of results (avoid setnil). */ok:  /* Whew, all checks done. Go for it! */  /* Start with the common leadin for inlined calls. */  jit_deopt_target(J, nargs);  |// Caveat: Must save TOP for open ops if jsub uses DEOPTIMIZE_CALLER.  |  isfunction func  |  jne L_DEOPTIMIZE			// Not a function? Deoptimize.  |  cmp aword BASE[func].value, &clvalue(callable)  |  jne L_DEOPTIMIZE			// Wrong closure? Deoptimize.  if (nargs == -1 && ii.xnargs >= 0) {    |  lea eax, BASE[func+1+ii.xnargs]    |  cmp TOP, eax    |  jne L_DEOPTIMIZE			// Wrong #args? Deoptimize.  }  /* Now inline the function itself. */  switch (JIT_IH_LIB(ii.hidx)) {  case JIT_IHLIB_BASE: jit_inline_base(J, &ii); break;#ifndef COCO_DISABLE  case JIT_IHLIB_COROUTINE: jit_inline_coroutine(J, &ii); break;#endif  case JIT_IHLIB_STRING: jit_inline_string(J, &ii); break;  case JIT_IHLIB_TABLE:  jit_inline_table(J, &ii); break;  case JIT_IHLIB_MATH:   jit_inline_math(J, &ii); break;  default: jit_assert(0); break;  }  /* And add the common leadout for inlined calls. */  if (ii.nresults == -1) {    if (ii.xnresults >= 0) {      |  lea TOP, BASE[ii.res+ii.xnresults]    }  } else if (ii.nargs == -1) {  /* Restore L->top only if needed. */    |  lea TOP, BASE[J->pt->maxstacksize]    |  mov L->top, TOP  }  if (nresults == -2) {  /* Results are in place. Add return for tailcalls. */    |  add esp, FRAME_OFFSET    |  sub BASE, #BASE    |  sub aword L->ci, #CI    |  ret  }  return -1;  /* Success, call has been inlined. */}/* ------------------------------------------------------------------------ *//* Helper function for inlined iterator code. Paraphrased from luaH_next. *//* TODO: GCC has trouble optimizing this. */static int jit_table_next(lua_State *L, TValue *ra){  Table *t = hvalue(&ra[TFOR_TAB]);  int i = ra[TFOR_CTL].value.b;  /* Hidden control variable. */  for (; i < t->sizearray; i++) {  /* First the array part. */    if (!ttisnil(&t->array[i])) {      setnvalue(&ra[TFOR_KEY], cast_num(i+1));      setobj2s(L, &ra[TFOR_VAL], &t->array[i]);      ra[TFOR_CTL].value.b = i+1;      return 1;    }  }  for (i -= t->sizearray; i < sizenode(t); i++) {  /* Then the hash part. */    if (!ttisnil(gval(gnode(t, i)))) {      setobj2s(L, &ra[TFOR_KEY], key2tval(gnode(t, i)));      setobj2s(L, &ra[TFOR_VAL], gval(gnode(t, i)));      ra[TFOR_CTL].value.b = i+1+t->sizearray;      return 1;    }  }  return 0;  /* End of iteration. */}/* Try to inline a TFORLOOP instruction. */static int jit_inline_tforloop(jit_State *J, int ra, int nresults, int target){  const TValue *oidx = hint_get(J, INLINE);  /* INLINE hint = lib/func idx. */  int idx;  if (!ttisnumber(oidx)) return 0;  /* No hint: don't inline anything. */  idx = (int)nvalue(oidx);  if (J->flags & JIT_F_DEBUG) return 0;  /* DWIM. */  switch (idx) {  case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_PAIRS):    |// The type checks can be omitted -- see the iterator constructor.    |  lea TOP, BASE[ra]    |  call &jit_table_next, L, TOP    |  test eax, eax    |  jnz =>target    return 1;  /* Success, iterator has been inlined. */  case JIT_IH_MKIDX(JIT_IHLIB_BASE, JIT_IH_BASE_IPAIRS):    |// The type checks can be omitted -- see the iterator constructor.    |  mov eax, BASE[ra+TFOR_CTL].value		// Hidden control variable.    |  inc eax    |   mov TABLE:edx, BASE[ra+TFOR_TAB].value	// Table object.    |  mov BASE[ra+TFOR_CTL].value, eax    |  call &luaH_getnum, TABLE:edx, eax    |  // This is really copyslot BASE[ra+TFOR_VAL], TVALUE:eax[0] plus compare.    |  mov ecx, TVALUE:eax->tt    |  test ecx, ecx				// Assumes: LUA_TNIL == 0.    |  jz >9					// nil value stops iteration.    |   fild dword BASE[ra+TFOR_CTL].value	// Set numeric key.    |   settt BASE[ra+TFOR_KEY], LUA_TNUMBER    |   fstp qword BASE[ra+TFOR_KEY].value    |  mov edx, TVALUE:eax->value    |  mov eax, TVALUE:eax->value.na[1]	// Overwrites eax.    |  mov BASE[ra+TFOR_VAL].tt, ecx		// Copy value from table slot.    |  mov BASE[ra+TFOR_VAL].value, edx    |  mov BASE[ra+TFOR_VAL].value.na[1], eax    |  jmp =>target    |9:    return 1;  /* Success, iterator has been inlined. */  }  return 0;  /* No support for inlining any other iterators. */}/* ------------------------------------------------------------------------ */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -