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

📄 common.cpp.svn-base

📁 这是一段游戏修改工具的源代码.ring3功能由dephi开发,驱动是C开发.希望对大家有帮助
💻 SVN-BASE
📖 第 1 页 / 共 5 页
字号:
/* common.cpp
 * Support logic for grammar
 * UnderC C++ interpreter
 * Steve Donovan, 2001
 * This is GPL'd software, and the usual disclaimers apply.
 * See LICENCE
 */
 #include "common.h"
 #include "function_match.h"
 #include "tparser.h"
 #include "code.h"
 #include "opcodes.h"
 #include "engine.h"
#include "directcall.h"
// for Module stuff.....
#include "module.h"
#include "input.h"
#include "tokens.h"

Table* gScopeContext;

#ifdef _DEBUG
extern int gDebugBreak;
extern FBlock* gFunBlock;
void __break(int);
#endif

Function* gLastFunction;  //*DEBUG
void* gObjectReturnPtr;

void next_statement();  // in uc_tokens.cpp
void skip_function_body(int brace_count=1); // *TEMP* in templates.cpp

// these are temporary places for stuff that must go in headers!
 void dissemble(PFBlock fb); // in DISSEM
 void dissembler_init();

 bool interactive_mode(); 

 // found in parser code - don't muck w/ in_declaration directly!
 extern bool IEF;
 void force_comma_flag();

 // found in type.cpp (of all places!)
 Signature *unique_signature(Signature *sig);

void *Entry::global_ptr()
{
    return Parser::global().addr(data);
}

char *Entry::object_ptr(char *obj)
{
    return obj + data;
}

// *add 1.1.4 Bit field management. Note the assumption here is that
// for a 32-bit word, the info can be packed into 20-bits, which is
// the operand size for our instruction set.
struct _BitField {
	int offs; //: 10;
	int bit_offs; //: 5;
	int bit_size; //: 5;
	int rest; // : 12;    // pack up to 32-bits
};

void Entry::set_bit_field(int offs, int bit_offs, int bit_size)
{
 int sz = sizeof(_BitField);
 data =  Parser::global().alloc(sz,NULL); 
 rmode = OREL_F;
 _BitField *bf = (_BitField *)Parser::global().addr(data);
 bf->offs = offs;
 bf->bit_offs = bit_offs;
 bf->bit_size = bit_size;
 bf->rest = 0;
// unsigned int rdata;
// memmove(&rdata,&bf,4); 
// data = rdata; 
}

void unpack_bitfield(int data, int& offs, int& bit_offs, int& bit_size)
{
 _BitField *bf = (_BitField *)Parser::global().addr(data);
 offs = bf->offs;
 bit_offs = bf->bit_offs;
 bit_size = bf->bit_size;
}

void Entry::get_bit_field(int& offs, int& bit_offs, int& bit_size)
{
  unpack_bitfield(data,offs,bit_offs,bit_size);
}

string itos(int i)
{
 char buff[20];
 itoa(i,buff,10);
 return buff;
}

string as_str(Type t)
{ static string str;
  t.as_string(str);
  return str;
}

void fail(const string& msg)
{ 
    throw msg;
}

 //... private to this module
 namespace {
  const int DATA_SIZE = 1000000;
  Global mGlobal(DATA_SIZE);
  FBlock mCodeBlock;
  LocalContext *mpTempContext=NULL;
  PClass mCatchHandlerObj=NULL;
  const int CONTINUEABLE = 1, IN_METHOD = 2, CONTEXT_PUSHED = 4,
            IN_SWITCH = 8, BREAKABLE = 16, FUN_BLOCK = 32, LOOP_SCOPE = 64;

 }
 //.......................

 void clear_global_namespace()
 {
  mGlobal.clear();
 }

