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

📄 directcall.cpp

📁 CE5.4英文源码,打造自己的CE 与大家分享一下.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
{
  if (data == NULL)
      throw BadPointer("NULL pointer");
  // other checks (dangling, invalid, etc) go here....
}

typedef int (*TWOFN)(int,int);

int _wrap(char *name)
{
 Function *pf = Function::lookup(name);
 if (pf == NULL) return 0;
 TWOFN pfn = (TWOFN)generate_native_stub(pf);
 return (*pfn)(10,20);
}

// *add 1.0.0 These exported functions support the fast specialization map<string,int>
// You can of course use any other associative container for this implementation.

typedef std::map<string,int> MSI;
typedef MSI *PMSI;
typedef MSI::iterator IMSI;
typedef IMSI *PIMSI;

struct StrPair {
     string first;
     int second;
};
typedef StrPair* PSP;

void* _map_create()
{ return new MSI;    }

void  _map_destroy(void *pm)
{ delete PMSI(pm);}

int   _map_size(void *pm)
{ return PMSI(pm)->size(); }

int*  _map_find(const string& key,void *pm) {
   MSI::iterator msi = PMSI(pm)->find(key);
   return msi != PMSI(pm)->end() ? &msi->second : 0;
}

int*  _map_insert(const string& key,int val,void *pm) {  
  int& res = (*PMSI(pm))[key] = val;
  return &res;
}

// *ad 1.2.9 corresponding iterator stuff
void* _map_iter_ep(void* pm, int which)
{
    MSI::iterator it;
    if (which==0) it = PMSI(pm)->begin();
            else  it = PMSI(pm)->end();
    return new IMSI(it);
}

void* _map_iter_find(void* pm, const string& key)
{
    MSI::iterator it = PMSI(pm)->find(key);
    return new IMSI(it);
}

int  _map_iter_equal(void* i1, void* i2)
{
  return *PIMSI(i1) == *PIMSI(i2);
}

void _map_iter_fetch(void* pi, void* dat)
{
  PSP(dat)->first =  (*PIMSI(pi))->first;
  PSP(dat)->second = (*PIMSI(pi))->second;
}

void _map_iter_next(void* pi, int wdir)
{
  ++(*PIMSI(pi));
}

void* _native_stub(FBlock *pfb)
{
//*fix 1.2.3a The function may well be NULL...
   if (pfb == NULL) return NULL;
   if (pfb->function->builtin()) return pfb->native_addr();
   else return generate_native_stub(pfb->function);
}

// *add 1.2.5 range checking: _range_check
int _range_check(int sz, int i)
{
    if (i >= sz || i < 0) {
        char buff[80];
        if (i >= sz) sprintf(buff,"Range Error: %d >= %d",i,sz);
               else  sprintf(buff,"Range Error: %d < 0",i);
#ifdef WIN32	
        throw RangeError(buff);
#else   
        throw_range_error(buff);
#endif
    }
    return i;
}

static int mRangeCheck;

//by dark byte, I can't seem to solve this overload-function to pointer thing
double sin2(double x)
{
	return sin(x);
}

double cos2(double x)
{
	return cos(x);
}

double tan2(double x)
{
	return tan(x);
}

double atan22(double x, double y)
{
	return atan2(x,y);
}

double pow2(double x, double y)
{
	return pow(x,y);
}

double exp2(double x)
{
	return exp(x);
}

double log2(double x)
{
	return log(x);
}

double sqrt2(double x)
{
	return sqrt(x);
}

char* strstr2(char *x, const char *y)
{
	return strstr(x,y);
}

char* strchr2(char *x, int _ch)
{
	return strchr(x,_ch);
}

char* strrchr2(char *x, int _ch)
{
	return strrchr(x,_ch);
}





void init()
{
 Type t_ccp = t_char_ptr;
 Type t_int_ptr = t_int;
 t_ccp.make_const();
 t_int_ptr.incr_pointer();
 Signature *sig = new Signature(t_int);
 sig->push_back(t_int);
 sig->push_back(t_int);
 Type st(sig);
 st.incr_pointer();

 add(Sig(t_void_ptr) << t_void_ptr,"_native_stub",(CALLFN)_native_stub);
 add(Sig(t_void_ptr) << t_int,          "_new",(CALLFN)&_new);
 add(Sig(t_void_ptr) << t_int << t_int, "_new_vect",(CALLFN)&_new_vect);
 add(Sig(t_void) << t_void_ptr << t_int,"_delete",(CALLFN)&_delete);
 add(Sig(t_void_ptr) << t_int,          "_new_ex",(CALLFN)&_new_ex);
 add(Sig(t_void_ptr) << t_int << t_int, "_new_vect_ex",(CALLFN)&_new_vect_ex);
 add(Sig(t_void) << t_void_ptr << t_int,"_delete_ex",(CALLFN)&_delete_ex);




 add(Sig(t_double) << t_double,"sin",(CALLFN)&sin2);
 add(Sig(t_double) << t_double,"cos",(CALLFN)&cos2);
 add(Sig(t_double) << t_double,"tan",(CALLFN)&tan2);
 add(Sig(t_double) << t_double << t_double,"atan2",(CALLFN)&atan22);
 add(Sig(t_double) << t_double << t_double,"pow",(CALLFN)&pow2);
 add(Sig(t_double) << t_double,"exp",(CALLFN)&exp2);
 add(Sig(t_double) << t_double,"log",(CALLFN)&log2);
 add(Sig(t_double) << t_double,"sqrt",(CALLFN)&sqrt2);
 add(Sig(t_double) << t_ccp,"atof",(CALLFN)&atof);
 add(Sig(t_long) << t_ccp,"atoi",(CALLFN)&atoi);
 add(Sig(t_char_ptr) << t_int << t_char_ptr << t_int, "itoa", (CALLFN)&_itoa);
 add(Sig(t_long),"rand",(CALLFN)&rand);

 add(Sig(t_char_ptr) << t_char_ptr << t_ccp,"strcpy",(CALLFN)&strcpy);
 add(Sig(t_char_ptr) << t_char_ptr << t_ccp << t_int,"strncpy",(CALLFN)&strncpy);
 add(Sig(t_char_ptr) << t_char_ptr << t_ccp,"strcat",(CALLFN)&strcat);
 add(Sig(t_int) << t_ccp << t_ccp,"strcmp",(CALLFN)&strcmp);
 add(Sig(t_char_ptr) << t_ccp,"strdup",(CALLFN)&_strdup);
 add(Sig(t_char_ptr) << t_char_ptr << t_ccp,"strtok",(CALLFN)&strtok);
 add(Sig(t_char_ptr) << t_char_ptr << t_char_ptr,"strstr",(CALLFN)&strstr2);
 add(Sig(t_char_ptr) << t_char_ptr << t_int,"strchr",(CALLFN)&strchr2);
 add(Sig(t_char_ptr) << t_char_ptr << t_int,"strrchr",(CALLFN)&strrchr2);
 add(Sig(t_int) << t_ccp,"strlen",(CALLFN)&strlen);
 add(Sig(t_void_ptr) << t_void_ptr << t_void_ptr << t_int,
      "memmove",(CALLFN)&memmove);

 add(Sig(t_void_ptr) << t_void_ptr << t_int, "_str_cpy", (CALLFN)&str_cpy);
 add(Sig(t_int) << t_int, "_str_eof", (CALLFN)&str_eof);

 // stdio builtins (first entry used to get stdin, etc)
 add(Sig(t_void_ptr) << t_int,"_get_std_stream",(CALLFN)&_get_std_stream);
 add(Sig(t_int) << t_ccp,"puts",(CALLFN)&puts);
 add(Sig(t_int) << t_ccp,"printf",(CALLFN)&printf,true);
 add(Sig(t_int) << t_ccp << t_ccp,"sprintf",(CALLFN)&sprintf,true);
 // *change 1.2.3 GCC has finally persuaded me not to export puts().
 // add(Sig(t_char_ptr) << t_char_ptr,"gets",(CALLFN)&gets);
 add(Sig(t_char_ptr) << t_char_ptr << t_int << t_void_ptr,"fgets",(CALLFN)&fgets);
 add(Sig(t_int) << t_void_ptr << t_ccp,"fprintf",(CALLFN)&fprintf,true);
 add(Sig(t_int) << t_void_ptr << t_ccp,"fscanf",(CALLFN)&fscanf,true);
 add(Sig(t_int) << t_int << t_void_ptr, "ungetc",(CALLFN)&ungetc,true);

 add(Sig(t_int) << t_void_ptr << t_ccp,"wcon_fscanf",(CALLFN)&wcon_fscanf,true);

 add(Sig(t_int) << t_void_ptr << t_int << t_int << t_void_ptr,"fread",(CALLFN)&fread);
 add(Sig(t_int) << t_void_ptr << t_int << t_int << t_void_ptr,"fwrite",(CALLFN)&fwrite);
 add(Sig(t_int) << t_void_ptr,"feof",(CALLFN)&feof);
 add(Sig(t_void_ptr) << t_char_ptr << t_char_ptr,"fopen",(CALLFN)&fopen);
 add(Sig(t_int) << t_void_ptr, "fclose",(CALLFN)&fclose);
 add(Sig(t_int) << t_void_ptr, "fflush",(CALLFN)&fflush);
 add(Sig(t_int) << t_char_ptr << t_char_ptr, "rename", (CALLFN)&rename);
 add(Sig(t_int) << t_void_ptr, "fgetc", (CALLFN)&fgetc);
 add(Sig(t_int) << t_int << t_void_ptr, "fputc", (CALLFN)&fputc);
 add(Sig(t_int) << t_void_ptr << t_long << t_int, "fseek", (CALLFN)&fseek);
 add(Sig(t_long) << t_void_ptr, "ftell", (CALLFN)&ftell);

 add(Sig(t_void) << t_ccp,"uc_cmd",(CALLFN)&uc_hash_cmd);
 add(Sig(t_void) << t_ccp << t_char_ptr << t_int,"uc_macro_subst",(CALLFN)&uc_macro_subst);
 add(Sig(t_int) << t_void_ptr, "_dissem",(CALLFN)&_dissem);
 //add(Sig(t_void), "_init_lib",(CALLFN)&Parser::init_lib);
 // *add 1.2.5 range checking: _range_check
 add(Sig(t_int) << t_int << t_int,"_range_check",(CALLFN)&_range_check);

 // *add 1.2.4 uc_exec(), uc_result()
 add(Sig(t_int) << t_ccp,"uc_exec",(CALLFN)&_uc_exec_1);
 add(Sig(t_int) << t_ccp << t_void_ptr << t_ccp << t_int,"uc_exec",(CALLFN)&_uc_exec);
 add(Sig(t_void) << t_int << t_char_ptr << t_int << t_char_ptr << t_void_ptr,"uc_result_pos",(CALLFN)&_uc_result);
 add(Sig(t_void_ptr) << t_char_ptr,"copy_body",(CALLFN)&_copy_body);

 // *add 1.2.6 uc_include_path() will find a system file using the UC include paths.
 add(Sig(t_int) << t_ccp << t_char_ptr << t_int,"uc_include_path",(CALLFN)&_uc_include_path);

// These support the specialization map<string,int> (see <map> in the pocket library)
 add(Sig(t_void_ptr),                                     "_map_create",  (CALLFN)&_map_create);
 add(Sig(t_void)    << t_void_ptr,                        "_map_destroy", (CALLFN)&_map_destroy);
 add(Sig(t_int)     << t_void_ptr,                        "_map_size",    (CALLFN)&_map_size);
 add(Sig(t_int_ptr) << t_void_ptr << t_void_ptr,          "_map_find",    (CALLFN)&_map_find);
 add(Sig(t_int_ptr) << t_void_ptr << t_int << t_void_ptr, "_map_insert",  (CALLFN)&_map_insert);
 // *add 1.2.9 iterator support for the fast specialization
 add(Sig(t_void_ptr) << t_void_ptr << t_int,              "_map_iter_ep", (CALLFN)&_map_iter_ep);
 add(Sig(t_void_ptr) << t_void_ptr << t_void_ptr,         "_map_iter_find",(CALLFN)&_map_iter_find);
 add(Sig(t_int)      << t_void_ptr << t_void_ptr,         "_map_iter_equal",(CALLFN)&_map_iter_equal);
 add(Sig(t_void)     << t_void_ptr << t_void_ptr,         "_map_iter_fetch",(CALLFN)&_map_iter_fetch);
 add(Sig(t_void)     << t_void_ptr << t_int,              "_map_iter_next", (CALLFN)&_map_iter_next);
 
 add(Sig(t_void) << t_int,"__break",(CALLFN)__break);
 add(Sig(t_void),"__mangle",(CALLFN)__mangle);
 
 // UCW Graphics
 #ifdef _WCON
 //unsigned long ucw_rgb(int r, int g, int b);
 //void ucw_set_colour(UCWin win, unsigned long clr, bool fg);

 add(Sig(t_int) << t_char_ptr << t_int << t_int << t_int << t_int,
         "ucw_create_window",(CALLFN)&ucw_create_window);
 add(Sig(t_int) << t_int << t_char_ptr,"ucw_title",(CALLFN)&ucw_title);
 add(Sig(t_int) << t_int << t_char_ptr,"ucw_cmd",(CALLFN)&ucw_cmd);
 add(Sig(t_int) << t_int << t_int << t_int << t_int << t_int,"ucw_size_window",(CALLFN)&ucw_size_window);         
 add(Sig(t_int) << t_int << t_int << t_int,"ucw_move_to",(CALLFN)&ucw_move_to);
 add(Sig(t_int) << t_int << t_int << t_int,"ucw_line_to",(CALLFN)&ucw_line_to);
 add(Sig(t_int) << t_int << t_char_ptr,"ucw_text_out",(CALLFN)&ucw_text_out);
 add(Sig(t_int) << t_int << t_char_ptr << t_int,"ucw_font",(CALLFN)&ucw_font);
 add(Sig(t_int) << t_int << t_float << t_float << t_float,"ucw_fcolour",(CALLFN)&ucw_fcolour);
 add(Sig(t_int) << t_int << t_float << t_float << t_float,"ucw_bcolour",(CALLFN)&ucw_bcolour);
 add(Sig(t_int) << t_int << t_int << t_int << t_int << t_int,"ucw_rectangle",(CALLFN)&ucw_rectangle);         
 add(Sig(t_int) << t_int << t_int << t_int << t_int << t_int,"ucw_ellipse",(CALLFN)&ucw_ellipse);         
 add(Sig(t_int) << t_char_ptr << t_int << t_bool,"exec",(CALLFN)&exec);
 add(Sig(t_long) << t_int << t_int << t_int,"ucw_rgb",(CALLFN)&ucw_rgb);
 add(Sig(t_void) << t_int << t_long << t_int,"ucw_set_colour",(CALLFN)&ucw_set_colour);
#endif

 Function* pf = Function::lookup("_range_check");
 mRangeCheck = NFBlock::create(pf,(CALLFN)pf->fun_block()->native_addr());
}

