push functions and some little fixes
authorBorja Ferrer <faluco@alliedmods.net>
Fri Aug 04 19:09:41 2006 +0000 (2006-08-04)
changeset 53805202a58dba
parent 52 97bdc78041aa
child 54 abf88d46dbd1
push functions and some little fixes
sourcepawn/vm/sp_reader.c
sourcepawn/vm/sp_vm.c
sourcepawn/vm/sp_vm.h
     1.1 --- a/sourcepawn/vm/sp_reader.c	Fri Aug 04 03:41:50 2006 +0000
     1.2 +++ b/sourcepawn/vm/sp_reader.c	Fri Aug 04 19:09:41 2006 +0000
     1.3 @@ -79,19 +79,27 @@
     1.4  	}
     1.5  
     1.6  	if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
     1.7 +	{
     1.8  		goto return_error;
     1.9 +	}
    1.10  
    1.11  	if ((plugin->flags == SP_FILE_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
    1.12 +	{
    1.13  		goto return_error;
    1.14 +	}
    1.15  
    1.16  	if (err)
    1.17 +	{
    1.18  		*err = SP_ERR_NONE;
    1.19 +	}
    1.20  
    1.21  	return plugin;
    1.22  
    1.23  return_error:
    1.24  	if (err)
    1.25 +	{
    1.26  		*err = SP_ERR_FILE_FORMAT;
    1.27 +	}
    1.28  
    1.29  	return NULL;
    1.30  }
    1.31 @@ -180,7 +188,9 @@
    1.32  
    1.33  return_error:
    1.34  	if (err)
    1.35 +	{
    1.36  		*err = error;
    1.37 +	}
    1.38  	return NULL;
    1.39  }
    1.40  
    1.41 @@ -200,7 +210,9 @@
    1.42  	if (!_ReadPlugin(&hdr, base, plugin, err))
    1.43  	{
    1.44  		if (noptr)
    1.45 +		{
    1.46  			free(plugin);
    1.47 +		}
    1.48  		return NULL;
    1.49  	}
    1.50  
     2.1 --- a/sourcepawn/vm/sp_vm.c	Fri Aug 04 03:41:50 2006 +0000
     2.2 +++ b/sourcepawn/vm/sp_vm.c	Fri Aug 04 19:09:41 2006 +0000
     2.3 @@ -24,6 +24,7 @@
     2.4  	assert(SP_HeapRelease(&ctx, 4) == SP_ERR_INVALID_ADDRESS);
     2.5  	assert(SP_HeapAlloc(&ctx, 500, &l, &p) == SP_ERR_NONE);
     2.6  	assert(SP_HeapRelease(&ctx, l) == SP_ERR_NONE);
     2.7 +	assert(SP_PushCell(&ctx, 1337) == SP_ERR_NONE);
     2.8  
     2.9  	return 0;
    2.10  }
    2.11 @@ -109,7 +110,8 @@
    2.12  
    2.13  int SP_FindNativeByName(sp_context_t *ctx, const char *name, uint32_t *index)
    2.14  {
    2.15 -	uint32_t mid, low, high, diff;
    2.16 +	uint32_t mid, low, high;
    2.17 +	int diff;
    2.18  
    2.19  	high = ctx->plugin->info.natives_num - 1;
    2.20  	low = 0;
    2.21 @@ -121,7 +123,9 @@
    2.22  		if (diff == 0)
    2.23  		{
    2.24  			if (index)
    2.25 +			{
    2.26  				*index = mid;
    2.27 +			}
    2.28  			return SP_ERR_NONE;
    2.29  		} else if (diff < 0) {
    2.30  			low = mid + 1;
    2.31 @@ -136,10 +140,14 @@
    2.32  int SP_GetNativeByIndex(sp_context_t *ctx, uint32_t index, sp_native_t **native)
    2.33  {
    2.34  	if (index >= ctx->plugin->info.natives_num)
    2.35 +	{
    2.36  		return SP_ERR_INDEX;
    2.37 +	}
    2.38  
    2.39  	if (native)
    2.40 +	{
    2.41  		*native = &(ctx->natives[index]);
    2.42 +	}
    2.43  
    2.44  	return SP_ERR_NONE;
    2.45  }
    2.46 @@ -153,7 +161,8 @@
    2.47  
    2.48  int SP_FindPublicByName(sp_context_t *ctx, const char *name, uint32_t *index)
    2.49  {
    2.50 -	uint32_t mid, low, high, diff;
    2.51 +	uint32_t mid, low, high;
    2.52 +	int diff;
    2.53  
    2.54  	high = ctx->plugin->info.publics_num - 1;
    2.55  	low = 0;
    2.56 @@ -165,7 +174,9 @@
    2.57  		if (diff == 0)
    2.58  		{
    2.59  			if (index)
    2.60 +			{
    2.61  				*index = mid;
    2.62 +			}
    2.63  			return SP_ERR_NONE;
    2.64  		} else if (diff < 0) {
    2.65  			low = mid + 1;
    2.66 @@ -180,10 +191,14 @@
    2.67  int SP_GetPublicByIndex(sp_context_t *ctx, uint32_t index, sp_public_t **pblic)
    2.68  {
    2.69  	if (index >= ctx->plugin->info.publics_num)
    2.70 +	{
    2.71  		return SP_ERR_INDEX;
    2.72 +	}
    2.73  
    2.74  	if (pblic)
    2.75 +	{
    2.76  		*pblic = &(ctx->publics[index]);
    2.77 +	}
    2.78  
    2.79  	return SP_ERR_NONE;
    2.80  }
    2.81 @@ -198,17 +213,22 @@
    2.82  int SP_GetPubvarByIndex(sp_context_t *ctx, uint32_t index, sp_pubvar_t **pubvar)
    2.83  {
    2.84  	if (index >= ctx->plugin->info.pubvars_num)
    2.85 +	{
    2.86  		return SP_ERR_INDEX;
    2.87 +	}
    2.88  
    2.89  	if (pubvar)
    2.90 +	{
    2.91  		*pubvar = &(ctx->pubvars[index]);
    2.92 +	}
    2.93  
    2.94  	return SP_ERR_NONE;
    2.95  }
    2.96  
    2.97  int SP_FindPubvarByName(sp_context_t *ctx, const char *name, uint32_t *index)
    2.98  {
    2.99 -	uint32_t mid, low, high, diff;
   2.100 +	uint32_t mid, low, high;
   2.101 +	int diff;
   2.102  
   2.103  	high = ctx->plugin->info.pubvars_num - 1;
   2.104  	low = 0;
   2.105 @@ -220,7 +240,9 @@
   2.106  		if (diff == 0)
   2.107  		{
   2.108  			if (index)
   2.109 +			{
   2.110  				*index = mid;
   2.111 +			}
   2.112  			return SP_ERR_NONE;
   2.113  		} else if (diff < 0) {
   2.114  			low = mid + 1;
   2.115 @@ -235,7 +257,9 @@
   2.116  int SP_GetPubvarAddrs(sp_context_t *ctx, uint32_t index, cell_t *local_addr, cell_t **phys_addr)
   2.117  {
   2.118  	if (index >= ctx->plugin->info.pubvars_num)
   2.119 +	{
   2.120  		return SP_ERR_INDEX;
   2.121 +	}
   2.122  
   2.123  	*local_addr = ctx->plugin->info.pubvars[index].address;
   2.124  	*phys_addr = ctx->pubvars[index].offs;
   2.125 @@ -259,7 +283,9 @@
   2.126  	for (i=0; i<max; i++)
   2.127  	{
   2.128  		if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite)
   2.129 +		{
   2.130  			continue;
   2.131 +		}
   2.132  
   2.133  		for (j=0; (natives[j].name) && (!num || j<num); j++)
   2.134  		{
   2.135 @@ -276,10 +302,13 @@
   2.136  
   2.137  int SP_BindNative(sp_context_t *ctx, sp_nativeinfo_t *native, uint32_t status)
   2.138  {
   2.139 -	uint32_t index, err;
   2.140 +	uint32_t index;
   2.141 +	int err;
   2.142  
   2.143  	if ((err = SP_FindNativeByName(ctx, native->name, &index)) != SP_ERR_NONE)
   2.144 +	{
   2.145  		return err;
   2.146 +	}
   2.147  
   2.148  	ctx->natives[index].pfn = native->func;
   2.149  	ctx->natives[index].status = status;
   2.150 @@ -308,10 +337,71 @@
   2.151  int SP_LocalToPhysAddr(sp_context_t *ctx, cell_t local_addr, cell_t **phys_addr)
   2.152  {
   2.153  	if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->memory))
   2.154 +	{
   2.155  		return SP_ERR_INVALID_ADDRESS;
   2.156 -	
   2.157 +	}
   2.158 +
   2.159  	if (phys_addr)
   2.160 +	{
   2.161  		*phys_addr = (cell_t *)(ctx->data + local_addr);
   2.162 +	}
   2.163 +
   2.164 +	return SP_ERR_NONE;
   2.165 +}
   2.166 +
   2.167 +int SP_PushCell(sp_context_t *ctx, cell_t value)
   2.168 +{
   2.169 +	if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
   2.170 +	{
   2.171 +		return SP_ERR_HEAPLOW;
   2.172 +	}
   2.173 +
   2.174 +	ctx->sp -= sizeof(cell_t);
   2.175 +	*(cell_t *)(ctx->data + ctx->sp) = value;
   2.176 +	ctx->pushcount++;
   2.177  
   2.178  	return SP_ERR_NONE;
   2.179 -}
   2.180 \ No newline at end of file
   2.181 +}
   2.182 +
   2.183 +int SP_PushCellsFromArray(sp_context_t *ctx, cell_t array[], unsigned int numcells)
   2.184 +{
   2.185 +	unsigned int i;
   2.186 +	int err;
   2.187 +
   2.188 +	for (i=0; i<numcells; i++)
   2.189 +	{
   2.190 +		if ((err = SP_PushCell(ctx, array[i])) != SP_ERR_NONE)
   2.191 +		{
   2.192 +			ctx->sp += i * sizeof(cell_t);
   2.193 +			ctx->pushcount -= i;
   2.194 +			return err;
   2.195 +		}
   2.196 +	}
   2.197 +
   2.198 +	return SP_ERR_NONE;
   2.199 +}
   2.200 +
   2.201 +int SP_PushCellArray(sp_context_t *ctx, cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells)
   2.202 +{
   2.203 +	cell_t *ph_addr;
   2.204 +	int err;
   2.205 +
   2.206 +	if ((err = SP_HeapAlloc(ctx, numcells, local_addr, &ph_addr)) != SP_ERR_NONE)
   2.207 +	{
   2.208 +		return err;
   2.209 +	}
   2.210 +
   2.211 +	memcpy(ph_addr, array, numcells * sizeof(cell_t));
   2.212 +	if (phys_addr)
   2.213 +	{
   2.214 +		*phys_addr = ph_addr;
   2.215 +	}
   2.216 +
   2.217 +	if ((err = SP_PushCell(ctx, *local_addr)) != SP_ERR_NONE)
   2.218 +	{
   2.219 +		SP_HeapRelease(ctx, *local_addr);
   2.220 +		return err;
   2.221 +	}
   2.222 +
   2.223 +	return SP_ERR_NONE;
   2.224 +}
     3.1 --- a/sourcepawn/vm/sp_vm.h	Fri Aug 04 03:41:50 2006 +0000
     3.2 +++ b/sourcepawn/vm/sp_vm.h	Fri Aug 04 19:09:41 2006 +0000
     3.3 @@ -8,6 +8,7 @@
     3.4   ** Note that all functions return a non-zero error code on failure
     3.5   *   unless otherwise noted.
     3.6   * All input pointers must be valid unless otherwise noted as optional.
     3.7 + * All output pointers on failure are undefined.
     3.8   * All local address are guaranteed to be positive.  However, they are stored
     3.9   *  as signed integers, because they must logically fit inside a cell.
    3.10   */
    3.11 @@ -195,6 +196,7 @@
    3.12  
    3.13  /** 
    3.14   * Pushes an array of cells onto the stack.  Increases the parameter count by one.
    3.15 + * If the function returns an error it will fail entirely, releasing anything allocated in the process.
    3.16   * Note that this does not release the heap, so you should release it after
    3.17   *  calling SP_Execute().
    3.18   *
    3.19 @@ -229,6 +231,7 @@
    3.20  /**
    3.21   * Individually pushes each cell of an array of cells onto the stack.  Increases the 
    3.22   *  parameter count by the number of cells pushed.
    3.23 + * If the function returns an error it will fail entirely, releasing anything allocated in the process.
    3.24   *
    3.25   * @param ctx			Context pointer.
    3.26   * @param array			Array of cells to read from.
    3.27 @@ -260,7 +263,7 @@
    3.28  int SP_BindNative(sp_context_t *ctx, sp_nativeinfo_t *native, uint32_t status);
    3.29  
    3.30  /**
    3.31 - * Binds a single native to any non-registered native.
    3.32 + * Binds a single native to any non-registered or pending native.
    3.33   * Status is automatically set to pending.
    3.34   *
    3.35   * @param ctx			Context pointer.