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

📄 lcode.c

📁 一个2D电磁场FEM计算的VC++源程序
💻 C
📖 第 1 页 / 共 2 页
字号:
/*** $Id: lcode.c,v 1.51 2000/09/29 12:42:13 roberto Exp $** Code generator for Lua** See Copyright Notice in lua.h*/#include "stdlib.h"#include "lua.h"#include "lcode.h"#include "ldo.h"#include "llex.h"#include "lmem.h"#include "lobject.h"#include "lopcodes.h"#include "lparser.h"void luaK_error (LexState *ls, const char *msg) {  luaX_error(ls, msg, ls->t.token);}/*** Returns the the previous instruction, for optimizations.** If there is a jump target between this and the current instruction,** returns a dummy instruction to avoid wrong optimizations.*/static Instruction previous_instruction (FuncState *fs) {  if (fs->pc > fs->lasttarget)  /* no jumps to current position? */    return fs->f->code[fs->pc-1];  /* returns previous instruction */  else    return CREATE_0(OP_END);  /* no optimizations after an `END' */}int luaK_jump (FuncState *fs) {  int j = luaK_code1(fs, OP_JMP, NO_JUMP);  if (j == fs->lasttarget) {  /* possible jumps to this jump? */    luaK_concat(fs, &j, fs->jlt);  /* keep them on hold */    fs->jlt = NO_JUMP;  }  return j;}static void luaK_fixjump (FuncState *fs, int pc, int dest) {  Instruction *jmp = &fs->f->code[pc];  if (dest == NO_JUMP)    SETARG_S(*jmp, NO_JUMP);  /* point to itself to represent end of list */  else {  /* jump is relative to position following jump instruction */    int offset = dest-(pc+1);    if (abs(offset) > MAXARG_S)      luaK_error(fs->ls, "control structure too long");    SETARG_S(*jmp, offset);  }}static int luaK_getjump (FuncState *fs, int pc) {  int offset = GETARG_S(fs->f->code[pc]);  if (offset == NO_JUMP)  /* point to itself represents end of list */    return NO_JUMP;  /* end of list */  else    return (pc+1)+offset;  /* turn offset into absolute position */}/*** returns current `pc' and marks it as a jump target (to avoid wrong** optimizations with consecutive instructions not in the same basic block).** discharge list of jumps to last target.*/int luaK_getlabel (FuncState *fs) {  if (fs->pc != fs->lasttarget) {    int lasttarget = fs->lasttarget;    fs->lasttarget = fs->pc;    luaK_patchlist(fs, fs->jlt, lasttarget);  /* discharge old list `jlt' */    fs->jlt = NO_JUMP;  /* nobody jumps to this new label (yet) */  }  return fs->pc;}void luaK_deltastack (FuncState *fs, int delta) {  fs->stacklevel += delta;  if (fs->stacklevel > fs->f->maxstacksize) {    if (fs->stacklevel > MAXSTACK)      luaK_error(fs->ls, "function or expression too complex");    fs->f->maxstacksize = fs->stacklevel;  }}void luaK_kstr (LexState *ls, int c) {  luaK_code1(ls->fs, OP_PUSHSTRING, c);}static int number_constant (FuncState *fs, Number r) {  /* check whether `r' has appeared within the last LOOKBACKNUMS entries */  Proto *f = fs->f;  int c = f->nknum;  int lim = c < LOOKBACKNUMS ? 0 : c-LOOKBACKNUMS;  while (--c >= lim)    if (f->knum[c] == r) return c;  /* not found; create a new entry */  luaM_growvector(fs->L, f->knum, f->nknum, 1, Number,                  "constant table overflow", MAXARG_U);  c = f->nknum++;  f->knum[c] = r;  return c;}void luaK_number (FuncState *fs, Number f) {  if (f <= (Number)MAXARG_S && (Number)(int)f == f)    luaK_code1(fs, OP_PUSHINT, (int)f);  /* f has a short integer value */  else    luaK_code1(fs, OP_PUSHNUM, number_constant(fs, f));}void luaK_adjuststack (FuncState *fs, int n) {  if (n > 0)    luaK_code1(fs, OP_POP, n);  else    luaK_code1(fs, OP_PUSHNIL, -n);}int luaK_lastisopen (FuncState *fs) {  /* check whether last instruction is an open function call */  Instruction i = previous_instruction(fs);  if (GET_OPCODE(i) == OP_CALL && GETARG_B(i) == MULT_RET)    return 1;  else return 0;}void luaK_setcallreturns (FuncState *fs, int nresults) {  if (luaK_lastisopen(fs)) {  /* expression is an open function call? */    SETARG_B(fs->f->code[fs->pc-1], nresults);  /* set number of results */    luaK_deltastack(fs, nresults);  /* push results */  }}static int discharge (FuncState *fs, expdesc *var) {  switch (var->k) {    case VLOCAL:      luaK_code1(fs, OP_GETLOCAL, var->u.index);      break;    case VGLOBAL:      luaK_code1(fs, OP_GETGLOBAL, var->u.index);      break;    case VINDEXED:      luaK_code0(fs, OP_GETTABLE);      break;    case VEXP:      return 0;  /* nothing to do */  }  var->k = VEXP;  var->u.l.t = var->u.l.f = NO_JUMP;  return 1;}static void discharge1 (FuncState *fs, expdesc *var) {  discharge(fs, var); /* if it has jumps then it is already discharged */  if (var->u.l.t == NO_JUMP && var->u.l.f  == NO_JUMP)    luaK_setcallreturns(fs, 1);  /* call must return 1 value */}void luaK_storevar (LexState *ls, const expdesc *var) {  FuncState *fs = ls->fs;  switch (var->k) {    case VLOCAL:      luaK_code1(fs, OP_SETLOCAL, var->u.index);      break;    case VGLOBAL:      luaK_code1(fs, OP_SETGLOBAL, var->u.index);      break;    case VINDEXED:  /* table is at top-3; pop 3 elements after operation */      luaK_code2(fs, OP_SETTABLE, 3, 3);      break;    default:      LUA_INTERNALERROR("invalid var kind to store");  }}static OpCode invertjump (OpCode op) {  switch (op) {    case OP_JMPNE: return OP_JMPEQ;    case OP_JMPEQ: return OP_JMPNE;    case OP_JMPLT: return OP_JMPGE;    case OP_JMPLE: return OP_JMPGT;    case OP_JMPGT: return OP_JMPLE;    case OP_JMPGE: return OP_JMPLT;    case OP_JMPT: case OP_JMPONT:  return OP_JMPF;    case OP_JMPF: case OP_JMPONF:  return OP_JMPT;    default:      LUA_INTERNALERROR("invalid jump instruction");      return OP_END;  /* to avoid warnings */  }}static void luaK_patchlistaux (FuncState *fs, int list, int target,                               OpCode special, int special_target) {  Instruction *code = fs->f->code;  while (list != NO_JUMP) {    int next = luaK_getjump(fs, list);    Instruction *i = &code[list];    OpCode op = GET_OPCODE(*i);    if (op == special)  /* this `op' already has a value */      luaK_fixjump(fs, list, special_target);    else {      luaK_fixjump(fs, list, target);  /* do the patch */      if (op == OP_JMPONT)  /* remove eventual values */        SET_OPCODE(*i, OP_JMPT);      else if (op == OP_JMPONF)        SET_OPCODE(*i, OP_JMPF);    }    list = next;  }}void luaK_patchlist (FuncState *fs, int list, int target) {  if (target == fs->lasttarget)  /* same target that list `jlt'? */    luaK_concat(fs, &fs->jlt, list);  /* delay fixing */  else    luaK_patchlistaux(fs, list, target, OP_END, 0);}static int need_value (FuncState *fs, int list, OpCode hasvalue) {  /* check whether list has a jump without a value */  for (; list != NO_JUMP; list = luaK_getjump(fs, list))    if (GET_OPCODE(fs->f->code[list]) != hasvalue) return 1;  return 0;  /* not found */}void luaK_concat (FuncState *fs, int *l1, int l2) {  if (*l1 == NO_JUMP)    *l1 = l2;  else {    int list = *l1;    for (;;) {  /* traverse `l1' */      int next = luaK_getjump(fs, list);      if (next == NO_JUMP) {  /* end of list? */        luaK_fixjump(fs, list, l2);        return;      }      list = next;    }  }}static void luaK_testgo (FuncState *fs, expdesc *v, int invert, OpCode jump) {  int prevpos;  /* position of last instruction */  Instruction *previous;  int *golist, *exitlist;  if (!invert) {    golist = &v->u.l.f;    /* go if false */    exitlist = &v->u.l.t;  /* exit if true */  }  else {    golist = &v->u.l.t;    /* go if true */    exitlist = &v->u.l.f;  /* exit if false */  }  discharge1(fs, v);  prevpos = fs->pc-1;  previous = &fs->f->code[prevpos];  LUA_ASSERT(*previous==previous_instruction(fs), "no jump allowed here");  if (!ISJUMP(GET_OPCODE(*previous)))    prevpos = luaK_code1(fs, jump, NO_JUMP);  else {  /* last instruction is already a jump */    if (invert)      SET_OPCODE(*previous, invertjump(GET_OPCODE(*previous)));  }  luaK_concat(fs, exitlist, prevpos);  /* insert last jump in `exitlist' */  luaK_patchlist(fs, *golist, luaK_getlabel(fs));  *golist = NO_JUMP;}void luaK_goiftrue (FuncState *fs, expdesc *v, int keepvalue) {  luaK_testgo(fs, v, 1, keepvalue ? OP_JMPONF : OP_JMPF);}static void luaK_goiffalse (FuncState *fs, expdesc *v, int keepvalue) {  luaK_testgo(fs, v, 0, keepvalue ? OP_JMPONT : OP_JMPT);}static int code_label (FuncState *fs, OpCode op, int arg) {  luaK_getlabel(fs);  /* those instructions may be jump targets */  return luaK_code1(fs, op, arg);}void luaK_tostack (LexState *ls, expdesc *v, int onlyone) {  FuncState *fs = ls->fs;  if (!discharge(fs, v)) {  /* `v' is an expression? */    OpCode previous = GET_OPCODE(fs->f->code[fs->pc-1]);    if (!ISJUMP(previous) && v->u.l.f == NO_JUMP && v->u.l.t == NO_JUMP) {      /* expression has no jumps */      if (onlyone)        luaK_setcallreturns(fs, 1);  /* call must return 1 value */    }    else {  /* expression has jumps */      int final;  /* position after whole expression */      int j = NO_JUMP;  /*  eventual  jump over values */      int p_nil = NO_JUMP;  /* position of an eventual PUSHNIL */      int p_1 = NO_JUMP;  /* position of an eventual PUSHINT */      if (ISJUMP(previous) || need_value(fs, v->u.l.f, OP_JMPONF)                           || need_value(fs, v->u.l.t, OP_JMPONT)) {        /* expression needs values */        if (ISJUMP(previous))          luaK_concat(fs, &v->u.l.t, fs->pc-1);  /* put `previous' in t. list */        else {          j = code_label(fs, OP_JMP, NO_JUMP);  /* to jump over both pushes */          /* correct stack for compiler and symbolic execution */          luaK_adjuststack(fs, 1);        }        p_nil = code_label(fs, OP_PUSHNILJMP, 0);        p_1 = code_label(fs, OP_PUSHINT, 1);        luaK_patchlist(fs, j, luaK_getlabel(fs));      }      final = luaK_getlabel(fs);      luaK_patchlistaux(fs, v->u.l.f, p_nil, OP_JMPONF, final);      luaK_patchlistaux(fs, v->u.l.t, p_1, OP_JMPONT, final);      v->u.l.f = v->u.l.t = NO_JUMP;    }  }}void luaK_prefix (LexState *ls, UnOpr op, expdesc *v) {  FuncState *fs = ls->fs;  if (op == OPR_MINUS) {

⌨️ 快捷键说明

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