//---------------------- adding builtin functions ---------------------------
// We keep a map of imported functions to quickly tell what they are imported as!
typedef std::map<CALLFN,FBlock *> ClassImportMap;
ClassImportMap mImportMap;

// *hack 1.2.0 The optimized Win32 MS build blows up here occaisionally - no idea why!
#pragma optimize( "", off )
static FBlock *_pfb;
static Function *_pfn;
static int _kount = 0;
void insert_ptr_map(CALLFN fn, Function *pfn)
{
  try {
  _pfn = pfn;
  _pfb = pfn->fun_block();
  mImportMap[fn] = _pfb; 
  } catch(...) {
     ++_kount;
  }
}
#pragma optimize( "", on ) 

void add(const Sig& sig,char *name, CALLFN fn, bool is_stdarg, int ftype)
// Builtin::add() assumes that the Signature has been collected in the proper way.
// It's usually called from state.declare_function(), but also from add_dll_function().
// In both cases the class Sig acts as a interface to the common signature stuff.
{
 Function *pfn = state.start_function(sig.m_type,name,true,ftype);
 FunctionContext *fe = pfn->context();
 int nargs = pfn->fun_block()->nargs;
 if (is_stdarg) pfn->stdarg(true);
 
 Parser::code().emit_native_function_call(pfn,fn);
 

#ifdef __GNUC__ 
 mImportMap[fn] = pfn->fun_block();
#else
 insert_ptr_map(fn,pfn);
#endif

 fe->finalize();
 state.pop_context(); // usually done by block-end!
}

// *add 1.2.5 Offset of range checking function
int range_check_function()
{
  return mRangeCheck;
}

FBlock *import_vmethod(CALLFN fn, PFBlock pfb)
// this is passed a native routine, and a UC function block which acts as a prototype
// for the _anonymous method import_
{
  Parser::set_function_code(true);  // enter function code context
  UCContext& code = Parser::code();
  Function *pf = pfb->function;
  FBlock *fb;
  try {
	fb = FBlock::create(pfb->entry,NULL);
	mImportMap[fn] = fb;
    code.emit_native_function_call(pf,fn);
    code.emit_return(pf->return_type());
    
	fb->finalize(0);
  } catch(...) { error("error when importing function"); }  
  Parser::set_function_code(false); // go back to static code context 
  return fb;
}

⌨️ 快捷键说明

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