updated all api to use new function id system

fixed a codegen bug in function ids
removed extra native status, simplified native binding

--HG--
extra : convert_revision : svn%3A39bc706e-5318-0410-9160-8a85361fbb7c/trunk%40169
This commit is contained in:
David Anderson 2006-11-08 08:41:18 +00:00
parent 2892ee1fa9
commit e060af14b4
7 changed files with 77 additions and 56 deletions

View File

@ -48,17 +48,24 @@ IPluginDebugInfo *BaseContext::GetDebugInfo()
return this; return this;
} }
int BaseContext::Execute(uint32_t public_func, cell_t *result) int BaseContext::Execute(funcid_t funcid, cell_t *result)
{ {
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase; IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
uint32_t pushcount = ctx->pushcount; uint32_t pushcount = ctx->pushcount;
uint32_t code_addr;
int err; int err;
sp_public_t *pubfunc;
if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERROR_NONE) if (funcid & 1)
{ {
return err; sp_public_t *pubfunc;
if ((err=GetPublicByIndex((funcid>>1), &pubfunc)) != SP_ERROR_NONE)
{
return err;
}
code_addr = pubfunc->code_offs;
} else {
code_addr = funcid >> 1;
} }
PushCell(pushcount++); PushCell(pushcount++);
@ -67,7 +74,7 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
cell_t save_sp = ctx->sp; cell_t save_sp = ctx->sp;
cell_t save_hp = ctx->hp; cell_t save_hp = ctx->hp;
err = vm->ContextExecute(ctx, pubfunc->offs, result); err = vm->ContextExecute(ctx, code_addr, result);
/** /**
* :TODO: turn this into an error check * :TODO: turn this into an error check
@ -338,7 +345,7 @@ int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int ove
for (i=0; i<max; i++) for (i=0; i<max; i++)
{ {
if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite) if ((ctx->natives[i].status == SP_NATIVE_BOUND) && !overwrite)
{ {
continue; continue;
} }
@ -348,7 +355,7 @@ int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int ove
if (!strcmp(ctx->natives[i].name, natives[j].name)) if (!strcmp(ctx->natives[i].name, natives[j].name))
{ {
ctx->natives[i].pfn = natives[j].func; ctx->natives[i].pfn = natives[j].func;
ctx->natives[i].status = SP_NATIVE_OKAY; ctx->natives[i].status = SP_NATIVE_BOUND;
} }
} }
} }
@ -356,7 +363,7 @@ int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int ove
return SP_ERROR_NONE; return SP_ERROR_NONE;
} }
int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status) int BaseContext::BindNative(sp_nativeinfo_t *native)
{ {
uint32_t index; uint32_t index;
int err; int err;
@ -367,7 +374,6 @@ int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status)
} }
ctx->natives[index].pfn = native->func; ctx->natives[index].pfn = native->func;
ctx->natives[index].status = status;
return SP_ERROR_NONE; return SP_ERROR_NONE;
} }
@ -380,10 +386,9 @@ int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
for (i=0; i<nativesnum; i++) for (i=0; i<nativesnum; i++)
{ {
if (ctx->natives[i].status != SP_NATIVE_OKAY) if (ctx->natives[i].status == SP_NATIVE_UNBOUND)
{ {
ctx->natives[i].pfn = native; ctx->natives[i].pfn = native;
ctx->natives[i].status = SP_NATIVE_PENDING;
} }
} }

View File

@ -38,9 +38,9 @@ namespace SourcePawn
virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string); virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string);
virtual int PushCellsFromArray(cell_t array[], unsigned int numcells); virtual int PushCellsFromArray(cell_t array[], unsigned int numcells);
virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite); virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite);
virtual int BindNative(sp_nativeinfo_t *native, uint32_t status); virtual int BindNative(sp_nativeinfo_t *native);
virtual int BindNativeToAny(SPVM_NATIVE_FUNC native); virtual int BindNativeToAny(SPVM_NATIVE_FUNC native);
virtual int Execute(uint32_t public_func, cell_t *result); virtual int Execute(funcid_t funcid, cell_t *result);
public: //IPluginDebugInfo public: //IPluginDebugInfo
virtual int LookupFile(ucell_t addr, const char **filename); virtual int LookupFile(ucell_t addr, const char **filename);
virtual int LookupFunction(ucell_t addr, const char **name); virtual int LookupFunction(ucell_t addr, const char **name);

View File

@ -1965,10 +1965,10 @@ restart:
lval1->ident=iCONSTEXPR; lval1->ident=iCONSTEXPR;
/* Generate a quick pseudo-tag! */ /* Generate a quick pseudo-tag! */
if (usage == uPUBLIC) { if (usage == uPUBLIC) {
lval1->constval=(n>>1)|(1<<1); lval1->constval=(n<<1)|1;
snprintf(faketag, sizeof(faketag)-1, "$Func@%d", n); snprintf(faketag, sizeof(faketag)-1, "$Func@%d", n);
} else { } else {
lval1->constval=(code_addr>>1)|(1<<0); lval1->constval=(code_addr<<1)|0;
snprintf(faketag, sizeof(faketag)-1, "$Func!%d", code_addr); snprintf(faketag, sizeof(faketag)-1, "$Func!%d", code_addr);
} }
lval1->tag=pc_addfunctag(faketag); lval1->tag=pc_addfunctag(faketag);

View File

@ -8,6 +8,9 @@ namespace SourcePawn
{ {
class IVirtualMachine; class IVirtualMachine;
/**
* @brief Interface to managing a debug context at runtime.
*/
class IPluginDebugInfo class IPluginDebugInfo
{ {
public: public:
@ -36,6 +39,9 @@ namespace SourcePawn
virtual int LookupLine(ucell_t addr, uint32_t *line) =0; virtual int LookupLine(ucell_t addr, uint32_t *line) =0;
}; };
/**
* @brief Interface to managing a context at runtime.
*/
class IPluginContext class IPluginContext
{ {
public: public:
@ -260,7 +266,6 @@ namespace SourcePawn
/** /**
* Binds a list of native names and their function pointers to a context. * Binds a list of native names and their function pointers to a context.
* If num is 0, the list is read until an entry with a NULL name is reached. * If num is 0, the list is read until an entry with a NULL name is reached.
* All natives are assigned a status of SP_NATIVE_OKAY by default.
* If overwrite is non-zero, already registered natives will be overwritten. * If overwrite is non-zero, already registered natives will be overwritten.
* *
* @param natives Array of natives. * @param natives Array of natives.
@ -272,29 +277,31 @@ namespace SourcePawn
/** /**
* Binds a single native. Overwrites any existing bind. * Binds a single native. Overwrites any existing bind.
* If the context does not contain the native that will be binded the function will return * If the context does not contain the native that will be binded the function will return
* with a SP_ERROR_OT_FOUND error. * with a SP_ERROR_NOT_FOUND error.
* *
* @param native Pointer to native. * @param native Pointer to native.
* @param status Status value to set (should be SP_NATIVE_OKAY).
*/ */
virtual int BindNative(sp_nativeinfo_t *native, uint32_t status) =0; virtual int BindNative(sp_nativeinfo_t *native) =0;
/** /**
* Binds a single native to any non-registered or pending native. * Binds a single native to any non-registered native.
* Status is automatically set to pending.
* *
* @param native Native to bind. * @param native Native to bind.
*/ */
virtual int BindNativeToAny(SPVM_NATIVE_FUNC native) =0; virtual int BindNativeToAny(SPVM_NATIVE_FUNC native) =0;
/** /**
* Executes a public function. * Executes a function ID located in this context.
*
* @param funcid Function id to execute.
* @param result Pointer to store the return value (required).
* @return Error code (if any) from the VM.
*/ */
virtual int Execute(uint32_t public_func, cell_t *result) =0; virtual int Execute(uint32_t funcid, cell_t *result) =0;
}; };
/** /**
* Contains helper functions used by VMs and the host app * @brief Contains helper functions used by VMs and the host app
*/ */
class ISourcePawnEngine class ISourcePawnEngine
{ {
@ -379,6 +386,9 @@ namespace SourcePawn
virtual ~ICompilation() { }; virtual ~ICompilation() { };
}; };
/**
* @brief Outlines the interface a Virtual Machine (JIT) must expose
*/
class IVirtualMachine class IVirtualMachine
{ {
public: public:

View File

@ -5,6 +5,7 @@
typedef uint32_t ucell_t; typedef uint32_t ucell_t;
typedef int32_t cell_t; typedef int32_t cell_t;
typedef uint32_t funcid_t;
/** /**
* Error codes * Error codes
@ -17,20 +18,20 @@ typedef int32_t cell_t;
#define SP_ERROR_INVALID_ADDRESS 5 /* A memory address was not valid */ #define SP_ERROR_INVALID_ADDRESS 5 /* A memory address was not valid */
#define SP_ERROR_NOT_FOUND 6 /* The object in question was not found */ #define SP_ERROR_NOT_FOUND 6 /* The object in question was not found */
#define SP_ERROR_INDEX 7 /* Invalid index parameter */ #define SP_ERROR_INDEX 7 /* Invalid index parameter */
#define SP_ERROR_NATIVE_PENDING 8 /* A script tried to exec an unbound native */ #define SP_ERROR_STACKLOW 8 /* Nnot enough space left on the stack */
#define SP_ERROR_STACKLOW 9 /* Nnot enough space left on the stack */ #define SP_ERROR_NOTDEBUGGING 9 /* Debug mode was not on or debug section not found */
#define SP_ERROR_NOTDEBUGGING 10 /* Debug mode was not on or debug section not found */ #define SP_ERROR_INVALID_INSTRUCTION 10 /* Invalid instruction was encountered */
#define SP_ERROR_INVALID_INSTRUCTION 11 /* Invalid instruction was encountered */ #define SP_ERROR_MEMACCESS 11 /* Invalid memory access */
#define SP_ERROR_MEMACCESS 12 /* Invalid memory access */ #define SP_ERROR_STACKMIN 12 /* Stack went beyond its minimum value */
#define SP_ERROR_STACKMIN 13 /* Stack went beyond its minimum value */ #define SP_ERROR_HEAPMIN 13 /* Heap went beyond its minimum value */
#define SP_ERROR_HEAPMIN 14 /* Heap went beyond its minimum value */ #define SP_ERROR_DIVIDE_BY_ZERO 14 /* Division by zero */
#define SP_ERROR_DIVIDE_BY_ZERO 15 /* Division by zero */ #define SP_ERROR_ARRAY_BOUNDS 15 /* Array index is out of bounds */
#define SP_ERROR_ARRAY_BOUNDS 16 /* Array index is out of bounds */ #define SP_ERROR_INSTRUCTION_PARAM 16 /* Instruction had an invalid parameter */
#define SP_ERROR_INSTRUCTION_PARAM 17 /* Instruction had an invalid parameter */ #define SP_ERROR_STACKLEAK 17 /* A native leaked an item on the stack */
#define SP_ERROR_STACKLEAK 18 /* A native leaked an item on the stack */ #define SP_ERROR_HEAPLEAK 18 /* A native leaked an item on the heap */
#define SP_ERROR_HEAPLEAK 19 /* A native leaked an item on the heap */ #define SP_ERROR_ARRAY_TOO_BIG 19 /* A dynamic array is too big */
#define SP_ERROR_ARRAY_TOO_BIG 20 /* A dynamic array is too big */ #define SP_ERROR_TRACKER_BOUNDS 20 /* Tracker stack is out of bounds */
#define SP_ERROR_TRACKER_BOUNDS 21 /* Tracker stack is out of bounds */ #define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
/********************************************** /**********************************************
*** The following structures are reference structures. *** The following structures are reference structures.
@ -117,7 +118,8 @@ typedef cell_t (*SPVM_NATIVE_FUNC)(struct sp_context_s *, cell_t *);
*/ */
typedef struct sp_public_s typedef struct sp_public_s
{ {
uint32_t offs; /* code offset */ funcid_t funcid; /* encoded function id */
uint32_t code_offs; /* code offset */
const char *name; /* name */ const char *name; /* name */
} sp_public_t; } sp_public_t;
@ -132,9 +134,8 @@ typedef struct sp_pubvar_s
const char *name; /* name */ const char *name; /* name */
} sp_pubvar_t; } sp_pubvar_t;
#define SP_NATIVE_NONE (0) /* Native is not yet found */ #define SP_NATIVE_UNBOUND (0) /* Native is undefined */
#define SP_NATIVE_OKAY (1) /* Native has been added */ #define SP_NATIVE_BOUND (1) /* Native is bound */
#define SP_NATIVE_PENDING (2) /* Native is marked as usable but replaceable */
/** /**
* Native lookup table, by default names * Native lookup table, by default names

View File

@ -1747,15 +1747,22 @@ cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
sp_native_t *native = &ctx->natives[native_idx]; sp_native_t *native = &ctx->natives[native_idx];
/* Technically both aren't needed, I guess */ /* Technically both aren't needed, I guess */
if (native->status == SP_NATIVE_NONE) if (native->status == SP_NATIVE_UNBOUND)
{ {
ctx->err = SP_ERROR_NATIVE_PENDING; ctx->err = SP_ERROR_INVALID_NATIVE;
return 0; return 0;
} }
return native->pfn(ctx, params); return native->pfn(ctx, params);
} }
cell_t InvalidNative(sp_context_t *ctx, cell_t *params)
{
ctx->err = SP_ERROR_INVALID_NATIVE;
return 0;
}
cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params) cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
{ {
cell_t save_sp = ctx->sp; cell_t save_sp = ctx->sp;
@ -2002,7 +2009,9 @@ jit_rewind:
for (iter=0; iter<max; iter++) for (iter=0; iter<max; iter++)
{ {
ctx->publics[iter].name = strbase + plugin->info.publics[iter].name; ctx->publics[iter].name = strbase + plugin->info.publics[iter].name;
ctx->publics[iter].offs = RelocLookup(jit, plugin->info.publics[iter].address, false); ctx->publics[iter].code_offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
/* Encode the ID as a straight code offset */
ctx->publics[iter].funcid = (ctx->publics[iter].code_offs << 1);
} }
} }
@ -2025,8 +2034,8 @@ jit_rewind:
for (iter=0; iter<max; iter++) for (iter=0; iter<max; iter++)
{ {
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name; ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
ctx->natives[iter].pfn = NULL; ctx->natives[iter].pfn = &InvalidNative;
ctx->natives[iter].status = SP_NATIVE_NONE; ctx->natives[iter].status = SP_NATIVE_UNBOUND;
} }
} }

View File

@ -247,23 +247,19 @@
> >
</File> </File>
<File <File
RelativePath="..\..\..\..\include\sp_file_headers.h" RelativePath="..\..\..\include\sp_file_headers.h"
> >
</File> </File>
<File <File
RelativePath="..\..\..\..\include\sp_vm_api.h" RelativePath="..\..\..\include\sp_vm_api.h"
> >
</File> </File>
<File <File
RelativePath="..\..\..\..\include\sp_vm_base.h" RelativePath="..\..\..\include\sp_vm_base.h"
> >
</File> </File>
<File <File
RelativePath="..\..\..\..\include\sp_vm_context.h" RelativePath="..\..\..\include\sp_vm_types.h"
>
</File>
<File
RelativePath="..\..\..\..\include\sp_vm_types.h"
> >
</File> </File>
</Filter> </Filter>