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:
parent
2892ee1fa9
commit
e060af14b4
@ -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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
|
@ -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:
|
||||||
|
@ -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
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
Loading…
Reference in New Issue
Block a user