📄 ucri.cpp
字号:
/* UnderC Reflection Interface (UCRI)
* UnderC C++ interpreter
* Steve Donovan, 2001,2002
* This is GPL'd software, and the usual disclaimers apply.
* See LICENCE
*
*
*
*/
#include <stdarg.h>
#include <stddef.h>
#include <stdio.h>
#include "module.h"
#include "directcall.h"
#include "program.h"
#include "imports.h"
#include <map>
#include "ucri.h"
// found in directcall.cpp
void *_new_ex(int sz);
void _delete_ex(char *ptr, int sz);
// found in main.cpp
int uc_eval(char *expr, bool append_semicolon=true, bool synchronous=false, char *name=NULL, int lineno=0);
bool do_str_to_val(Type t,char *buff,void *ptr); // at end of this module
// found in code.cpp
bool is_double_number(const Type& t);
// found in engine.cpp
void engine_set_tracing(bool yesno);
unsigned long* set_instruction_counter(bool do_profiling);
PClass get_class_object(void* p);
PPClass& get_object_VMT(void* p);
const char *TEMP_VAR = "__T0_tmp_";
static XNTable *mUC_std = 0, *mUC_glob = 0;
static ImportScheme *mUC_import_scheme;
template <class T1, class T2>
class Wrapper {
std::map<T2*,T1*> m_map;
public:
T1* operator()(T2* p)
{
if (p==NULL) return NULL; // NULL maps onto NULL...
T1* pw = m_map[p];
if (! pw) {
pw = new T1(p);
m_map[p] = pw;
}
return pw;
}
};
static Wrapper<XFunction,Function> mXFunctionWrap;
static Wrapper<XType,Type> mXTypeWrap;
static Wrapper<XClass,Class> mXClassWrap;
static Wrapper<XEntry,Entry> mXEntryWrap;
XEntry* wrap_XEntry(Entry* pe)
{
return mXEntryWrap(pe);
}
XFunction* wrap_XFunction(Function *fun)
{
return mXFunctionWrap(fun);
}
XType* wrap_XType(Type *t)
{
return mXTypeWrap(t);
}
XClass* wrap_XClass(Class *pc)
{
return mXClassWrap(pc);
}
XType::XType(Type* t)
{
m_type = t;
}
// Typically most compilers implement 'bool' as
// single unsigned byte, whereas in UC bools are
// 32-bit integers. In MS at least, functions returning
// byte values are not guaranteed to clear out the
// rest of the EAX register!
bool bool4(unsigned long ul)
{ return (bool) ul; }
bool XType::is_const() const
{
return bool4(m_type->is_const());
}
bool XType::is_reference() const
{
return bool4(m_type->is_reference());
}
bool XType::is_pointer() const
{
return bool4(m_type->is_pointer());
}
bool XType::is_array() const
{
return bool4(m_type->is_array());
}
bool XType::is_unsigned() const
{
return bool4(m_type->is_unsigned());
}
bool XType::is_number() const
{
return bool4(m_type->is_number());
}
bool XType::is_int() const
{
return bool4(m_type->is_int());
}
bool XType::is_float() const
{
return bool4(m_type->is_float());
}
bool XType::is_single() const
{
return bool4(m_type->is_single());
}
bool XType::is_long() const
{
return bool4(m_type->is_long());
}
bool XType::is_short() const
{
return bool4(m_type->is_short());
}
bool XType::is_char() const
{
return bool4(m_type->is_char());
}
bool XType::is_double() const
{
return bool4(m_type->is_double());
}
bool XType::is_signature() const
{
return bool4(m_type->is_signature());
}
bool XType::is_function() const
{
return bool4(m_type->is_function());
}
bool XType::is_class() const
{
return bool4(m_type->is_class());
}
bool XType::is_object() const
{
return bool4(m_type->is_object());
}
bool XType::is_bool() const
{
return bool4(m_type->is_bool());
}
bool XType::is_void() const
{
return bool4(m_type->is_void());
}
bool XType::is_namespace() const
{
return bool4(m_type->is_namespace());
}
int XType::pointer_depth() const
{
return m_type->pointer_depth();
}
int XType::size() const
{
return m_type->size();
}
XClass* XType::as_class() const
{
return wrap_XClass(m_type->as_class());
}
char* XType::as_str() const
{
static string s;
m_type->as_string(s);
return s.c_str();
}
void XType::val_as_str(string& s, void *ptr) const
{
s = m_type->value_as_string(ptr,false);
}
void XType::str_to_val(char *buff, void *ptr)
{
do_str_to_val(*m_type,buff,ptr);
}
Type* XType::type()
{ return m_type; }
XType* XType::from_str(char *str)
{
char buff[200];
sprintf(buff,"%s %s;",str,TEMP_VAR);
uc_eval(buff,false,true);
XEntry *xe = mUC_glob->lookup((char *)TEMP_VAR);
return xe->type();
}
XTList& XType::typelist(XType* t1,...)
{
// copy type parms into a type list...
va_list args;
va_start(args,t1);
static XTList tl;
tl.clear();
tl.push_back(t1);
XType *xt;
while (xt = va_arg(args,XType*))
tl.push_back(xt);
va_end(args);
return tl;
}
XEntry::XEntry(PEntry pe)
: m_entry(pe) { }
XEntry *XEntry::clone()
{
PEntry pe = new Entry;
*pe = *m_entry;
return wrap_XEntry(pe);
}
XEntry *XEntry::base_entry()
{
// generate a copy of an array entry
// appropriate for accessing its elements
XEntry* xe = clone();
Type t = *type()->type();
t.strip_array();
t.decr_pointer();
xe->m_entry->type = t;
return xe;
}
char* XEntry::name()
{ return m_entry->name.c_str(); }
int XEntry::data()
{ return m_entry->data; }
void* XEntry::ptr(void *base)
{
if (base == NULL) return Parser::global().addr(m_entry->data);
else return (char *)base + m_entry->data;
}
void XEntry::set_data(int x)
{
m_entry->data = x;
}
void XEntry::set_ptr(void *p, void *base)
{
if (base == NULL)
m_entry->data = Parser::global().offset(p);
else
m_entry->data = (char *)p - (char *)base;
}
int XEntry::size()
{
return m_entry->size;
}
XType* XEntry::type()
{
return wrap_XType(&m_entry->type);
}
void *XEntry::entry()
{ return m_entry; }
void XEntry::val_as_str(string& s, void *base)
{
type()->val_as_str(s,ptr(base));
}
void XEntry::str_to_val(char *buff, void *base)
{
type()->str_to_val(buff,ptr(base));
}
int XEntry::nfun()
{
Type t = m_entry->type;
if (! t.is_function()) return 0;
return reinterpret_cast<FunctionEntry *>(m_entry->data)->size();
}
XFunction *XEntry::function(int idx)
{
Function *pf = reinterpret_cast<FunctionEntry *>(m_entry->data)
->nth_fun(idx);
return wrap_XFunction(pf);
}
int XEntry::addr_mode()
{ return (int)m_entry->rmode; }
XNTable::XNTable(NamedTable *tbl)
: m_table(tbl) { }
XEntry* XNTable::lookup(char *name,bool in_parent)
{
PEntry pe = m_table->lookup(name,in_parent);
if (!pe) return NULL; // not found!
return wrap_XEntry(pe);
}
XClass* XNTable::lookup_class(char *name, bool in_parent)
{
PEntry pe = m_table->lookup(name,in_parent);
if (!pe) return NULL; // not found!
if (pe->is_class()) return wrap_XClass(pe->type.as_class());
else return NULL;
}
XTemplateFun* XNTable::lookup_template(char *name, bool in_p)
{
PEntry pe = m_table->lookup(name,in_p);
if (!pe) return NULL; // not found!
if (pe->type.is_signature()) {
FunctionEntry *pfe = (FunctionEntry *)pe->data;
if (pfe->get_template())
return new XTemplateFun(pfe->get_template());
else return NULL; // just a normal function
} else return NULL; // not a function at all
}
char* XNTable::name()
{
return m_table->entry()->name.c_str();
}
//* add 1.2.4 Given a pointer allocated by a table, find its offset
// (useful for globally allocated stuff like fblocks, etc)
int XNTable::offset(void* p)
{
return m_table->offset(p);
}
NamedTable* XNTable::table()
{
return m_table;
}
// this creates an entry with a given name and (opt)
// type. Just as with variables added with Parser::add_variable(),
// we allocate some direct data space as well.
XEntry* XNTable::create(char *nm, XType *xt)
{
PEntry pe = m_table->new_entry(nm);
if (xt) pe->type = *xt->type();
pe->data = Parser::global().alloc(pe->type.size(),NULL);
return wrap_XEntry(pe);
}
// issue: who deallocates these lists of ptrs?
void XNTable::get_functions(XFunctions& flist, int flags, char *pattern)
{
EntryList ls;
EntryList::iterator eli;
flags |= FUNCTIONS;
if (pattern == NULL) m_table->list_entries(ls,flags);
else m_table->search_entries(pattern,&ls,flags);
flist.clear();
for(eli = ls.begin(); eli != ls.end(); ++eli) {
FunctionEntry *pfe = reinterpret_cast<FunctionEntry *>((*eli)->data);
FunctionEntry::iterator fei;
for(fei = pfe->begin(); fei != pfe->end(); ++fei)
flist.push_back(wrap_XFunction((Function *)*fei));
}
}
void XNTable::get_variables(XEntries& vlist, int flags, char *pattern)
{
EntryList ls;
EntryList::iterator eli;
if (pattern == NULL) m_table->list_entries(ls,flags);
else m_table->search_entries(pattern,&ls,flags);
vlist.clear();
for(eli = ls.begin(); eli != ls.end(); ++eli)
vlist.push_back(wrap_XEntry(*eli));
}
XFunctions& XNTable::functions(int flags)
{
static XFunctions flist;
get_functions(flist,flags,NULL);
return flist;
}
XEntries& XNTable::variables(int flags)
{
static XEntries vlist;
get_variables(vlist,flags,NULL);
return vlist;
}
void XNTable::dispose_of_entries(XEntries& vars)
{
vars.clear();
}
XClass::XClass(NamedTable *tbl)
: XNTable(tbl)
{}
Class *XClass::class_obj()
{
return static_cast<Class *>(m_table);
}
XClass *XClass::base_class()
{
Class *bc = class_obj()->base_class();
if (bc) return wrap_XClass(bc);
else return NULL;
}
bool XClass::has_VMT()
{
return class_obj()->has_VMT();
}
void * XClass::create()
{
// Allocate properly (this overallocates!)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -