opt.c
Upload User: kairuinn
Upload Date: 2009-02-07
Package Size: 2922k
Code Size: 2k
Category:

Graph program

Development Platform:

Visual C++

  1. /*
  2. ** $Id: opt.c,v 1.22 2000/10/31 16:57:23 lhf Exp $
  3. ** optimize bytecodes
  4. ** See Copyright Notice in lua.h
  5. */
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include "luac.h"
  10. static int MapConstant(Hash* t, int j, const TObject* key)
  11. {
  12.  const TObject* o=luaH_get(L,t,key);
  13.  if (ttype(o)==LUA_TNUMBER)
  14.   return (int) nvalue(o);
  15.  else
  16.  {
  17.   TObject val;
  18.   ttype(&val)=LUA_TNUMBER;
  19.   nvalue(&val)=j;
  20.   *luaH_set(L,t,key)=val;
  21.   LUA_ASSERT(j>=0,"MapConstant returns negative!");
  22.   return j;
  23.  }
  24. }
  25. static int MapConstants(Proto* tf, Hash* map)
  26. {
  27.  int i,j,k,n,m=0;
  28.  TObject o;
  29.  j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
  30.  for (i=0; i<n; i++)
  31.  {
  32.   nvalue(&o)=tf->knum[i];
  33.   k=MapConstant(map,j,&o);
  34.   if (k==j) j++;
  35.  }
  36.  m=j;
  37.  j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
  38.  for (i=0; i<n; i++)
  39.  {
  40.   tsvalue(&o)=tf->kstr[i];
  41.   k=MapConstant(map,j,&o);
  42.   if (k==j) j++;
  43.  }
  44.  return m+j;
  45. }
  46. static void PackConstants(Proto* tf, Hash* map)
  47. {
  48.  int i,j,k,n;
  49.  TObject o;
  50.  j=0; n=tf->nknum; ttype(&o)=LUA_TNUMBER;
  51.  for (i=0; i<n; i++)
  52.  {
  53.   nvalue(&o)=tf->knum[i];
  54.   k=MapConstant(map,-1,&o);
  55.   if (k==j) tf->knum[j++]=tf->knum[i];
  56.  }
  57.  tf->nknum=j;
  58.  j=0; n=tf->nkstr; ttype(&o)=LUA_TSTRING;
  59.  for (i=0; i<n; i++)
  60.  {
  61.   tsvalue(&o)=tf->kstr[i];
  62.   k=MapConstant(map,-1,&o);
  63.   if (k==j) tf->kstr[j++]=tf->kstr[i];
  64.  }
  65.  tf->nkstr=j;
  66. }
  67. static void OptConstants(Proto* tf)
  68. {
  69.  Instruction* p;
  70.  int n=tf->nknum+tf->nkstr;
  71.  Hash* map=luaH_new(L,n);
  72.  int m=MapConstants(tf,map);
  73.  if (m==n) return;
  74.  for (p=tf->code;; p++)
  75.  {
  76.   Instruction i=*p;
  77.   int op=GET_OPCODE(i);
  78.   switch (op)
  79.   {
  80.    TObject o;
  81.    int j,k;
  82.    case OP_PUSHNUM: case OP_PUSHNEGNUM:
  83.     j=GETARG_U(i);
  84.     ttype(&o)=LUA_TNUMBER; nvalue(&o)=tf->knum[j];
  85.     k=MapConstant(map,-1,&o);
  86.     if (k!=j) *p=CREATE_U(op,k);
  87.     break;
  88.    case OP_PUSHSTRING: case OP_GETGLOBAL: case OP_GETDOTTED:
  89.    case OP_PUSHSELF:   case OP_SETGLOBAL:
  90.     j=GETARG_U(i);
  91.     ttype(&o)=LUA_TSTRING; tsvalue(&o)=tf->kstr[j];
  92.     k=MapConstant(map,-1,&o);
  93.     if (k!=j) *p=CREATE_U(op,k);
  94.     break;
  95.    case OP_END:
  96.     PackConstants(tf,map);
  97.     luaH_free(L,map);
  98.     return;
  99.    default:
  100.     break;
  101.   }
  102.  }
  103. }
  104. #define OptFunction luaU_optchunk
  105. void OptFunction(Proto* tf)
  106. {
  107.  int i,n=tf->nkproto;
  108.  OptConstants(tf);
  109.  for (i=0; i<n; i++) OptFunction(tf->kproto[i]);
  110. }