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;
}
int BaseContext::Execute(uint32_t public_func, cell_t *result)
int BaseContext::Execute(funcid_t funcid, cell_t *result)
{
IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
uint32_t pushcount = ctx->pushcount;
uint32_t code_addr;
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++);
@ -67,7 +74,7 @@ int BaseContext::Execute(uint32_t public_func, cell_t *result)
cell_t save_sp = ctx->sp;
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
@ -338,7 +345,7 @@ int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int ove
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;
}
@ -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))
{
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;
}
int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status)
int BaseContext::BindNative(sp_nativeinfo_t *native)
{
uint32_t index;
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].status = status;
return SP_ERROR_NONE;
}
@ -380,10 +386,9 @@ int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
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].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 PushCellsFromArray(cell_t array[], unsigned int numcells);
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 Execute(uint32_t public_func, cell_t *result);
virtual int Execute(funcid_t funcid, cell_t *result);
public: //IPluginDebugInfo
virtual int LookupFile(ucell_t addr, const char **filename);
virtual int LookupFunction(ucell_t addr, const char **name);

View File

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

View File

@ -8,6 +8,9 @@ namespace SourcePawn
{
class IVirtualMachine;
/**
* @brief Interface to managing a debug context at runtime.
*/
class IPluginDebugInfo
{
public:
@ -36,6 +39,9 @@ namespace SourcePawn
virtual int LookupLine(ucell_t addr, uint32_t *line) =0;
};
/**
* @brief Interface to managing a context at runtime.
*/
class IPluginContext
{
public:
@ -260,7 +266,6 @@ namespace SourcePawn
/**
* 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.
* All natives are assigned a status of SP_NATIVE_OKAY by default.
* If overwrite is non-zero, already registered natives will be overwritten.
*
* @param natives Array of natives.
@ -272,29 +277,31 @@ namespace SourcePawn
/**
* Binds a single native. Overwrites any existing bind.
* 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 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.
* Status is automatically set to pending.
* Binds a single native to any non-registered native.
*
* @param native Native to bind.
*/
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
{
@ -379,6 +386,9 @@ namespace SourcePawn
virtual ~ICompilation() { };
};
/**
* @brief Outlines the interface a Virtual Machine (JIT) must expose
*/
class IVirtualMachine
{
public:

View File

@ -5,6 +5,7 @@
typedef uint32_t ucell_t;
typedef int32_t cell_t;
typedef uint32_t funcid_t;
/**
* 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_NOT_FOUND 6 /* The object in question was not found */
#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 9 /* Nnot enough space left on the stack */
#define SP_ERROR_NOTDEBUGGING 10 /* Debug mode was not on or debug section not found */
#define SP_ERROR_INVALID_INSTRUCTION 11 /* Invalid instruction was encountered */
#define SP_ERROR_MEMACCESS 12 /* Invalid memory access */
#define SP_ERROR_STACKMIN 13 /* Stack went beyond its minimum value */
#define SP_ERROR_HEAPMIN 14 /* Heap went beyond its minimum value */
#define SP_ERROR_DIVIDE_BY_ZERO 15 /* Division by zero */
#define SP_ERROR_ARRAY_BOUNDS 16 /* Array index is out of bounds */
#define SP_ERROR_INSTRUCTION_PARAM 17 /* Instruction had an invalid parameter */
#define SP_ERROR_STACKLEAK 18 /* A native leaked an item on the stack */
#define SP_ERROR_HEAPLEAK 19 /* A native leaked an item on the heap */
#define SP_ERROR_ARRAY_TOO_BIG 20 /* A dynamic array is too big */
#define SP_ERROR_TRACKER_BOUNDS 21 /* Tracker stack is out of bounds */
#define SP_ERROR_STACKLOW 8 /* 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_INVALID_INSTRUCTION 10 /* Invalid instruction was encountered */
#define SP_ERROR_MEMACCESS 11 /* Invalid memory access */
#define SP_ERROR_STACKMIN 12 /* Stack went beyond its minimum value */
#define SP_ERROR_HEAPMIN 13 /* Heap went beyond its minimum value */
#define SP_ERROR_DIVIDE_BY_ZERO 14 /* Division by zero */
#define SP_ERROR_ARRAY_BOUNDS 15 /* Array index is out of bounds */
#define SP_ERROR_INSTRUCTION_PARAM 16 /* Instruction had an invalid parameter */
#define SP_ERROR_STACKLEAK 17 /* A native leaked an item on the stack */
#define SP_ERROR_HEAPLEAK 18 /* A native leaked an item on the heap */
#define SP_ERROR_ARRAY_TOO_BIG 19 /* A dynamic array is too big */
#define SP_ERROR_TRACKER_BOUNDS 20 /* Tracker stack is out of bounds */
#define SP_ERROR_INVALID_NATIVE 21 /* Native was pending or invalid */
/**********************************************
*** 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
{
uint32_t offs; /* code offset */
funcid_t funcid; /* encoded function id */
uint32_t code_offs; /* code offset */
const char *name; /* name */
} sp_public_t;
@ -132,9 +134,8 @@ typedef struct sp_pubvar_s
const char *name; /* name */
} sp_pubvar_t;
#define SP_NATIVE_NONE (0) /* Native is not yet found */
#define SP_NATIVE_OKAY (1) /* Native has been added */
#define SP_NATIVE_PENDING (2) /* Native is marked as usable but replaceable */
#define SP_NATIVE_UNBOUND (0) /* Native is undefined */
#define SP_NATIVE_BOUND (1) /* Native is bound */
/**
* 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];
/* 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 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 save_sp = ctx->sp;
@ -2002,7 +2009,9 @@ jit_rewind:
for (iter=0; iter<max; iter++)
{
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++)
{
ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
ctx->natives[iter].pfn = NULL;
ctx->natives[iter].status = SP_NATIVE_NONE;
ctx->natives[iter].pfn = &InvalidNative;
ctx->natives[iter].status = SP_NATIVE_UNBOUND;
}
}

View File

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