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

📄 ljitlib.c

📁 采用C语言写的Lua的解释器的代码!Lua不用介绍了吧
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** Lua library for the JIT engine.** Copyright (C) 2005-2008 Mike Pall. See Copyright Notice in luajit.h*/#include <stdio.h>#include <string.h>#define ljitlib_c#define LUA_LIB#include "lua.h"#include "lauxlib.h"#include "luajit.h"#include "lualib.h"/* This file is not a pure C API user. Some internals are required. */#include "lobject.h"#include "lstate.h"#include "lstring.h"#include "ltable.h"#include "lfunc.h"#include "lgc.h"#include "lopcodes.h"#include "ljit.h"#include "ljit_hints.h"#define STRING_HINTS#include "ljit_hints.h"/* ------------------------------------------------------------------------ *//* Static pointer addresses used as registry keys. *//* The values do not matter, but must be different to prevent joining. */static const int regkey_frontend = 0x6c6a6c01;static const int regkey_comthread = 0x6c6a6c02;/* Check that the first argument is a Lua function and return its closure. */static Closure *check_LCL(lua_State *L){  StkId o = L->base;  switch (lua_type(L, 1)) {  case LUA_TBOOLEAN:    o = (L->ci-1)->func;  case LUA_TFUNCTION:    if (isLfunction(o))      return clvalue(o);    break;  }  luaL_argerror(L, 1, "Lua function expected");  return NULL;}/* Create a new closure from a prototype. *//* Note: upvalues are assumed to be after first two slots. */static void push_LCL(lua_State *L, Proto *pt, Table *env){  Closure *cl;  int i, nup = pt->nups;  /* Adjust the number of stack slots to the number of upvalues. */  luaL_checkstack(L, nup, "too many upvalues");  lua_settop(L, 2+nup);  /* Create a closure from the subroutine prototype. */  cl = luaF_newLclosure(L, nup, env);  cl->l.p = pt;  /* Allocate new upvalues and close them. */  for (i = 0; i < nup; i++)    cl->l.upvals[i] = luaF_findupval(L, L->base + (2+i));  luaF_close(L, L->base + 2);  lua_settop(L, 2);  /* Remove upvalues. */  setclvalue(L, L->top++, cl);  /* Return closure on top of stack. */  luaC_checkGC(L);}/* ------------------------------------------------------------------------ *//* Set JIT mode for the engine or a closure and/or its subroutines. */static int setmode(lua_State *L, int mode){  int idx = 0;  switch (lua_type(L, 1)) {  case LUA_TNONE:	/* jit.on/off() */  case LUA_TNIL:	/* jit.on/off(nil) */    luaJIT_setmode(L, 0, mode | LUAJIT_MODE_ENGINE);    break;  case LUA_TFUNCTION:	/* jit.on/off(func, nil|true|false) */    idx = 1;  case LUA_TBOOLEAN:	/* jit.on/off(true, nil|true|false) (parent frame) */    if (lua_isboolean(L, 2))      mode |= lua_toboolean(L, 2)?LUAJIT_MODE_ALLFUNC:LUAJIT_MODE_ALLSUBFUNC;    else      mode |= LUAJIT_MODE_FUNC;    if (luaJIT_setmode(L, idx, mode) == 1)  /* Ok? */      break;  default:    luaL_argerror(L, 1, "Lua function expected");    break;  }  return 0;}/* Set JIT mode to on: (re-)enable compilation. */static int j_on(lua_State *L){  return setmode(L, LUAJIT_MODE_ON);}/* Set JIT mode to off: disable compilation. */static int j_off(lua_State *L){  return setmode(L, LUAJIT_MODE_OFF);}/* Set JIT debug level. Defaults to maximum level for use with -j. */static int j_debug(lua_State *L){  luaJIT_setmode(L, luaL_optinteger(L, 1, 100), LUAJIT_MODE_DEBUG);  return 0;}/* ------------------------------------------------------------------------ *//* Report the compilation status. */static int compstatus(lua_State *L, int status){  if (status == -1)    return luaL_argerror(L, 1, "Lua function expected");  else if (status == JIT_S_OK)    return 0;  else {    lua_pushinteger(L, status);    return 1;  }}/* Compile a function. Pass typical args to help the optimizer. */static int j_compile(lua_State *L){  int nargs = lua_gettop(L) - 1;  return compstatus(L, nargs >= 0 ? luaJIT_compile(L, nargs) : -1);}/* Recursively compile all subroutine prototypes. */static int rec_compile(lua_State *L, Proto *pt, Table *env, int stoponerror){  int rstatus = JIT_S_OK;  int i;  for (i = 0; i < pt->sizep; i++) {    Proto *pti = pt->p[i];    int status;    push_LCL(L, pti, env);  /* Assumes stack is at 2 (no upvalues). */    status = luaJIT_compile(L, 0);    lua_settop(L, 2);  /* Clear stack */    if (status != JIT_S_OK) {      rstatus = status;      if (stoponerror) break;    }    status = rec_compile(L, pti, env, stoponerror);    if (status != JIT_S_OK) {      rstatus = status;      if (stoponerror) break;    }  }  return rstatus;}/* Compile all subroutines of a function. *//* Note: the function itself is _not_ compiled (use jit.compile()). */static int j_compilesub(lua_State *L){  Closure *cl = check_LCL(L);  int stoponerror = lua_toboolean(L, 2);  /* Stop on first error? */  lua_settop(L, 2);  return compstatus(L, rec_compile(L, cl->l.p, cl->l.env, stoponerror));}/* jit.* functions. */static const luaL_Reg jitlib[] = {  { "on",		j_on },  { "off",		j_off },  { "debug",		j_debug },  { "compile",		j_compile },  { "compilesub",	j_compilesub },  /* j_attach is added below. */  { NULL, NULL }};/* ------------------------------------------------------------------------ *//* Get the compiler pipeline table from an upvalue (j_attach, j_frontend). */#define COMPIPE		lua_upvalueindex(1)/* Attach/detach handler to/from compiler pipeline. */static int j_attach(lua_State *L){  int pipesz;  luaL_checktype(L, 1, LUA_TFUNCTION);  pipesz = lua_objlen(L, COMPIPE);  if (lua_isnoneornil(L, 2)) {  /* Detach if no priority given. */    int i;    for (i = 1; i <= pipesz; i += 2) {      lua_rawgeti(L, COMPIPE, i);      if (lua_rawequal(L, 1, -1)) {  /* Found: delete from pipeline. */	for (; i+2 <= pipesz; i++) {  /* Shift down. */	  lua_rawgeti(L, COMPIPE, i+2);	  lua_rawseti(L, COMPIPE, i);	}	/* Clear last two elements. */	lua_pushnil(L); lua_rawseti(L, COMPIPE, i);	lua_pushnil(L); lua_rawseti(L, COMPIPE, i+1);	return 0;      }      lua_pop(L, 1);    }    return 0;  /* Not found: ignore detach request. */  } else {  /* Attach if priority given. */    int prio = luaL_checkint(L, 2);    int pos, i;    for (pos = 2; pos <= pipesz; pos += 2) {      lua_rawgeti(L, COMPIPE, pos);      if (prio > (int)lua_tointeger(L, -1)) break; /* Insertion point found. */      lua_pop(L, 1);    }    for (i = pipesz+2; i > pos; i--) {  /* Shift up. */      lua_rawgeti(L, COMPIPE, i-2);      lua_rawseti(L, COMPIPE, i);    }    /* Set handler and priority. */    lua_pushvalue(L, 1); lua_rawseti(L, COMPIPE, i-1);    lua_pushvalue(L, 2); lua_rawseti(L, COMPIPE, i);    return 0;  }}/* Compiler frontend. Runs in the compiler thread. *//* First and only arg is the compiler state table. */static int j_frontend(lua_State *L){  int status = JIT_S_OK;  int pos;  /* Loop through all handlers in the compiler pipeline. */  for (pos = 1; ; pos += 2) {    if (status != JIT_S_OK) {  /* Pending failure? */      int prio;      lua_rawgeti(L, COMPIPE, pos+1);  /* Must check for odd/even priority. */      if (lua_isnil(L, -1)) break;  /* End of pipeline. */      prio = (int)lua_tointeger(L, -1);      lua_pop(L, 1);      if ((prio & 1) == 0) continue;  /* Skip handlers with even priority. */    }    /* Call handler with compiler state table and optional failure status. */    lua_rawgeti(L, COMPIPE, pos);    if (lua_isnil(L, -1)) break;  /* End of pipeline. */    lua_pushvalue(L, 1);    if (status != JIT_S_OK)      lua_pushinteger(L, status);    lua_call(L, status ? 2 : 1, 1);    if (!lua_isnil(L, -1))  /* Remember failure status. */      status = (int)lua_tointeger(L, -1);    lua_pop(L, 1);  }  lua_pushinteger(L, status);  return 1;}/* Compiler frontend wrapper. */static int frontwrap(lua_State *L, Table *st){  jit_State *J = G(L)->jit_state;  lua_State *JL;  int status;  /* Allocate compiler thread on demand. */  if (J->L == NULL) {    if (!lua_checkstack(L, 3)) return JIT_S_COMPILER_ERROR;    sethvalue(L, L->top++, st);  /* Prevent GC of state table. */    lua_pushlightuserdata(L, (void *)&regkey_comthread);    /* Cannot use C stack, since it's deallocated early in Coco. */    /* But we don't need one -- the compiler thread never yields, anyway. */    J->L = lua_newthread(L);    lua_rawset(L, LUA_REGISTRYINDEX);    L->top--;  /* Remove state table from this stack. */  }  JL = J->L;  /* Initialize compiler thread stack with frontend and state table. */  lua_settop(JL, 0);  lua_pushlightuserdata(JL, (void *)&regkey_frontend);  lua_rawget(JL, LUA_REGISTRYINDEX);  sethvalue(JL, JL->top, st);  JL->top++;  /* Start the frontend by resuming the compiler thread. */  if (lua_resume(JL, 1) != 0) {  /* Failed? */    /* Note: LUA_YIELD is treated like any other error. */    J->L = NULL;  /* Get a new thread next time. */    fprintf(stderr, "[LuaJIT frontend failed: %s]\n",      lua_isstring(JL, -1) ? lua_tostring(JL, -1) : "(unknown error)");    return JIT_S_COMPILER_ERROR;  }  /* Get status from terminated thread. */  status = (int)lua_tointeger(JL, -1);  lua_settop(JL, 0);  /* Help the GC. */  return status;}/* Create the compiler pipeline and register it. */static void makepipeline(lua_State *L){  lua_createtable(L, 20, 0);  /* 10 handlers+priorities should be enough. */  lua_pushcfunction(L, luaJIT_backend);  lua_rawseti(L, -2, 1);  lua_pushinteger(L, 0);  /* Fill in the backend at prio 0. */  lua_rawseti(L, -2, 2);  /* Store the compiler frontend in the registry. */  lua_pushlightuserdata(L, (void *)&regkey_frontend);

⌨️ 快捷键说明

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