int yyerror(const char *s);  

 void error(string msg)
 {
 using Parser::state;
 // this flag forces an orderly exit from the parser!
  if (state.err != "") yyerror(state.err.c_str());
  state.err = msg;
  state.file = Input::filename();
  state.lineno = Input::lineno();
 }

 void warning(string _msg)
 {
   cmsg << Input::filename() << ' ' << Input::lineno() << ": "
       << _msg << endl;
 }

 string make_temp_name()
 {
  static int k = 0;
  return "$" + itos(k++);
 }

 int tstack_depth()
 { return Parser::state.tstack.depth(); }

 static Parser::ExprFun s_expr_handler;

 // shared w/ parser,for the mo!
 namespace Parser {
  
  ParserState state; 
  PEntry mEIntDivByZero=NULL,mEAccessViolation=NULL,mEFloatDivByZero=NULL,
         mEException=NULL,mERangeError=NULL;
  PExpr mOCout=NULL;
  PExpr mObjectReturnExpr;
  Namespace* sStdNamespace = NULL;

  int s_array_size = 1;
  int s_twodim_array = 1;

  DebugFlags debug;

  Global& global() { return mGlobal; }

  Table*  std_namespace() 
  {
    return (Table*) sStdNamespace;
  }

  bool set_alignment(int ipack)
  {
    if (ipack != 1 && ipack != 4 && ipack != 8) return false;
	Parser::debug.class_dword_align = ipack;
    return true;
  }
 
// temporary stuff used by the grammar to Express Itself.
void out(char *s)
 { cout << s; }
void outln(char *s)
 { cout << s << endl; }

string quotes(const string& s)
{ return "'" + s + "'"; }

// type stack stuff
void  tpush(Type t)
{ 
  state.tstack.push(t);
  if (state.tstack.depth() >= state.tstack.capacity())
	  state.tstack.pop();
}

Type& tots()
 { return state.tstack.TOS(); }

void  stots(TType tt)
{ state.tstack.TOS() = AsType(tt); }

Type  tpop()
 { return state.tstack.pop(); }
TType ttots()
 { return AsTType(tots()); }
TType make_ref(TType t)
 { AsType(t).make_reference(); return t; }
TType incr_ptr(TType t)
 { AsType(t).incr_pointer();   return t; }
TType make_unsigned(TType t)
 { AsType(t).make_unsigned(); return t; }

int block_depth()
{
 return state.block_stack.depth();
}

void *ExprToPtr(Expression e)
{
// *SJD* This is specialized to operate with _globally allocated_ data
 if (!e->is_entry()) return NULL;
 return e->entry()->global_ptr();
}

// *fix 1.2.3a (Eric) Can now have expressions as array sizes
TType make_array(TType t, Expression psz)
{
 int sz=0; // defaults to zero so we know to infer size from initializer...
 if (psz) {
    try { sz = const_int_expr(psz); }
    catch(string msg) { error(msg); return t; }
 }
 AsType(t).make_array(sz);
 if (s_array_size > 1) s_twodim_array = sz;
 else s_array_size = sz;
 return t;
}

void reset_array_size()
{
  s_array_size = 1; //*SJD* Temporary hack!
  s_twodim_array = 1;
}


LocalContext *temp_context()
{ return mpTempContext; }

PClass try_block_class()
{ return mCatchHandlerObj; }

void set_function_code(bool is_fn)
{
 state.m_PCode = is_fn ? &state.m_FContext : &state.m_SContext;
}

UCContext& static_code() { return state.m_SContext; }

bool is_function_code() { return state.m_PCode == &state.m_FContext; }
UCContext& code()       { return *state.m_PCode; }

FBlock *temp_fun_block() { return &mCodeBlock; }


// support code for grammar starts here....

bool is_class(Table *pc)        { return pc->type()==IS_STRUCT; }
bool is_namespace(Table *pc)    { return pc->type()==IS_NAMESPACE;}
bool in_class_context()         { return is_class(&state.context()); }
bool is_local(Table *fc)        { return fc->type()==FUNCTION;}
bool is_class_entry(PEntry pe)
 { return in_class_context() && pe == PClass(&state.context())->entry(); }

bool is_global(Table* pc)       { return pc == &mGlobal; }
bool is_global_entry(PEntry pe) { return is_global(pe->context);}

Function *current_function(Table *context)
{
 if (context==NULL) context = &state.context();
 if (is_local(context)) return PLocalContext(context)->function();
 else return NULL;
}

int a;

PEntry symbol_lookup(const string& name)
{
  Table *context = &state.context() ;
  PEntry pe = context->lookup(name);
  if (!pe) return NULL;
  if (debug.no_access_control) return pe;  
  if (!is_class(pe->context)) {
    return pe; // interactive!!
  }

  // Access control - this entry came from a class....  
  PClass pe_class = (Class *)pe->context;

  // if we are in a function, see if it is a friend!
  Function *function = current_function(context);
  if (function && pe_class->is_friend_function(function)) return pe;

  // What is our current class context?
  PClass this_class;
  if (is_class(context)) this_class = (Class *)context; else
  if (function) this_class = function->class_context();
  else this_class = NULL;
  if (this_class == pe_class) return pe;  // trivial case!

  int access = pe->access(), base_access = pe_class->base_access_mode();
  if (base_access != Public) {
    if (base_access == Private) access = Private; else
    if (base_access == Protected && access == Public) access = Protected;
  }
  if (access==Public) return pe; 

  if (this_class) {
   if (access == Protected && this_class->inherits_from(pe_class)) return pe;
   if (pe_class->is_friend_class(this_class)) return pe;

  //*SJD* Does this entry come from an _enclosing_ class?
  // (can tell this if we do have the right parent but it isn't a base class!)
   if (this_class->parent_context() == pe_class && this_class->base_class()==NULL)
         return pe;

  }
  // sorry, no can do.
  warning("cannot access " + quotes(pe->name));
  return pe; ///NULL;  *Behaviour is different in 'console mode'

}

// *add 0.9.4 support for extern "C".  Returns int because we may need to be explicit.
bool in_extern()
{ return state.extern_flag; }

bool in_extern_C()
{ return state.extern_flag_C; }

// parser state management
void ParserState::reset()
{
  in_match = false;
  was_fun_ptr = false;
  in_declaration = false;
  in_typedef = false;
  in_class = false;
  in_method = false;
  in_switch = false;  
  class_dcl = t_void;
  scope_context = NULL;
  in_loop = false;
  in_construct_destruct = IsPlain;
  extern_flag = false;
  extern_flag_C = false;
  modifier = None;
  err = "";
  arg_list.clear(); 
  // NB to restore any stacks!
  // note this mucks up the state while we are paused...need
  // to think this one through HACK04
  if (!Engine::paused()) {
    context_stack.clear();
    push_context(&global());
  }
//  mCodeBlock.pstart = code().end_code();  // will clear static code buffer 
  if (is_function_code()) {
    code().end_code();          // clear the function code buffer   
    set_function_code(false);   // so we're back in static code 
  }
  block_stack.clear();         // clear any pending blocks
  tstack.clear();             // clear the type stack
  IEF=false;

  s_expr_handler = NULL;

  dcl_init_list.clear();  
}

void ParserState::push_context(Table *tbl) 
{
  context_stack.push(tbl);
}

Table& ParserState::context() 

⌨️ 快捷键说明

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