1.1 --- a/sourcepawn/include/sp_vm_api.h Tue Nov 07 23:26:40 2006 +0000
1.2 +++ b/sourcepawn/include/sp_vm_api.h Wed Nov 08 06:24:28 2006 +0000
1.3 @@ -3,11 +3,295 @@
1.4
1.5 #include <stdio.h>
1.6 #include "sp_vm_types.h"
1.7 -#include "sp_vm_context.h"
1.8
1.9 namespace SourcePawn
1.10 {
1.11 - class IPluginContext;
1.12 + class IVirtualMachine;
1.13 +
1.14 + class IPluginDebugInfo
1.15 + {
1.16 + public:
1.17 + /**
1.18 + * Given a code pointer, finds the file it is associated with.
1.19 + *
1.20 + * @param addr Code address offset.
1.21 + * @param filename Pointer to store filename pointer in.
1.22 + */
1.23 + virtual int LookupFile(ucell_t addr, const char **filename) =0;
1.24 +
1.25 + /**
1.26 + * Given a code pointer, finds the function it is associated with.
1.27 + *
1.28 + * @param addr Code address offset.
1.29 + * @param name Pointer to store function name pointer in.
1.30 + */
1.31 + virtual int LookupFunction(ucell_t addr, const char **name) =0;
1.32 +
1.33 + /**
1.34 + * Given a code pointer, finds the line it is associated with.
1.35 + *
1.36 + * @param addr Code address offset.
1.37 + * @param line Pointer to store line number in.
1.38 + */
1.39 + virtual int LookupLine(ucell_t addr, uint32_t *line) =0;
1.40 + };
1.41 +
1.42 + class IPluginContext
1.43 + {
1.44 + public:
1.45 + virtual ~IPluginContext() { };
1.46 + public:
1.47 + /**
1.48 + * Returns the parent IVirtualMachine.
1.49 + *
1.50 + * @return Parent virtual machine pointer.
1.51 + */
1.52 + virtual IVirtualMachine *GetVirtualMachine() =0;
1.53 +
1.54 + /**
1.55 + * Returns the child sp_context_t structure.
1.56 + *
1.57 + * @return Child sp_context_t structure.
1.58 + */
1.59 + virtual sp_context_t *GetContext() =0;
1.60 +
1.61 + /**
1.62 + * Returns true if the plugin is in debug mode.
1.63 + *
1.64 + * @return True if in debug mode, false otherwise.
1.65 + */
1.66 + virtual bool IsDebugging() =0;
1.67 +
1.68 + /**
1.69 + * Installs a debug break and returns the old one, if any.
1.70 + * This will fail if the plugin is not debugging.
1.71 + *
1.72 + * @param newpfn New function pointer.
1.73 + * @param oldpfn Pointer to retrieve old function pointer.
1.74 + */
1.75 + virtual int SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn) =0;
1.76 +
1.77 + /**
1.78 + * Returns debug info.
1.79 + *
1.80 + * @return IPluginDebugInfo, or NULL if no debug info found.
1.81 + */
1.82 + virtual IPluginDebugInfo *GetDebugInfo() =0;
1.83 +
1.84 + /**
1.85 + * Allocs memory on the secondary stack of a plugin.
1.86 + * Note that although called a heap, it is in fact a stack.
1.87 + *
1.88 + * @param cells Number of cells to allocate.
1.89 + * @param local_adddr Will be filled with data offset to heap.
1.90 + * @param phys_addr Physical address to heap memory.
1.91 + */
1.92 + virtual int HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys_addr) =0;
1.93 +
1.94 + /**
1.95 + * Pops a heap address off the heap stack. Use this to free memory allocated with
1.96 + * SP_HeapAlloc().
1.97 + * Note that in SourcePawn, the heap is in fact a bottom-up stack. Deallocations
1.98 + * with this native should be performed in precisely the REVERSE order.
1.99 + *
1.100 + * @param local_addr Local address to free.
1.101 + */
1.102 + virtual int HeapPop(cell_t local_addr) =0;
1.103 +
1.104 + /**
1.105 + * Releases a heap address using a different method than SP_HeapPop().
1.106 + * This allows you to release in any order. However, if you allocate N
1.107 + * objects, release only some of them, then begin allocating again,
1.108 + * you cannot go back and starting freeing the originals.
1.109 + * In other words, for each chain of allocations, if you start deallocating,
1.110 + * then allocating more in a chain, you must only deallocate from the current
1.111 + * allocation chain. This is basically HeapPop() except on a larger scale.
1.112 + *
1.113 + * @param local_addr Local address to free.
1.114 + */
1.115 + virtual int HeapRelease(cell_t local_addr) =0;
1.116 +
1.117 + /**
1.118 + * Finds a native by name.
1.119 + *
1.120 + * @param name Name of native.
1.121 + * @param index Optionally filled with native index number.
1.122 + */
1.123 + virtual int FindNativeByName(const char *name, uint32_t *index) =0;
1.124 +
1.125 + /**
1.126 + * Gets native info by index.
1.127 + *
1.128 + * @param index Index number of native.
1.129 + * @param native Optionally filled with pointer to native structure.
1.130 + */
1.131 + virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0;
1.132 +
1.133 + /**
1.134 + * Gets the number of natives.
1.135 + *
1.136 + * @return Filled with the number of natives.
1.137 + */
1.138 + virtual uint32_t GetNativesNum() =0;
1.139 +
1.140 + /**
1.141 + * Finds a public function by name.
1.142 + *
1.143 + * @param name Name of public
1.144 + * @param index Optionally filled with public index number.
1.145 + */
1.146 + virtual int FindPublicByName(const char *name, uint32_t *index) =0;
1.147 +
1.148 + /**
1.149 + * Gets public function info by index.
1.150 + *
1.151 + * @param index Public function index number.
1.152 + * @param public Optionally filled with pointer to public structure.
1.153 + */
1.154 + virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr) =0;
1.155 +
1.156 + /**
1.157 + * Gets the number of public functions.
1.158 + *
1.159 + * @return Filled with the number of public functions.
1.160 + */
1.161 + virtual uint32_t GetPublicsNum() =0;
1.162 +
1.163 + /**
1.164 + * Gets public variable info by index.
1.165 + * @param index Public variable index number.
1.166 + * @param pubvar Optionally filled with pointer to pubvar structure.
1.167 + */
1.168 + virtual int GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar) =0;
1.169 +
1.170 + /**
1.171 + * Finds a public variable by name.
1.172 + *
1.173 + * @param name Name of pubvar
1.174 + * @param index Optionally filled with pubvar index number.
1.175 + */
1.176 + virtual int FindPubvarByName(const char *name, uint32_t *index) =0;
1.177 +
1.178 + /**
1.179 + * Gets the addresses of a public variable.
1.180 + *
1.181 + * @param index Index of public variable.
1.182 + * @param local_addr Address to store local address in.
1.183 + * @param phys_addr Address to store physically relocated in.
1.184 + */
1.185 + virtual int GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr) =0;
1.186 +
1.187 + /**
1.188 + * Returns the number of public variables.
1.189 + *
1.190 + * @return Number of public variables.
1.191 + */
1.192 + virtual uint32_t GetPubVarsNum() =0;
1.193 +
1.194 + /**
1.195 + * Round-about method of converting a plugin reference to a physical address
1.196 + *
1.197 + * @param local_addr Local address in plugin.
1.198 + * @param phys_addr Optionally filled with relocated physical address.
1.199 + */
1.200 + virtual int LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr) =0;
1.201 +
1.202 + /**:TODO: FIX ALL PACKED STUFF COMMENTS!
1.203 + * Converts a local address to a physical string.
1.204 + * Note that SourcePawn does not support packed strings, as such this function is
1.205 + * 'cell to char' only.
1.206 + *
1.207 + * @param local_addr Local address in plugin.
1.208 + * @param addr Destination output pointer.
1.209 + */
1.210 + virtual int LocalToString(cell_t local_addr, char **addr) =0;
1.211 +
1.212 + /**
1.213 + * Converts a physical string to a local address.
1.214 + * Note that SourcePawn does not support packed strings.
1.215 + *
1.216 + * @param local_addr Local address in plugin.
1.217 + * @param chars Number of chars to write, including NULL terminator.
1.218 + * @param source Source string to copy.
1.219 + */
1.220 + virtual int StringToLocal(cell_t local_addr, size_t chars, const char *source) =0;
1.221 +
1.222 + /**
1.223 + * Pushes a cell onto the stack. Increases the parameter count by one.
1.224 + *
1.225 + * @param value Cell value.
1.226 + */
1.227 + virtual int PushCell(cell_t value) =0;
1.228 +
1.229 + /**
1.230 + * Pushes an array of cells onto the stack. Increases the parameter count by one.
1.231 + * If the function returns an error it will fail entirely, releasing anything allocated in the process.
1.232 + * Note that this does not release the heap, so you should release it after
1.233 + * calling Execute().
1.234 + *
1.235 + * @param local_addr Filled with local address to release.
1.236 + * @param phys_addr Optionally filled with physical address of new array.
1.237 + * @param array Cell array to copy.
1.238 + * @param numcells Number of cells in the array to copy.
1.239 + */
1.240 + virtual int PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells) =0;
1.241 +
1.242 + /**
1.243 + * Pushes a string onto the stack (by reference) and increases the parameter count by one.
1.244 + * Note that this does not release the heap, so you should release it after
1.245 + * calling Execute().
1.246 + *
1.247 + * @param local_addr Filled with local address to release.
1.248 + * @param phys_addr Optionally filled with physical address of new array.
1.249 + * @param string Source string to push.
1.250 + */
1.251 + virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string) =0;
1.252 +
1.253 + /**
1.254 + * Individually pushes each cell of an array of cells onto the stack. Increases the
1.255 + * parameter count by the number of cells pushed.
1.256 + * If the function returns an error it will fail entirely, releasing anything allocated in the process.
1.257 + *
1.258 + * @param array Array of cells to read from.
1.259 + * @param numcells Number of cells to read.
1.260 + */
1.261 + virtual int PushCellsFromArray(cell_t array[], unsigned int numcells) =0;
1.262 +
1.263 + /**
1.264 + * Binds a list of native names and their function pointers to a context.
1.265 + * If num is 0, the list is read until an entry with a NULL name is reached.
1.266 + * All natives are assigned a status of SP_NATIVE_OKAY by default.
1.267 + * If overwrite is non-zero, already registered natives will be overwritten.
1.268 + *
1.269 + * @param natives Array of natives.
1.270 + * @param num Number of natives in array.
1.271 + * @param overwrite Toggles overwrite.
1.272 + */
1.273 + virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite) =0;
1.274 +
1.275 + /**
1.276 + * Binds a single native. Overwrites any existing bind.
1.277 + * If the context does not contain the native that will be binded the function will return
1.278 + * with a SP_ERROR_OT_FOUND error.
1.279 + *
1.280 + * @param native Pointer to native.
1.281 + * @param status Status value to set (should be SP_NATIVE_OKAY).
1.282 + */
1.283 + virtual int BindNative(sp_nativeinfo_t *native, uint32_t status) =0;
1.284 +
1.285 + /**
1.286 + * Binds a single native to any non-registered or pending native.
1.287 + * Status is automatically set to pending.
1.288 + *
1.289 + * @param native Native to bind.
1.290 + */
1.291 + virtual int BindNativeToAny(SPVM_NATIVE_FUNC native) =0;
1.292 +
1.293 + /**
1.294 + * Executes a public function.
1.295 + */
1.296 + virtual int Execute(uint32_t public_func, cell_t *result) =0;
1.297 + };
1.298
1.299 /**
1.300 * Contains helper functions used by VMs and the host app
2.1 --- a/sourcepawn/include/sp_vm_context.h Tue Nov 07 23:26:40 2006 +0000
2.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
2.3 @@ -1,305 +0,0 @@
2.4 -#ifndef _INCLUDE_SOURCEPAWN_VM_CONTEXT_H_
2.5 -#define _INCLUDE_SOURCEPAWN_VM_CONTEXT_H_
2.6 -
2.7 -#include "sp_vm_types.h"
2.8 -
2.9 -/*****************
2.10 - ** Note that all functions return a non-zero error code on failure
2.11 - * unless otherwise noted.
2.12 - * All input pointers must be valid unless otherwise noted as optional.
2.13 - * All output pointers on failure are undefined.
2.14 - * All local address are guaranteed to be positive. However, they are stored
2.15 - * as signed integers, because they must logically fit inside a cell.
2.16 - */
2.17 -
2.18 -namespace SourcePawn
2.19 -{
2.20 - class IVirtualMachine;
2.21 -
2.22 - class IPluginDebugInfo
2.23 - {
2.24 - public:
2.25 - /**
2.26 - * Given a code pointer, finds the file it is associated with.
2.27 - *
2.28 - * @param addr Code address offset.
2.29 - * @param filename Pointer to store filename pointer in.
2.30 - */
2.31 - virtual int LookupFile(ucell_t addr, const char **filename) =0;
2.32 -
2.33 - /**
2.34 - * Given a code pointer, finds the function it is associated with.
2.35 - *
2.36 - * @param addr Code address offset.
2.37 - * @param name Pointer to store function name pointer in.
2.38 - */
2.39 - virtual int LookupFunction(ucell_t addr, const char **name) =0;
2.40 -
2.41 - /**
2.42 - * Given a code pointer, finds the line it is associated with.
2.43 - *
2.44 - * @param addr Code address offset.
2.45 - * @param line Pointer to store line number in.
2.46 - */
2.47 - virtual int LookupLine(ucell_t addr, uint32_t *line) =0;
2.48 - };
2.49 -
2.50 - class IPluginContext
2.51 - {
2.52 - public:
2.53 - virtual ~IPluginContext() { };
2.54 - public:
2.55 - /**
2.56 - * Returns the parent IVirtualMachine.
2.57 - *
2.58 - * @return Parent virtual machine pointer.
2.59 - */
2.60 - virtual IVirtualMachine *GetVirtualMachine() =0;
2.61 -
2.62 - /**
2.63 - * Returns the child sp_context_t structure.
2.64 - *
2.65 - * @return Child sp_context_t structure.
2.66 - */
2.67 - virtual sp_context_t *GetContext() =0;
2.68 -
2.69 - /**
2.70 - * Returns true if the plugin is in debug mode.
2.71 - *
2.72 - * @return True if in debug mode, false otherwise.
2.73 - */
2.74 - virtual bool IsDebugging() =0;
2.75 -
2.76 - /**
2.77 - * Installs a debug break and returns the old one, if any.
2.78 - * This will fail if the plugin is not debugging.
2.79 - *
2.80 - * @param newpfn New function pointer.
2.81 - * @param oldpfn Pointer to retrieve old function pointer.
2.82 - */
2.83 - virtual int SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn) =0;
2.84 -
2.85 - /**
2.86 - * Returns debug info.
2.87 - *
2.88 - * @return IPluginDebugInfo, or NULL if no debug info found.
2.89 - */
2.90 - virtual IPluginDebugInfo *GetDebugInfo() =0;
2.91 -
2.92 - /**
2.93 - * Allocs memory on the secondary stack of a plugin.
2.94 - * Note that although called a heap, it is in fact a stack.
2.95 - *
2.96 - * @param cells Number of cells to allocate.
2.97 - * @param local_adddr Will be filled with data offset to heap.
2.98 - * @param phys_addr Physical address to heap memory.
2.99 - */
2.100 - virtual int HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys_addr) =0;
2.101 -
2.102 - /**
2.103 - * Pops a heap address off the heap stack. Use this to free memory allocated with
2.104 - * SP_HeapAlloc().
2.105 - * Note that in SourcePawn, the heap is in fact a bottom-up stack. Deallocations
2.106 - * with this native should be performed in precisely the REVERSE order.
2.107 - *
2.108 - * @param local_addr Local address to free.
2.109 - */
2.110 - virtual int HeapPop(cell_t local_addr) =0;
2.111 -
2.112 - /**
2.113 - * Releases a heap address using a different method than SP_HeapPop().
2.114 - * This allows you to release in any order. However, if you allocate N
2.115 - * objects, release only some of them, then begin allocating again,
2.116 - * you cannot go back and starting freeing the originals.
2.117 - * In other words, for each chain of allocations, if you start deallocating,
2.118 - * then allocating more in a chain, you must only deallocate from the current
2.119 - * allocation chain. This is basically HeapPop() except on a larger scale.
2.120 - *
2.121 - * @param local_addr Local address to free.
2.122 - */
2.123 - virtual int HeapRelease(cell_t local_addr) =0;
2.124 -
2.125 - /**
2.126 - * Finds a native by name.
2.127 - *
2.128 - * @param name Name of native.
2.129 - * @param index Optionally filled with native index number.
2.130 - */
2.131 - virtual int FindNativeByName(const char *name, uint32_t *index) =0;
2.132 -
2.133 - /**
2.134 - * Gets native info by index.
2.135 - *
2.136 - * @param index Index number of native.
2.137 - * @param native Optionally filled with pointer to native structure.
2.138 - */
2.139 - virtual int GetNativeByIndex(uint32_t index, sp_native_t **native) =0;
2.140 -
2.141 - /**
2.142 - * Gets the number of natives.
2.143 - *
2.144 - * @return Filled with the number of natives.
2.145 - */
2.146 - virtual uint32_t GetNativesNum() =0;
2.147 -
2.148 - /**
2.149 - * Finds a public function by name.
2.150 - *
2.151 - * @param name Name of public
2.152 - * @param index Optionally filled with public index number.
2.153 - */
2.154 - virtual int FindPublicByName(const char *name, uint32_t *index) =0;
2.155 -
2.156 - /**
2.157 - * Gets public function info by index.
2.158 - *
2.159 - * @param index Public function index number.
2.160 - * @param public Optionally filled with pointer to public structure.
2.161 - */
2.162 - virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr) =0;
2.163 -
2.164 - /**
2.165 - * Gets the number of public functions.
2.166 - *
2.167 - * @return Filled with the number of public functions.
2.168 - */
2.169 - virtual uint32_t GetPublicsNum() =0;
2.170 -
2.171 - /**
2.172 - * Gets public variable info by index.
2.173 - * @param index Public variable index number.
2.174 - * @param pubvar Optionally filled with pointer to pubvar structure.
2.175 - */
2.176 - virtual int GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar) =0;
2.177 -
2.178 - /**
2.179 - * Finds a public variable by name.
2.180 - *
2.181 - * @param name Name of pubvar
2.182 - * @param index Optionally filled with pubvar index number.
2.183 - */
2.184 - virtual int FindPubvarByName(const char *name, uint32_t *index) =0;
2.185 -
2.186 - /**
2.187 - * Gets the addresses of a public variable.
2.188 - *
2.189 - * @param index Index of public variable.
2.190 - * @param local_addr Address to store local address in.
2.191 - * @param phys_addr Address to store physically relocated in.
2.192 - */
2.193 - virtual int GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr) =0;
2.194 -
2.195 - /**
2.196 - * Returns the number of public variables.
2.197 - *
2.198 - * @return Number of public variables.
2.199 - */
2.200 - virtual uint32_t GetPubVarsNum() =0;
2.201 -
2.202 - /**
2.203 - * Round-about method of converting a plugin reference to a physical address
2.204 - *
2.205 - * @param local_addr Local address in plugin.
2.206 - * @param phys_addr Optionally filled with relocated physical address.
2.207 - */
2.208 - virtual int LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr) =0;
2.209 -
2.210 - /**:TODO: FIX ALL PACKED STUFF COMMENTS!
2.211 - * Converts a local address to a physical string.
2.212 - * Note that SourcePawn does not support packed strings, as such this function is
2.213 - * 'cell to char' only.
2.214 - *
2.215 - * @param local_addr Local address in plugin.
2.216 - * @param addr Destination output pointer.
2.217 - */
2.218 - virtual int LocalToString(cell_t local_addr, char **addr) =0;
2.219 -
2.220 - /**
2.221 - * Converts a physical string to a local address.
2.222 - * Note that SourcePawn does not support packed strings.
2.223 - *
2.224 - * @param local_addr Local address in plugin.
2.225 - * @param chars Number of chars to write, including NULL terminator.
2.226 - * @param source Source string to copy.
2.227 - */
2.228 - virtual int StringToLocal(cell_t local_addr, size_t chars, const char *source) =0;
2.229 -
2.230 - /**
2.231 - * Pushes a cell onto the stack. Increases the parameter count by one.
2.232 - *
2.233 - * @param value Cell value.
2.234 - */
2.235 - virtual int PushCell(cell_t value) =0;
2.236 -
2.237 - /**
2.238 - * Pushes an array of cells onto the stack. Increases the parameter count by one.
2.239 - * If the function returns an error it will fail entirely, releasing anything allocated in the process.
2.240 - * Note that this does not release the heap, so you should release it after
2.241 - * calling Execute().
2.242 - *
2.243 - * @param local_addr Filled with local address to release.
2.244 - * @param phys_addr Optionally filled with physical address of new array.
2.245 - * @param array Cell array to copy.
2.246 - * @param numcells Number of cells in the array to copy.
2.247 - */
2.248 - virtual int PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells) =0;
2.249 -
2.250 - /**
2.251 - * Pushes a string onto the stack (by reference) and increases the parameter count by one.
2.252 - * Note that this does not release the heap, so you should release it after
2.253 - * calling Execute().
2.254 - *
2.255 - * @param local_addr Filled with local address to release.
2.256 - * @param phys_addr Optionally filled with physical address of new array.
2.257 - * @param string Source string to push.
2.258 - */
2.259 - virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string) =0;
2.260 -
2.261 - /**
2.262 - * Individually pushes each cell of an array of cells onto the stack. Increases the
2.263 - * parameter count by the number of cells pushed.
2.264 - * If the function returns an error it will fail entirely, releasing anything allocated in the process.
2.265 - *
2.266 - * @param array Array of cells to read from.
2.267 - * @param numcells Number of cells to read.
2.268 - */
2.269 - virtual int PushCellsFromArray(cell_t array[], unsigned int numcells) =0;
2.270 -
2.271 - /**
2.272 - * Binds a list of native names and their function pointers to a context.
2.273 - * If num is 0, the list is read until an entry with a NULL name is reached.
2.274 - * All natives are assigned a status of SP_NATIVE_OKAY by default.
2.275 - * If overwrite is non-zero, already registered natives will be overwritten.
2.276 - *
2.277 - * @param natives Array of natives.
2.278 - * @param num Number of natives in array.
2.279 - * @param overwrite Toggles overwrite.
2.280 - */
2.281 - virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite) =0;
2.282 -
2.283 - /**
2.284 - * Binds a single native. Overwrites any existing bind.
2.285 - * If the context does not contain the native that will be binded the function will return
2.286 - * with a SP_ERROR_OT_FOUND error.
2.287 - *
2.288 - * @param native Pointer to native.
2.289 - * @param status Status value to set (should be SP_NATIVE_OKAY).
2.290 - */
2.291 - virtual int BindNative(sp_nativeinfo_t *native, uint32_t status) =0;
2.292 -
2.293 - /**
2.294 - * Binds a single native to any non-registered or pending native.
2.295 - * Status is automatically set to pending.
2.296 - *
2.297 - * @param native Native to bind.
2.298 - */
2.299 - virtual int BindNativeToAny(SPVM_NATIVE_FUNC native) =0;
2.300 -
2.301 - /**
2.302 - * Executes a public function.
2.303 - */
2.304 - virtual int Execute(uint32_t public_func, cell_t *result) =0;
2.305 - };
2.306 -};
2.307 -
2.308 -#endif //_INCLUDE_SOURCEPAWN_VM_CONTEXT_H_
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/sourcepawn/jit/jit_helpers.h Wed Nov 08 06:24:28 2006 +0000
3.3 @@ -0,0 +1,95 @@
3.4 +#ifndef _INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
3.5 +#define _INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
3.6 +
3.7 +#include <sp_vm_types.h>
3.8 +#include <sp_vm_api.h>
3.9 +
3.10 +#if defined HAVE_STDINT_H && !defined WIN32
3.11 +#include <stdint.h>
3.12 +typedef int8_t jit_int8_t;
3.13 +typedef uint8_t jit_uint8_t;
3.14 +typedef int32_t jit_int32_t;
3.15 +typedef uint32_t jit_uint32_t;
3.16 +typedef int64_t jit_int64_t;
3.17 +typedef uint64_t jit_uint64_t;
3.18 +#elif defined WIN32
3.19 +typedef __int8 jit_int8_t;
3.20 +typedef unsigned __int8 jit_uint8_t;
3.21 +typedef __int32 jit_int32_t;
3.22 +typedef unsigned __int32 jit_uint32_t;
3.23 +typedef __int64 jit_int64_t;
3.24 +typedef unsigned __int64 jit_uint64_t;
3.25 +#endif
3.26 +
3.27 +typedef char * jitcode_t;
3.28 +typedef unsigned int jitoffs_t;
3.29 +typedef signed int jitrel_t;
3.30 +
3.31 +class JitWriter
3.32 +{
3.33 +public:
3.34 + inline cell_t read_cell()
3.35 + {
3.36 + cell_t val = *(inptr);
3.37 + inptr++;
3.38 + return val;
3.39 + }
3.40 + inline cell_t *read_cellptr()
3.41 + {
3.42 + cell_t *val = *(cell_t **)(inptr);
3.43 + inptr++;
3.44 + return val;
3.45 + }
3.46 + inline void write_ubyte(jit_uint8_t c)
3.47 + {
3.48 + if (outbase)
3.49 + {
3.50 + *outptr = c;
3.51 + }
3.52 + outptr++;
3.53 + }
3.54 + inline void write_byte(jit_int8_t c)
3.55 + {
3.56 + if (outbase)
3.57 + {
3.58 + *outptr = c;
3.59 + }
3.60 + outptr++;
3.61 + }
3.62 + inline void write_int32(jit_int32_t c)
3.63 + {
3.64 + if (outbase)
3.65 + {
3.66 + *(jit_int32_t *)outptr = c;
3.67 + }
3.68 + outptr += sizeof(jit_int32_t);
3.69 + }
3.70 + inline void write_uint32(jit_uint32_t c)
3.71 + {
3.72 + if (outbase)
3.73 + {
3.74 + *(jit_uint32_t *)outptr = c;
3.75 + }
3.76 + outptr += sizeof(jit_uint32_t);
3.77 + }
3.78 + inline jitoffs_t get_outputpos()
3.79 + {
3.80 + return (outptr - outbase);
3.81 + }
3.82 + inline void set_outputpos(jitoffs_t offs)
3.83 + {
3.84 + outptr = outbase + offs;
3.85 + }
3.86 + inline jitoffs_t get_inputpos()
3.87 + {
3.88 + return (jitoffs_t)((char *)inptr - (char *)inbase);
3.89 + }
3.90 +public:
3.91 + cell_t *inptr; /* input pointer */
3.92 + cell_t *inbase; /* input base */
3.93 + jitcode_t outbase; /* output pointer */
3.94 + jitcode_t outptr; /* output base */
3.95 + SourcePawn::ICompilation *data; /* compiler live info */
3.96 +};
3.97 +
3.98 +#endif //_INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/sourcepawn/jit/x86/dll_exports.cpp Wed Nov 08 06:24:28 2006 +0000
4.3 @@ -0,0 +1,33 @@
4.4 +#include <sp_vm_api.h>
4.5 +#include "jit_x86.h"
4.6 +#include "dll_exports.h"
4.7 +
4.8 +SourcePawn::ISourcePawnEngine *engine = NULL;
4.9 +JITX86 jit;
4.10 +
4.11 +EXPORTFUNC void GiveEnginePointer(SourcePawn::ISourcePawnEngine *engine_p)
4.12 +{
4.13 + engine = engine_p;
4.14 +}
4.15 +
4.16 +EXPORTFUNC unsigned int GetExportCount()
4.17 +{
4.18 + return 1;
4.19 +}
4.20 +
4.21 +EXPORTFUNC SourcePawn::IVirtualMachine *GetExport(unsigned int exportnum)
4.22 +{
4.23 + /* Don't return anything if we're not initialized yet */
4.24 + if (!engine)
4.25 + {
4.26 + return NULL;
4.27 + }
4.28 +
4.29 + /* We only have one export - 0 */
4.30 + if (exportnum)
4.31 + {
4.32 + return NULL;
4.33 + }
4.34 +
4.35 + return &jit;
4.36 +}
5.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
5.2 +++ b/sourcepawn/jit/x86/dll_exports.h Wed Nov 08 06:24:28 2006 +0000
5.3 @@ -0,0 +1,16 @@
5.4 +#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
5.5 +#define _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
5.6 +
5.7 +#include <sp_vm_base.h>
5.8 +
5.9 +#if defined WIN32
5.10 +#define EXPORTFUNC extern "C" __declspec(dllexport)
5.11 +#elif defined __GNUC__
5.12 +#if __GNUC__ >= 3
5.13 +#define EXPORTFUNC extern "C" __attribute__((visibility("default")))
5.14 +#else
5.15 +#define EXPORTFUNC extern "C"
5.16 +#endif //__GNUC__ >= 3
5.17 +#endif //defined __GNUC__
5.18 +
5.19 +#endif //_INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
6.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
6.2 +++ b/sourcepawn/jit/x86/jit_x86.cpp Wed Nov 08 06:24:28 2006 +0000
6.3 @@ -0,0 +1,2165 @@
6.4 +#include <string.h>
6.5 +#include <stdlib.h>
6.6 +#include <assert.h>
6.7 +#include "jit_x86.h"
6.8 +#include "opcode_helpers.h"
6.9 +#include "x86_macros.h"
6.10 +
6.11 +#if defined USE_UNGEN_OPCODES
6.12 +#include "ungen_opcodes.h"
6.13 +#endif
6.14 +
6.15 +inline void WriteOp_Move_Pri(JitWriter *jit)
6.16 +{
6.17 + //mov eax, edx
6.18 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.19 +}
6.20 +
6.21 +inline void WriteOp_Move_Alt(JitWriter *jit)
6.22 +{
6.23 + //mov edx, eax
6.24 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_PRI, MOD_REG);
6.25 +}
6.26 +
6.27 +inline void WriteOp_Xchg(JitWriter *jit)
6.28 +{
6.29 + //xchg eax, edx
6.30 + IA32_Xchg_Eax_Reg(jit, AMX_REG_ALT);
6.31 +}
6.32 +
6.33 +inline void WriteOp_Push(JitWriter *jit)
6.34 +{
6.35 + //push stack, DAT offset based
6.36 + //sub edi, 4
6.37 + //mov ecx, [ebp+<val>]
6.38 + //mov [edi], ecx
6.39 + cell_t val = jit->read_cell();
6.40 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.41 + //optimize encoding a bit...
6.42 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.43 + {
6.44 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
6.45 + } else {
6.46 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
6.47 + }
6.48 + IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
6.49 +}
6.50 +
6.51 +inline void WriteOp_Push_C(JitWriter *jit)
6.52 +{
6.53 + //push stack
6.54 + //mov [edi-4], <val>
6.55 + //sub edi, 4
6.56 + cell_t val = jit->read_cell();
6.57 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, val, -4);
6.58 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.59 +}
6.60 +
6.61 +inline void WriteOp_Zero(JitWriter *jit)
6.62 +{
6.63 + //mov [ebp+<val>], 0
6.64 + cell_t val = jit->read_cell();
6.65 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.66 + {
6.67 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, 0, (jit_int8_t)val);
6.68 + } else {
6.69 + IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, 0, val);
6.70 + }
6.71 +}
6.72 +
6.73 +inline void WriteOp_Zero_S(JitWriter *jit)
6.74 +{
6.75 + //mov [ebx+<val>], 0
6.76 + cell_t val = jit->read_cell();
6.77 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.78 + {
6.79 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, 0, (jit_int8_t)val);
6.80 + } else {
6.81 + IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, 0, val);
6.82 + }
6.83 +}
6.84 +
6.85 +inline void WriteOp_Push_S(JitWriter *jit)
6.86 +{
6.87 + //push stack, FRM offset based
6.88 + //sub edi, 4
6.89 + //mov ecx, [ebx+<val>]
6.90 + //mov [edi], ecx
6.91 + cell_t val = jit->read_cell();
6.92 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.93 + //optimize encoding a bit...
6.94 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.95 + {
6.96 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
6.97 + } else {
6.98 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
6.99 + }
6.100 + IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
6.101 +}
6.102 +
6.103 +inline void WriteOp_Push_Pri(JitWriter *jit)
6.104 +{
6.105 + //mov [edi-4], eax
6.106 + //sub edi, 4
6.107 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_PRI, -4);
6.108 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.109 +}
6.110 +
6.111 +inline void WriteOp_Push_Alt(JitWriter *jit)
6.112 +{
6.113 + //mov [edi-4], edx
6.114 + //sub edi, 4
6.115 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_ALT, -4);
6.116 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.117 +}
6.118 +
6.119 +inline void WriteOp_Push2_C(JitWriter *jit)
6.120 +{
6.121 + Macro_PushN_C(jit, 2);
6.122 +}
6.123 +
6.124 +inline void WriteOp_Push3_C(JitWriter *jit)
6.125 +{
6.126 + Macro_PushN_C(jit, 3);
6.127 +}
6.128 +
6.129 +inline void WriteOp_Push4_C(JitWriter *jit)
6.130 +{
6.131 + Macro_PushN_C(jit, 4);
6.132 +}
6.133 +
6.134 +inline void WriteOp_Push5_C(JitWriter *jit)
6.135 +{
6.136 + Macro_PushN_C(jit, 5);
6.137 +}
6.138 +
6.139 +inline void WriteOp_Push2_Adr(JitWriter *jit)
6.140 +{
6.141 + Macro_PushN_Addr(jit, 2);
6.142 +}
6.143 +
6.144 +inline void WriteOp_Push3_Adr(JitWriter *jit)
6.145 +{
6.146 + Macro_PushN_Addr(jit, 3);
6.147 +}
6.148 +
6.149 +inline void WriteOp_Push4_Adr(JitWriter *jit)
6.150 +{
6.151 + Macro_PushN_Addr(jit, 4);
6.152 +}
6.153 +
6.154 +inline void WriteOp_Push5_Adr(JitWriter *jit)
6.155 +{
6.156 + Macro_PushN_Addr(jit, 5);
6.157 +}
6.158 +
6.159 +inline void WriteOp_Push2_S(JitWriter *jit)
6.160 +{
6.161 + Macro_PushN_S(jit, 2);
6.162 +}
6.163 +
6.164 +inline void WriteOp_Push3_S(JitWriter *jit)
6.165 +{
6.166 + Macro_PushN_S(jit, 3);
6.167 +}
6.168 +
6.169 +inline void WriteOp_Push4_S(JitWriter *jit)
6.170 +{
6.171 + Macro_PushN_S(jit, 4);
6.172 +}
6.173 +
6.174 +inline void WriteOp_Push5_S(JitWriter *jit)
6.175 +{
6.176 + Macro_PushN_S(jit, 5);
6.177 +}
6.178 +
6.179 +inline void WriteOp_Push5(JitWriter *jit)
6.180 +{
6.181 + Macro_PushN(jit, 5);
6.182 +}
6.183 +
6.184 +inline void WriteOp_Push4(JitWriter *jit)
6.185 +{
6.186 + Macro_PushN(jit, 4);
6.187 +}
6.188 +
6.189 +inline void WriteOp_Push3(JitWriter *jit)
6.190 +{
6.191 + Macro_PushN(jit, 3);
6.192 +}
6.193 +
6.194 +inline void WriteOp_Push2(JitWriter *jit)
6.195 +{
6.196 + Macro_PushN(jit, 2);
6.197 +}
6.198 +
6.199 +inline void WriteOp_Zero_Pri(JitWriter *jit)
6.200 +{
6.201 + //xor eax, eax
6.202 + IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
6.203 +}
6.204 +
6.205 +inline void WriteOp_Zero_Alt(JitWriter *jit)
6.206 +{
6.207 + //xor edx, edx
6.208 + IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
6.209 +}
6.210 +
6.211 +inline void WriteOp_Add(JitWriter *jit)
6.212 +{
6.213 + //add eax, edx
6.214 + IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.215 +}
6.216 +
6.217 +inline void WriteOp_Sub(JitWriter *jit)
6.218 +{
6.219 + //sub eax, edx
6.220 + IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.221 +}
6.222 +
6.223 +inline void WriteOp_Sub_Alt(JitWriter *jit)
6.224 +{
6.225 + //neg eax
6.226 + //add eax, edx
6.227 + IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
6.228 + IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.229 +}
6.230 +
6.231 +inline void WriteOp_Proc(JitWriter *jit)
6.232 +{
6.233 + /* align this to four byte boundaries!
6.234 + * This is a decent optimization - x86 likes calls to be properly aligned, otherwise there's an alignment exception
6.235 + * Since all calls are jumped to by relocation, the nops/garbage will never be hit by the runtime process.
6.236 + * Just in case, we guard this memory with INT3 to break into the debugger.
6.237 + */
6.238 + jitoffs_t cur_offs = jit->get_outputpos();
6.239 + if (cur_offs % 4)
6.240 + {
6.241 + cur_offs = 4 - (cur_offs % 4);
6.242 + for (unsigned int i=0; i<cur_offs; i++)
6.243 + {
6.244 + jit->write_ubyte(IA32_INT3);
6.245 + }
6.246 + /* add this amt to the offset we relocated */
6.247 + jitoffs_t offs = jit->get_inputpos() - sizeof(cell_t);
6.248 + jitcode_t rebase = ((CompData *)jit->data)->rebase;
6.249 + *(jitoffs_t *)((unsigned char *)rebase + offs) = jit->get_outputpos();
6.250 + }
6.251 + //push old frame on stack:
6.252 + //mov ecx, [esi+frm]
6.253 + //mov [edi-4], ecx
6.254 + //sub edi, 8 ;extra un-used slot for non-existant CIP
6.255 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_INFO, MOD_MEM_REG);
6.256 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4);
6.257 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
6.258 + //save frame:
6.259 + //mov ecx, edi - get new frame
6.260 + //mov ebx, edi - store frame back
6.261 + //sub ecx, ebp - relocate local frame
6.262 + //mov [esi+frm], ecx
6.263 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
6.264 + IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
6.265 + IA32_Sub_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
6.266 + IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_TMP, MOD_MEM_REG);
6.267 +}
6.268 +
6.269 +inline void WriteOp_Lidx_B(JitWriter *jit)
6.270 +{
6.271 + cell_t val = jit->read_cell();
6.272 + //shl eax, <val>
6.273 + //add eax, edx
6.274 + //mov eax, [ebp+eax]
6.275 + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
6.276 + IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.277 + Write_Check_VerifyAddr(jit, AMX_REG_PRI);
6.278 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.279 +}
6.280 +
6.281 +inline void WriteOp_Idxaddr_B(JitWriter *jit)
6.282 +{
6.283 + //shl eax, <val>
6.284 + //add eax, edx
6.285 + cell_t val = jit->read_cell();
6.286 + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
6.287 + IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.288 +}
6.289 +
6.290 +inline void WriteOp_Shl(JitWriter *jit)
6.291 +{
6.292 + //mov ecx, edx
6.293 + //shl eax, cl
6.294 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
6.295 + IA32_Shl_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
6.296 +}
6.297 +
6.298 +inline void WriteOp_Shr(JitWriter *jit)
6.299 +{
6.300 + //mov ecx, edx
6.301 + //shr eax, cl
6.302 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
6.303 + IA32_Shr_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
6.304 +}
6.305 +
6.306 +inline void WriteOp_Sshr(JitWriter *jit)
6.307 +{
6.308 + //mov ecx, edx
6.309 + //sar eax, cl
6.310 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
6.311 + IA32_Sar_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
6.312 +}
6.313 +
6.314 +inline void WriteOp_Shl_C_Pri(JitWriter *jit)
6.315 +{
6.316 + //shl eax, <val>
6.317 + jit_uint8_t val = (jit_uint8_t)jit->read_cell();
6.318 + if (val == 1)
6.319 + {
6.320 + IA32_Shl_Rm_1(jit, AMX_REG_PRI, MOD_REG);
6.321 + } else {
6.322 + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG);
6.323 + }
6.324 +}
6.325 +
6.326 +inline void WriteOp_Shl_C_Alt(JitWriter *jit)
6.327 +{
6.328 + //shl edx, <val>
6.329 + jit_uint8_t val = (jit_uint8_t)jit->read_cell();
6.330 + if (val == 1)
6.331 + {
6.332 + IA32_Shl_Rm_1(jit, AMX_REG_ALT, MOD_REG);
6.333 + } else {
6.334 + IA32_Shl_Rm_Imm8(jit, AMX_REG_ALT, val, MOD_REG);
6.335 + }
6.336 +}
6.337 +
6.338 +inline void WriteOp_Shr_C_Pri(JitWriter *jit)
6.339 +{
6.340 + //shr eax, <val>
6.341 + jit_uint8_t val = (jit_uint8_t)jit->read_cell();
6.342 + if (val == 1)
6.343 + {
6.344 + IA32_Shr_Rm_1(jit, AMX_REG_PRI, MOD_REG);
6.345 + } else {
6.346 + IA32_Shr_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG);
6.347 + }
6.348 +}
6.349 +
6.350 +inline void WriteOp_Shr_C_Alt(JitWriter *jit)
6.351 +{
6.352 + //shr edx, <val>
6.353 + jit_uint8_t val = (jit_uint8_t)jit->read_cell();
6.354 + if (val == 1)
6.355 + {
6.356 + IA32_Shr_Rm_1(jit, AMX_REG_ALT, MOD_REG);
6.357 + } else {
6.358 + IA32_Shr_Rm_Imm8(jit, AMX_REG_ALT, val, MOD_REG);
6.359 + }
6.360 +}
6.361 +
6.362 +inline void WriteOp_SMul(JitWriter *jit)
6.363 +{
6.364 + //mov ecx, edx
6.365 + //imul edx
6.366 + //mov edx, ecx
6.367 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
6.368 + IA32_IMul_Rm(jit, AMX_REG_ALT, MOD_REG);
6.369 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
6.370 +}
6.371 +
6.372 +inline void WriteOp_Not(JitWriter *jit)
6.373 +{
6.374 + //test eax, eax
6.375 + //mov eax, 0
6.376 + //sete al
6.377 + IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
6.378 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.379 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
6.380 +}
6.381 +
6.382 +inline void WriteOp_Neg(JitWriter *jit)
6.383 +{
6.384 + //neg eax
6.385 + IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
6.386 +}
6.387 +
6.388 +inline void WriteOp_Xor(JitWriter *jit)
6.389 +{
6.390 + //xor eax, edx
6.391 + IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.392 +}
6.393 +
6.394 +inline void WriteOp_Or(JitWriter *jit)
6.395 +{
6.396 + //or eax, edx
6.397 + IA32_Or_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.398 +}
6.399 +
6.400 +inline void WriteOp_And(JitWriter *jit)
6.401 +{
6.402 + //and eax, edx
6.403 + IA32_And_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.404 +}
6.405 +
6.406 +inline void WriteOp_Invert(JitWriter *jit)
6.407 +{
6.408 + //not eax
6.409 + IA32_Not_Rm(jit, AMX_REG_PRI, MOD_REG);
6.410 +}
6.411 +
6.412 +inline void WriteOp_Add_C(JitWriter *jit)
6.413 +{
6.414 + //add eax, <val>
6.415 + cell_t val = jit->read_cell();
6.416 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.417 + IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, (jit_int8_t)val, MOD_REG);
6.418 + else
6.419 + IA32_Add_Eax_Imm32(jit, val);
6.420 +}
6.421 +
6.422 +inline void WriteOp_SMul_C(JitWriter *jit)
6.423 +{
6.424 + //imul eax, <val>
6.425 + cell_t val = jit->read_cell();
6.426 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.427 + IA32_IMul_Reg_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
6.428 + else
6.429 + IA32_IMul_Reg_Imm32(jit, AMX_REG_PRI, MOD_REG, val);
6.430 +}
6.431 +
6.432 +inline void WriteOp_Sign_Pri(JitWriter *jit)
6.433 +{
6.434 + //shl eax, 24
6.435 + //sar eax, 24
6.436 + IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, 24, MOD_REG);
6.437 + IA32_Sar_Rm_Imm8(jit, AMX_REG_PRI, 24, MOD_REG);
6.438 +}
6.439 +
6.440 +inline void WriteOp_Sign_Alt(JitWriter *jit)
6.441 +{
6.442 + //shl edx, 24
6.443 + //sar edx, 24
6.444 + IA32_Shl_Rm_Imm8(jit, AMX_REG_ALT, 24, MOD_REG);
6.445 + IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 24, MOD_REG);
6.446 +}
6.447 +
6.448 +inline void WriteOp_Eq(JitWriter *jit)
6.449 +{
6.450 + //cmp eax, edx ; PRI == ALT ?
6.451 + //mov eax, 0
6.452 + //sete al
6.453 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.454 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.455 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
6.456 +}
6.457 +
6.458 +inline void WriteOp_Neq(JitWriter *jit)
6.459 +{
6.460 + //cmp eax, edx ; PRI != ALT ?
6.461 + //mov eax, 0
6.462 + //setne al
6.463 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.464 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.465 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_NE);
6.466 +}
6.467 +
6.468 +inline void WriteOp_Sless(JitWriter *jit)
6.469 +{
6.470 + //cmp eax, edx ; PRI < ALT ? (signed)
6.471 + //mov eax, 0
6.472 + //setl al
6.473 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.474 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.475 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_L);
6.476 +}
6.477 +
6.478 +inline void WriteOp_Sleq(JitWriter *jit)
6.479 +{
6.480 + //cmp eax, edx ; PRI <= ALT ? (signed)
6.481 + //mov eax, 0
6.482 + //setle al
6.483 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.484 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.485 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_LE);
6.486 +}
6.487 +
6.488 +inline void WriteOp_Sgrtr(JitWriter *jit)
6.489 +{
6.490 + //cmp eax, edx ; PRI > ALT ? (signed)
6.491 + //mov eax, 0
6.492 + //setg al
6.493 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.494 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.495 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_G);
6.496 +}
6.497 +
6.498 +inline void WriteOp_Sgeq(JitWriter *jit)
6.499 +{
6.500 + //cmp eax, edx ; PRI >= ALT ? (signed)
6.501 + //mov eax, 0
6.502 + //setge al
6.503 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.504 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.505 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_GE);
6.506 +}
6.507 +
6.508 +inline void WriteOp_Eq_C_Pri(JitWriter *jit)
6.509 +{
6.510 + //cmp eax, <val> ; PRI == value ?
6.511 + //mov eax, 0
6.512 + //sete al
6.513 + cell_t val = jit->read_cell();
6.514 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.515 + IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
6.516 + else
6.517 + IA32_Cmp_Eax_Imm32(jit, val);
6.518 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
6.519 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
6.520 +}
6.521 +
6.522 +inline void WriteOp_Eq_C_Alt(JitWriter *jit)
6.523 +{
6.524 + //xor eax, eax
6.525 + //cmp edx, <val> ; ALT == value ?
6.526 + //sete al
6.527 + cell_t val = jit->read_cell();
6.528 + IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
6.529 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.530 + IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_ALT, (jit_int8_t)val);
6.531 + else
6.532 + IA32_Cmp_Rm_Imm32(jit, MOD_REG, AMX_REG_ALT, val);
6.533 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
6.534 +}
6.535 +
6.536 +inline void WriteOp_Inc_Pri(JitWriter *jit)
6.537 +{
6.538 + //add eax, 1
6.539 + IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, 1, MOD_REG);
6.540 +}
6.541 +
6.542 +inline void WriteOp_Inc_Alt(JitWriter *jit)
6.543 +{
6.544 + //add edx, 1
6.545 + IA32_Add_Rm_Imm8(jit, AMX_REG_ALT, 1, MOD_REG);
6.546 +}
6.547 +
6.548 +inline void WriteOp_Inc(JitWriter *jit)
6.549 +{
6.550 + //add [ebp+<val>], 1
6.551 + cell_t val = jit->read_cell();
6.552 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.553 + IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_DAT, 1, (jit_int8_t)val);
6.554 + else
6.555 + IA32_Add_Rm_Imm8_Disp32(jit, AMX_REG_DAT, 1, val);
6.556 +}
6.557 +
6.558 +inline void WriteOp_Inc_S(JitWriter *jit)
6.559 +{
6.560 + //add [ebx+<val>], 1
6.561 + cell_t val = jit->read_cell();
6.562 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.563 + IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_FRM, 1, (jit_int8_t)val);
6.564 + else
6.565 + IA32_Add_Rm_Imm8_Disp32(jit, AMX_REG_FRM, 1, val);
6.566 +}
6.567 +
6.568 +inline void WriteOp_Inc_I(JitWriter *jit)
6.569 +{
6.570 + //add [ebp+eax], 1
6.571 + IA32_Add_RmEBP_Imm8_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_PRI, NOSCALE, 1);
6.572 +}
6.573 +
6.574 +inline void WriteOp_Dec_Pri(JitWriter *jit)
6.575 +{
6.576 + //sub eax, 1
6.577 + IA32_Sub_Rm_Imm8(jit, AMX_REG_PRI, 1, MOD_REG);
6.578 +}
6.579 +
6.580 +inline void WriteOp_Dec_Alt(JitWriter *jit)
6.581 +{
6.582 + //sub edx, 1
6.583 + IA32_Sub_Rm_Imm8(jit, AMX_REG_ALT, 1, MOD_REG);
6.584 +}
6.585 +
6.586 +inline void WriteOp_Dec(JitWriter *jit)
6.587 +{
6.588 + //sub [ebp+<val>], 1
6.589 + cell_t val = jit->read_cell();
6.590 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.591 + {
6.592 + IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_DAT, 1, (jit_int8_t)val);
6.593 + } else {
6.594 + IA32_Sub_Rm_Imm8_Disp32(jit, AMX_REG_DAT, 1, val);
6.595 + }
6.596 +}
6.597 +
6.598 +inline void WriteOp_Dec_S(JitWriter *jit)
6.599 +{
6.600 + //sub [ebx+<val>], 1
6.601 + cell_t val = jit->read_cell();
6.602 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.603 + {
6.604 + IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_FRM, 1, (jit_int8_t)val);
6.605 + } else {
6.606 + IA32_Sub_Rm_Imm8_Disp32(jit, AMX_REG_FRM, 1, val);
6.607 + }
6.608 +}
6.609 +
6.610 +inline void WriteOp_Dec_I(JitWriter *jit)
6.611 +{
6.612 + //sub [ebp+eax], 1
6.613 + IA32_Sub_RmEBP_Imm8_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_PRI, NOSCALE, 1);
6.614 +}
6.615 +
6.616 +inline void WriteOp_Load_Pri(JitWriter *jit)
6.617 +{
6.618 + //mov eax, [ebp+<val>]
6.619 + cell_t val = jit->read_cell();
6.620 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.621 + {
6.622 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_DAT, (jit_int8_t)val);
6.623 + } else {
6.624 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
6.625 + }
6.626 +}
6.627 +
6.628 +inline void WriteOp_Load_Alt(JitWriter *jit)
6.629 +{
6.630 + //mov edx, [ebp+<val>]
6.631 + cell_t val = jit->read_cell();
6.632 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.633 + {
6.634 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_DAT, (jit_int8_t)val);
6.635 + } else {
6.636 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
6.637 + }
6.638 +}
6.639 +
6.640 +inline void WriteOp_Load_S_Pri(JitWriter *jit)
6.641 +{
6.642 + //mov eax, [ebx+<val>]
6.643 + cell_t val = jit->read_cell();
6.644 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.645 + {
6.646 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_FRM, (jit_int8_t)val);
6.647 + } else {
6.648 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
6.649 + }
6.650 +}
6.651 +
6.652 +inline void WriteOp_Load_S_Alt(JitWriter *jit)
6.653 +{
6.654 + //mov edx, [ebx+<val>]
6.655 + cell_t val = jit->read_cell();
6.656 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.657 + {
6.658 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_FRM, (jit_int8_t)val);
6.659 + } else {
6.660 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
6.661 + }
6.662 +}
6.663 +
6.664 +inline void WriteOp_Lref_Pri(JitWriter *jit)
6.665 +{
6.666 + //mov eax, [ebp+<val>]
6.667 + //mov eax, [ebp+eax]
6.668 + cell_t val = jit->read_cell();
6.669 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.670 + {
6.671 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_DAT, (jit_int8_t)val);
6.672 + } else {
6.673 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
6.674 + }
6.675 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.676 +}
6.677 +
6.678 +inline void WriteOp_Lref_Alt(JitWriter *jit)
6.679 +{
6.680 + //mov edx, [ebp+<val>]
6.681 + //mov edx, [ebp+edx]
6.682 + cell_t val = jit->read_cell();
6.683 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.684 + {
6.685 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_DAT, (jit_int8_t)val);
6.686 + } else {
6.687 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
6.688 + }
6.689 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
6.690 +}
6.691 +
6.692 +inline void WriteOp_Lref_S_Pri(JitWriter *jit)
6.693 +{
6.694 + //mov eax, [ebx+<val>]
6.695 + //mov eax, [ebp+eax]
6.696 + cell_t val = jit->read_cell();
6.697 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.698 + {
6.699 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_FRM, (jit_int8_t)val);
6.700 + } else {
6.701 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
6.702 + }
6.703 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.704 +}
6.705 +
6.706 +inline void WriteOp_Lref_S_Alt(JitWriter *jit)
6.707 +{
6.708 + //mov edx, [ebx+<val>]
6.709 + //mov edx, [ebp+edx]
6.710 + cell_t val = jit->read_cell();
6.711 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.712 + {
6.713 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_FRM, (jit_int8_t)val);
6.714 + } else {
6.715 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
6.716 + }
6.717 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
6.718 +}
6.719 +
6.720 +inline void WriteOp_Const_Pri(JitWriter *jit)
6.721 +{
6.722 + //mov eax, <val>
6.723 + cell_t val = jit->read_cell();
6.724 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, val);
6.725 +}
6.726 +
6.727 +inline void WriteOp_Const_Alt(JitWriter *jit)
6.728 +{
6.729 + //mov edx, <val>
6.730 + cell_t val = jit->read_cell();
6.731 + IA32_Mov_Reg_Imm32(jit, AMX_REG_ALT, val);
6.732 +}
6.733 +
6.734 +inline void WriteOp_Addr_Pri(JitWriter *jit)
6.735 +{
6.736 + //mov eax, [esi+frm]
6.737 + //add eax, <val>
6.738 + cell_t val = jit->read_cell();
6.739 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
6.740 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.741 + {
6.742 + IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, (jit_int8_t)val, MOD_REG);
6.743 + } else {
6.744 + IA32_Add_Eax_Imm32(jit, val);
6.745 + }
6.746 +}
6.747 +
6.748 +inline void WriteOp_Addr_Alt(JitWriter *jit)
6.749 +{
6.750 + //mov edx, [esi+frm]
6.751 + //add edx, <val>
6.752 + cell_t val = jit->read_cell();
6.753 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_INFO, MOD_MEM_REG);
6.754 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.755 + {
6.756 + IA32_Add_Rm_Imm8(jit, AMX_REG_ALT, (jit_int8_t)val, MOD_REG);
6.757 + } else {
6.758 + IA32_Add_Rm_Imm32(jit, AMX_REG_ALT, val, MOD_REG);
6.759 + }
6.760 +}
6.761 +
6.762 +inline void WriteOp_Stor_Pri(JitWriter *jit)
6.763 +{
6.764 + //mov [ebp+<val>], eax
6.765 + cell_t val = jit->read_cell();
6.766 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.767 + {
6.768 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_DAT, AMX_REG_PRI, (jit_int8_t)val);
6.769 + } else {
6.770 + IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_DAT, AMX_REG_PRI, val);
6.771 + }
6.772 +}
6.773 +
6.774 +inline void WriteOp_Stor_Alt(JitWriter *jit)
6.775 +{
6.776 + //mov [ebp+<val>], edx
6.777 + cell_t val = jit->read_cell();
6.778 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.779 + {
6.780 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_DAT, AMX_REG_ALT, (jit_int8_t)val);
6.781 + } else {
6.782 + IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_DAT, AMX_REG_ALT, val);
6.783 + }
6.784 +}
6.785 +
6.786 +inline void WriteOp_Stor_S_Pri(JitWriter *jit)
6.787 +{
6.788 + //mov [ebx+<val>], eax
6.789 + cell_t val = jit->read_cell();
6.790 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.791 + {
6.792 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_FRM, AMX_REG_PRI, (jit_int8_t)val);
6.793 + } else {
6.794 + IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_FRM, AMX_REG_PRI, val);
6.795 + }
6.796 +}
6.797 +
6.798 +inline void WriteOp_Stor_S_Alt(JitWriter *jit)
6.799 +{
6.800 + //mov [ebx+<val>], edx
6.801 + cell_t val = jit->read_cell();
6.802 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.803 + {
6.804 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_FRM, AMX_REG_ALT, (jit_int8_t)val);
6.805 + } else {
6.806 + IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_FRM, AMX_REG_ALT, val);
6.807 + }
6.808 +}
6.809 +
6.810 +inline void WriteOp_Idxaddr(JitWriter *jit)
6.811 +{
6.812 + //lea eax, [edx+4*eax]
6.813 + IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
6.814 +}
6.815 +
6.816 +inline void WriteOp_Sref_Pri(JitWriter *jit)
6.817 +{
6.818 + //mov ecx, [ebp+<val>]
6.819 + //mov [ebp+ecx], eax
6.820 + cell_t val = jit->read_cell();
6.821 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.822 + {
6.823 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
6.824 + } else {
6.825 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
6.826 + }
6.827 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
6.828 +}
6.829 +
6.830 +inline void WriteOp_Sref_Alt(JitWriter *jit)
6.831 +{
6.832 + //mov ecx, [ebp+<val>]
6.833 + //mov [ebp+ecx], edx
6.834 + cell_t val = jit->read_cell();
6.835 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.836 + {
6.837 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
6.838 + } else {
6.839 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
6.840 + }
6.841 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
6.842 +}
6.843 +
6.844 +inline void WriteOp_Sref_S_Pri(JitWriter *jit)
6.845 +{
6.846 + //mov ecx, [ebx+<val>]
6.847 + //mov [ebp+ecx], eax
6.848 + cell_t val = jit->read_cell();
6.849 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.850 + {
6.851 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
6.852 + } else {
6.853 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
6.854 + }
6.855 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
6.856 +}
6.857 +
6.858 +inline void WriteOp_Sref_S_Alt(JitWriter *jit)
6.859 +{
6.860 + //mov ecx, [ebx+<val>]
6.861 + //mov [ebp+ecx], edx
6.862 + cell_t val = jit->read_cell();
6.863 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.864 + {
6.865 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
6.866 + } else {
6.867 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
6.868 + }
6.869 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
6.870 +}
6.871 +
6.872 +inline void WriteOp_Pop_Pri(JitWriter *jit)
6.873 +{
6.874 + //mov eax, [edi]
6.875 + //add edi, 4
6.876 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_MEM_REG);
6.877 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.878 +}
6.879 +
6.880 +inline void WriteOp_Pop_Alt(JitWriter *jit)
6.881 +{
6.882 + //mov edx, [edi]
6.883 + //add edi, 4
6.884 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_MEM_REG);
6.885 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.886 +}
6.887 +
6.888 +inline void WriteOp_Swap_Pri(JitWriter *jit)
6.889 +{
6.890 + //add [edi], eax
6.891 + //sub eax, [edi]
6.892 + //add [edi], eax
6.893 + //neg eax
6.894 + IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_PRI, MOD_MEM_REG);
6.895 + IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_MEM_REG);
6.896 + IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_PRI, MOD_MEM_REG);
6.897 + IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
6.898 +}
6.899 +
6.900 +inline void WriteOp_Swap_Alt(JitWriter *jit)
6.901 +{
6.902 + //add [edi], edx
6.903 + //sub edx, [edi]
6.904 + //add [edi], edx
6.905 + //neg edx
6.906 + IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
6.907 + IA32_Sub_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_MEM_REG);
6.908 + IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
6.909 + IA32_Neg_Rm(jit, AMX_REG_ALT, MOD_REG);
6.910 +}
6.911 +
6.912 +inline void WriteOp_PushAddr(JitWriter *jit)
6.913 +{
6.914 + //mov ecx, [esi+frm] ;get address (offset from frame)
6.915 + //sub edi, 4
6.916 + //add ecx, <val>
6.917 + //mov [edi], ecx
6.918 + cell_t val = jit->read_cell();
6.919 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_INFO, MOD_MEM_REG);
6.920 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.921 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.922 + {
6.923 + IA32_Add_Rm_Imm8(jit, AMX_REG_TMP, (jit_int8_t)val, MOD_REG);
6.924 + } else {
6.925 + IA32_Add_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_REG);
6.926 + }
6.927 + IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
6.928 +}
6.929 +
6.930 +inline void WriteOp_Movs(JitWriter *jit)
6.931 +{
6.932 + //cld
6.933 + //push esi
6.934 + //push edi
6.935 + //lea esi, [ebp+eax]
6.936 + //lea edi, [ebp+edx]
6.937 + //if dword:
6.938 + // mov ecx, dword
6.939 + // rep movsd
6.940 + //if byte:
6.941 + // mov ecx, byte
6.942 + // rep movsb
6.943 + //pop edi
6.944 + //pop esi
6.945 + cell_t val = jit->read_cell();
6.946 + unsigned int dwords = val >> 2;
6.947 + unsigned int bytes = val & 0x3;
6.948 +
6.949 + IA32_Cld(jit);
6.950 + IA32_Push_Reg(jit, REG_ESI);
6.951 + IA32_Push_Reg(jit, REG_EDI);
6.952 + IA32_Lea_Reg_DispEBPRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.953 + IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
6.954 + if (dwords)
6.955 + {
6.956 + IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
6.957 + IA32_Rep(jit);
6.958 + IA32_Movsd(jit);
6.959 + }
6.960 + if (bytes)
6.961 + {
6.962 + IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
6.963 + IA32_Rep(jit);
6.964 + IA32_Movsb(jit);
6.965 + }
6.966 + IA32_Pop_Reg(jit, REG_EDI);
6.967 + IA32_Pop_Reg(jit, REG_ESI);
6.968 +}
6.969 +
6.970 +inline void WriteOp_Fill(JitWriter *jit)
6.971 +{
6.972 + //push edi
6.973 + //lea edi, [ebp+edx]
6.974 + //mov ecx, <val> >> 2
6.975 + //cld
6.976 + //rep stosd
6.977 + //pop edi
6.978 + unsigned int val = jit->read_cell() >> 2;
6.979 +
6.980 + IA32_Push_Reg(jit, REG_EDI);
6.981 + IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
6.982 + IA32_Mov_Reg_Imm32(jit, REG_ECX, val);
6.983 + IA32_Cld(jit);
6.984 + IA32_Rep(jit);
6.985 + IA32_Stosd(jit);
6.986 + IA32_Pop_Reg(jit, REG_EDI);
6.987 +}
6.988 +
6.989 +inline void WriteOp_GenArray(JitWriter *jit, bool autozero)
6.990 +{
6.991 + cell_t val = jit->read_cell();
6.992 + if (val == 1)
6.993 + {
6.994 + /* flat array. we can generate this without indirection tables. */
6.995 + /* Note that we can overwrite ALT because technically STACK should be destroying ALT */
6.996 + //mov edx, [esi+info.heap]
6.997 + //mov ecx, [edi]
6.998 + //mov [edi], edx ;store base of array into stack
6.999 + //lea edx, [edx+ecx*4] ;get the final new heap pointer
6.1000 + //mov [esi+info.heap], edx ;store heap pointer back
6.1001 + //add edx, ebp ;relocate
6.1002 + //cmp edx, edi ;compare against stack pointer
6.1003 + //jae :error ;error out if not enough space
6.1004 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
6.1005 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_MEM_REG);
6.1006 + IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
6.1007 + IA32_Lea_Reg_DispRegMult(jit, AMX_REG_ALT, AMX_REG_ALT, AMX_REG_TMP, SCALE4);
6.1008 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_ALT, AMX_INFO_HEAP);
6.1009 + IA32_Add_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG);
6.1010 + IA32_Cmp_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG);
6.1011 + IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_heaplow);
6.1012 +
6.1013 + WriteOp_Tracker_Push_Reg(jit, REG_ECX);
6.1014 +
6.1015 + if (autozero)
6.1016 + {
6.1017 + /* Zero out the array - inline a quick fill */
6.1018 + //push eax ;save pri
6.1019 + //push edi ;save stk
6.1020 + //xor eax, eax ;zero source
6.1021 + //mov edi, [edi] ;get heap ptr out of the stack
6.1022 + //add edi, ebp ;relocate
6.1023 + //cld ;clear direction flag
6.1024 + //rep stosd ;copy (note: ECX is sane from above)
6.1025 + //pop edi ;pop stk
6.1026 + //pop eax ;pop pri
6.1027 + IA32_Push_Reg(jit, REG_EAX);
6.1028 + IA32_Push_Reg(jit, REG_EDI);
6.1029 + IA32_Xor_Reg_Rm(jit, REG_EAX, REG_EAX, MOD_REG);
6.1030 + IA32_Mov_Reg_Rm(jit, REG_EDI, REG_EDI, MOD_MEM_REG);
6.1031 + IA32_Add_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG);
6.1032 + IA32_Cld(jit);
6.1033 + IA32_Rep(jit);
6.1034 + IA32_Stosd(jit);
6.1035 + IA32_Pop_Reg(jit, REG_EDI);
6.1036 + IA32_Pop_Reg(jit, REG_EAX);
6.1037 + }
6.1038 + } else {
6.1039 + //mov ecx, num_dims
6.1040 + //mov edx, 0/1
6.1041 + //call [genarray]
6.1042 + IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, val);
6.1043 + if (autozero)
6.1044 + {
6.1045 + IA32_Mov_Reg_Imm32(jit, REG_EDX, 1);
6.1046 + } else {
6.1047 + IA32_Mov_Reg_Imm32(jit, REG_EDX, 0);
6.1048 + }
6.1049 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1050 + IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_genarray);
6.1051 + }
6.1052 +}
6.1053 +
6.1054 +inline void WriteOp_Load_Both(JitWriter *jit)
6.1055 +{
6.1056 + WriteOp_Load_Pri(jit);
6.1057 + WriteOp_Load_Alt(jit);
6.1058 +}
6.1059 +
6.1060 +inline void WriteOp_Load_S_Both(JitWriter *jit)
6.1061 +{
6.1062 + WriteOp_Load_S_Pri(jit);
6.1063 + WriteOp_Load_S_Alt(jit);
6.1064 +}
6.1065 +
6.1066 +inline void WriteOp_Const(JitWriter *jit)
6.1067 +{
6.1068 + //mov [ebp+<addr>], <val>
6.1069 + cell_t addr = jit->read_cell();
6.1070 + cell_t val = jit->read_cell();
6.1071 + if (addr < SCHAR_MAX && addr > SCHAR_MIN)
6.1072 + {
6.1073 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, val, (jit_int8_t)addr);
6.1074 + } else {
6.1075 + IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, val, addr);
6.1076 + }
6.1077 +}
6.1078 +
6.1079 +inline void WriteOp_Const_S(JitWriter *jit)
6.1080 +{
6.1081 + //mov [ebx+<offs>], <val>
6.1082 + cell_t offs = jit->read_cell();
6.1083 + cell_t val = jit->read_cell();
6.1084 + if (offs < SCHAR_MAX && offs > SCHAR_MIN)
6.1085 + {
6.1086 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, val, (jit_int8_t)offs);
6.1087 + } else {
6.1088 + IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, val, offs);
6.1089 + }
6.1090 +}
6.1091 +
6.1092 +inline void WriteOp_Load_I(JitWriter *jit)
6.1093 +{
6.1094 + //mov eax, [ebp+eax]
6.1095 + Write_Check_VerifyAddr(jit, AMX_REG_PRI);
6.1096 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.1097 +}
6.1098 +
6.1099 +inline void WriteOp_Lodb_I(JitWriter *jit)
6.1100 +{
6.1101 + Write_Check_VerifyAddr(jit, AMX_REG_PRI);
6.1102 +
6.1103 + //mov eax, [ebp+eax]
6.1104 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.1105 +
6.1106 + //and eax, <bitmask>
6.1107 + cell_t val = jit->read_cell();
6.1108 + switch(val)
6.1109 + {
6.1110 + case 1:
6.1111 + {
6.1112 + IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x000000FF);
6.1113 + break;
6.1114 + }
6.1115 + case 2:
6.1116 + {
6.1117 + IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF);
6.1118 + break;
6.1119 + }
6.1120 + }
6.1121 +}
6.1122 +
6.1123 +inline void WriteOp_Stor_I(JitWriter *jit)
6.1124 +{
6.1125 + //mov [ebp+edx], eax
6.1126 + Write_Check_VerifyAddr(jit, AMX_REG_ALT);
6.1127 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
6.1128 +}
6.1129 +
6.1130 +inline void WriteOp_Strb_I(JitWriter *jit)
6.1131 +{
6.1132 + Write_Check_VerifyAddr(jit, AMX_REG_ALT);
6.1133 + //mov [ebp+edx], eax
6.1134 + cell_t val = jit->read_cell();
6.1135 + switch (val)
6.1136 + {
6.1137 + case 1:
6.1138 + {
6.1139 + IA32_Mov_Rm8EBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
6.1140 + break;
6.1141 + }
6.1142 + case 2:
6.1143 + {
6.1144 + IA32_Mov_Rm16EBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
6.1145 + break;
6.1146 + }
6.1147 + case 4:
6.1148 + {
6.1149 + IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
6.1150 + break;
6.1151 + }
6.1152 + }
6.1153 +}
6.1154 +
6.1155 +inline void WriteOp_Lidx(JitWriter *jit)
6.1156 +{
6.1157 + //lea eax, [edx+4*eax]
6.1158 + //mov eax, [ebp+eax]
6.1159 + IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
6.1160 + Write_Check_VerifyAddr(jit, AMX_REG_PRI);
6.1161 + IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
6.1162 +}
6.1163 +
6.1164 +inline void WriteOp_Stack(JitWriter *jit)
6.1165 +{
6.1166 + //add edi, <val>
6.1167 + cell_t val = jit->read_cell();
6.1168 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.1169 + {
6.1170 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)val, MOD_REG);
6.1171 + } else {
6.1172 + IA32_Add_Rm_Imm32(jit, AMX_REG_STK, val, MOD_REG);
6.1173 + }
6.1174 +
6.1175 + if (val > 0)
6.1176 + {
6.1177 + Write_CheckStack_Min(jit);
6.1178 + } else if (val < 0) {
6.1179 + Write_CheckStack_Low(jit);
6.1180 + }
6.1181 +}
6.1182 +
6.1183 +inline void WriteOp_Heap(JitWriter *jit)
6.1184 +{
6.1185 + //mov edx, [esi+hea]
6.1186 + //add [esi+hea], <val>
6.1187 + cell_t val = jit->read_cell();
6.1188 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
6.1189 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.1190 + {
6.1191 + IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_INFO, (jit_int8_t)val, AMX_INFO_HEAP);
6.1192 + } else {
6.1193 + IA32_Add_Rm_Imm32_Disp8(jit, AMX_REG_INFO, val, AMX_INFO_HEAP);
6.1194 + }
6.1195 +
6.1196 + /* NOTE: Backwards from op.stack */
6.1197 + if (val > 0)
6.1198 + {
6.1199 + Write_CheckHeap_Low(jit);
6.1200 + } else if (val < 0) {
6.1201 + Write_CheckHeap_Min(jit);
6.1202 + }
6.1203 +}
6.1204 +
6.1205 +inline void WriteOp_SDiv(JitWriter *jit)
6.1206 +{
6.1207 + //mov ecx, edx
6.1208 + //mov edx, eax
6.1209 + //sar edx, 31
6.1210 + //idiv ecx
6.1211 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
6.1212 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_PRI, MOD_REG);
6.1213 + IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 31, MOD_REG);
6.1214 + Write_Check_DivZero(jit, AMX_REG_TMP);
6.1215 + IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
6.1216 +}
6.1217 +
6.1218 +inline void WriteOp_SDiv_Alt(JitWriter *jit)
6.1219 +{
6.1220 + //mov ecx, eax
6.1221 + //mov eax, edx
6.1222 + //sar edx, 31
6.1223 + //idiv ecx
6.1224 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
6.1225 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1226 + IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 31, MOD_REG);
6.1227 + Write_Check_DivZero(jit, AMX_REG_TMP);
6.1228 + IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
6.1229 +}
6.1230 +
6.1231 +inline void WriteOp_Retn(JitWriter *jit)
6.1232 +{
6.1233 + //mov ebx, [edi+4] - get old frm
6.1234 + //add edi, 8 - pop stack
6.1235 + //mov [esi+frm], ebx - restore frame pointer
6.1236 + //add ebx, ebp - relocate
6.1237 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_FRM, AMX_REG_STK, 4);
6.1238 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
6.1239 + IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_FRM, MOD_MEM_REG);
6.1240 + IA32_Add_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
6.1241 +
6.1242 + /* pop params */
6.1243 + //mov ecx, [edi]
6.1244 + //lea edi, [edi+ecx*4+4]
6.1245 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_MEM_REG);
6.1246 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, AMX_REG_TMP, SCALE4, 4);
6.1247 +
6.1248 + //ret - return (EIP on real stack!)
6.1249 + IA32_Return(jit);
6.1250 +}
6.1251 +
6.1252 +inline void WriteOp_Call(JitWriter *jit)
6.1253 +{
6.1254 + cell_t offs = jit->read_cell();
6.1255 +
6.1256 + jitoffs_t jmp = IA32_Call_Imm32(jit, 0);
6.1257 + IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
6.1258 +}
6.1259 +
6.1260 +inline void WriteOp_Bounds(JitWriter *jit)
6.1261 +{
6.1262 + cell_t val = jit->read_cell();
6.1263 +
6.1264 + //cmp eax, <val>
6.1265 + //ja :error
6.1266 + if (val < SCHAR_MAX && val > SCHAR_MIN)
6.1267 + {
6.1268 + IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
6.1269 + } else {
6.1270 + IA32_Cmp_Eax_Imm32(jit, val);
6.1271 + }
6.1272 + IA32_Jump_Cond_Imm32_Abs(jit, CC_A, ((CompData *)jit->data)->jit_error_bounds);
6.1273 +}
6.1274 +
6.1275 +inline void WriteOp_Halt(JitWriter *jit)
6.1276 +{
6.1277 + //mov ecx, [esi+ret]
6.1278 + //mov [ecx], eax
6.1279 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_RETVAL);
6.1280 + IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_MEM_REG);
6.1281 +
6.1282 + /* :TODO:
6.1283 + * We don't support sleeping or halting with weird values.
6.1284 + * So we're omitting the mov eax <val> that was here.
6.1285 + */
6.1286 + jit->read_cell();
6.1287 +
6.1288 + CompData *data = (CompData *)jit->data;
6.1289 + IA32_Jump_Imm32_Abs(jit, data->jit_return);
6.1290 +}
6.1291 +
6.1292 +inline void WriteOp_Break(JitWriter *jit)
6.1293 +{
6.1294 + CompData *data = (CompData *)jit->data;
6.1295 + if (data->debug)
6.1296 + {
6.1297 + //mov ecx, <cip>
6.1298 + jitoffs_t wr = IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, 0);
6.1299 + jitoffs_t save = jit->get_outputpos();
6.1300 + jit->set_outputpos(wr);
6.1301 + jit->write_uint32((uint32_t)(jit->outbase + wr));
6.1302 + jit->set_outputpos(save);
6.1303 +
6.1304 + wr = IA32_Call_Imm32(jit, 0);
6.1305 + IA32_Write_Jump32(jit, wr, data->jit_break);
6.1306 + }
6.1307 +}
6.1308 +
6.1309 +inline void WriteOp_Jump(JitWriter *jit)
6.1310 +{
6.1311 + //jmp <offs>
6.1312 + cell_t amx_offs = jit->read_cell();
6.1313 + IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, amx_offs, false));
6.1314 +}
6.1315 +
6.1316 +inline void WriteOp_Jzer(JitWriter *jit)
6.1317 +{
6.1318 + //test eax, eax
6.1319 + //jz <target>
6.1320 + cell_t target = jit->read_cell();
6.1321 + IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
6.1322 + IA32_Jump_Cond_Imm32_Abs(jit, CC_Z, RelocLookup(jit, target, false));
6.1323 +}
6.1324 +
6.1325 +inline void WriteOp_Jnz(JitWriter *jit)
6.1326 +{
6.1327 + //test eax, eax
6.1328 + //jnz <target>
6.1329 + cell_t target = jit->read_cell();
6.1330 + IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
6.1331 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, RelocLookup(jit, target, false));
6.1332 +}
6.1333 +
6.1334 +inline void WriteOp_Jeq(JitWriter *jit)
6.1335 +{
6.1336 + //cmp eax, edx
6.1337 + //je <target>
6.1338 + cell_t target = jit->read_cell();
6.1339 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1340 + IA32_Jump_Cond_Imm32_Abs(jit, CC_E, RelocLookup(jit, target, false));
6.1341 +}
6.1342 +
6.1343 +inline void WriteOp_Jneq(JitWriter *jit)
6.1344 +{
6.1345 + //cmp eax, edx
6.1346 + //jne <target>
6.1347 + cell_t target = jit->read_cell();
6.1348 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1349 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NE, RelocLookup(jit, target, false));
6.1350 +}
6.1351 +
6.1352 +inline void WriteOp_Jsless(JitWriter *jit)
6.1353 +{
6.1354 + //cmp eax, edx
6.1355 + //jl <target>
6.1356 + cell_t target = jit->read_cell();
6.1357 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1358 + IA32_Jump_Cond_Imm32_Abs(jit, CC_L, RelocLookup(jit, target, false));
6.1359 +}
6.1360 +
6.1361 +inline void WriteOp_Jsleq(JitWriter *jit)
6.1362 +{
6.1363 + //cmp eax, edx
6.1364 + //jle <target>
6.1365 + cell_t target = jit->read_cell();
6.1366 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1367 + IA32_Jump_Cond_Imm32_Abs(jit, CC_LE, RelocLookup(jit, target, false));
6.1368 +}
6.1369 +
6.1370 +inline void WriteOp_JsGrtr(JitWriter *jit)
6.1371 +{
6.1372 + //cmp eax, edx
6.1373 + //jg <target>
6.1374 + cell_t target = jit->read_cell();
6.1375 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1376 + IA32_Jump_Cond_Imm32_Abs(jit, CC_G, RelocLookup(jit, target, false));
6.1377 +}
6.1378 +
6.1379 +inline void WriteOp_JsGeq(JitWriter *jit)
6.1380 +{
6.1381 + //cmp eax, edx
6.1382 + //jge <target>
6.1383 + cell_t target = jit->read_cell();
6.1384 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
6.1385 + IA32_Jump_Cond_Imm32_Abs(jit, CC_GE, RelocLookup(jit, target, false));
6.1386 +}
6.1387 +
6.1388 +inline void WriteOp_Switch(JitWriter *jit)
6.1389 +{
6.1390 + cell_t offs = jit->read_cell();
6.1391 + cell_t *tbl = (cell_t *)((char *)jit->inbase + offs + sizeof(cell_t));
6.1392 +
6.1393 + struct casetbl
6.1394 + {
6.1395 + cell_t val;
6.1396 + cell_t offs;
6.1397 + };
6.1398 +
6.1399 + /* Read the number of cases, then advance by one */
6.1400 + cell_t num_cases = *tbl++;
6.1401 + if (!num_cases)
6.1402 + {
6.1403 + /* Special treatment for 0 cases */
6.1404 + //jmp <default>
6.1405 + IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, *tbl, false));
6.1406 + } else {
6.1407 + /* Check if the case layout is fully sequential */
6.1408 + casetbl *iter = (casetbl *)(tbl + 1);
6.1409 + casetbl *cases = iter;
6.1410 + cell_t first = iter[0].val;
6.1411 + cell_t last = first;
6.1412 + bool sequential = true;
6.1413 + for (cell_t i=1; i<num_cases; i++)
6.1414 + {
6.1415 + if (iter[i].val != ++last)
6.1416 + {
6.1417 + sequential = false;
6.1418 + break;
6.1419 + }
6.1420 + }
6.1421 + /* Time to generate.
6.1422 + * First check whether the bounds are correct: if (a < LOW || a > HIGH)
6.1423 + * This check is valid for both sequential and non-sequential.
6.1424 + */
6.1425 + cell_t low_bound = cases[0].val;
6.1426 + if (low_bound != 0)
6.1427 + {
6.1428 + /* negate it so we'll get a lower bound of 0 */
6.1429 + //lea ecx, [eax-<LOWER_BOUND>]
6.1430 + low_bound = -low_bound;
6.1431 + if (low_bound > SCHAR_MIN && low_bound < SCHAR_MAX)
6.1432 + {
6.1433 + IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, low_bound);
6.1434 + } else {
6.1435 + IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, low_bound);
6.1436 + }
6.1437 + }
6.1438 + cell_t high_bound = abs(cases[0].val - cases[num_cases-1].val);
6.1439 + //cmp ecx, <UPPER BOUND BOUND>
6.1440 + if (high_bound > SCHAR_MIN && high_bound < SCHAR_MAX)
6.1441 + {
6.1442 + IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_TMP, high_bound);
6.1443 + } else {
6.1444 + IA32_Cmp_Rm_Imm32(jit, MOD_REG, AMX_REG_TMP, high_bound);
6.1445 + }
6.1446 + //ja <default case>
6.1447 + IA32_Jump_Cond_Imm32_Abs(jit, CC_A, RelocLookup(jit, *tbl, false));
6.1448 +
6.1449 + /**
6.1450 + * Now we've taken the default case out of the way, it's time to do the
6.1451 + * full check, which is different for sequential vs. non-sequential.
6.1452 + */
6.1453 + if (sequential)
6.1454 + {
6.1455 + /* we're now theoretically guaranteed to be jumping to a correct offset.
6.1456 + * ECX still has the correctly bound offset in it, luckily!
6.1457 + * thus, we simply need to relocate ECX and store the cases.
6.1458 + */
6.1459 + //lea ecx, [ecx*4]
6.1460 + //add ecx, <case table start>
6.1461 + IA32_Lea_Reg_RegMultImm32(jit, AMX_REG_TMP, AMX_REG_TMP, SCALE4, 0);
6.1462 + jitoffs_t tbl_offs = IA32_Add_Rm_Imm32_Later(jit, AMX_REG_TMP, MOD_REG);
6.1463 + IA32_Jump_Rm(jit, AMX_REG_TMP, MOD_MEM_REG);
6.1464 + /* The case table starts here. Go back and write the output pointer. */
6.1465 + jitoffs_t cur_pos = jit->get_outputpos();
6.1466 + jit->set_outputpos(tbl_offs);
6.1467 + jit->write_uint32((jit_uint32_t)(jit->outbase + cur_pos));
6.1468 + jit->set_outputpos(cur_pos);
6.1469 + //now we can write the case table, finally!
6.1470 + jit_uint32_t base = (jit_uint32_t)jit->outbase;
6.1471 + for (cell_t i=0; i<num_cases; i++)
6.1472 + {
6.1473 + jit->write_uint32(base + RelocLookup(jit, cases[i].offs, false));
6.1474 + }
6.1475 + } else {
6.1476 + /* The slow version. Go through each case and generate a check.
6.1477 + * In the future we should replace case tables of more than ~8 cases with a
6.1478 + * hash table lookup.
6.1479 + * :THOUGHT: Another method of optimizing this - fill in the gaps with jumps to the default case,
6.1480 + * but only if we're under N cases or so!
6.1481 + * :THOUGHT: Write out a static btree lookup :)
6.1482 + */
6.1483 + cell_t val;
6.1484 + for (cell_t i=0; i<num_cases; i++)
6.1485 + {
6.1486 + val = cases[i].val;
6.1487 + //cmp eax, <val> OR cmp al, <val>
6.1488 + if (val > SCHAR_MIN && val < SCHAR_MAX)
6.1489 + {
6.1490 + IA32_Cmp_Al_Imm8(jit, val);
6.1491 + } else {
6.1492 + IA32_Cmp_Eax_Imm32(jit, cases[i].val);
6.1493 + }
6.1494 + IA32_Jump_Cond_Imm32_Abs(jit, CC_E, RelocLookup(jit, cases[i].offs, false));
6.1495 + }
6.1496 + /* After all this, jump to the default case! */
6.1497 + IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, *tbl, false));
6.1498 + }
6.1499 + }
6.1500 +}
6.1501 +
6.1502 +inline void WriteOp_Casetbl(JitWriter *jit)
6.1503 +{
6.1504 + /* do nothing here, switch does all ze work */
6.1505 + cell_t num_cases = jit->read_cell();
6.1506 +
6.1507 + /* Two cells per case, one extra case for the default jump */
6.1508 + num_cases = (num_cases * 2) + 1;
6.1509 + jit->inptr += num_cases;
6.1510 +}
6.1511 +
6.1512 +inline void WriteOp_Sysreq_C(JitWriter *jit)
6.1513 +{
6.1514 + /* store the number of parameters on the stack,
6.1515 + * and store the native index as well.
6.1516 + */
6.1517 + cell_t native_index = jit->read_cell();
6.1518 +
6.1519 + if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
6.1520 + {
6.1521 + ((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
6.1522 + return;
6.1523 + }
6.1524 +
6.1525 + //mov ecx, <native_index>
6.1526 + IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
6.1527 +
6.1528 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1529 + IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_c);
6.1530 +}
6.1531 +
6.1532 +inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
6.1533 +{
6.1534 + /* store the number of parameters on the stack,
6.1535 + * and store the native index as well.
6.1536 + */
6.1537 + cell_t native_index = jit->read_cell();
6.1538 + cell_t num_params = jit->read_cell();
6.1539 +
6.1540 + if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
6.1541 + {
6.1542 + ((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
6.1543 + return;
6.1544 + }
6.1545 +
6.1546 + //mov eax, <num_params>
6.1547 + //mov ecx, <native_index>
6.1548 + IA32_Mov_Reg_Imm32(jit, REG_EAX, num_params);
6.1549 + IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
6.1550 +
6.1551 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1552 + IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_n);
6.1553 +}
6.1554 +
6.1555 +inline void WriteOp_Sysreq_N(JitWriter *jit)
6.1556 +{
6.1557 + /* The big daddy of opcodes. */
6.1558 + cell_t native_index = jit->read_cell();
6.1559 + cell_t num_params = jit->read_cell();
6.1560 + CompData *data = (CompData *)jit->data;
6.1561 +
6.1562 + if ((uint32_t)native_index >= data->plugin->info.natives_num)
6.1563 + {
6.1564 + data->error_set = SP_ERROR_INSTRUCTION_PARAM;
6.1565 + return;
6.1566 + }
6.1567 +
6.1568 + /* store the number of parameters on the stack */
6.1569 + //mov [edi-4], num_params
6.1570 + //sub edi, 4
6.1571 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, num_params, -4);
6.1572 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
6.1573 +
6.1574 + /* save registers we will need */
6.1575 + //push edx
6.1576 + IA32_Push_Reg(jit, AMX_REG_ALT);
6.1577 +
6.1578 + /* push some callback stuff */
6.1579 + //push edi ; stack
6.1580 + //push <native> ; native index
6.1581 + IA32_Push_Reg(jit, AMX_REG_STK);
6.1582 + if (native_index < SCHAR_MAX && native_index > SCHAR_MIN)
6.1583 + {
6.1584 + IA32_Push_Imm8(jit, (jit_int8_t)native_index);
6.1585 + } else {
6.1586 + IA32_Push_Imm32(jit, native_index);
6.1587 + }
6.1588 +
6.1589 + /* Relocate stack, heap, frm information, then store back */
6.1590 + //mov eax, [esi+context]
6.1591 + //mov ecx, [esi+hea]
6.1592 + //sub edi, ebp
6.1593 + //mov [eax+hp], ecx
6.1594 + //mov ecx, [esi]
6.1595 + //mov [eax+sp], edi
6.1596 + //mov [eax+frm], ecx
6.1597 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
6.1598 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
6.1599 + IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
6.1600 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
6.1601 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
6.1602 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
6.1603 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
6.1604 +
6.1605 + /* finally, push the last parameter and make the call */
6.1606 + //push eax ; context
6.1607 + //call NativeCallback
6.1608 + IA32_Push_Reg(jit, REG_EAX);
6.1609 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1610 + if (!data->debug)
6.1611 + {
6.1612 + IA32_Write_Jump32_Abs(jit, call, NativeCallback);
6.1613 + } else {
6.1614 + IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
6.1615 + }
6.1616 +
6.1617 + /* check for errors */
6.1618 + //mov ecx, [esi+context]
6.1619 + //cmp [ecx+err], 0
6.1620 + //jnz :error
6.1621 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
6.1622 + IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
6.1623 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
6.1624 +
6.1625 + /* restore what we damaged */
6.1626 + //add esp, 4*3
6.1627 + //add edi, ebp
6.1628 + //pop edx
6.1629 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
6.1630 + IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
6.1631 + IA32_Pop_Reg(jit, AMX_REG_ALT);
6.1632 +
6.1633 + /* pop the stack. do not check the margins.
6.1634 + * Note that this is not a true macro - we don't bother to
6.1635 + * set ALT here because nothing will be using it.
6.1636 + */
6.1637 + num_params++;
6.1638 + num_params *= 4;
6.1639 + //add edi, <val*4+4>
6.1640 + if (num_params < SCHAR_MAX && num_params > SCHAR_MIN)
6.1641 + {
6.1642 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)num_params, MOD_REG);
6.1643 + } else {
6.1644 + IA32_Add_Rm_Imm32(jit, AMX_REG_STK, num_params, MOD_REG);
6.1645 + }
6.1646 +}
6.1647 +
6.1648 +inline void WriteOp_Tracker_Push_C(JitWriter *jit)
6.1649 +{
6.1650 + CompData *data = (CompData *)jit->data;
6.1651 + cell_t val = jit->read_cell();
6.1652 +
6.1653 + /* Save registers that may be damaged by the call */
6.1654 + //push eax
6.1655 + //push edx
6.1656 + IA32_Push_Reg(jit, AMX_REG_PRI);
6.1657 + IA32_Push_Reg(jit, AMX_REG_ALT);
6.1658 +
6.1659 + /* Get the context ptr, push it and call the check */
6.1660 + //mov eax, [esi+context]
6.1661 + //push eax
6.1662 + //call JIT_VerifyOrAllocateTracker
6.1663 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
6.1664 + IA32_Push_Reg(jit, REG_EAX);
6.1665 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1666 + IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
6.1667 +
6.1668 + /* Check for errors */
6.1669 + //pop eax
6.1670 + //cmp [eax+err], 0
6.1671 + //jnz :error
6.1672 + IA32_Pop_Reg(jit, REG_EAX);
6.1673 + IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
6.1674 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
6.1675 +
6.1676 + /* Push the value into the stack and increment pCur */
6.1677 + //mov edx, [eax+vm[]]
6.1678 + //mov ecx, [edx+pcur]
6.1679 + //add [edx+pcur], 4
6.1680 + //mov [ecx], <val>*4 ; we want the count in bytes not in cells
6.1681 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
6.1682 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
6.1683 + IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
6.1684 + IA32_Mov_Rm_Imm32(jit, AMX_REG_TMP, val*4, MOD_MEM_REG);
6.1685 +
6.1686 + /* Restore PRI & ALT */
6.1687 + //pop edx
6.1688 + //pop eax
6.1689 + IA32_Pop_Reg(jit, AMX_REG_ALT);
6.1690 + IA32_Pop_Reg(jit, AMX_REG_PRI);
6.1691 +}
6.1692 +
6.1693 +inline void WriteOp_Tracker_Pop_SetHeap(JitWriter *jit)
6.1694 +{
6.1695 + CompData *data = (CompData *)jit->data;
6.1696 +
6.1697 + /* Save registers that may be damaged by the call */
6.1698 + //push eax
6.1699 + //push edx
6.1700 + IA32_Push_Reg(jit, AMX_REG_PRI);
6.1701 + IA32_Push_Reg(jit, AMX_REG_ALT);
6.1702 +
6.1703 + /* Get the context ptr, push it and call the check */
6.1704 + //mov eax, [esi+context]
6.1705 + //push eax
6.1706 + //call JIT_VerifyLowBoundTracker
6.1707 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
6.1708 + IA32_Push_Reg(jit, REG_EAX);
6.1709 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
6.1710 + IA32_Write_Jump32_Abs(jit, call, JIT_VerifyLowBoundTracker);
6.1711 +
6.1712 + /* Check for errors */
6.1713 + //pop eax
6.1714 + //cmp [eax+err], 0
6.1715 + //jnz :error
6.1716 + IA32_Pop_Reg(jit, REG_EAX);
6.1717 + IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
6.1718 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
6.1719 +
6.1720 + /* Pop the value from the stack and decrease the heap by it*/
6.1721 + //mov edx, [eax+vm[]]
6.1722 + //sub [edx+pcur], 4
6.1723 + //mov ecx, [edx+pcur]
6.1724 + //mov ecx, [ecx]
6.1725 + //sub [esi+hea], ecx
6.1726 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
6.1727 + IA32_Sub_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
6.1728 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
6.1729 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_TMP, MOD_MEM_REG);
6.1730 + IA32_Sub_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP);
6.1731 +
6.1732 + Write_CheckHeap_Min(jit);
6.1733 +
6.1734 + /* Restore PRI & ALT */
6.1735 + //pop edx
6.1736 + //pop eax
6.1737 + IA32_Pop_Reg(jit, AMX_REG_ALT);
6.1738 + IA32_Pop_Reg(jit, AMX_REG_PRI);
6.1739 +}
6.1740 +
6.1741 +/*************************************************
6.1742 + *************************************************
6.1743 + * JIT PROPER ************************************
6.1744 + * The rest from now on is the JIT engine *
6.1745 + *************************************************
6.1746 + *************************************************/
6.1747 +
6.1748 +cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
6.1749 +{
6.1750 + sp_native_t *native = &ctx->natives[native_idx];
6.1751 +
6.1752 + /* Technically both aren't needed, I guess */
6.1753 + if (native->status == SP_NATIVE_NONE)
6.1754 + {
6.1755 + ctx->err = SP_ERROR_NATIVE_PENDING;
6.1756 + return 0;
6.1757 + }
6.1758 +
6.1759 + return native->pfn(ctx, params);
6.1760 +}
6.1761 +
6.1762 +cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
6.1763 +{
6.1764 + cell_t save_sp = ctx->sp;
6.1765 + cell_t save_hp = ctx->hp;
6.1766 +
6.1767 + if (ctx->hp < ctx->heap_base)
6.1768 + {
6.1769 + ctx->err = SP_ERROR_HEAPMIN;
6.1770 + return 0;
6.1771 + }
6.1772 +
6.1773 + if (ctx->hp + STACK_MARGIN > ctx->sp)
6.1774 + {
6.1775 + ctx->err = SP_ERROR_STACKLOW;
6.1776 + return 0;
6.1777 + }
6.1778 +
6.1779 + if ((uint32_t)ctx->sp >= ctx->mem_size)
6.1780 + {
6.1781 + ctx->err = SP_ERROR_STACKMIN;
6.1782 + return 0;
6.1783 + }
6.1784 +
6.1785 + cell_t result = NativeCallback(ctx, native_idx, params);
6.1786 +
6.1787 + if (ctx->err != SP_ERROR_NONE)
6.1788 + {
6.1789 + return result;
6.1790 + }
6.1791 +
6.1792 + if (save_sp != ctx->sp)
6.1793 + {
6.1794 + ctx->err = SP_ERROR_STACKLEAK;
6.1795 + return result;
6.1796 + } else if (save_hp != ctx->hp) {
6.1797 + ctx->err = SP_ERROR_HEAPLEAK;
6.1798 + return result;
6.1799 + }
6.1800 +
6.1801 + return result;
6.1802 +}
6.1803 +
6.1804 +jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
6.1805 +{
6.1806 + if (jit->outptr)
6.1807 + {
6.1808 + CompData *data = (CompData *)jit->data;
6.1809 + if (relative)
6.1810 + {
6.1811 + /* The actual offset is EIP relative. We need to relocate it.
6.1812 + * Note that this assumes that we're pointing to the next op.
6.1813 + */
6.1814 + pcode_offs += jit->get_inputpos();
6.1815 + }
6.1816 + /* Offset must always be 1)positive and 2)less than the codesize */
6.1817 + assert(pcode_offs >= 0 && (uint32_t)pcode_offs < data->codesize);
6.1818 + /* Do the lookup in the native dictionary. */
6.1819 + return *(jitoffs_t *)(data->rebase + pcode_offs);
6.1820 + } else {
6.1821 + return 0;
6.1822 + }
6.1823 +}
6.1824 +
6.1825 +void WriteErrorRoutines(CompData *data, JitWriter *jit)
6.1826 +{
6.1827 + data->jit_error_divzero = jit->get_outputpos();
6.1828 + Write_SetError(jit, SP_ERROR_DIVIDE_BY_ZERO);
6.1829 +
6.1830 + data->jit_error_stacklow = jit->get_outputpos();
6.1831 + Write_SetError(jit, SP_ERROR_STACKLOW);
6.1832 +
6.1833 + data->jit_error_stackmin = jit->get_outputpos();
6.1834 + Write_SetError(jit, SP_ERROR_STACKMIN);
6.1835 +
6.1836 + data->jit_error_bounds = jit->get_outputpos();
6.1837 + Write_SetError(jit, SP_ERROR_ARRAY_BOUNDS);
6.1838 +
6.1839 + data->jit_error_memaccess = jit->get_outputpos();
6.1840 + Write_SetError(jit, SP_ERROR_MEMACCESS);
6.1841 +
6.1842 + data->jit_error_heaplow = jit->get_outputpos();
6.1843 + Write_SetError(jit, SP_ERROR_HEAPLOW);
6.1844 +
6.1845 + data->jit_error_heapmin = jit->get_outputpos();
6.1846 + Write_SetError(jit, SP_ERROR_HEAPMIN);
6.1847 +
6.1848 + data->jit_error_array_too_big = jit->get_outputpos();
6.1849 + Write_SetError(jit, SP_ERROR_ARRAY_TOO_BIG);
6.1850 +
6.1851 + data->jit_error_tracker_bounds = jit->get_outputpos();
6.1852 + Write_SetError(jit, SP_ERROR_TRACKER_BOUNDS);
6.1853 +
6.1854 + data->jit_extern_error = jit->get_outputpos();
6.1855 + Write_GetError(jit);
6.1856 +}
6.1857 +
6.1858 +sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
6.1859 +{
6.1860 + CompData *data = (CompData *)co;
6.1861 + sp_plugin_t *plugin = data->plugin;
6.1862 +
6.1863 + /* The first phase is to browse */
6.1864 + uint8_t *code = plugin->pcode;
6.1865 + uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
6.1866 + OPCODE op;
6.1867 +
6.1868 + /*********************************************
6.1869 + * FIRST PASS (medium load): writer.outbase is NULL, getting size only
6.1870 + * SECOND PASS (heavy load!!): writer.outbase is valid and output is written
6.1871 + *********************************************/
6.1872 +
6.1873 + JitWriter writer;
6.1874 + JitWriter *jit = &writer;
6.1875 + cell_t *endptr = (cell_t *)(end_cip);
6.1876 +
6.1877 + /* Initial code is written "blank,"
6.1878 + * so we can check the exact memory usage.
6.1879 + */
6.1880 + data->codesize = plugin->pcode_size;
6.1881 + writer.data = data;
6.1882 + writer.inbase = (cell_t *)code;
6.1883 + writer.outptr = NULL;
6.1884 + writer.outbase = NULL;
6.1885 + data->rebase = (jitcode_t)engine->BaseAlloc(plugin->pcode_size);
6.1886 +
6.1887 + /* We will jump back here for second pass */
6.1888 +jit_rewind:
6.1889 + /* Initialize pass vars */
6.1890 + writer.inptr = writer.inbase;
6.1891 + data->jit_verify_addr_eax = 0;
6.1892 + data->jit_verify_addr_edx = 0;
6.1893 +
6.1894 + /* Write the prologue of the JIT */
6.1895 + data->jit_return = Write_Execute_Function(jit);
6.1896 +
6.1897 + /* Write the SYSREQ.N opcode if we need to */
6.1898 + if (!(data->inline_level & JIT_INLINE_NATIVES))
6.1899 + {
6.1900 + data->jit_sysreq_n = jit->get_outputpos();
6.1901 + WriteOp_Sysreq_N_Function(jit);
6.1902 + }
6.1903 +
6.1904 + /* Plugins compiled with -O0 will need this! */
6.1905 + data->jit_sysreq_c = jit->get_outputpos();
6.1906 + WriteOp_Sysreq_C_Function(jit);
6.1907 +
6.1908 + data->jit_genarray = jit->get_outputpos();
6.1909 + WriteIntrinsic_GenArray(jit);
6.1910 +
6.1911 + /* Write error checking routines that are called to */
6.1912 + if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
6.1913 + {
6.1914 + data->jit_verify_addr_eax = jit->get_outputpos();
6.1915 + Write_Check_VerifyAddr(jit, REG_EAX);
6.1916 +
6.1917 + data->jit_verify_addr_edx = jit->get_outputpos();
6.1918 + Write_Check_VerifyAddr(jit, REG_EDX);
6.1919 + }
6.1920 +
6.1921 + /* Actual code generation! */
6.1922 + if (writer.outbase == NULL)
6.1923 + {
6.1924 + /* First Pass - find codesize and resolve relocation */
6.1925 + jitoffs_t pcode_offs;
6.1926 + jitoffs_t native_offs;
6.1927 +
6.1928 + for (; writer.inptr < endptr;)
6.1929 + {
6.1930 + /* Store the native offset into the rebase memory.
6.1931 + * This large chunk of memory lets us do an instant lookup
6.1932 + * based on an original pcode offset.
6.1933 + */
6.1934 + pcode_offs = (jitoffs_t)((uint8_t *)writer.inptr - code);
6.1935 + native_offs = jit->get_outputpos();
6.1936 + *((jitoffs_t *)(data->rebase + pcode_offs)) = native_offs;
6.1937 +
6.1938 + /* Now read the opcode and continue. */
6.1939 + op = (OPCODE)writer.read_cell();
6.1940 + switch (op)
6.1941 + {
6.1942 + #include "opcode_switch.inc"
6.1943 + }
6.1944 + /* Check for errors. This should only happen in the first pass. */
6.1945 + if (data->error_set != SP_ERROR_NONE)
6.1946 + {
6.1947 + *err = data->error_set;
6.1948 + AbortCompilation(co);
6.1949 + return NULL;
6.1950 + }
6.1951 + }
6.1952 + /* Write these last because error jumps should be unpredicted, and thus forward */
6.1953 + WriteErrorRoutines(data, jit);
6.1954 +
6.1955 + /* the total codesize is now known! */
6.1956 + uint32_t mem = writer.get_outputpos();
6.1957 + writer.outbase = (jitcode_t)engine->ExecAlloc(mem);
6.1958 + writer.outptr = writer.outbase;
6.1959 + /* go back for third pass */
6.1960 + goto jit_rewind;
6.1961 + } else {
6.1962 + /*******
6.1963 + * THIRD PASS - write opcode info
6.1964 + *******/
6.1965 + for (; writer.inptr < endptr;)
6.1966 + {
6.1967 + op = (OPCODE)writer.read_cell();
6.1968 + switch (op)
6.1969 + {
6.1970 + #include "opcode_switch.inc"
6.1971 + }
6.1972 + }
6.1973 + /* Write these last because error jumps should be unpredicted, and thus forward */
6.1974 + WriteErrorRoutines(data, jit);
6.1975 + }
6.1976 +
6.1977 + /*************
6.1978 + * FOURTH PASS - Context Setup
6.1979 + *************/
6.1980 +
6.1981 + sp_context_t *ctx = new sp_context_t;
6.1982 + memset(ctx, 0, sizeof(sp_context_t));
6.1983 +
6.1984 + /* setup basics */
6.1985 + ctx->codebase = writer.outbase;
6.1986 + ctx->plugin = plugin;
6.1987 + ctx->vmbase = this;
6.1988 + ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
6.1989 +
6.1990 + /* setup memory */
6.1991 + ctx->memory = new uint8_t[plugin->memory];
6.1992 + memcpy(ctx->memory, plugin->data, plugin->data_size);
6.1993 + ctx->mem_size = plugin->memory;
6.1994 + ctx->heap_base = plugin->data_size;
6.1995 + ctx->hp = ctx->heap_base;
6.1996 + ctx->sp = ctx->mem_size - sizeof(cell_t);
6.1997 +
6.1998 + const char *strbase = plugin->info.stringbase;
6.1999 + uint32_t max, iter;
6.2000 +
6.2001 + /* relocate public info */
6.2002 + if ((max = plugin->info.publics_num))
6.2003 + {
6.2004 + ctx->publics = new sp_public_t[max];
6.2005 + for (iter=0; iter<max; iter++)
6.2006 + {
6.2007 + ctx->publics[iter].name = strbase + plugin->info.publics[iter].name;
6.2008 + ctx->publics[iter].offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
6.2009 + }
6.2010 + }
6.2011 +
6.2012 + /* relocate pubvar info */
6.2013 + if ((max = plugin->info.pubvars_num))
6.2014 + {
6.2015 + uint8_t *dat = ctx->memory;
6.2016 + ctx->pubvars = new sp_pubvar_t[max];
6.2017 + for (iter=0; iter<max; iter++)
6.2018 + {
6.2019 + ctx->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
6.2020 + ctx->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
6.2021 + }
6.2022 + }
6.2023 +
6.2024 + /* relocate native info */
6.2025 + if ((max = plugin->info.natives_num))
6.2026 + {
6.2027 + ctx->natives = new sp_native_t[max];
6.2028 + for (iter=0; iter<max; iter++)
6.2029 + {
6.2030 + ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
6.2031 + ctx->natives[iter].pfn = NULL;
6.2032 + ctx->natives[iter].status = SP_NATIVE_NONE;
6.2033 + }
6.2034 + }
6.2035 +
6.2036 + /**
6.2037 + * If we're debugging, make sure we copy the necessary info.
6.2038 + */
6.2039 + if (data->debug)
6.2040 + {
6.2041 + strbase = plugin->debug.stringbase;
6.2042 +
6.2043 + /* relocate files */
6.2044 + max = plugin->debug.files_num;
6.2045 + ctx->files = new sp_debug_file_t[max];
6.2046 + for (iter=0; iter<max; iter++)
6.2047 + {
6.2048 + ctx->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
6.2049 + ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
6.2050 + }
6.2051 +
6.2052 + /* relocate lines */
6.2053 + max = plugin->debug.lines_num;
6.2054 + ctx->lines = new sp_debug_line_t[max];
6.2055 + for (iter=0; iter<max; iter++)
6.2056 + {
6.2057 + ctx->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
6.2058 + ctx->lines[iter].line = plugin->debug.lines[iter].line;
6.2059 + }
6.2060 +
6.2061 + /* relocate arrays */
6.2062 + sp_fdbg_symbol_t *sym;
6.2063 + sp_fdbg_arraydim_t *arr;
6.2064 + uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
6.2065 +
6.2066 + max = plugin->debug.syms_num;
6.2067 + ctx->symbols = new sp_debug_symbol_t[max];
6.2068 + for (iter=0; iter<max; iter++)
6.2069 + {
6.2070 + sym = (sp_fdbg_symbol_t *)cursor;
6.2071 +
6.2072 + ctx->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
6.2073 + ctx->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
6.2074 + ctx->symbols[iter].name = strbase + sym->name;
6.2075 + ctx->symbols[iter].sym = sym;
6.2076 +
6.2077 + if (sym->dimcount > 0)
6.2078 + {
6.2079 + cursor += sizeof(sp_fdbg_symbol_t);
6.2080 + arr = (sp_fdbg_arraydim_t *)cursor;
6.2081 + ctx->symbols[iter].dims = arr;
6.2082 + cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
6.2083 + continue;
6.2084 + }
6.2085 +
6.2086 + ctx->symbols[iter].dims = NULL;
6.2087 + cursor += sizeof(sp_fdbg_symbol_t);
6.2088 + }
6.2089 + }
6.2090 +
6.2091 + tracker_t *trk = new tracker_t;
6.2092 + ctx->vm[JITVARS_TRACKER] = trk;
6.2093 + trk->pBase = (ucell_t *)malloc(1024);
6.2094 + trk->pCur = trk->pBase;
6.2095 + trk->size = 1024 / sizeof(cell_t);
6.2096 +
6.2097 + /* clean up relocation+compilation memory */
6.2098 + AbortCompilation(co);
6.2099 +
6.2100 + *err = SP_ERROR_NONE;
6.2101 +
6.2102 + return ctx;
6.2103 +}
6.2104 +
6.2105 +const char *JITX86::GetVMName()
6.2106 +{
6.2107 + return "JIT (x86)";
6.2108 +}
6.2109 +
6.2110 +int JITX86::ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result)
6.2111 +{
6.2112 + typedef int (*CONTEXT_EXECUTE)(sp_context_t *, uint32_t, cell_t *);
6.2113 + CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)ctx->codebase;
6.2114 + return fn(ctx, code_idx, result);
6.2115 +}
6.2116 +
6.2117 +void JITX86::FreeContext(sp_context_t *ctx)
6.2118 +{
6.2119 + engine->ExecFree(ctx->codebase);
6.2120 + delete [] ctx->memory;
6.2121 + delete [] ctx->files;
6.2122 + delete [] ctx->lines;
6.2123 + delete [] ctx->natives;
6.2124 + delete [] ctx->publics;
6.2125 + delete [] ctx->pubvars;
6.2126 + delete [] ctx->symbols;
6.2127 + free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
6.2128 + delete ctx->vm[JITVARS_TRACKER];
6.2129 + delete ctx;
6.2130 +}
6.2131 +
6.2132 +ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
6.2133 +{
6.2134 + CompData *data = new CompData;
6.2135 +
6.2136 + data->plugin = plugin;
6.2137 + data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
6.2138 + data->error_set = SP_ERROR_NONE;
6.2139 +
6.2140 + return data;
6.2141 +}
6.2142 +
6.2143 +void JITX86::AbortCompilation(ICompilation *co)
6.2144 +{
6.2145 + if (((CompData *)co)->rebase)
6.2146 + {
6.2147 + engine->BaseFree(((CompData *)co)->rebase);
6.2148 + }
6.2149 + delete (CompData *)co;
6.2150 +}
6.2151 +
6.2152 +bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char *val)
6.2153 +{
6.2154 + CompData *data = (CompData *)co;
6.2155 +
6.2156 + if (strcmp(key, "debug") == 0)
6.2157 + {
6.2158 + data->debug = (atoi(val) == 1);
6.2159 + if (data->debug && !(data->plugin->flags & SP_FLAG_DEBUG))
6.2160 + {
6.2161 + data->debug = false;
6.2162 + return false;
6.2163 + }
6.2164 + return true;
6.2165 + }
6.2166 +
6.2167 + return false;
6.2168 +}
7.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
7.2 +++ b/sourcepawn/jit/x86/jit_x86.h Wed Nov 08 06:24:28 2006 +0000
7.3 @@ -0,0 +1,90 @@
7.4 +#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_H_
7.5 +#define _INCLUDE_SOURCEPAWN_JIT_X86_H_
7.6 +
7.7 +#include <sp_vm_types.h>
7.8 +#include <sp_vm_api.h>
7.9 +#include "..\jit_helpers.h"
7.10 +
7.11 +using namespace SourcePawn;
7.12 +
7.13 +#define JIT_INLINE_ERRORCHECKS (1<<0)
7.14 +#define JIT_INLINE_NATIVES (1<<1)
7.15 +#define STACK_MARGIN 64 //8 parameters of safety, I guess
7.16 +
7.17 +#define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
7.18 +
7.19 +typedef struct tracker_s
7.20 +{
7.21 + size_t size;
7.22 + ucell_t *pBase;
7.23 + ucell_t *pCur;
7.24 +} tracker_t;
7.25 +
7.26 +class CompData : public ICompilation
7.27 +{
7.28 +public:
7.29 + CompData() : plugin(NULL),
7.30 + debug(false), inline_level(0), rebase(NULL),
7.31 + error_set(SP_ERROR_NONE)
7.32 + {
7.33 + };
7.34 +public:
7.35 + sp_plugin_t *plugin; /* plugin handle */
7.36 + jitcode_t rebase; /* relocation map */
7.37 + jitoffs_t jit_return; /* point in main call to return to */
7.38 + jitoffs_t jit_verify_addr_eax;
7.39 + jitoffs_t jit_verify_addr_edx;
7.40 + jitoffs_t jit_break; /* call to op.break */
7.41 + jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
7.42 + jitoffs_t jit_genarray; /* call to genarray intrinsic */
7.43 + jitoffs_t jit_error_bounds;
7.44 + jitoffs_t jit_error_divzero;
7.45 + jitoffs_t jit_error_stacklow;
7.46 + jitoffs_t jit_error_stackmin;
7.47 + jitoffs_t jit_error_memaccess;
7.48 + jitoffs_t jit_error_heaplow;
7.49 + jitoffs_t jit_error_heapmin;
7.50 + jitoffs_t jit_error_array_too_big;
7.51 + jitoffs_t jit_error_tracker_bounds;
7.52 + jitoffs_t jit_extern_error; /* returning generic error */
7.53 + jitoffs_t jit_sysreq_c; /* old version! */
7.54 + uint32_t codesize; /* total codesize */
7.55 + int inline_level; /* inline optimization level */
7.56 + int error_set; /* error code to halt process */
7.57 + bool debug; /* whether to compile debug mode */
7.58 +};
7.59 +
7.60 +class JITX86 : public IVirtualMachine
7.61 +{
7.62 +public:
7.63 + const char *GetVMName();
7.64 + ICompilation *StartCompilation(sp_plugin_t *plugin);
7.65 + bool SetCompilationOption(ICompilation *co, const char *key, const char *val);
7.66 + sp_context_t *CompileToContext(ICompilation *co, int *err);
7.67 + void AbortCompilation(ICompilation *co);
7.68 + void FreeContext(sp_context_t *ctx);
7.69 + int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result);
7.70 +};
7.71 +
7.72 +cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
7.73 +cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
7.74 +jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
7.75 +
7.76 +#define AMX_REG_PRI REG_EAX
7.77 +#define AMX_REG_ALT REG_EDX
7.78 +#define AMX_REG_STK REG_EDI
7.79 +#define AMX_REG_DAT REG_EBP
7.80 +#define AMX_REG_TMP REG_ECX
7.81 +#define AMX_REG_INFO REG_ESI
7.82 +#define AMX_REG_FRM REG_EBX
7.83 +
7.84 +#define AMX_INFO_FRM AMX_REG_INFO //not relocated
7.85 +#define AMX_INFO_FRAME 0 //(same thing as above)
7.86 +#define AMX_INFO_HEAP 4 //not relocated
7.87 +#define AMX_INFO_RETVAL 8 //physical
7.88 +#define AMX_INFO_CONTEXT 12 //physical
7.89 +#define AMX_INFO_STACKTOP 16 //relocated
7.90 +
7.91 +extern ISourcePawnEngine *engine;
7.92 +
7.93 +#endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_
8.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
8.2 +++ b/sourcepawn/jit/x86/opcode_helpers.cpp Wed Nov 08 06:24:28 2006 +0000
8.3 @@ -0,0 +1,779 @@
8.4 +#include <limits.h>
8.5 +#include <string.h>
8.6 +#include <malloc.h>
8.7 +#include "jit_x86.h"
8.8 +#include "opcode_helpers.h"
8.9 +#include "x86_macros.h"
8.10 +
8.11 +#define NUM_INFO_PARAMS 5
8.12 +
8.13 +jitoffs_t Write_Execute_Function(JitWriter *jit)
8.14 +{
8.15 + /**
8.16 + * The variables we're passed in:
8.17 + * sp_context_t *ctx, uint32_t code_idx, cell_t *result
8.18 + */
8.19 +
8.20 + /**
8.21 + * !NOTE!
8.22 + * Currently, we do not accept ctx->frm as the new frame pointer.
8.23 + * Instead, we copy the frame from the stack pointer.
8.24 + * This is because we do not support resuming or sleeping!
8.25 + */
8.26 +
8.27 + //push ebp
8.28 + //mov ebp, esp
8.29 + IA32_Push_Reg(jit, REG_EBP);
8.30 + IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
8.31 +
8.32 + //push esi
8.33 + //push edi
8.34 + //push ebx
8.35 + IA32_Push_Reg(jit, REG_ESI);
8.36 + IA32_Push_Reg(jit, REG_EDI);
8.37 + IA32_Push_Reg(jit, REG_EBX);
8.38 +
8.39 + //sub esp, 4*n - reserve info array
8.40 + //mov esi, esp - save info pointer
8.41 + IA32_Sub_Rm_Imm8(jit, REG_ESP, 4*NUM_INFO_PARAMS, MOD_REG);
8.42 + IA32_Mov_Reg_Rm(jit, AMX_REG_INFO, REG_ESP, MOD_REG);
8.43 +
8.44 + /* Initial memory setup */
8.45 + //mov eax, [ebp+16] - get result pointer
8.46 + //mov [esi+8], eax - store into info pointer
8.47 + //mov eax, [ebp+8] - get context
8.48 + //mov [esi+12], eax - store context into info pointer
8.49 + //mov ecx, [eax+<offs>] - get heap pointer
8.50 + //mov [esi+4], ecx - store heap into info pointer
8.51 + //mov ebp, [eax+<offs>] - get data pointer
8.52 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
8.53 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_RETVAL);
8.54 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
8.55 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_CONTEXT);
8.56 + IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
8.57 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAP);
8.58 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, memory));
8.59 +
8.60 + /* Frame setup */
8.61 + //mov edi, [eax+<offs>] - get stack pointer
8.62 + //add edi, ebp - relocate to data section
8.63 + //mov ebx, edi - copy sp to frm
8.64 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_STK, REG_EAX, offsetof(sp_context_t, sp));
8.65 + IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
8.66 + IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
8.67 +
8.68 + /* Info memory setup */
8.69 + //mov ecx, [eax+<offs>] - copy memsize to temp var
8.70 + //add ecx, ebp - relocate
8.71 + //mov [esi+x], ecx - store relocated
8.72 + IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
8.73 + IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
8.74 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
8.75 +
8.76 + /* Remaining needed vars */
8.77 + //mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
8.78 + //add ecx, [eax+<offs>] - add code base to index
8.79 + IA32_Mov_Reg_Esp_Disp8(jit, REG_ECX, 12+(4*(NUM_INFO_PARAMS+3)));
8.80 + IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
8.81 +
8.82 + /* by now, everything is set up, so we can call into the plugin */
8.83 + //call ecx
8.84 + IA32_Call_Reg(jit, REG_ECX);
8.85 +
8.86 + /* if the code flow gets to here, there was a normal return */
8.87 + //mov ecx, [esi+8] - get retval pointer
8.88 + //mov [ecx], eax - store retval from PRI
8.89 + //mov eax, SP_ERROR_NONE - set no error
8.90 + IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, AMX_REG_INFO, AMX_INFO_RETVAL);
8.91 + IA32_Mov_Rm_Reg(jit, REG_ECX, AMX_REG_PRI, MOD_MEM_REG);
8.92 + IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERROR_NONE);
8.93 +
8.94 + /* save where error checking/halting functions should go to */
8.95 + jitoffs_t offs_return = jit->get_outputpos();
8.96 + //mov esp, esi - restore stack pointer
8.97 + IA32_Mov_Reg_Rm(jit, REG_ESP, REG_ESI, MOD_REG);
8.98 +
8.99 + /* _FOR NOW_ ...
8.100 + * We are going to restore SP, HP, and FRM for now. This is for
8.101 + * debugging only, to check for alignment errors. As such:
8.102 + * :TODO: probably remove this.
8.103 + */
8.104 + //mov ecx, [esi+context]
8.105 + //sub edi, ebp
8.106 + //mov edx, [esi+heap]
8.107 + //mov [ecx+sp], edi
8.108 + //mov [ecx+hp], edx
8.109 + IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_ESI, AMX_INFO_CONTEXT);
8.110 + IA32_Sub_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG);
8.111 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_ESI, AMX_INFO_HEAP);
8.112 + IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDI, offsetof(sp_context_t, sp));
8.113 + IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDX, offsetof(sp_context_t, hp));
8.114 +
8.115 + //add esp, 4*NUM_INFO_PARAMS
8.116 + //pop ebx
8.117 + //pop edi
8.118 + //pop esi
8.119 + //pop ebp
8.120 + //ret
8.121 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*NUM_INFO_PARAMS, MOD_REG);
8.122 + IA32_Pop_Reg(jit, REG_EBX);
8.123 + IA32_Pop_Reg(jit, REG_EDI);
8.124 + IA32_Pop_Reg(jit, REG_ESI);
8.125 + IA32_Pop_Reg(jit, REG_EBP);
8.126 + IA32_Return(jit);
8.127 +
8.128 + return offs_return;
8.129 +}
8.130 +
8.131 +void Write_BreakDebug(JitWriter *jit)
8.132 +{
8.133 + //push ecx
8.134 + //mov ecx, [esi+ctx]
8.135 + //cmp [ecx+dbreak], 0
8.136 + //jnz :nocall
8.137 + IA32_Push_Reg(jit, AMX_REG_TMP);
8.138 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.139 + IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, dbreak), 0);
8.140 + jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0);
8.141 +
8.142 + //pushad
8.143 + IA32_Pushad(jit);
8.144 +
8.145 + //push [esi+frm]
8.146 + //push [ecx+context]
8.147 + //mov ecx, [ecx+dbreak]
8.148 + //call ecx
8.149 + //add esp, 8
8.150 + //popad
8.151 + IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
8.152 + IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, context));
8.153 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
8.154 + IA32_Call_Reg(jit, AMX_REG_TMP);
8.155 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
8.156 + IA32_Popad(jit);
8.157 +
8.158 + //:nocall
8.159 + IA32_Send_Jump8_Here(jit, jmp);
8.160 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*1, MOD_REG);
8.161 + IA32_Return(jit);
8.162 +}
8.163 +
8.164 +void Write_GetError(JitWriter *jit)
8.165 +{
8.166 + CompData *data = (CompData *)jit->data;
8.167 +
8.168 + //mov eax, [esi+info.context]
8.169 + //mov eax, [eax+ctx.error]
8.170 + //jmp [jit_return]
8.171 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.172 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EAX, offsetof(sp_context_t, err));
8.173 + IA32_Jump_Imm32_Abs(jit, data->jit_return);
8.174 +}
8.175 +
8.176 +void Write_SetError(JitWriter *jit, int error)
8.177 +{
8.178 + CompData *data = (CompData *)jit->data;
8.179 +
8.180 + //mov eax, <error>
8.181 + //jmp [jit_return]
8.182 + IA32_Mov_Reg_Imm32(jit, REG_EAX, error);
8.183 + IA32_Jump_Imm32_Abs(jit, data->jit_return);
8.184 +}
8.185 +
8.186 +void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg)
8.187 +{
8.188 + //test reg, reg
8.189 + //jz :error
8.190 + IA32_Test_Rm_Reg(jit, reg, reg, MOD_REG);
8.191 + IA32_Jump_Cond_Imm32_Abs(jit, CC_Z, ((CompData *)jit->data)->jit_error_divzero);
8.192 +}
8.193 +
8.194 +void Write_CheckHeap_Min(JitWriter *jit)
8.195 +{
8.196 + /* Check if the stack went beyond the heap low.
8.197 + * This usually means there was a compiler error.
8.198 + * NOTE: Special optimization here.
8.199 + * The heap low is always known ahead of time! :)
8.200 + */
8.201 + CompData *data = (CompData *)jit->data;
8.202 + //cmp [esi+info.heap], <heaplow>
8.203 + //jb :error
8.204 + IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_INFO, AMX_INFO_HEAP, data->plugin->data_size);
8.205 + IA32_Jump_Cond_Imm32_Abs(jit, CC_B, data->jit_error_heapmin);
8.206 +}
8.207 +
8.208 +void Write_CheckHeap_Low(JitWriter *jit)
8.209 +{
8.210 + /* Check if the heap is trying to grow beyond the stack.
8.211 + */
8.212 + //mov ecx, [esi+info.heap]
8.213 + //lea ecx, [ebp+ecx+STACK_MARGIN]
8.214 + //cmp ecx, edi
8.215 + //ja :error ; I think this is right
8.216 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
8.217 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, STACK_MARGIN);
8.218 + IA32_Cmp_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
8.219 + IA32_Jump_Cond_Imm32_Abs(jit, CC_A, ((CompData *)jit->data)->jit_error_heaplow);
8.220 +}
8.221 +
8.222 +void Write_CheckStack_Min(JitWriter *jit)
8.223 +{
8.224 + /* Check if the stack went beyond the stack top
8.225 + * This usually means there was a compiler error.
8.226 + */
8.227 + //cmp edi, [esi+info.stacktop]
8.228 + //jae :error
8.229 + IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_STK, AMX_REG_INFO, AMX_INFO_STACKTOP);
8.230 + IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_stackmin);
8.231 +}
8.232 +
8.233 +void Write_CheckStack_Low(JitWriter *jit)
8.234 +{
8.235 + /* Check if the stack went beyond the heap boundary.
8.236 + * Unfortunately this one isn't as quick as the other check.
8.237 + * The stack margin check is important for sysreq.n having space.
8.238 + */
8.239 + //mov ecx, [esi+info.heap]
8.240 + //lea ecx, [ebp+ecx+STACK_MARGIN]
8.241 + //cmp edi, ecx
8.242 + //jb :error ; I think this is right
8.243 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
8.244 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, STACK_MARGIN);
8.245 + IA32_Cmp_Reg_Rm(jit, AMX_REG_STK, AMX_REG_TMP, MOD_REG);
8.246 + IA32_Jump_Cond_Imm32_Abs(jit, CC_B, ((CompData *)jit->data)->jit_error_stacklow);
8.247 +}
8.248 +
8.249 +void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg)
8.250 +{
8.251 + CompData *data = (CompData *)jit->data;
8.252 +
8.253 + /* :TODO: Should this be checking for below heaplow?
8.254 + * The old JIT did not.
8.255 + */
8.256 +
8.257 + bool call = false;
8.258 + if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
8.259 + {
8.260 + /* If we're not in the initial generation phase,
8.261 + * Write a call to the actual routine instead.
8.262 + */
8.263 + if ((reg == REG_EAX) && data->jit_verify_addr_eax)
8.264 + {
8.265 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
8.266 + IA32_Write_Jump32(jit, call, data->jit_verify_addr_eax);
8.267 + return;
8.268 + } else if ((reg == REG_EDX) && data->jit_verify_addr_edx) {
8.269 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
8.270 + IA32_Write_Jump32(jit, call, data->jit_verify_addr_edx);
8.271 + return;
8.272 + }
8.273 + call = true;
8.274 + }
8.275 +
8.276 + /**
8.277 + * :TODO: If we can't find a nicer way of doing this,
8.278 + * then scrap it on high optimizations. The second portion is not needed at all!
8.279 + */
8.280 +
8.281 + /* Part 1: Check if we're in the memory bounds */
8.282 + //cmp <reg>, <stpu>
8.283 + //jae :error
8.284 + IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->memory);
8.285 + IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_memaccess);
8.286 +
8.287 + /* Part 2: Check if we're in the invalid region between HP and SP */
8.288 + jitoffs_t jmp;
8.289 + //cmp <reg>, [esi+info.heap]
8.290 + //jb :continue
8.291 + //lea ecx, [ebp+<reg>]
8.292 + //cmp edi, ecx
8.293 + //jb :error
8.294 + //:continue
8.295 + IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_HEAP);
8.296 + jmp = IA32_Jump_Cond_Imm8(jit, CC_B, 0);
8.297 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, reg, NOSCALE, 0);
8.298 + IA32_Cmp_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
8.299 + IA32_Jump_Cond_Imm32_Abs(jit, CC_B, ((CompData *)jit->data)->jit_error_memaccess);
8.300 + IA32_Send_Jump8_Here(jit, jmp);
8.301 +
8.302 + if (call)
8.303 + {
8.304 + IA32_Return(jit);
8.305 + }
8.306 +}
8.307 +
8.308 +void Macro_PushN_Addr(JitWriter *jit, int i)
8.309 +{
8.310 + //push eax
8.311 + //mov eax, [esi+frm]
8.312 + //loop i times:
8.313 + // lea ecx, [eax+<val>]
8.314 + // mov [edi-4*i], ecx
8.315 + //sub edi, 4*N
8.316 + //pop eax
8.317 +
8.318 + cell_t val;
8.319 + int n = 1;
8.320 + IA32_Push_Reg(jit, AMX_REG_PRI);
8.321 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
8.322 + do
8.323 + {
8.324 + val = jit->read_cell();
8.325 + if (val < SCHAR_MAX && val > SCHAR_MIN)
8.326 + IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, (jit_int8_t)val);
8.327 + else
8.328 + IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, val);
8.329 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
8.330 + } while (n++ < i);
8.331 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
8.332 + IA32_Pop_Reg(jit, AMX_REG_PRI);
8.333 +}
8.334 +
8.335 +void Macro_PushN_S(JitWriter *jit, int i)
8.336 +{
8.337 + //loop i times:
8.338 + // mov ecx, [ebx+<val>]
8.339 + // mov [edi-4*i], ecx
8.340 + //sub edi, 4*N
8.341 +
8.342 + cell_t val;
8.343 + int n = 1;
8.344 + do
8.345 + {
8.346 + val = jit->read_cell();
8.347 + if (val < SCHAR_MAX && val > SCHAR_MIN)
8.348 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
8.349 + else
8.350 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
8.351 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
8.352 + } while (n++ < i);
8.353 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
8.354 +}
8.355 +
8.356 +void Macro_PushN_C(JitWriter *jit, int i)
8.357 +{
8.358 + //loop i times:
8.359 + // mov [edi-4*i], <val>
8.360 + //sub edi, 4*N
8.361 +
8.362 + int n = 1;
8.363 + do
8.364 + {
8.365 + IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, jit->read_cell(), -4*n);
8.366 + } while (n++ < i);
8.367 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
8.368 +}
8.369 +
8.370 +void Macro_PushN(JitWriter *jit, int i)
8.371 +{
8.372 + //loop i times:
8.373 + // mov ecx, [ebp+<val>]
8.374 + // mov [edi-4*i], ecx
8.375 + //sub edi, 4*N
8.376 +
8.377 + cell_t val;
8.378 + int n = 1;
8.379 + do
8.380 + {
8.381 + val = jit->read_cell();
8.382 + if (val < SCHAR_MAX && val > SCHAR_MIN)
8.383 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
8.384 + else
8.385 + IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
8.386 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
8.387 + } while (n++ < i);
8.388 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
8.389 +}
8.390 +
8.391 +void WriteOp_Sysreq_C_Function(JitWriter *jit)
8.392 +{
8.393 + /* The small daddy of the big daddy of opcodes.
8.394 + * ecx - native index
8.395 + */
8.396 + CompData *data = (CompData *)jit->data;
8.397 +
8.398 + /* save registers we will need */
8.399 + //push edx
8.400 + IA32_Push_Reg(jit, AMX_REG_ALT);
8.401 +
8.402 + /* push some callback stuff */
8.403 + //push edi ; stack
8.404 + //push ecx ; native index
8.405 + IA32_Push_Reg(jit, AMX_REG_STK);
8.406 + IA32_Push_Reg(jit, REG_ECX);
8.407 +
8.408 + /* Relocate stack, heap, frm information, then store back */
8.409 + //mov eax, [esi+context]
8.410 + //mov ecx, [esi+hea]
8.411 + //sub edi, ebp
8.412 + //mov [eax+hp], ecx
8.413 + //mov ecx, [esi]
8.414 + //mov [eax+sp], edi
8.415 + //mov [eax+frm], ecx
8.416 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.417 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
8.418 + IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
8.419 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
8.420 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
8.421 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
8.422 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
8.423 +
8.424 + /* finally, push the last parameter and make the call */
8.425 + //push eax ; context
8.426 + //call NativeCallback
8.427 + IA32_Push_Reg(jit, REG_EAX);
8.428 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
8.429 + if (!data->debug)
8.430 + {
8.431 + IA32_Write_Jump32_Abs(jit, call, NativeCallback);
8.432 + } else {
8.433 + IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
8.434 + }
8.435 +
8.436 + /* Test for error */
8.437 + //mov ecx, [esi+context]
8.438 + //cmp [ecx+err], 0
8.439 + //jnz :error
8.440 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.441 + IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
8.442 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
8.443 +
8.444 + /* restore what we damaged */
8.445 + //add esp, 4*3
8.446 + //add edi, ebp
8.447 + //pop edx
8.448 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
8.449 + IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
8.450 + IA32_Pop_Reg(jit, AMX_REG_ALT);
8.451 +
8.452 + //ret
8.453 + IA32_Return(jit);
8.454 +}
8.455 +
8.456 +void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t _dimcount, bool autozero)
8.457 +{
8.458 + cell_t vectors = 1; /* we need one vector to start off with */
8.459 + cell_t cur_offs = 0;
8.460 + cell_t cur_write = 0;
8.461 + cell_t dimcount = _dimcount;
8.462 +
8.463 + /* Initialize rotation */
8.464 + cur_write = dims[dimcount-1];
8.465 +
8.466 + while (--dimcount >= 1)
8.467 + {
8.468 + cell_t cur_dim = dims[dimcount];
8.469 + cell_t sub_dim = dims[dimcount-1];
8.470 + for (cell_t i=0; i<vectors; i++)
8.471 + {
8.472 + for (cell_t j=0; j<cur_dim; j++)
8.473 + {
8.474 + arraybase[cur_offs] = (cur_write - cur_offs)*sizeof(cell_t);
8.475 + cur_offs++;
8.476 + cur_write += sub_dim;
8.477 + }
8.478 + }
8.479 + vectors = cur_dim;
8.480 + }
8.481 +
8.482 + /* everything after cur_offs can be zeroed */
8.483 + if (autozero)
8.484 + {
8.485 + size_t size = 1;
8.486 + for (ucell_t i=0; i<_dimcount; i++)
8.487 + {
8.488 + size *= dims[i];
8.489 + }
8.490 + memset(&arraybase[cur_offs], 0, size*sizeof(cell_t));
8.491 + }
8.492 +
8.493 + return;
8.494 +}
8.495 +
8.496 +/**
8.497 + * A few notes about this function.
8.498 + * I was more concerned about efficient use of registers here, rather than
8.499 + * fine-tuned optimization. The reason is that the code is already complicated,
8.500 + * and it is very easy to mess up.
8.501 + */
8.502 +void WriteIntrinsic_GenArray(JitWriter *jit)
8.503 +{
8.504 + /**
8.505 + * save important values
8.506 + */
8.507 + //push ebx
8.508 + //push eax
8.509 + //push edx
8.510 + //push ecx ;value is referenced on stack
8.511 + IA32_Push_Reg(jit, REG_EBX);
8.512 + IA32_Push_Reg(jit, REG_EAX);
8.513 + IA32_Push_Reg(jit, REG_EDX);
8.514 + IA32_Push_Reg(jit, REG_ECX);
8.515 +
8.516 + /**
8.517 + * Calculate how many cells will be needed.
8.518 + */
8.519 + //mov edx, [edi] ;get last dimension's count
8.520 + //mov eax, 1 ;position at second to last dimension
8.521 + //:loop
8.522 + //cmp eax, [esp] ;compare to # of params
8.523 + //jae :done ;end loop if done
8.524 + //mov ecx, [edi+eax*4] ;get dimension size
8.525 + //imul edx, ecx ;multiply by size
8.526 + //add eax, 1 ;increment
8.527 + //add edx, ecx ;add size (indirection vector)
8.528 + //jmp :loop ;jump back
8.529 + //:done
8.530 + IA32_Mov_Reg_Rm(jit, REG_EDX, AMX_REG_STK, MOD_MEM_REG);
8.531 + IA32_Mov_Reg_Imm32(jit, REG_EAX, 1);
8.532 + jitoffs_t loop1 = jit->get_outputpos();
8.533 + IA32_Cmp_Reg_Rm_ESP(jit, REG_EAX);
8.534 + jitoffs_t done1 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0);
8.535 + IA32_Mov_Reg_Rm_Disp_Reg(jit, REG_ECX, AMX_REG_STK, REG_EAX, SCALE4);
8.536 + IA32_IMul_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG);
8.537 + IA32_Add_Rm_Imm8(jit, REG_EAX, 1, MOD_REG);
8.538 + IA32_Add_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG);
8.539 + IA32_Write_Jump8(jit, IA32_Jump_Imm8(jit, loop1), loop1);
8.540 + IA32_Send_Jump8_Here(jit, done1);
8.541 +
8.542 + /* Test if we have heap space for this */
8.543 + //mov eax, [esi+info.heap] ;get heap pointer
8.544 + //lea eax, [eax+edx*4] ;new heap pointer
8.545 + //cmp eax, <hlw> ;compare to heap low
8.546 + //jbe :error ;die if we hit this (it should always be >)
8.547 + //add eax, ebp ;relocate to stack
8.548 + //cmp eax, edi ;die if above the stack pointer
8.549 + //jae :error
8.550 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
8.551 + IA32_Lea_Reg_DispRegMult(jit, REG_EAX, REG_EAX, REG_EDX, SCALE4);
8.552 + IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, ((CompData *)jit->data)->plugin->data_size);
8.553 + IA32_Jump_Cond_Imm32_Abs(jit, CC_BE, ((CompData *)jit->data)->jit_error_array_too_big);
8.554 + IA32_Add_Reg_Rm(jit, REG_EAX, AMX_REG_DAT, MOD_REG);
8.555 + IA32_Cmp_Reg_Rm(jit, REG_EAX, AMX_REG_STK, MOD_REG);
8.556 + IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_array_too_big);
8.557 +
8.558 + /* Prepare for indirection iteration */
8.559 + //mov eax, [esi+info.heap] ;get heap pointer
8.560 + //lea ebx, [eax+edx*4] ;new heap pointer
8.561 + //mov [esi+info.heap], ebx ;store back
8.562 + //push eax ;save heap pointer - we need it
8.563 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
8.564 + IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EDX, SCALE4);
8.565 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EBX, AMX_INFO_HEAP);
8.566 + IA32_Push_Reg(jit, REG_EAX);
8.567 +
8.568 + WriteOp_Tracker_Push_Reg(jit, REG_EDX);
8.569 +
8.570 + /* This part is too messy to do in straight assembly.
8.571 + * I'm letting the compiler handle it and thus it's in C.
8.572 + */
8.573 + //lea ebx, [ebp+eax] ;get base pointer
8.574 + //push dword [esp-8] ;push autozero
8.575 + //push dword [esp-8] ;push dimension count
8.576 + //push edi ;push dim array
8.577 + //push ebx
8.578 + //call GenerateArrayIndirectionVectors
8.579 + //add esp, 4*4
8.580 + IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EBP, NOSCALE);
8.581 + IA32_Push_Rm_Disp8_ESP(jit, 8);
8.582 + IA32_Push_Rm_Disp8_ESP(jit, 8);
8.583 + IA32_Push_Reg(jit, REG_EDI);
8.584 + IA32_Push_Reg(jit, REG_EBX);
8.585 + IA32_Write_Jump32_Abs(jit, IA32_Call_Imm32(jit, 0), (void *)&GenerateArrayIndirectionVectors);
8.586 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*4, MOD_REG);
8.587 +
8.588 + /* Store the heap pointer back into the stack */
8.589 + //pop eax ;restore heap pointer
8.590 + //pop ecx ;restore param count
8.591 + //lea edi, [edi+ecx*4-4] ;pop params-4 off the stack
8.592 + //mov [edi], eax ;store back the heap pointer
8.593 + IA32_Pop_Reg(jit, REG_EAX);
8.594 + IA32_Pop_Reg(jit, REG_ECX);
8.595 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, REG_ECX, SCALE4, -4);
8.596 + IA32_Mov_Rm_Reg(jit, AMX_REG_STK, REG_EAX, MOD_MEM_REG);
8.597 +
8.598 + /* Return to caller */
8.599 + //pop edx
8.600 + //pop eax
8.601 + //pop ebx
8.602 + //ret
8.603 + IA32_Pop_Reg(jit, REG_ECX);
8.604 + IA32_Pop_Reg(jit, REG_EAX);
8.605 + IA32_Pop_Reg(jit, REG_EBX);
8.606 + IA32_Return(jit);
8.607 +}
8.608 +
8.609 +void WriteOp_Sysreq_N_Function(JitWriter *jit)
8.610 +{
8.611 + /* The big daddy of opcodes.
8.612 + * eax - num_params
8.613 + * ecx - native index
8.614 + */
8.615 + CompData *data = (CompData *)jit->data;
8.616 +
8.617 + /* store the number of parameters on the stack */
8.618 + //mov [edi-4], eax
8.619 + //sub edi, 4
8.620 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, REG_EAX, -4);
8.621 + IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
8.622 +
8.623 + /* save registers we will need */
8.624 + //push eax ; num_params for stack popping
8.625 + //push edx
8.626 + IA32_Push_Reg(jit, REG_EAX);
8.627 + IA32_Push_Reg(jit, AMX_REG_ALT);
8.628 +
8.629 + /* push some callback stuff */
8.630 + //push edi ; stack
8.631 + //push ecx ; native index
8.632 + IA32_Push_Reg(jit, AMX_REG_STK);
8.633 + IA32_Push_Reg(jit, REG_ECX);
8.634 +
8.635 + /* Relocate stack, heap, frm information, then store back */
8.636 + //mov eax, [esi+context]
8.637 + //mov ecx, [esi+hea]
8.638 + //sub edi, ebp
8.639 + //mov [eax+hp], ecx
8.640 + //mov ecx, [esi]
8.641 + //mov [eax+sp], edi
8.642 + //mov [eax+frm], ecx
8.643 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.644 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
8.645 + IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
8.646 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
8.647 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
8.648 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
8.649 + IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
8.650 +
8.651 + /* finally, push the last parameter and make the call */
8.652 + //push eax ; context
8.653 + //call NativeCallback
8.654 + IA32_Push_Reg(jit, REG_EAX);
8.655 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
8.656 + if (!data->debug)
8.657 + {
8.658 + IA32_Write_Jump32_Abs(jit, call, NativeCallback);
8.659 + } else {
8.660 + IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
8.661 + }
8.662 +
8.663 + /* Test for error */
8.664 + //mov ecx, [esi+context]
8.665 + //cmp [ecx+err], 0
8.666 + //jnz :error
8.667 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.668 + IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
8.669 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
8.670 +
8.671 + /* restore what we damaged */
8.672 + //add esp, 4*3
8.673 + //add edi, ebp
8.674 + //pop edx
8.675 + //pop ecx ; num_params
8.676 + IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
8.677 + IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
8.678 + IA32_Pop_Reg(jit, AMX_REG_ALT);
8.679 + IA32_Pop_Reg(jit, REG_ECX);
8.680 +
8.681 + /* pop the AMX stack. do not check the margins.
8.682 + * Note that this is not a true macro - we don't bother to
8.683 + * set ALT here because nothing will be using it.
8.684 + */
8.685 + //lea edi, [edi+ecx*4+4]
8.686 + IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, REG_ECX, SCALE4, 4);
8.687 +
8.688 + //ret
8.689 + IA32_Return(jit);
8.690 +}
8.691 +
8.692 +void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg)
8.693 +{
8.694 + CompData *data = (CompData *)jit->data;
8.695 +
8.696 + /* Save registers that may be damaged by the call */
8.697 + //push eax
8.698 + //push ecx
8.699 + //push edi
8.700 + //lea edi, [<reg>*4] ; we want the count in bytes not in cells
8.701 + IA32_Push_Reg(jit, AMX_REG_PRI);
8.702 + if (reg == REG_ECX)
8.703 + {
8.704 + IA32_Push_Reg(jit, AMX_REG_TMP);
8.705 + }
8.706 + IA32_Push_Reg(jit, AMX_REG_STK);
8.707 + IA32_Lea_Reg_RegMultImm32(jit, REG_EDI, reg, SCALE4, 0);
8.708 +
8.709 + /* Get the context ptr, push it and call the check */
8.710 + //mov eax, [esi+context]
8.711 + //push eax
8.712 + //call JIT_VerifyOrAllocateTracker
8.713 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
8.714 + IA32_Push_Reg(jit, REG_EAX);
8.715 + jitoffs_t call = IA32_Call_Imm32(jit, 0);
8.716 + IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
8.717 +
8.718 + /* Check for errors */
8.719 + //pop eax
8.720 + //cmp [eax+err], 0
8.721 + //jnz :error
8.722 + IA32_Pop_Reg(jit, REG_EAX);
8.723 + IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
8.724 + IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
8.725 +
8.726 + /* Push the register into the stack and increment pCur */
8.727 + //mov edx, [eax+vm[]]
8.728 + //mov eax, [edx+pcur]
8.729 + //add [edx+pcur], 4
8.730 + //mov [eax], edi
8.731 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
8.732 + IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EDX, offsetof(tracker_t, pCur));
8.733 + IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
8.734 + IA32_Mov_Rm_Reg(jit, REG_EAX, REG_EDI, MOD_MEM_REG);
8.735 +
8.736 + /* Restore PRI, ALT and STK */
8.737 + //pop edi
8.738 + //pop ecx
8.739 + //pop eax
8.740 + IA32_Pop_Reg(jit, AMX_REG_STK);
8.741 + if (reg == REG_ECX)
8.742 + {
8.743 + IA32_Pop_Reg(jit, AMX_REG_TMP);
8.744 + }
8.745 + IA32_Pop_Reg(jit, AMX_REG_PRI);
8.746 +}
8.747 +
8.748 +void JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
8.749 +{
8.750 + tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
8.751 +
8.752 + if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
8.753 + {
8.754 + ctx->err = SP_ERROR_TRACKER_BOUNDS;
8.755 + return;
8.756 + }
8.757 +
8.758 + if (trk->pCur+1 - (trk->pBase + trk->size) == 0)
8.759 + {
8.760 + size_t disp = trk->size - 1;
8.761 + trk->size *= 2;
8.762 + trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size * sizeof(cell_t));
8.763 +
8.764 + if (!trk->pBase)
8.765 + {
8.766 + ctx->err = SP_ERROR_TRACKER_BOUNDS;
8.767 + return;
8.768 + }
8.769 +
8.770 + trk->pCur = trk->pBase + disp;
8.771 + }
8.772 +}
8.773 +
8.774 +void JIT_VerifyLowBoundTracker(sp_context_t *ctx)
8.775 +{
8.776 + tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
8.777 +
8.778 + if (trk->pCur <= trk->pBase)
8.779 + {
8.780 + ctx->err = SP_ERROR_TRACKER_BOUNDS;
8.781 + }
8.782 +}
8.783 \ No newline at end of file
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/sourcepawn/jit/x86/opcode_helpers.h Wed Nov 08 06:24:28 2006 +0000
9.3 @@ -0,0 +1,285 @@
9.4 +#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
9.5 +#define _INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
9.6 +
9.7 +#include "..\jit_helpers.h"
9.8 +
9.9 +/**
9.10 + * This outputs the execution function for a plugin.
9.11 + * It also returns the 'return' offset, which is used for
9.12 + * breaking out of the JIT during runtime.
9.13 + */
9.14 +jitoffs_t Write_Execute_Function(JitWriter *jit);
9.15 +
9.16 +/**
9.17 + * Writes the Sysreq.* opcodes as a function call.
9.18 + */
9.19 +void WriteOp_Sysreq_N_Function(JitWriter *jit);
9.20 +void WriteOp_Sysreq_C_Function(JitWriter *jit);
9.21 +
9.22 +/**
9.23 + * Write the GENARRAY intrinsic function.
9.24 + */
9.25 +void WriteIntrinsic_GenArray(JitWriter *jit);
9.26 +
9.27 +/**
9.28 + * Generates code to set an error state in the VM and return.
9.29 + * This is used for generating the error set points in the VM.
9.30 + * GetError writes the error from the context. SetError hardcodes.
9.31 + */
9.32 +void Write_GetError(JitWriter *jit);
9.33 +void Write_SetError(JitWriter *jit, int error);
9.34 +
9.35 +/**
9.36 + * Checks the stacks for min and low errors.
9.37 + * :TODO: Should a variation of this go in the pushN opcodes?
9.38 + */
9.39 +void Write_CheckStack_Min(JitWriter *jit);
9.40 +void Write_CheckStack_Low(JitWriter *jit);
9.41 +
9.42 +/**
9.43 + * Checks the heap for min and low errors.
9.44 + */
9.45 +void Write_CheckHeap_Min(JitWriter *jit);
9.46 +void Write_CheckHeap_Low(JitWriter *jit);
9.47 +
9.48 +/**
9.49 + * Verifies an address by register. The address must reside
9.50 + * between DAT and HP and SP and STP.
9.51 + */
9.52 +void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg);
9.53 +
9.54 +/**
9.55 + * Checks for division by zero.
9.56 + */
9.57 +void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg);
9.58 +
9.59 +/**
9.60 + * Writes the break debug function.
9.61 + */
9.62 +void Write_BreakDebug(JitWriter *jit);
9.63 +
9.64 +/**
9.65 + * These are for writing the PushN opcodes.
9.66 + */
9.67 +void Macro_PushN_Addr(JitWriter *jit, int i);
9.68 +void Macro_PushN_S(JitWriter *jit, int i);
9.69 +void Macro_PushN_C(JitWriter *jit, int i);
9.70 +void Macro_PushN(JitWriter *jit, int i);
9.71 +
9.72 +/**
9.73 +* Bound checking for the tracker stack,
9.74 +*/
9.75 +void JIT_VerifyLowBoundTracker(sp_context_t *ctx);
9.76 +void JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
9.77 +
9.78 +/**
9.79 +* Writes the push into tracker function.
9.80 +*/
9.81 +void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg);
9.82 +
9.83 +/**
9.84 + * Legend for Statuses:
9.85 + * ****** *** ********
9.86 + * DONE -> code generation is done
9.87 + * !GEN -> code generation is deliberate skipped because:
9.88 + * (default): compiler does not generate
9.89 + * DEPRECATED: this feature no longer exists/supported
9.90 + * UNSUPPORTED: this opcode is not supported
9.91 + * TODO: done in case needed
9.92 + * VERIFIED -> code generation is checked as run-time working. prefixes:
9.93 + * ! errors are not checked yet.
9.94 + * - non-inline errors are not checked yet.
9.95 + * ~ assumed checked because of related variation, but not actually checked
9.96 + */
9.97 +
9.98 +typedef enum
9.99 +{
9.100 + OP_NONE, /* invalid opcode */
9.101 + OP_LOAD_PRI, //!VERIFIED
9.102 + OP_LOAD_ALT, //~!VERIFIED (load.pri)
9.103 + OP_LOAD_S_PRI, //VERIFIED
9.104 + OP_LOAD_S_ALT, //VERIFIED
9.105 + OP_LREF_PRI, // !GEN :TODO: we will need this for dynarrays
9.106 + OP_LREF_ALT, // !GEN :TODO: we will need this for dynarrays
9.107 + OP_LREF_S_PRI, //VERIFIED
9.108 + OP_LREF_S_ALT, //~VERIFIED (lref.s.pri)
9.109 + OP_LOAD_I, //VERIFIED
9.110 + OP_LODB_I, //VERIFIED
9.111 + OP_CONST_PRI, //VERIFIED
9.112 + OP_CONST_ALT, //~VERIFIED (const.pri)
9.113 + OP_ADDR_PRI, //VERIFIED
9.114 + OP_ADDR_ALT, //VERIFIED
9.115 + OP_STOR_PRI, //VERIFIED
9.116 + OP_STOR_ALT, //~VERIFIED (stor.pri)
9.117 + OP_STOR_S_PRI, //VERIFIED
9.118 + OP_STOR_S_ALT, //~VERIFIED (stor.s.pri)
9.119 + OP_SREF_PRI, // !GEN :TODO: we will need this for dynarrays
9.120 + OP_SREF_ALT, // !GEN :TODO: we will need this for dynarrays
9.121 + OP_SREF_S_PRI, //VERIFIED
9.122 + OP_SREF_S_ALT, //~VERIFIED (stor.s.alt)
9.123 + OP_STOR_I, //VERIFIED
9.124 + OP_STRB_I, //VERIFIED
9.125 + OP_LIDX, //VERIFIED
9.126 + OP_LIDX_B, //DONE
9.127 + OP_IDXADDR, //VERIFIED
9.128 + OP_IDXADDR_B, //DONE
9.129 + OP_ALIGN_PRI, // !GEN :TODO: - only used for pack access, drop support in compiler first
9.130 + OP_ALIGN_ALT, // !GEN :TODO: - only used for pack access, drop support in compiler first
9.131 + OP_LCTRL, // !GEN
9.132 + OP_SCTRL, // !GEN
9.133 + OP_MOVE_PRI, //~VERIFIED (move.alt)
9.134 + OP_MOVE_ALT, //VERIFIED
9.135 + OP_XCHG, //DONE
9.136 + OP_PUSH_PRI, //DONE
9.137 + OP_PUSH_ALT, //DONE
9.138 + OP_PUSH_R, // !GEN DEPRECATED
9.139 + OP_PUSH_C, //VERIFIED
9.140 + OP_PUSH, //DONE
9.141 + OP_PUSH_S, //VERIFIED
9.142 + OP_POP_PRI, //VERIFIED
9.143 + OP_POP_ALT, //VERIFIED
9.144 + OP_STACK, //VERIFIED
9.145 + OP_HEAP, //VERIFIED
9.146 + OP_PROC, //VERIFIED
9.147 + OP_RET, // !GEN
9.148 + OP_RETN, //VERIFIED
9.149 + OP_CALL, //VERIFIED
9.150 + OP_CALL_PRI, // !GEN
9.151 + OP_JUMP, //VERIFIED
9.152 + OP_JREL, // !GEN
9.153 + OP_JZER, //VERIFIED
9.154 + OP_JNZ, //DONE
9.155 + OP_JEQ, //VERIFIED
9.156 + OP_JNEQ, //VERIFIED
9.157 + OP_JLESS, // !GEN
9.158 + OP_JLEQ, // !GEN
9.159 + OP_JGRTR, // !GEN
9.160 + OP_JGEQ, // !GEN
9.161 + OP_JSLESS, //VERIFIED
9.162 + OP_JSLEQ, //VERIFIED
9.163 + OP_JSGRTR, //VERIFIED
9.164 + OP_JSGEQ, //VERIFIED
9.165 + OP_SHL, //VERIFIED
9.166 + OP_SHR, //VERIFIED (Note: operator >>>)
9.167 + OP_SSHR, //VERIFIED (Note: operator >>)
9.168 + OP_SHL_C_PRI, //DONE
9.169 + OP_SHL_C_ALT, //DONE
9.170 + OP_SHR_C_PRI, //DONE
9.171 + OP_SHR_C_ALT, //DONE
9.172 + OP_SMUL, //VERIFIED
9.173 + OP_SDIV, //DONE
9.174 + OP_SDIV_ALT, //VERIFIED
9.175 + OP_UMUL, // !GEN
9.176 + OP_UDIV, // !GEN
9.177 + OP_UDIV_ALT, // !GEN
9.178 + OP_ADD, //VERIFIED
9.179 + OP_SUB, //DONE
9.180 + OP_SUB_ALT, //VERIFIED
9.181 + OP_AND, //VERIFIED
9.182 + OP_OR, //VERIFIED
9.183 + OP_XOR, //VERIFIED
9.184 + OP_NOT, //VERIFIED
9.185 + OP_NEG, //VERIFIED
9.186 + OP_INVERT, //VERIFIED
9.187 + OP_ADD_C, //VERIFIED
9.188 + OP_SMUL_C, //VERIFIED
9.189 + OP_ZERO_PRI, //VERIFIED
9.190 + OP_ZERO_ALT, //~VERIFIED
9.191 + OP_ZERO, //VERIFIED
9.192 + OP_ZERO_S, //VERIFIED
9.193 + OP_SIGN_PRI, //DONE
9.194 + OP_SIGN_ALT, //DONE
9.195 + OP_EQ, //VERIFIED
9.196 + OP_NEQ, //VERIFIED
9.197 + OP_LESS, // !GEN
9.198 + OP_LEQ, // !GEN
9.199 + OP_GRTR, // !GEN
9.200 + OP_GEQ, // !GEN
9.201 + OP_SLESS, //VERIFIED
9.202 + OP_SLEQ, //VERIFIED
9.203 + OP_SGRTR, //VERIFIED
9.204 + OP_SGEQ, //VERIFIED
9.205 + OP_EQ_C_PRI, //DONE
9.206 + OP_EQ_C_ALT, //DONE
9.207 + OP_INC_PRI, //VERIFIED
9.208 + OP_INC_ALT, //~VERIFIED (inc.pri)
9.209 + OP_INC, //VERIFIED
9.210 + OP_INC_S, //VERIFIED
9.211 + OP_INC_I, //VERIFIED
9.212 + OP_DEC_PRI, //VERIFIED
9.213 + OP_DEC_ALT, //~VERIFIED (dec.pri)
9.214 + OP_DEC, //VERIFIED
9.215 + OP_DEC_S, //VERIFIED
9.216 + OP_DEC_I, //VERIFIED
9.217 + OP_MOVS, //VERIFIED
9.218 + OP_CMPS, // !GEN
9.219 + OP_FILL, //VERIFIED
9.220 + OP_HALT, //DONE
9.221 + OP_BOUNDS, //VERIFIED
9.222 + OP_SYSREQ_PRI, // !GEN
9.223 + OP_SYSREQ_C, //VERIFIED
9.224 + OP_FILE, // !GEN DEPRECATED
9.225 + OP_LINE, // !GEN DEPRECATED
9.226 + OP_SYMBOL, // !GEN DEPRECATED
9.227 + OP_SRANGE, // !GEN DEPRECATED
9.228 + OP_JUMP_PRI, // !GEN
9.229 + OP_SWITCH, //VERIFIED
9.230 + OP_CASETBL, //VERIFIED
9.231 + OP_SWAP_PRI, //VERIFIED
9.232 + OP_SWAP_ALT, //~VERIFIED (swap.alt)
9.233 + OP_PUSH_ADR, //VERIFIED
9.234 + OP_NOP, //VERIFIED (lol)
9.235 + OP_SYSREQ_N, //VERIFIED
9.236 + OP_SYMTAG, // !GEN DEPRECATED
9.237 + OP_BREAK, //DONE
9.238 + OP_PUSH2_C, //~VERIFIED (push3.c)
9.239 + OP_PUSH2, //VERIFIED
9.240 + OP_PUSH2_S, //VERIFIED
9.241 + OP_PUSH2_ADR, //VERIFIED
9.242 + OP_PUSH3_C, //VERIFIED
9.243 + OP_PUSH3, //~VERIFIED (push2)
9.244 + OP_PUSH3_S, //~VERIFIED (push2.s)
9.245 + OP_PUSH3_ADR, //~VERIFIED (push2.adr)
9.246 + OP_PUSH4_C, //~VERIFIED (push3.c)
9.247 + OP_PUSH4, //~VERIFIED (push2)
9.248 + OP_PUSH4_S, //~VERIFIED (push2.s)
9.249 + OP_PUSH4_ADR, //~VERIFIED (push2.adr)
9.250 + OP_PUSH5_C, //~VERIFIED (push3.c)
9.251 + OP_PUSH5, //~VERIFIED (push2)
9.252 + OP_PUSH5_S, //~VERIFIED (push2.s)
9.253 + OP_PUSH5_ADR, //~VERIFIED (push2.adr)
9.254 + OP_LOAD_BOTH, //VERIFIED
9.255 + OP_LOAD_S_BOTH, //VERIFIED
9.256 + OP_CONST, //VERIFIED
9.257 + OP_CONST_S, //DONE
9.258 + /* ----- */
9.259 + OP_SYSREQ_D, // !GEN UNSUPPORT
9.260 + OP_SYSREQ_ND, // !GEN UNSUPPORT
9.261 + /* ----- */
9.262 + OP_TRACKER_PUSH_C, //DONE
9.263 + OP_TRACKER_POP_SETHEAP, //VERIFIED
9.264 + OP_GENARRAY, //VERIFIED
9.265 + OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays)
9.266 + /* ----- */
9.267 + OP_NUM_OPCODES
9.268 +} OPCODE;
9.269 +
9.270 +/*
9.271 +* :TODO: List of ASM Opts
9.272 +* from jit_x86.cpp
9.273 +* DONE: Rest of opcodes including the SYSREQ.N inlined version (rev2)
9.274 +* Including genarray and the 2 tracker ones
9.275 +* DONE: ALL ungen opcodes (rev1)
9.276 +* from opcode_helpers.cpp
9.277 +* DONE: SYSREQ.N .C (rev2)
9.278 +* MACRO OPCODES (rev2)
9.279 +* ERROR CHECKS\{VERIFY ADDR} (rev2)
9.280 +* ARRAY STUFF
9.281 +* TODO: BrkDebug
9.282 +* EXEC FUNCTION
9.283 +* VERIFY ADDR
9.284 +*
9.285 +* Oh and ALIGN all stuff that is called via CALL like what's done with PROC.
9.286 +*/
9.287 +
9.288 +#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/sourcepawn/jit/x86/opcode_switch.inc Wed Nov 08 06:24:28 2006 +0000
10.3 @@ -0,0 +1,684 @@
10.4 + case OP_MOVE_PRI:
10.5 + {
10.6 + WriteOp_Move_Pri(jit);
10.7 + break;
10.8 + }
10.9 + case OP_MOVE_ALT:
10.10 + {
10.11 + WriteOp_Move_Alt(jit);
10.12 + break;
10.13 + }
10.14 + case OP_XCHG:
10.15 + {
10.16 + WriteOp_Xchg(jit);
10.17 + break;
10.18 + }
10.19 + case OP_PUSH:
10.20 + {
10.21 + WriteOp_Push(jit);
10.22 + break;
10.23 + }
10.24 + case OP_PUSH_S:
10.25 + {
10.26 + WriteOp_Push_S(jit);
10.27 + break;
10.28 + }
10.29 + case OP_PUSH2_C:
10.30 + {
10.31 + WriteOp_Push2_C(jit);
10.32 + break;
10.33 + }
10.34 + case OP_PUSH3_C:
10.35 + {
10.36 + WriteOp_Push3_C(jit);
10.37 + break;
10.38 + }
10.39 + case OP_PUSH4_C:
10.40 + {
10.41 + WriteOp_Push4_C(jit);
10.42 + break;
10.43 + }
10.44 + case OP_PUSH5_C:
10.45 + {
10.46 + WriteOp_Push5_C(jit);
10.47 + break;
10.48 + }
10.49 + case OP_PUSH2_ADR:
10.50 + {
10.51 + WriteOp_Push2_Adr(jit);
10.52 + break;
10.53 + }
10.54 + case OP_PUSH3_ADR:
10.55 + {
10.56 + WriteOp_Push3_Adr(jit);
10.57 + break;
10.58 + }
10.59 + case OP_PUSH4_ADR:
10.60 + {
10.61 + WriteOp_Push4_Adr(jit);
10.62 + break;
10.63 + }
10.64 + case OP_PUSH5_ADR:
10.65 + {
10.66 + WriteOp_Push5_Adr(jit);
10.67 + break;
10.68 + }
10.69 + case OP_PUSH2_S:
10.70 + {
10.71 + WriteOp_Push2_S(jit);
10.72 + break;
10.73 + }
10.74 + case OP_PUSH3_S:
10.75 + {
10.76 + WriteOp_Push3_S(jit);
10.77 + break;
10.78 + }
10.79 + case OP_PUSH4_S:
10.80 + {
10.81 + WriteOp_Push4_S(jit);
10.82 + break;
10.83 + }
10.84 + case OP_PUSH5_S:
10.85 + {
10.86 + WriteOp_Push5_S(jit);
10.87 + break;
10.88 + }
10.89 + case OP_PUSH5:
10.90 + {
10.91 + WriteOp_Push5(jit);
10.92 + break;
10.93 + }
10.94 + case OP_PUSH4:
10.95 + {
10.96 + WriteOp_Push4(jit);
10.97 + break;
10.98 + }
10.99 + case OP_PUSH3:
10.100 + {
10.101 + WriteOp_Push3(jit);
10.102 + break;
10.103 + }
10.104 + case OP_PUSH2:
10.105 + {
10.106 + WriteOp_Push2(jit);
10.107 + break;
10.108 + }
10.109 + case OP_ZERO_PRI:
10.110 + {
10.111 + WriteOp_Zero_Pri(jit);
10.112 + break;
10.113 + }
10.114 + case OP_ZERO_ALT:
10.115 + {
10.116 + WriteOp_Zero_Alt(jit);
10.117 + break;
10.118 + }
10.119 + case OP_PROC:
10.120 + {
10.121 + WriteOp_Proc(jit);
10.122 + break;
10.123 + }
10.124 + case OP_SHL:
10.125 + {
10.126 + WriteOp_Shl(jit);
10.127 + break;
10.128 + }
10.129 + case OP_SHR:
10.130 + {
10.131 + WriteOp_Shr(jit);
10.132 + break;
10.133 + }
10.134 + case OP_SSHR:
10.135 + {
10.136 + WriteOp_Sshr(jit);
10.137 + break;
10.138 + }
10.139 + case OP_SHL_C_PRI:
10.140 + {
10.141 + WriteOp_Shl_C_Pri(jit);
10.142 + break;
10.143 + }
10.144 + case OP_SHL_C_ALT:
10.145 + {
10.146 + WriteOp_Shl_C_Alt(jit);
10.147 + break;
10.148 + }
10.149 + case OP_SHR_C_PRI:
10.150 + {
10.151 + WriteOp_Shr_C_Pri(jit);
10.152 + break;
10.153 + }
10.154 + case OP_SHR_C_ALT:
10.155 + {
10.156 + WriteOp_Shr_C_Alt(jit);
10.157 + break;
10.158 + }
10.159 + case OP_SMUL:
10.160 + {
10.161 + WriteOp_SMul(jit);
10.162 + break;
10.163 + }
10.164 + case OP_ADD:
10.165 + {
10.166 + WriteOp_Add(jit);
10.167 + break;
10.168 + }
10.169 + case OP_SUB:
10.170 + {
10.171 + WriteOp_Sub(jit);
10.172 + break;
10.173 + }
10.174 + case OP_SUB_ALT:
10.175 + {
10.176 + WriteOp_Sub_Alt(jit);
10.177 + break;
10.178 + }
10.179 + case OP_NOP:
10.180 + {
10.181 + /* do nothing */
10.182 + break;
10.183 + }
10.184 + case OP_NOT:
10.185 + {
10.186 + WriteOp_Not(jit);
10.187 + break;
10.188 + }
10.189 + case OP_NEG:
10.190 + {
10.191 + WriteOp_Neg(jit);
10.192 + break;
10.193 + }
10.194 + case OP_XOR:
10.195 + {
10.196 + WriteOp_Xor(jit);
10.197 + break;
10.198 + }
10.199 + case OP_OR:
10.200 + {
10.201 + WriteOp_Or(jit);
10.202 + break;
10.203 + }
10.204 + case OP_AND:
10.205 + {
10.206 + WriteOp_And(jit);
10.207 + break;
10.208 + }
10.209 + case OP_INVERT:
10.210 + {
10.211 + WriteOp_Invert(jit);
10.212 + break;
10.213 + }
10.214 + case OP_ADD_C:
10.215 + {
10.216 + WriteOp_Add_C(jit);
10.217 + break;
10.218 + }
10.219 + case OP_SMUL_C:
10.220 + {
10.221 + WriteOp_SMul_C(jit);
10.222 + break;
10.223 + }
10.224 + case OP_SIGN_PRI:
10.225 + {
10.226 + WriteOp_Sign_Pri(jit);
10.227 + break;
10.228 + }
10.229 + case OP_SIGN_ALT:
10.230 + {
10.231 + WriteOp_Sign_Alt(jit);
10.232 + break;
10.233 + }
10.234 + case OP_EQ:
10.235 + {
10.236 + WriteOp_Eq(jit);
10.237 + break;
10.238 + }
10.239 + case OP_NEQ:
10.240 + {
10.241 + WriteOp_Neq(jit);
10.242 + break;
10.243 + }
10.244 + case OP_SLESS:
10.245 + {
10.246 + WriteOp_Sless(jit);
10.247 + break;
10.248 + }
10.249 + case OP_SLEQ:
10.250 + {
10.251 + WriteOp_Sleq(jit);
10.252 + break;
10.253 + }
10.254 + case OP_SGRTR:
10.255 + {
10.256 + WriteOp_Sgrtr(jit);
10.257 + break;
10.258 + }
10.259 + case OP_SGEQ:
10.260 + {
10.261 + WriteOp_Sgeq(jit);
10.262 + break;
10.263 + }
10.264 + case OP_EQ_C_PRI:
10.265 + {
10.266 + WriteOp_Eq_C_Pri(jit);
10.267 + break;
10.268 + }
10.269 + case OP_EQ_C_ALT:
10.270 + {
10.271 + WriteOp_Eq_C_Alt(jit);
10.272 + break;
10.273 + }
10.274 + case OP_INC_PRI:
10.275 + {
10.276 + WriteOp_Inc_Pri(jit);
10.277 + break;
10.278 + }
10.279 + case OP_INC_ALT:
10.280 + {
10.281 + WriteOp_Inc_Alt(jit);
10.282 + break;
10.283 + }
10.284 + case OP_INC:
10.285 + {
10.286 + WriteOp_Inc(jit);
10.287 + break;
10.288 + }
10.289 + case OP_INC_S:
10.290 + {
10.291 + WriteOp_Inc_S(jit);
10.292 + break;
10.293 + }
10.294 + case OP_INC_I:
10.295 + {
10.296 + WriteOp_Inc_I(jit);
10.297 + break;
10.298 + }
10.299 + case OP_DEC_PRI:
10.300 + {
10.301 + WriteOp_Dec_Pri(jit);
10.302 + break;
10.303 + }
10.304 + case OP_DEC_ALT:
10.305 + {
10.306 + WriteOp_Dec_Alt(jit);
10.307 + break;
10.308 + }
10.309 + case OP_DEC:
10.310 + {
10.311 + WriteOp_Dec(jit);
10.312 + break;
10.313 + }
10.314 + case OP_DEC_S:
10.315 + {
10.316 + WriteOp_Dec_S(jit);
10.317 + break;
10.318 + }
10.319 + case OP_DEC_I:
10.320 + {
10.321 + WriteOp_Dec_I(jit);
10.322 + break;
10.323 + }
10.324 + case OP_LOAD_PRI:
10.325 + {
10.326 + WriteOp_Load_Pri(jit);
10.327 + break;
10.328 + }
10.329 + case OP_LOAD_ALT:
10.330 + {
10.331 + WriteOp_Load_Alt(jit);
10.332 + break;
10.333 + }
10.334 + case OP_LOAD_S_PRI:
10.335 + {
10.336 + WriteOp_Load_S_Pri(jit);
10.337 + break;
10.338 + }
10.339 + case OP_LOAD_S_ALT:
10.340 + {
10.341 + WriteOp_Load_S_Alt(jit);
10.342 + break;
10.343 + }
10.344 + case OP_LREF_PRI:
10.345 + {
10.346 + WriteOp_Lref_Pri(jit);
10.347 + break;
10.348 + }
10.349 + case OP_LREF_ALT:
10.350 + {
10.351 + WriteOp_Lref_Alt(jit);
10.352 + break;
10.353 + }
10.354 + case OP_LREF_S_PRI:
10.355 + {
10.356 + WriteOp_Lref_S_Pri(jit);
10.357 + break;
10.358 + }
10.359 + case OP_LREF_S_ALT:
10.360 + {
10.361 + WriteOp_Lref_S_Alt(jit);
10.362 + break;
10.363 + }
10.364 + case OP_CONST_PRI:
10.365 + {
10.366 + WriteOp_Const_Pri(jit);
10.367 + break;
10.368 + }
10.369 + case OP_CONST_ALT:
10.370 + {
10.371 + WriteOp_Const_Alt(jit);
10.372 + break;
10.373 + }
10.374 + case OP_ADDR_PRI:
10.375 + {
10.376 + WriteOp_Addr_Pri(jit);
10.377 + break;
10.378 + }
10.379 + case OP_ADDR_ALT:
10.380 + {
10.381 + WriteOp_Addr_Alt(jit);
10.382 + break;
10.383 + }
10.384 + case OP_STOR_PRI:
10.385 + {
10.386 + WriteOp_Stor_Pri(jit);
10.387 + break;
10.388 + }
10.389 + case OP_STOR_ALT:
10.390 + {
10.391 + WriteOp_Stor_Alt(jit);
10.392 + break;
10.393 + }
10.394 + case OP_STOR_S_PRI:
10.395 + {
10.396 + WriteOp_Stor_S_Pri(jit);
10.397 + break;
10.398 + }
10.399 + case OP_STOR_S_ALT:
10.400 + {
10.401 + WriteOp_Stor_S_Alt(jit);
10.402 + break;
10.403 + }
10.404 + case OP_IDXADDR:
10.405 + {
10.406 + WriteOp_Idxaddr(jit);
10.407 + break;
10.408 + }
10.409 + case OP_SREF_PRI:
10.410 + {
10.411 + WriteOp_Sref_Pri(jit);
10.412 + break;
10.413 + }
10.414 + case OP_SREF_ALT:
10.415 + {
10.416 + WriteOp_Sref_Alt(jit);
10.417 + break;
10.418 + }
10.419 + case OP_SREF_S_PRI:
10.420 + {
10.421 + WriteOp_Sref_S_Pri(jit);
10.422 + break;
10.423 + }
10.424 + case OP_SREF_S_ALT:
10.425 + {
10.426 + WriteOp_Sref_S_Alt(jit);
10.427 + break;
10.428 + }
10.429 + case OP_POP_PRI:
10.430 + {
10.431 + WriteOp_Pop_Pri(jit);
10.432 + break;
10.433 + }
10.434 + case OP_POP_ALT:
10.435 + {
10.436 + WriteOp_Pop_Alt(jit);
10.437 + break;
10.438 + }
10.439 + case OP_SWAP_PRI:
10.440 + {
10.441 + WriteOp_Swap_Pri(jit);
10.442 + break;
10.443 + }
10.444 + case OP_SWAP_ALT:
10.445 + {
10.446 + WriteOp_Swap_Alt(jit);
10.447 + break;
10.448 + }
10.449 + case OP_PUSH_ADR:
10.450 + {
10.451 + WriteOp_PushAddr(jit);
10.452 + break;
10.453 + }
10.454 + case OP_MOVS:
10.455 + {
10.456 + WriteOp_Movs(jit);
10.457 + break;
10.458 + }
10.459 + case OP_FILL:
10.460 + {
10.461 + WriteOp_Fill(jit);
10.462 + break;
10.463 + }
10.464 + case OP_PUSH_C:
10.465 + {
10.466 + WriteOp_Push_C(jit);
10.467 + break;
10.468 + }
10.469 + case OP_ZERO:
10.470 + {
10.471 + WriteOp_Zero(jit);
10.472 + break;
10.473 + }
10.474 + case OP_ZERO_S:
10.475 + {
10.476 + WriteOp_Zero_S(jit);
10.477 + break;
10.478 + }
10.479 + case OP_PUSH_PRI:
10.480 + {
10.481 + WriteOp_Push_Pri(jit);
10.482 + break;
10.483 + }
10.484 + case OP_PUSH_ALT:
10.485 + {
10.486 + WriteOp_Push_Alt(jit);
10.487 + break;
10.488 + }
10.489 + case OP_LOAD_BOTH:
10.490 + {
10.491 + WriteOp_Load_Both(jit);
10.492 + break;
10.493 + }
10.494 + case OP_LOAD_S_BOTH:
10.495 + {
10.496 + WriteOp_Load_S_Both(jit);
10.497 + break;
10.498 + }
10.499 + case OP_CONST:
10.500 + {
10.501 + WriteOp_Const(jit);
10.502 + break;
10.503 + }
10.504 + case OP_CONST_S:
10.505 + {
10.506 + WriteOp_Const_S(jit);
10.507 + break;
10.508 + }
10.509 + case OP_LOAD_I:
10.510 + {
10.511 + WriteOp_Load_I(jit);
10.512 + break;
10.513 + }
10.514 + case OP_LODB_I:
10.515 + {
10.516 + WriteOp_Lodb_I(jit);
10.517 + break;
10.518 + }
10.519 + case OP_STOR_I:
10.520 + {
10.521 + WriteOp_Stor_I(jit);
10.522 + break;
10.523 + }
10.524 + case OP_STRB_I:
10.525 + {
10.526 + WriteOp_Strb_I(jit);
10.527 + break;
10.528 + }
10.529 + case OP_LIDX:
10.530 + {
10.531 + WriteOp_Lidx(jit);
10.532 + break;
10.533 + }
10.534 + case OP_LIDX_B:
10.535 + {
10.536 + WriteOp_Lidx_B(jit);
10.537 + break;
10.538 + }
10.539 + case OP_IDXADDR_B:
10.540 + {
10.541 + WriteOp_Idxaddr_B(jit);
10.542 + break;
10.543 + }
10.544 + case OP_STACK:
10.545 + {
10.546 + WriteOp_Stack(jit);
10.547 + break;
10.548 + }
10.549 + case OP_HEAP:
10.550 + {
10.551 + WriteOp_Heap(jit);
10.552 + break;
10.553 + }
10.554 + case OP_SDIV:
10.555 + {
10.556 + WriteOp_SDiv(jit);
10.557 + break;
10.558 + }
10.559 + case OP_SDIV_ALT:
10.560 + {
10.561 + WriteOp_SDiv_Alt(jit);
10.562 + break;
10.563 + }
10.564 + case OP_RETN:
10.565 + {
10.566 + WriteOp_Retn(jit);
10.567 + break;
10.568 + }
10.569 + case OP_BOUNDS:
10.570 + {
10.571 + WriteOp_Bounds(jit);
10.572 + break;
10.573 + }
10.574 + case OP_HALT:
10.575 + {
10.576 + WriteOp_Halt(jit);
10.577 + break;
10.578 + }
10.579 + case OP_BREAK:
10.580 + {
10.581 + WriteOp_Break(jit);
10.582 + break;
10.583 + }
10.584 + case OP_JUMP:
10.585 + {
10.586 + WriteOp_Jump(jit);
10.587 + break;
10.588 + }
10.589 + case OP_JZER:
10.590 + {
10.591 + WriteOp_Jzer(jit);
10.592 + break;
10.593 + }
10.594 + case OP_JNZ:
10.595 + {
10.596 + WriteOp_Jnz(jit);
10.597 + break;
10.598 + }
10.599 + case OP_JEQ:
10.600 + {
10.601 + WriteOp_Jeq(jit);
10.602 + break;
10.603 + }
10.604 + case OP_JNEQ:
10.605 + {
10.606 + WriteOp_Jneq(jit);
10.607 + break;
10.608 + }
10.609 + case OP_JSLESS:
10.610 + {
10.611 + WriteOp_Jsless(jit);
10.612 + break;
10.613 + }
10.614 + case OP_JSGRTR:
10.615 + {
10.616 + WriteOp_JsGrtr(jit);
10.617 + break;
10.618 + }
10.619 + case OP_JSGEQ:
10.620 + {
10.621 + WriteOp_JsGeq(jit);
10.622 + break;
10.623 + }
10.624 + case OP_JSLEQ:
10.625 + {
10.626 + WriteOp_Jsleq(jit);
10.627 + break;
10.628 + }
10.629 + case OP_SWITCH:
10.630 + {
10.631 + WriteOp_Switch(jit);
10.632 + break;
10.633 + }
10.634 + case OP_CASETBL:
10.635 + {
10.636 + WriteOp_Casetbl(jit);
10.637 + break;
10.638 + }
10.639 + case OP_CALL:
10.640 + {
10.641 + WriteOp_Call(jit);
10.642 + break;
10.643 + }
10.644 + case OP_SYSREQ_C:
10.645 + {
10.646 + WriteOp_Sysreq_C(jit);
10.647 + break;
10.648 + }
10.649 + case OP_SYSREQ_N:
10.650 + {
10.651 + if (data->inline_level & JIT_INLINE_NATIVES)
10.652 + {
10.653 + WriteOp_Sysreq_N(jit);
10.654 + } else {
10.655 + WriteOp_Sysreq_N_NoInline(jit);
10.656 + }
10.657 + break;
10.658 + }
10.659 + case OP_TRACKER_PUSH_C:
10.660 + {
10.661 + WriteOp_Tracker_Push_C(jit);
10.662 + break;
10.663 + }
10.664 + case OP_TRACKER_POP_SETHEAP:
10.665 + {
10.666 + WriteOp_Tracker_Pop_SetHeap(jit);
10.667 + break;
10.668 + }
10.669 + case OP_GENARRAY:
10.670 + {
10.671 + WriteOp_GenArray(jit, false);
10.672 + break;
10.673 + }
10.674 + case OP_GENARRAY_Z:
10.675 + {
10.676 + WriteOp_GenArray(jit, true);
10.677 + break;
10.678 + }
10.679 +#if defined USE_UNGEN_OPCODES
10.680 + #include "ungen_opcode_switch.inc"
10.681 +#endif
10.682 + default:
10.683 + {
10.684 + data->error_set = SP_ERROR_INVALID_INSTRUCTION;
10.685 + break;
10.686 + }
10.687 +
10.688 \ No newline at end of file
11.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
11.2 +++ b/sourcepawn/jit/x86/ungen_opcode_switch.inc Wed Nov 08 06:24:28 2006 +0000
11.3 @@ -0,0 +1,90 @@
11.4 + case OP_UMUL:
11.5 + {
11.6 + WriteOp_UMul(jit);
11.7 + break;
11.8 + }
11.9 + case OP_LESS:
11.10 + {
11.11 + WriteOp_Less(jit);
11.12 + break;
11.13 + }
11.14 + case OP_LEQ:
11.15 + {
11.16 + WriteOp_Leq(jit);
11.17 + break;
11.18 + }
11.19 + case OP_GRTR:
11.20 + {
11.21 + WriteOp_Grtr(jit);
11.22 + break;
11.23 + }
11.24 + case OP_GEQ:
11.25 + {
11.26 + WriteOp_Geq(jit);
11.27 + break;
11.28 + }
11.29 + case OP_ALIGN_PRI:
11.30 + {
11.31 + WriteOp_Align_Pri(jit);
11.32 + break;
11.33 + }
11.34 + case OP_ALIGN_ALT:
11.35 + {
11.36 + WriteOp_Align_Alt(jit);
11.37 + break;
11.38 + }
11.39 + case OP_LCTRL:
11.40 + {
11.41 + WriteOp_Lctrl(jit);
11.42 + break;
11.43 + }
11.44 + case OP_SCTRL:
11.45 + {
11.46 + WriteOp_Sctrl(jit);
11.47 + break;
11.48 + }
11.49 + case OP_UDIV:
11.50 + {
11.51 + WriteOp_UDiv(jit);
11.52 + break;
11.53 + }
11.54 + case OP_UDIV_ALT:
11.55 + {
11.56 + WriteOp_UDiv_Alt(jit);
11.57 + break;
11.58 + }
11.59 + case OP_RET:
11.60 + {
11.61 + WriteOp_Ret(jit);
11.62 + break;
11.63 + }
11.64 + case OP_CMPS:
11.65 + {
11.66 + WriteOp_Cmps(jit);
11.67 + break;
11.68 + }
11.69 + case OP_JREL:
11.70 + {
11.71 + WriteOp_JRel(jit);
11.72 + break;
11.73 + }
11.74 + case OP_JLESS:
11.75 + {
11.76 + WriteOp_Jless(jit);
11.77 + break;
11.78 + }
11.79 + case OP_JLEQ:
11.80 + {
11.81 + WriteOp_Jeq(jit);
11.82 + break;
11.83 + }
11.84 + case OP_JGRTR:
11.85 + {
11.86 + WriteOp_Jgrtr(jit);
11.87 + break;
11.88 + }
11.89 + case OP_JGEQ:
11.90 + {
11.91 + WriteOp_Jgeq(jit);
11.92 + break;
11.93 + }
11.94 \ No newline at end of file
12.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
12.2 +++ b/sourcepawn/jit/x86/ungen_opcodes.h Wed Nov 08 06:24:28 2006 +0000
12.3 @@ -0,0 +1,294 @@
12.4 +#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
12.5 +#define _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
12.6 +
12.7 +inline void WriteOp_UMul(JitWriter *jit)
12.8 +{
12.9 + //mov ecx, edx
12.10 + //mul edx
12.11 + //mov edx, ecx
12.12 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
12.13 + IA32_Mul_Rm(jit, AMX_REG_ALT, MOD_REG);
12.14 + IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
12.15 +}
12.16 +
12.17 +inline void WriteOp_Less(JitWriter *jit)
12.18 +{
12.19 + //cmp eax, edx ; PRI < ALT ? (unsigned)
12.20 + //mov eax, 0
12.21 + //setb al
12.22 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.23 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
12.24 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_B);
12.25 +}
12.26 +
12.27 +inline void WriteOp_Leq(JitWriter *jit)
12.28 +{
12.29 + //cmp eax, edx ; PRI <= ALT ? (unsigned)
12.30 + //mov eax, 0
12.31 + //setbe al
12.32 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.33 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
12.34 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_BE);
12.35 +}
12.36 +
12.37 +inline void WriteOp_Grtr(JitWriter *jit)
12.38 +{
12.39 + //cmp eax, edx ; PRI > ALT ? (unsigned)
12.40 + //mov eax, 0
12.41 + //seta al
12.42 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.43 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
12.44 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_A);
12.45 +}
12.46 +
12.47 +inline void WriteOp_Geq(JitWriter *jit)
12.48 +{
12.49 + //cmp eax, edx ; PRI >= ALT ? (unsigned)
12.50 + //mov eax, 0
12.51 + //setae al
12.52 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.53 + IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
12.54 + IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_AE);
12.55 +}
12.56 +
12.57 +inline void WriteOp_Align_Pri(JitWriter *jit)
12.58 +{
12.59 + //xor eax, <cellsize - val>
12.60 + cell_t val = sizeof(cell_t) - jit->read_cell();
12.61 + if (val < SCHAR_MAX && val > SCHAR_MIN)
12.62 + {
12.63 + IA32_Xor_Rm_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
12.64 + } else {
12.65 + IA32_Xor_Eax_Imm32(jit, val);
12.66 + }
12.67 +}
12.68 +
12.69 +inline void WriteOp_Align_Alt(JitWriter *jit)
12.70 +{
12.71 + //xor edx, <cellsize - val>
12.72 + cell_t val = sizeof(cell_t) - jit->read_cell();
12.73 + if (val < SCHAR_MAX && val > SCHAR_MIN)
12.74 + {
12.75 + IA32_Xor_Rm_Imm8(jit, AMX_REG_ALT, MOD_REG, (jit_int8_t)val);
12.76 + } else {
12.77 + IA32_Xor_Rm_Imm32(jit, AMX_REG_ALT, MOD_REG, val);
12.78 + }
12.79 +}
12.80 +
12.81 +inline void WriteOp_Cmps(JitWriter *jit)
12.82 +{
12.83 + //push edi
12.84 + //push esi
12.85 + //lea esi, [ebp+edx]
12.86 + //lea edi, [ebp+eax]
12.87 + //mov ecx, <val>
12.88 + unsigned int val = jit->read_cell();
12.89 +
12.90 + IA32_Push_Reg(jit, REG_EDI);
12.91 + IA32_Push_Reg(jit, REG_ESI);
12.92 + IA32_Lea_Reg_DispEBPRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
12.93 + IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
12.94 + IA32_Mov_Reg_Imm32(jit, REG_ECX, val);
12.95 +
12.96 + //xor eax, eax
12.97 + //repe cmpsb
12.98 + //je :cmps1
12.99 + IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
12.100 + IA32_Rep(jit);
12.101 + IA32_Cmpsb(jit);
12.102 + jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_E, 0);
12.103 +
12.104 + //sbb eax, eax
12.105 + //sbb eax, -1
12.106 + IA32_Sbb_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
12.107 + IA32_Sbb_Rm_Imm8(jit, AMX_REG_PRI, -1, MOD_REG);
12.108 +
12.109 + //:cmps1
12.110 + //pop esi
12.111 + //pop edi
12.112 + IA32_Send_Jump8_Here(jit, jmp);
12.113 + IA32_Pop_Reg(jit, REG_ESI);
12.114 + IA32_Pop_Reg(jit, REG_EDI);
12.115 +}
12.116 +
12.117 +inline void WriteOp_Lctrl(JitWriter *jit)
12.118 +{
12.119 + cell_t val = jit->read_cell();
12.120 + switch (val)
12.121 + {
12.122 + case 0:
12.123 + {
12.124 + //mov ecx, [esi+ctx]
12.125 + //mov eax, [ecx+ctx.codebase]
12.126 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
12.127 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, codebase));
12.128 + break;
12.129 + }
12.130 + case 1:
12.131 + {
12.132 + //mov eax, ebp
12.133 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
12.134 + break;
12.135 + }
12.136 + case 2:
12.137 + {
12.138 + //mov eax, [esi+hea]
12.139 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_HEAP);
12.140 + break;
12.141 + }
12.142 + case 3:
12.143 + {
12.144 + //mov ecx, [esi+ctx]
12.145 + //mov eax, [ecx+ctx.memory]
12.146 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
12.147 + IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, memory));
12.148 + break;
12.149 + }
12.150 + case 4:
12.151 + {
12.152 + //mov eax, edi
12.153 + //sub eax, ebp - unrelocate
12.154 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_REG);
12.155 + IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
12.156 + break;
12.157 + }
12.158 + case 5:
12.159 + {
12.160 + //mov eax, [esi+frm]
12.161 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
12.162 + break;
12.163 + }
12.164 + case 6:
12.165 + {
12.166 + //mov eax, [cip]
12.167 + jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
12.168 + jitoffs_t save = jit->get_outputpos();
12.169 + jit->set_outputpos(imm32);
12.170 + jit->write_int32((uint32_t)(jit->outbase + save));
12.171 + jit->set_outputpos(save);
12.172 + break;
12.173 + }
12.174 + }
12.175 +}
12.176 +
12.177 +inline void WriteOp_Sctrl(JitWriter *jit)
12.178 +{
12.179 + cell_t val = jit->read_cell();
12.180 + switch (val)
12.181 + {
12.182 + case 2:
12.183 + {
12.184 + //mov [esi+hea], eax
12.185 + IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_PRI, AMX_INFO_HEAP);
12.186 + break;
12.187 + }
12.188 + case 4:
12.189 + {
12.190 + //lea edi, [ebp+eax]
12.191 + IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_STK, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
12.192 + break;
12.193 + }
12.194 + case 5:
12.195 + {
12.196 + //lea ebx, [ebp+eax] - overwrite frm
12.197 + //mov [esi+frm], eax - overwrite stacked frame
12.198 + IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_FRM, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
12.199 + IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_PRI, MOD_MEM_REG);
12.200 + break;
12.201 + }
12.202 + case 6:
12.203 + {
12.204 + IA32_Jump_Reg(jit, AMX_REG_PRI);
12.205 + break;
12.206 + }
12.207 + }
12.208 +}
12.209 +
12.210 +inline void WriteOp_UDiv(JitWriter *jit)
12.211 +{
12.212 + //mov ecx, edx
12.213 + //xor edx, edx
12.214 + //div ecx
12.215 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
12.216 + IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
12.217 + Write_Check_DivZero(jit, AMX_REG_TMP);
12.218 + IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
12.219 +}
12.220 +
12.221 +inline void WriteOp_UDiv_Alt(JitWriter *jit)
12.222 +{
12.223 + //mov ecx, eax
12.224 + //mov eax, edx
12.225 + //xor edx, edx
12.226 + //div ecx
12.227 + IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
12.228 + IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.229 + IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
12.230 + Write_Check_DivZero(jit, AMX_REG_TMP);
12.231 + IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
12.232 +}
12.233 +
12.234 +inline void WriteOp_Ret(JitWriter *jit)
12.235 +{
12.236 + //mov ebx, [edi] - get old FRM
12.237 + //add edi, 4 - pop stack
12.238 + //mov [esi+frm], ebx - restore
12.239 + //add ebx, ebp - relocate
12.240 + //ret
12.241 + IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG);
12.242 + IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
12.243 + IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_FRM, MOD_MEM_REG);
12.244 + IA32_Add_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
12.245 + IA32_Return(jit);
12.246 +}
12.247 +
12.248 +inline void WriteOp_JRel(JitWriter *jit)
12.249 +{
12.250 + //jmp <offs> ;relative jump
12.251 + cell_t cip_offs = jit->read_cell();
12.252 +
12.253 + /* Note that since code size calculation has to be done in the same
12.254 + * phase as building relocation information, we cannot know the jump size
12.255 + * beforehand. Thus, we always write full 32bit jumps for safety.
12.256 + */
12.257 + jitoffs_t jmp = IA32_Jump_Imm32(jit, 0);
12.258 + IA32_Write_Jump32(jit, jmp, RelocLookup(jit, cip_offs));
12.259 +}
12.260 +
12.261 +inline void WriteOp_Jless(JitWriter *jit)
12.262 +{
12.263 + //cmp eax, edx
12.264 + //jb <target>
12.265 + cell_t target = jit->read_cell();
12.266 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.267 + IA32_Jump_Cond_Imm32(jit, CC_B, RelocLookup(jit, target, false));
12.268 +}
12.269 +
12.270 +inline void WriteOp_Jleq(JitWriter *jit)
12.271 +{
12.272 + //cmp eax, edx
12.273 + //jbe <target>
12.274 + cell_t target = jit->read_cell();
12.275 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.276 + IA32_Jump_Cond_Imm32(jit, CC_BE, RelocLookup(jit, target, false));
12.277 +}
12.278 +
12.279 +inline void WriteOp_Jgrtr(JitWriter *jit)
12.280 +{
12.281 + //cmp eax, edx
12.282 + //ja <target>
12.283 + cell_t target = jit->read_cell();
12.284 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.285 + IA32_Jump_Cond_Imm32(jit, CC_A, RelocLookup(jit, target, false));
12.286 +}
12.287 +
12.288 +inline void WriteOp_Jgeq(JitWriter *jit)
12.289 +{
12.290 + //cmp eax, edx
12.291 + //jae <target>
12.292 + cell_t target = jit->read_cell();
12.293 + IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
12.294 + IA32_Jump_Cond_Imm32(jit, CC_AE, RelocLookup(jit, target, false));
12.295 +}
12.296 +
12.297 +#endif //_INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
13.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
13.2 +++ b/sourcepawn/jit/x86/x86_macros.h Wed Nov 08 06:24:28 2006 +0000
13.3 @@ -0,0 +1,1135 @@
13.4 +#ifndef _INCLUDE_JIT_X86_MACROS_H
13.5 +#define _INCLUDE_JIT_X86_MACROS_H
13.6 +
13.7 +#include <limits.h>
13.8 +
13.9 +//MOD R/M
13.10 +#define MOD_MEM_REG 0
13.11 +#define MOD_DISP8 1
13.12 +#define MOD_DISP32 2
13.13 +#define MOD_REG 3
13.14 +
13.15 +//SIB
13.16 +#define NOSCALE 0
13.17 +#define SCALE2 1
13.18 +#define SCALE4 2
13.19 +#define SCALE8 3
13.20 +
13.21 +//Register codes
13.22 +#define REG_EAX 0
13.23 +#define REG_ECX 1
13.24 +#define REG_EDX 2
13.25 +#define REG_EBX 3
13.26 +#define REG_ESP 4
13.27 +#define REG_SIB 4
13.28 +#define REG_NOIDX 4
13.29 +#define REG_IMM_BASE 5
13.30 +#define REG_EBP 5
13.31 +#define REG_ESI 6
13.32 +#define REG_EDI 7
13.33 +
13.34 +#define IA32_16BIT_PREFIX 0x66
13.35 +
13.36 +//condition codes (for example, Jcc opcodes)
13.37 +#define CC_B 0x2
13.38 +#define CC_NAE CC_B
13.39 +#define CC_NB 0x3
13.40 +#define CC_AE CC_NB
13.41 +#define CC_E 0x4
13.42 +#define CC_Z CC_E
13.43 +#define CC_NE 0x5
13.44 +#define CC_NZ CC_NE
13.45 +#define CC_NA 0x6
13.46 +#define CC_BE CC_NA
13.47 +#define CC_A 0x7
13.48 +#define CC_NBE CC_A
13.49 +#define CC_L 0xC
13.50 +#define CC_NGE CC_L
13.51 +#define CC_NL 0xD
13.52 +#define CC_GE CC_NL
13.53 +#define CC_NG 0xE
13.54 +#define CC_LE CC_NG
13.55 +#define CC_G 0xF
13.56 +#define CC_NLE CC_G
13.57 +
13.58 +//Opcodes with encoding information
13.59 +#define IA32_XOR_RM_REG 0x31 // encoding is /r
13.60 +#define IA32_XOR_REG_RM 0x33 // encoding is /r
13.61 +#define IA32_XOR_EAX_IMM32 0x35 // encoding is /r
13.62 +#define IA32_XOR_RM_IMM32 0x81 // encoding is /6
13.63 +#define IA32_XOR_RM_IMM8 0x83 // encoding is /6
13.64 +#define IA32_ADD_RM_REG 0x01 // encoding is /r
13.65 +#define IA32_ADD_REG_RM 0x03 // encoding is /r
13.66 +#define IA32_ADD_RM_IMM32 0x81 // encoding is /0
13.67 +#define IA32_ADD_RM_IMM8 0x83 // encoding is /0
13.68 +#define IA32_ADD_EAX_IMM32 0x05 // no extra encoding
13.69 +#define IA32_SUB_RM_REG 0x29 // encoding is /r
13.70 +#define IA32_SUB_REG_RM 0x2B // encoding is /r
13.71 +#define IA32_SUB_RM_IMM8 0x83 // encoding is /5 <imm8>
13.72 +#define IA32_SUB_RM_IMM32 0x81 // encoding is /5 <imm32>
13.73 +#define IA32_SBB_REG_RM 0x1B // encoding is /r
13.74 +#define IA32_SBB_RM_IMM8 0x83 // encoding is <imm32>
13.75 +#define IA32_JMP_IMM32 0xE9 // encoding is imm32
13.76 +#define IA32_JMP_IMM8 0xEB // encoding is imm8
13.77 +#define IA32_JMP_RM 0xFF // encoding is /4
13.78 +#define IA32_CALL_IMM32 0xE8 // relative call, <imm32>
13.79 +#define IA32_CALL_RM 0xFF // encoding is /2
13.80 +#define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32>
13.81 +#define IA32_MOV_RM8_REG 0x88 // encoding is /r
13.82 +#define IA32_MOV_RM_REG 0x89 // encoding is /r
13.83 +#define IA32_MOV_REG_MEM 0x8B // encoding is /r
13.84 +#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0
13.85 +#define IA32_CMP_RM_IMM32 0x81 // encoding is /7 <imm32>
13.86 +#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 <imm8>
13.87 +#define IA32_CMP_AL_IMM32 0x3C // no extra encoding
13.88 +#define IA32_CMP_EAX_IMM32 0x3D // no extra encoding
13.89 +#define IA32_CMP_RM_REG 0x39 // encoding is /r
13.90 +#define IA32_CMP_REG_RM 0x3B // encoding is /r
13.91 +#define IA32_CMPSB 0xA6 // no extra encoding
13.92 +#define IA32_TEST_RM_REG 0x85 // encoding is /r
13.93 +#define IA32_JCC_IMM 0x70 // encoding is +cc <imm8>
13.94 +#define IA32_JCC_IMM32_1 0x0F // opcode part 1
13.95 +#define IA32_JCC_IMM32_2 0x80 // encoding is +cc <imm32>
13.96 +#define IA32_RET 0xC3 // no extra encoding
13.97 +#define IA32_NEG_RM 0xF7 // encoding is /3
13.98 +#define IA32_INC_REG 0x40 // encoding is +r
13.99 +#define IA32_INC_RM 0xFF // encoding is /0
13.100 +#define IA32_DEC_REG 0x48 // encoding is +r
13.101 +#define IA32_DEC_RM 0xFF // encoding is /1
13.102 +#define IA32_OR_REG_RM 0x0B // encoding is /r
13.103 +#define IA32_AND_REG_RM 0x23 // encoding is /r
13.104 +#define IA32_AND_EAX_IMM32 0x25 // encoding is <imm32>
13.105 +#define IA32_AND_RM_IMM32 0x81 // encoding is /4
13.106 +#define IA32_NOT_RM 0xF7 // encoding is /2
13.107 +#define IA32_DIV_RM 0xF7 // encoding is /6
13.108 +#define IA32_MUL_RM 0xF7 // encoding is /4
13.109 +#define IA32_IDIV_RM 0xF7 // encoding is /7
13.110 +#define IA32_IMUL_RM 0xF7 // encoding is /5
13.111 +#define IA32_IMUL_REG_IMM32 0x69 // encoding is /r
13.112 +#define IA32_IMUL_REG_IMM8 0x6B // encoding is /r
13.113 +#define IA32_IMUL_REG_RM_1 0x0F // encoding is _2
13.114 +#define IA32_IMUL_REG_RM_2 0xAF // encoding is /r
13.115 +#define IA32_SHR_RM_IMM8 0xC1 // encoding is /5 <ib>
13.116 +#define IA32_SHR_RM_1 0xD1 // encoding is /5
13.117 +#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 <ib>
13.118 +#define IA32_SHL_RM_1 0xD1 // encoding is /4
13.119 +#define IA32_SAR_RM_CL 0xD3 // encoding is /7
13.120 +#define IA32_SHR_RM_CL 0xD3 // encoding is /5
13.121 +#define IA32_SHL_RM_CL 0xD3 // encoding is /4
13.122 +#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 <ib>
13.123 +#define IA32_SETCC_RM8_1 0x0F // opcode part 1
13.124 +#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits)
13.125 +#define IA32_XCHG_EAX_REG 0x90 // encoding is +r
13.126 +#define IA32_LEA_REG_MEM 0x8D // encoding is /r
13.127 +#define IA32_POP_REG 0x58 // encoding is +r
13.128 +#define IA32_PUSH_REG 0x50 // encoding is +r
13.129 +#define IA32_PUSH_RM 0xFF // encoding is /6
13.130 +#define IA32_PUSH_IMM32 0x68 // encoding is <imm32>
13.131 +#define IA32_PUSH_IMM8 0x6A // encoding is <imm8>
13.132 +#define IA32_REP 0xF3 // no extra encoding
13.133 +#define IA32_MOVSD 0xA5 // no extra encoding
13.134 +#define IA32_MOVSB 0xA4 // no extra encoding
13.135 +#define IA32_STOSD 0xAB // no extra encoding
13.136 +#define IA32_CLD 0xFC // no extra encoding
13.137 +#define IA32_PUSHAD 0x60 // no extra encoding
13.138 +#define IA32_POPAD 0x61 // no extra encoding
13.139 +#define IA32_NOP 0x90 // no extra encoding
13.140 +#define IA32_INT3 0xCC // no extra encoding
13.141 +
13.142 +inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
13.143 +{
13.144 + jit_uint8_t modrm = (mode << 6);
13.145 +
13.146 + modrm |= (reg << 3);
13.147 + modrm |= (rm);
13.148 +
13.149 + return modrm;
13.150 +}
13.151 +
13.152 +//mode is the scaling method - NOSCALE ... SCALE8
13.153 +//index is the register that is scaled
13.154 +//base is the base register
13.155 +inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t base)
13.156 +{
13.157 + jit_uint8_t sib = (mode << 6);
13.158 +
13.159 + sib |= (index << 3);
13.160 + sib |= (base);
13.161 +
13.162 + return sib;
13.163 +}
13.164 +
13.165 +/***********************
13.166 + * INCREMENT/DECREMENT *
13.167 + ***********************/
13.168 +
13.169 +inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
13.170 +{
13.171 + jit->write_ubyte(IA32_INC_RM);
13.172 + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg));
13.173 + jit->write_int32(disp);
13.174 +}
13.175 +
13.176 +inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
13.177 +{
13.178 + jit->write_ubyte(IA32_INC_RM);
13.179 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, reg));
13.180 + jit->write_byte(disp);
13.181 +}
13.182 +
13.183 +inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
13.184 +{
13.185 + jit->write_ubyte(IA32_INC_RM);
13.186 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB));
13.187 + jit->write_ubyte(ia32_sib(scale, reg, base));
13.188 +}
13.189 +
13.190 +inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg)
13.191 +{
13.192 + jit->write_ubyte(IA32_INC_REG+reg);
13.193 +}
13.194 +
13.195 +inline void IA32_Dec_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
13.196 +{
13.197 + jit->write_ubyte(IA32_DEC_RM);
13.198 + jit->write_ubyte(ia32_modrm(MOD_DISP32, 1, reg));
13.199 + jit->write_int32(disp);
13.200 +}
13.201 +
13.202 +inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
13.203 +{
13.204 + jit->write_ubyte(IA32_DEC_RM);
13.205 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, reg));
13.206 + jit->write_byte(disp);
13.207 +}
13.208 +
13.209 +inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
13.210 +{
13.211 + jit->write_ubyte(IA32_DEC_RM);
13.212 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 1, REG_SIB));
13.213 + jit->write_ubyte(ia32_sib(scale, reg, base));
13.214 +}
13.215 +
13.216 +inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg)
13.217 +{
13.218 + jit->write_ubyte(IA32_DEC_REG+reg);
13.219 +}
13.220 +
13.221 +/****************
13.222 + * BINARY LOGIC *
13.223 + ****************/
13.224 +
13.225 +inline void IA32_Xor_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
13.226 +{
13.227 + jit->write_ubyte(IA32_XOR_RM_REG);
13.228 + jit->write_ubyte(ia32_modrm(dest_mode, src, dest));
13.229 +}
13.230 +
13.231 +inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
13.232 +{
13.233 + jit->write_ubyte(IA32_XOR_REG_RM);
13.234 + jit->write_ubyte(ia32_modrm(dest_mode, dest, src));
13.235 +}
13.236 +
13.237 +inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value)
13.238 +{
13.239 + jit->write_ubyte(IA32_XOR_EAX_IMM32);
13.240 + jit->write_int32(value);
13.241 +}
13.242 +
13.243 +inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
13.244 +{
13.245 + jit->write_ubyte(IA32_XOR_RM_IMM32);
13.246 + jit->write_ubyte(ia32_modrm(mode, 6, reg));
13.247 + jit->write_int32(value);
13.248 +}
13.249 +
13.250 +inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
13.251 +{
13.252 + jit->write_ubyte(IA32_XOR_RM_IMM8);
13.253 + jit->write_ubyte(ia32_modrm(mode, 6, reg));
13.254 + jit->write_byte(value);
13.255 +}
13.256 +
13.257 +inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.258 +{
13.259 + jit->write_ubyte(IA32_NEG_RM);
13.260 + jit->write_ubyte(ia32_modrm(mode, 3, reg));
13.261 +}
13.262 +
13.263 +inline void IA32_Or_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.264 +{
13.265 + jit->write_ubyte(IA32_OR_REG_RM);
13.266 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.267 +}
13.268 +
13.269 +inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.270 +{
13.271 + jit->write_ubyte(IA32_AND_REG_RM);
13.272 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.273 +}
13.274 +
13.275 +inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t c)
13.276 +{
13.277 + if (reg == REG_EAX)
13.278 + {
13.279 + jit->write_ubyte(IA32_AND_EAX_IMM32);
13.280 + } else {
13.281 + jit->write_ubyte(IA32_AND_RM_IMM32);
13.282 + jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg));
13.283 + }
13.284 + jit->write_int32(c);
13.285 +}
13.286 +
13.287 +inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.288 +{
13.289 + jit->write_ubyte(IA32_NOT_RM);
13.290 + jit->write_ubyte(ia32_modrm(mode, 2, reg));
13.291 +}
13.292 +
13.293 +inline void IA32_Shr_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
13.294 +{
13.295 + jit->write_ubyte(IA32_SHR_RM_IMM8);
13.296 + jit->write_ubyte(ia32_modrm(mode, 5, dest));
13.297 + jit->write_ubyte(value);
13.298 +}
13.299 +
13.300 +inline void IA32_Shr_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
13.301 +{
13.302 + jit->write_ubyte(IA32_SHR_RM_1);
13.303 + jit->write_ubyte(ia32_modrm(mode, 5, dest));
13.304 +}
13.305 +
13.306 +inline void IA32_Shl_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
13.307 +{
13.308 + jit->write_ubyte(IA32_SHL_RM_IMM8);
13.309 + jit->write_ubyte(ia32_modrm(mode, 4, dest));
13.310 + jit->write_ubyte(value);
13.311 +}
13.312 +
13.313 +inline void IA32_Shl_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
13.314 +{
13.315 + jit->write_ubyte(IA32_SHL_RM_1);
13.316 + jit->write_ubyte(ia32_modrm(mode, 4, dest));
13.317 +}
13.318 +
13.319 +inline void IA32_Sar_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
13.320 +{
13.321 + jit->write_ubyte(IA32_SAR_RM_IMM8);
13.322 + jit->write_ubyte(ia32_modrm(mode, 7, dest));
13.323 + jit->write_ubyte(value);
13.324 +}
13.325 +
13.326 +inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.327 +{
13.328 + jit->write_ubyte(IA32_SAR_RM_CL);
13.329 + jit->write_ubyte(ia32_modrm(mode, 7, reg));
13.330 +}
13.331 +
13.332 +inline void IA32_Shr_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.333 +{
13.334 + jit->write_ubyte(IA32_SHR_RM_CL);
13.335 + jit->write_ubyte(ia32_modrm(mode, 5, reg));
13.336 +}
13.337 +
13.338 +inline void IA32_Shl_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.339 +{
13.340 + jit->write_ubyte(IA32_SHL_RM_CL);
13.341 + jit->write_ubyte(ia32_modrm(mode, 4, reg));
13.342 +}
13.343 +
13.344 +inline void IA32_Xchg_Eax_Reg(JitWriter *jit, jit_uint8_t reg)
13.345 +{
13.346 + jit->write_ubyte(IA32_XCHG_EAX_REG+reg);
13.347 +}
13.348 +
13.349 +/**********************
13.350 + * ARITHMETIC (BASIC) *
13.351 + **********************/
13.352 +
13.353 +inline void IA32_Add_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.354 +{
13.355 + jit->write_ubyte(IA32_ADD_RM_REG);
13.356 + jit->write_ubyte(ia32_modrm(mode, src, dest));
13.357 +}
13.358 +
13.359 +inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.360 +{
13.361 + jit->write_ubyte(IA32_ADD_REG_RM);
13.362 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.363 +}
13.364 +
13.365 +inline void IA32_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
13.366 +{
13.367 + jit->write_ubyte(IA32_ADD_RM_IMM8);
13.368 + jit->write_ubyte(ia32_modrm(mode, 0, reg));
13.369 + jit->write_byte(value);
13.370 +}
13.371 +
13.372 +inline void IA32_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
13.373 +{
13.374 + jit->write_ubyte(IA32_ADD_RM_IMM32);
13.375 + jit->write_ubyte(ia32_modrm(mode, 0, reg));
13.376 + jit->write_int32(value);
13.377 +}
13.378 +
13.379 +inline void IA32_Add_Eax_Imm32(JitWriter *jit, jit_int32_t value)
13.380 +{
13.381 + jit->write_ubyte(IA32_ADD_EAX_IMM32);
13.382 + jit->write_int32(value);
13.383 +}
13.384 +
13.385 +inline void IA32_Sub_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.386 +{
13.387 + jit->write_ubyte(IA32_SUB_RM_REG);
13.388 + jit->write_ubyte(ia32_modrm(mode, src, dest));
13.389 +}
13.390 +
13.391 +inline void IA32_Sub_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.392 +{
13.393 + jit->write_ubyte(IA32_SUB_REG_RM);
13.394 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.395 +}
13.396 +
13.397 +inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
13.398 +{
13.399 + jit->write_ubyte(IA32_SUB_REG_RM);
13.400 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
13.401 + jit->write_byte(disp8);
13.402 +}
13.403 +
13.404 +inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
13.405 +{
13.406 + jit->write_ubyte(IA32_SUB_RM_REG);
13.407 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
13.408 + jit->write_byte(disp8);
13.409 +}
13.410 +
13.411 +inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
13.412 +{
13.413 + jit->write_ubyte(IA32_SUB_RM_IMM8);
13.414 + jit->write_ubyte(ia32_modrm(mode, 5, reg));
13.415 + jit->write_byte(val);
13.416 +}
13.417 +
13.418 +inline void IA32_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
13.419 +{
13.420 + jit->write_ubyte(IA32_SUB_RM_IMM32);
13.421 + jit->write_ubyte(ia32_modrm(mode, 5, reg));
13.422 + jit->write_int32(val);
13.423 +}
13.424 +
13.425 +inline void IA32_Sbb_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.426 +{
13.427 + jit->write_ubyte(IA32_SBB_REG_RM);
13.428 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.429 +}
13.430 +
13.431 +inline void IA32_Sbb_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value, jit_uint8_t mode)
13.432 +{
13.433 + jit->write_ubyte(IA32_SBB_RM_IMM8);
13.434 + jit->write_ubyte(ia32_modrm(mode, 3, dest));
13.435 + jit->write_byte(value);
13.436 +}
13.437 +
13.438 +inline void IA32_Div_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.439 +{
13.440 + jit->write_ubyte(IA32_DIV_RM);
13.441 + jit->write_ubyte(ia32_modrm(mode, 6, reg));
13.442 +}
13.443 +
13.444 +inline void IA32_IDiv_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.445 +{
13.446 + jit->write_ubyte(IA32_IDIV_RM);
13.447 + jit->write_ubyte(ia32_modrm(mode, 7, reg));
13.448 +}
13.449 +
13.450 +inline void IA32_Mul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.451 +{
13.452 + jit->write_ubyte(IA32_MUL_RM);
13.453 + jit->write_ubyte(ia32_modrm(mode, 4, reg));
13.454 +}
13.455 +
13.456 +inline void IA32_IMul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.457 +{
13.458 + jit->write_ubyte(IA32_IMUL_RM);
13.459 + jit->write_ubyte(ia32_modrm(mode, 5, reg));
13.460 +}
13.461 +
13.462 +inline void IA32_IMul_Reg_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
13.463 +{
13.464 + jit->write_ubyte(IA32_IMUL_REG_IMM8);
13.465 + jit->write_ubyte(ia32_modrm(mode, 0, reg));
13.466 + jit->write_byte(value);
13.467 +}
13.468 +
13.469 +inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
13.470 +{
13.471 + jit->write_ubyte(IA32_IMUL_REG_IMM32);
13.472 + jit->write_ubyte(ia32_modrm(mode, 0, reg));
13.473 + jit->write_int32(value);
13.474 +}
13.475 +
13.476 +inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.477 +{
13.478 + jit->write_ubyte(IA32_IMUL_REG_RM_1);
13.479 + jit->write_ubyte(IA32_IMUL_REG_RM_2);
13.480 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.481 +}
13.482 +
13.483 +inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
13.484 +{
13.485 + jit->write_ubyte(IA32_ADD_RM_REG);
13.486 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
13.487 + jit->write_byte(disp);
13.488 +}
13.489 +
13.490 +inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
13.491 +{
13.492 + jit->write_ubyte(IA32_ADD_REG_RM);
13.493 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
13.494 + jit->write_byte(disp);
13.495 +}
13.496 +
13.497 +inline void IA32_Add_Rm_Imm8_Disp8(JitWriter *jit,
13.498 + jit_uint8_t dest,
13.499 + jit_int8_t val,
13.500 + jit_int8_t disp8)
13.501 +{
13.502 + jit->write_ubyte(IA32_ADD_RM_IMM8);
13.503 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
13.504 + jit->write_byte(disp8);
13.505 + jit->write_byte(val);
13.506 +}
13.507 +
13.508 +inline void IA32_Add_Rm_Imm32_Disp8(JitWriter *jit,
13.509 + jit_uint8_t dest,
13.510 + jit_int32_t val,
13.511 + jit_int8_t disp8)
13.512 +{
13.513 + jit->write_ubyte(IA32_ADD_RM_IMM32);
13.514 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
13.515 + jit->write_byte(disp8);
13.516 + jit->write_int32(val);
13.517 +}
13.518 +
13.519 +inline jitoffs_t IA32_Add_Rm_Imm32_Later(JitWriter *jit,
13.520 + jit_uint8_t dest,
13.521 + jit_uint8_t mode)
13.522 +{
13.523 + jit->write_ubyte(IA32_ADD_RM_IMM32);
13.524 + jit->write_ubyte(ia32_modrm(mode, 0, dest));
13.525 + jitoffs_t ptr = jit->get_outputpos();
13.526 + jit->write_int32(0);
13.527 + return ptr;
13.528 +}
13.529 +
13.530 +inline void IA32_Add_Rm_Imm8_Disp32(JitWriter *jit,
13.531 + jit_uint8_t dest,
13.532 + jit_int8_t val,
13.533 + jit_int32_t disp32)
13.534 +{
13.535 + jit->write_ubyte(IA32_ADD_RM_IMM8);
13.536 + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
13.537 + jit->write_int32(disp32);
13.538 + jit->write_byte(val);
13.539 +}
13.540 +
13.541 +inline void IA32_Add_RmEBP_Imm8_Disp_Reg(JitWriter *jit,
13.542 + jit_uint8_t dest_base,
13.543 + jit_uint8_t dest_index,
13.544 + jit_uint8_t dest_scale,
13.545 + jit_int8_t val)
13.546 +{
13.547 + jit->write_ubyte(IA32_ADD_RM_IMM8);
13.548 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
13.549 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.550 + jit->write_byte(0);
13.551 + jit->write_byte(val);
13.552 +}
13.553 +
13.554 +inline void IA32_Sub_Rm_Imm8_Disp8(JitWriter *jit,
13.555 + jit_uint8_t dest,
13.556 + jit_int8_t val,
13.557 + jit_int8_t disp8)
13.558 +{
13.559 + jit->write_ubyte(IA32_SUB_RM_IMM8);
13.560 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, dest));
13.561 + jit->write_byte(disp8);
13.562 + jit->write_byte(val);
13.563 +}
13.564 +
13.565 +inline void IA32_Sub_Rm_Imm8_Disp32(JitWriter *jit,
13.566 + jit_uint8_t dest,
13.567 + jit_int8_t val,
13.568 + jit_int32_t disp32)
13.569 +{
13.570 + jit->write_ubyte(IA32_SUB_RM_IMM8);
13.571 + jit->write_ubyte(ia32_modrm(MOD_DISP32, 5, dest));
13.572 + jit->write_int32(disp32);
13.573 + jit->write_byte(val);
13.574 +}
13.575 +
13.576 +inline void IA32_Sub_RmEBP_Imm8_Disp_Reg(JitWriter *jit,
13.577 + jit_uint8_t dest_base,
13.578 + jit_uint8_t dest_index,
13.579 + jit_uint8_t dest_scale,
13.580 + jit_int8_t val)
13.581 +{
13.582 + jit->write_ubyte(IA32_SUB_RM_IMM8);
13.583 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB));
13.584 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.585 + jit->write_byte(0);
13.586 + jit->write_byte(val);
13.587 +}
13.588 +
13.589 +/**
13.590 +* Memory Instructions
13.591 +*/
13.592 +
13.593 +inline void IA32_Lea_Reg_DispRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
13.594 +{
13.595 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.596 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
13.597 + jit->write_ubyte(ia32_sib(scale, src_index, src_base));
13.598 +}
13.599 +
13.600 +inline void IA32_Lea_Reg_DispEBPRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
13.601 +{
13.602 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.603 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
13.604 + jit->write_ubyte(ia32_sib(scale, src_index, src_base));
13.605 + jit->write_byte(0);
13.606 +}
13.607 +
13.608 +inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit,
13.609 + jit_uint8_t dest,
13.610 + jit_uint8_t src_base,
13.611 + jit_uint8_t src_index,
13.612 + jit_uint8_t scale,
13.613 + jit_int8_t val)
13.614 +{
13.615 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.616 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
13.617 + jit->write_ubyte(ia32_sib(scale, src_index, src_base));
13.618 + jit->write_byte(val);
13.619 +}
13.620 +
13.621 +inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit,
13.622 + jit_uint8_t dest,
13.623 + jit_uint8_t src_index,
13.624 + jit_uint8_t scale,
13.625 + jit_int32_t val)
13.626 +{
13.627 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.628 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
13.629 + jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE));
13.630 + jit->write_int32(val);
13.631 +}
13.632 +
13.633 +inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
13.634 +{
13.635 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.636 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src_base));
13.637 + jit->write_byte(val);
13.638 +}
13.639 +
13.640 +inline void IA32_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
13.641 +{
13.642 + jit->write_ubyte(IA32_LEA_REG_MEM);
13.643 + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src_base));
13.644 + jit->write_int32(val);
13.645 +}
13.646 +
13.647 +/**
13.648 +* Stack Instructions
13.649 +*/
13.650 +
13.651 +inline void IA32_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
13.652 +{
13.653 + jit->write_ubyte(IA32_POP_REG+reg);
13.654 +}
13.655 +
13.656 +inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg)
13.657 +{
13.658 + jit->write_ubyte(IA32_PUSH_REG+reg);
13.659 +}
13.660 +
13.661 +inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val)
13.662 +{
13.663 + jit->write_ubyte(IA32_PUSH_IMM8);
13.664 + jit->write_byte(val);
13.665 +}
13.666 +
13.667 +inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val)
13.668 +{
13.669 + jit->write_ubyte(IA32_PUSH_IMM32);
13.670 + jit->write_int32(val);
13.671 +}
13.672 +
13.673 +inline void IA32_Pushad(JitWriter *jit)
13.674 +{
13.675 + jit->write_ubyte(IA32_PUSHAD);
13.676 +}
13.677 +
13.678 +inline void IA32_Popad(JitWriter *jit)
13.679 +{
13.680 + jit->write_ubyte(IA32_POPAD);
13.681 +}
13.682 +
13.683 +inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8)
13.684 +{
13.685 + jit->write_ubyte(IA32_PUSH_RM);
13.686 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg));
13.687 + jit->write_byte(disp8);
13.688 +}
13.689 +
13.690 +inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
13.691 +{
13.692 + jit->write_ubyte(IA32_PUSH_RM);
13.693 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB));
13.694 + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
13.695 + jit->write_byte(disp8);
13.696 +}
13.697 +
13.698 +/**
13.699 + * Moving from REGISTER/MEMORY to REGISTER
13.700 + */
13.701 +
13.702 +inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.703 +{
13.704 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.705 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.706 +}
13.707 +
13.708 +inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
13.709 +{
13.710 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.711 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
13.712 + jit->write_byte(disp);
13.713 +}
13.714 +
13.715 +inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp)
13.716 +{
13.717 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.718 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
13.719 + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
13.720 + jit->write_byte(disp);
13.721 +}
13.722 +
13.723 +inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
13.724 +{
13.725 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.726 + jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
13.727 + jit->write_int32(disp);
13.728 +}
13.729 +
13.730 +inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit,
13.731 + jit_uint8_t dest,
13.732 + jit_uint8_t src_base,
13.733 + jit_uint8_t src_index,
13.734 + jit_uint8_t src_scale)
13.735 +{
13.736 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.737 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
13.738 + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
13.739 +}
13.740 +
13.741 +inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit,
13.742 + jit_uint8_t dest,
13.743 + jit_uint8_t src_base,
13.744 + jit_uint8_t src_index,
13.745 + jit_uint8_t src_scale,
13.746 + jit_int8_t disp8)
13.747 +{
13.748 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.749 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
13.750 + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
13.751 + jit->write_byte(disp8);
13.752 +}
13.753 +
13.754 +inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit,
13.755 + jit_uint8_t dest,
13.756 + jit_uint8_t src_base,
13.757 + jit_uint8_t src_index,
13.758 + jit_uint8_t src_scale)
13.759 +{
13.760 + jit->write_ubyte(IA32_MOV_REG_MEM);
13.761 + jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
13.762 + jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
13.763 + jit->write_byte(0);
13.764 +}
13.765 +
13.766 +/**
13.767 + * Moving from REGISTER to REGISTER/MEMORY
13.768 + */
13.769 +
13.770 +inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.771 +{
13.772 + jit->write_ubyte(IA32_MOV_RM_REG);
13.773 + jit->write_ubyte(ia32_modrm(mode, src, dest));
13.774 +}
13.775 +
13.776 +inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
13.777 +{
13.778 + jit->write_ubyte(IA32_MOV_RM_REG);
13.779 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
13.780 + jit->write_byte(disp);
13.781 +}
13.782 +
13.783 +inline void IA32_Mov_Rm_Reg_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
13.784 +{
13.785 + jit->write_ubyte(IA32_MOV_RM_REG);
13.786 + jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest));
13.787 + jit->write_int32(disp);
13.788 +}
13.789 +
13.790 +inline void IA32_Mov_RmEBP_Reg_Disp_Reg(JitWriter *jit,
13.791 + jit_uint8_t dest_base,
13.792 + jit_uint8_t dest_index,
13.793 + jit_uint8_t dest_scale,
13.794 + jit_uint8_t src)
13.795 +{
13.796 + jit->write_ubyte(IA32_MOV_RM_REG);
13.797 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
13.798 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.799 + jit->write_byte(0);
13.800 +}
13.801 +
13.802 +inline void IA32_Mov_Rm8EBP_Reg_Disp_Reg(JitWriter *jit,
13.803 + jit_uint8_t dest_base,
13.804 + jit_uint8_t dest_index,
13.805 + jit_uint8_t dest_scale,
13.806 + jit_uint8_t src)
13.807 +{
13.808 + jit->write_ubyte(IA32_MOV_RM8_REG);
13.809 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
13.810 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.811 + jit->write_byte(0);
13.812 +}
13.813 +
13.814 +inline void IA32_Mov_Rm16EBP_Reg_Disp_Reg(JitWriter *jit,
13.815 + jit_uint8_t dest_base,
13.816 + jit_uint8_t dest_index,
13.817 + jit_uint8_t dest_scale,
13.818 + jit_uint8_t src)
13.819 +{
13.820 + jit->write_ubyte(IA32_16BIT_PREFIX);
13.821 + jit->write_ubyte(IA32_MOV_RM_REG);
13.822 + jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
13.823 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.824 + jit->write_byte(0);
13.825 +}
13.826 +
13.827 +/**
13.828 + * Moving from IMMEDIATE to REGISTER
13.829 + */
13.830 +
13.831 +inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
13.832 +{
13.833 + jitoffs_t offs;
13.834 + jit->write_ubyte(IA32_MOV_REG_IMM+dest);
13.835 + offs = jit->get_outputpos();
13.836 + jit->write_int32(num);
13.837 + return offs;
13.838 +}
13.839 +
13.840 +inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit,
13.841 + jit_uint8_t dest,
13.842 + jit_int32_t val,
13.843 + jit_int8_t disp8)
13.844 +{
13.845 + jit->write_ubyte(IA32_MOV_RM_IMM32);
13.846 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
13.847 + jit->write_byte(disp8);
13.848 + jit->write_int32(val);
13.849 +}
13.850 +
13.851 +inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode)
13.852 +{
13.853 + jit->write_ubyte(IA32_MOV_RM_IMM32);
13.854 + jit->write_ubyte(ia32_modrm(mode, 0, dest));
13.855 + jit->write_int32(val);
13.856 +}
13.857 +
13.858 +inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit,
13.859 + jit_uint8_t dest,
13.860 + jit_int32_t val,
13.861 + jit_int32_t disp32)
13.862 +{
13.863 + jit->write_ubyte(IA32_MOV_RM_IMM32);
13.864 + jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
13.865 + jit->write_int32(disp32);
13.866 + jit->write_int32(val);
13.867 +}
13.868 +
13.869 +inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit,
13.870 + jit_uint8_t dest_base,
13.871 + jit_uint8_t dest_index,
13.872 + jit_uint8_t dest_scale,
13.873 + jit_int32_t val)
13.874 +{
13.875 + jit->write_ubyte(IA32_MOV_RM_IMM32);
13.876 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
13.877 + jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
13.878 + jit->write_byte(0);
13.879 + jit->write_int32(val);
13.880 +}
13.881 +
13.882 +/**
13.883 + * Branching/Jumping
13.884 + */
13.885 +
13.886 +inline jitoffs_t IA32_Jump_Cond_Imm8(JitWriter *jit, jit_uint8_t cond, jit_int8_t disp)
13.887 +{
13.888 + jitoffs_t ptr;
13.889 + jit->write_ubyte(IA32_JCC_IMM+cond);
13.890 + ptr = jit->get_outputpos();
13.891 + jit->write_byte(disp);
13.892 + return ptr;
13.893 +}
13.894 +
13.895 +inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp)
13.896 +{
13.897 + jitoffs_t ptr;
13.898 + jit->write_ubyte(IA32_JMP_IMM32);
13.899 + ptr = jit->get_outputpos();
13.900 + jit->write_int32(disp);
13.901 + return ptr;
13.902 +}
13.903 +
13.904 +inline jitoffs_t IA32_Jump_Imm8(JitWriter *jit, jit_int8_t disp)
13.905 +{
13.906 + jitoffs_t ptr;
13.907 + jit->write_ubyte(IA32_JMP_IMM8);
13.908 + ptr = jit->get_outputpos();
13.909 + jit->write_byte(disp);
13.910 + return ptr;
13.911 +}
13.912 +
13.913 +inline jitoffs_t IA32_Jump_Cond_Imm32(JitWriter *jit, jit_uint8_t cond, jit_int32_t disp)
13.914 +{
13.915 + jitoffs_t ptr;
13.916 + jit->write_ubyte(IA32_JCC_IMM32_1);
13.917 + jit->write_ubyte(IA32_JCC_IMM32_2+cond);
13.918 + ptr = jit->get_outputpos();
13.919 + jit->write_int32(disp);
13.920 + return ptr;
13.921 +}
13.922 +
13.923 +inline void IA32_Jump_Reg(JitWriter *jit, jit_uint8_t reg)
13.924 +{
13.925 + jit->write_ubyte(IA32_JMP_RM);
13.926 + jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg));
13.927 +}
13.928 +
13.929 +inline void IA32_Jump_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
13.930 +{
13.931 + jit->write_ubyte(IA32_JMP_RM);
13.932 + jit->write_ubyte(ia32_modrm(mode, 4, reg));
13.933 +}
13.934 +
13.935 +inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp)
13.936 +{
13.937 + jitoffs_t ptr;
13.938 + jit->write_ubyte(IA32_CALL_IMM32);
13.939 + ptr = jit->get_outputpos();
13.940 + jit->write_int32(disp);
13.941 + return ptr;
13.942 +}
13.943 +
13.944 +inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg)
13.945 +{
13.946 + jit->write_ubyte(IA32_CALL_RM);
13.947 + jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg));
13.948 +}
13.949 +
13.950 +inline void IA32_Write_Jump8(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
13.951 +{
13.952 + //save old ptr
13.953 + jitcode_t oldptr = jit->outptr;
13.954 + //get relative difference
13.955 + jit_int8_t diff = (target - (jmp + 1));
13.956 + //overwrite old value
13.957 + jit->outptr = jit->outbase + jmp;
13.958 + jit->write_byte(diff);
13.959 + //restore old ptr
13.960 + jit->outptr = oldptr;
13.961 +}
13.962 +
13.963 +inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
13.964 +{
13.965 + //save old ptr
13.966 + jitcode_t oldptr = jit->outptr;
13.967 + //get relative difference
13.968 + jit_int32_t diff = (target - (jmp + 4));
13.969 + //overwrite old value
13.970 + jit->outptr = jit->outbase + jmp;
13.971 + jit->write_int32(diff);
13.972 + //restore old ptr
13.973 + jit->outptr = oldptr;
13.974 +}
13.975 +
13.976 +/**
13.977 + * Corrects a jump using an absolute offset, not a relative one.
13.978 + */
13.979 +inline void IA32_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
13.980 +{
13.981 + //save old ptr
13.982 + jitcode_t oldptr = jit->outptr;
13.983 + //get relative difference
13.984 + long diff = ((long)target - ((long)jit->outbase + jmp + 4));
13.985 + //overwrite old value
13.986 + jit->outptr = jit->outbase + jmp;
13.987 + jit->write_int32(diff);
13.988 + //restore old ptr
13.989 + jit->outptr = oldptr;
13.990 +}
13.991 +
13.992 +/* For writing and auto-calculating an absolute target */
13.993 +inline void IA32_Jump_Imm32_Abs(JitWriter *jit, jitoffs_t target)
13.994 +{
13.995 + /* :TODO: this should work, but does it? */
13.996 + jit->write_ubyte(IA32_JMP_IMM32);
13.997 + IA32_Write_Jump32(jit, jit->get_outputpos(), target);
13.998 + jit->outptr += 4;
13.999 +}
13.1000 +
13.1001 +inline void IA32_Jump_Cond_Imm32_Abs(JitWriter *jit, jit_uint8_t cond, jitoffs_t target)
13.1002 +{
13.1003 + /* :TODO: this should work, but does it? */
13.1004 + jit->write_ubyte(IA32_JCC_IMM32_1);
13.1005 + jit->write_ubyte(IA32_JCC_IMM32_2+cond);
13.1006 + IA32_Write_Jump32(jit, jit->get_outputpos(), target);
13.1007 + jit->outptr += 4;
13.1008 +}
13.1009 +
13.1010 +inline void IA32_Send_Jump8_Here(JitWriter *jit, jitoffs_t jmp)
13.1011 +{
13.1012 + jitoffs_t curptr = jit->get_outputpos();
13.1013 + IA32_Write_Jump8(jit, jmp, curptr);
13.1014 +}
13.1015 +
13.1016 +inline void IA32_Send_Jump32_Here(JitWriter *jit, jitoffs_t jmp)
13.1017 +{
13.1018 + jitoffs_t curptr = jit->get_outputpos();
13.1019 + IA32_Write_Jump32(jit, jmp, curptr);
13.1020 +}
13.1021 +
13.1022 +inline void IA32_Return(JitWriter *jit)
13.1023 +{
13.1024 + jit->write_ubyte(IA32_RET);
13.1025 +}
13.1026 +
13.1027 +inline void IA32_Test_Rm_Reg(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode)
13.1028 +{
13.1029 + jit->write_ubyte(IA32_TEST_RM_REG);
13.1030 + jit->write_ubyte(ia32_modrm(mode, reg2, reg1));
13.1031 +}
13.1032 +
13.1033 +inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.1034 +{
13.1035 + jit->write_ubyte(IA32_CMP_RM_REG);
13.1036 + jit->write_ubyte(ia32_modrm(mode, src, dest));
13.1037 +}
13.1038 +
13.1039 +inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
13.1040 +{
13.1041 + jit->write_ubyte(IA32_CMP_REG_RM);
13.1042 + jit->write_ubyte(ia32_modrm(mode, dest, src));
13.1043 +}
13.1044 +
13.1045 +inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg)
13.1046 +{
13.1047 + jit->write_ubyte(IA32_CMP_REG_RM);
13.1048 + jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB));
13.1049 + jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
13.1050 +}
13.1051 +
13.1052 +inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8)
13.1053 +{
13.1054 + jit->write_ubyte(IA32_CMP_REG_RM);
13.1055 + jit->write_ubyte(ia32_modrm(MOD_DISP8, reg1, reg2));
13.1056 + jit->write_byte(disp8);
13.1057 +}
13.1058 +
13.1059 +inline void IA32_Cmp_Rm_Imm8(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int8_t imm8)
13.1060 +{
13.1061 + jit->write_ubyte(IA32_CMP_RM_IMM8);
13.1062 + jit->write_ubyte(ia32_modrm(mode, 7, rm));
13.1063 + jit->write_byte(imm8);
13.1064 +}
13.1065 +
13.1066 +inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int32_t imm32)
13.1067 +{
13.1068 + jit->write_ubyte(IA32_CMP_RM_IMM32);
13.1069 + jit->write_ubyte(ia32_modrm(mode, 7, rm));
13.1070 + jit->write_int32(imm32);
13.1071 +}
13.1072 +
13.1073 +inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8, jit_int32_t imm32)
13.1074 +{
13.1075 + jit->write_ubyte(IA32_CMP_RM_IMM32);
13.1076 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
13.1077 + jit->write_byte(disp8);
13.1078 + jit->write_int32(imm32);
13.1079 +}
13.1080 +
13.1081 +inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8)
13.1082 +{
13.1083 + jit->write_ubyte(IA32_CMP_RM_IMM8);
13.1084 + jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
13.1085 + jit->write_byte(disp);
13.1086 + jit->write_byte(imm8);
13.1087 +}
13.1088 +
13.1089 +inline void IA32_Cmp_Al_Imm8(JitWriter *jit, jit_int8_t value)
13.1090 +{
13.1091 + jit->write_ubyte(IA32_CMP_AL_IMM32);
13.1092 + jit->write_byte(value);
13.1093 +}
13.1094 +
13.1095 +inline void IA32_Cmp_Eax_Imm32(JitWriter *jit, jit_int32_t value)
13.1096 +{
13.1097 + jit->write_ubyte(IA32_CMP_EAX_IMM32);
13.1098 + jit->write_int32(value);
13.1099 +}
13.1100 +
13.1101 +inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond)
13.1102 +{
13.1103 + jit->write_ubyte(IA32_SETCC_RM8_1);
13.1104 + jit->write_ubyte(IA32_SETCC_RM8_2+cond);
13.1105 + jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg));
13.1106 +}
13.1107 +
13.1108 +inline void IA32_Cmpsb(JitWriter *jit)
13.1109 +{
13.1110 + jit->write_ubyte(IA32_CMPSB);
13.1111 +}
13.1112 +
13.1113 +inline void IA32_Rep(JitWriter *jit)
13.1114 +{
13.1115 + jit->write_ubyte(IA32_REP);
13.1116 +}
13.1117 +
13.1118 +inline void IA32_Movsd(JitWriter *jit)
13.1119 +{
13.1120 + jit->write_ubyte(IA32_MOVSD);
13.1121 +}
13.1122 +
13.1123 +inline void IA32_Movsb(JitWriter *jit)
13.1124 +{
13.1125 + jit->write_ubyte(IA32_MOVSB);
13.1126 +}
13.1127 +
13.1128 +inline void IA32_Stosd(JitWriter *jit)
13.1129 +{
13.1130 + jit->write_ubyte(IA32_STOSD);
13.1131 +}
13.1132 +
13.1133 +inline void IA32_Cld(JitWriter *jit)
13.1134 +{
13.1135 + jit->write_ubyte(IA32_CLD);
13.1136 +}
13.1137 +
13.1138 +#endif //_INCLUDE_JIT_X86_MACROS_H
14.1 --- a/sourcepawn/vm/jit/jit_helpers.h Tue Nov 07 23:26:40 2006 +0000
14.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
14.3 @@ -1,95 +0,0 @@
14.4 -#ifndef _INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
14.5 -#define _INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
14.6 -
14.7 -#include <sp_vm_types.h>
14.8 -#include <sp_vm_api.h>
14.9 -
14.10 -#if defined HAVE_STDINT_H && !defined WIN32
14.11 -#include <stdint.h>
14.12 -typedef int8_t jit_int8_t;
14.13 -typedef uint8_t jit_uint8_t;
14.14 -typedef int32_t jit_int32_t;
14.15 -typedef uint32_t jit_uint32_t;
14.16 -typedef int64_t jit_int64_t;
14.17 -typedef uint64_t jit_uint64_t;
14.18 -#elif defined WIN32
14.19 -typedef __int8 jit_int8_t;
14.20 -typedef unsigned __int8 jit_uint8_t;
14.21 -typedef __int32 jit_int32_t;
14.22 -typedef unsigned __int32 jit_uint32_t;
14.23 -typedef __int64 jit_int64_t;
14.24 -typedef unsigned __int64 jit_uint64_t;
14.25 -#endif
14.26 -
14.27 -typedef char * jitcode_t;
14.28 -typedef unsigned int jitoffs_t;
14.29 -typedef signed int jitrel_t;
14.30 -
14.31 -class JitWriter
14.32 -{
14.33 -public:
14.34 - inline cell_t read_cell()
14.35 - {
14.36 - cell_t val = *(inptr);
14.37 - inptr++;
14.38 - return val;
14.39 - }
14.40 - inline cell_t *read_cellptr()
14.41 - {
14.42 - cell_t *val = *(cell_t **)(inptr);
14.43 - inptr++;
14.44 - return val;
14.45 - }
14.46 - inline void write_ubyte(jit_uint8_t c)
14.47 - {
14.48 - if (outbase)
14.49 - {
14.50 - *outptr = c;
14.51 - }
14.52 - outptr++;
14.53 - }
14.54 - inline void write_byte(jit_int8_t c)
14.55 - {
14.56 - if (outbase)
14.57 - {
14.58 - *outptr = c;
14.59 - }
14.60 - outptr++;
14.61 - }
14.62 - inline void write_int32(jit_int32_t c)
14.63 - {
14.64 - if (outbase)
14.65 - {
14.66 - *(jit_int32_t *)outptr = c;
14.67 - }
14.68 - outptr += sizeof(jit_int32_t);
14.69 - }
14.70 - inline void write_uint32(jit_uint32_t c)
14.71 - {
14.72 - if (outbase)
14.73 - {
14.74 - *(jit_uint32_t *)outptr = c;
14.75 - }
14.76 - outptr += sizeof(jit_uint32_t);
14.77 - }
14.78 - inline jitoffs_t get_outputpos()
14.79 - {
14.80 - return (outptr - outbase);
14.81 - }
14.82 - inline void set_outputpos(jitoffs_t offs)
14.83 - {
14.84 - outptr = outbase + offs;
14.85 - }
14.86 - inline jitoffs_t get_inputpos()
14.87 - {
14.88 - return (jitoffs_t)((char *)inptr - (char *)inbase);
14.89 - }
14.90 -public:
14.91 - cell_t *inptr; /* input pointer */
14.92 - cell_t *inbase; /* input base */
14.93 - jitcode_t outbase; /* output pointer */
14.94 - jitcode_t outptr; /* output base */
14.95 - SourcePawn::ICompilation *data; /* compiler live info */
14.96 -};
14.97 -
14.98 -#endif //_INCLUDE_SOURCEPAWN_JIT_HELPERS_H_
15.1 --- a/sourcepawn/vm/jit/x86/dll_exports.cpp Tue Nov 07 23:26:40 2006 +0000
15.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
15.3 @@ -1,33 +0,0 @@
15.4 -#include <sp_vm_api.h>
15.5 -#include "jit_x86.h"
15.6 -#include "dll_exports.h"
15.7 -
15.8 -SourcePawn::ISourcePawnEngine *engine = NULL;
15.9 -JITX86 jit;
15.10 -
15.11 -EXPORTFUNC void GiveEnginePointer(SourcePawn::ISourcePawnEngine *engine_p)
15.12 -{
15.13 - engine = engine_p;
15.14 -}
15.15 -
15.16 -EXPORTFUNC unsigned int GetExportCount()
15.17 -{
15.18 - return 1;
15.19 -}
15.20 -
15.21 -EXPORTFUNC SourcePawn::IVirtualMachine *GetExport(unsigned int exportnum)
15.22 -{
15.23 - /* Don't return anything if we're not initialized yet */
15.24 - if (!engine)
15.25 - {
15.26 - return NULL;
15.27 - }
15.28 -
15.29 - /* We only have one export - 0 */
15.30 - if (exportnum)
15.31 - {
15.32 - return NULL;
15.33 - }
15.34 -
15.35 - return &jit;
15.36 -}
16.1 --- a/sourcepawn/vm/jit/x86/dll_exports.h Tue Nov 07 23:26:40 2006 +0000
16.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
16.3 @@ -1,16 +0,0 @@
16.4 -#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
16.5 -#define _INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
16.6 -
16.7 -#include <sp_vm_base.h>
16.8 -
16.9 -#if defined WIN32
16.10 -#define EXPORTFUNC extern "C" __declspec(dllexport)
16.11 -#elif defined __GNUC__
16.12 -#if __GNUC__ >= 3
16.13 -#define EXPORTFUNC extern "C" __attribute__((visibility("default")))
16.14 -#else
16.15 -#define EXPORTFUNC extern "C"
16.16 -#endif //__GNUC__ >= 3
16.17 -#endif //defined __GNUC__
16.18 -
16.19 -#endif //_INCLUDE_SOURCEPAWN_JIT_X86_DLL_H_
17.1 --- a/sourcepawn/vm/jit/x86/jit_x86.cpp Tue Nov 07 23:26:40 2006 +0000
17.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
17.3 @@ -1,2165 +0,0 @@
17.4 -#include <string.h>
17.5 -#include <stdlib.h>
17.6 -#include <assert.h>
17.7 -#include "jit_x86.h"
17.8 -#include "opcode_helpers.h"
17.9 -#include "x86_macros.h"
17.10 -
17.11 -#if defined USE_UNGEN_OPCODES
17.12 -#include "ungen_opcodes.h"
17.13 -#endif
17.14 -
17.15 -inline void WriteOp_Move_Pri(JitWriter *jit)
17.16 -{
17.17 - //mov eax, edx
17.18 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.19 -}
17.20 -
17.21 -inline void WriteOp_Move_Alt(JitWriter *jit)
17.22 -{
17.23 - //mov edx, eax
17.24 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_PRI, MOD_REG);
17.25 -}
17.26 -
17.27 -inline void WriteOp_Xchg(JitWriter *jit)
17.28 -{
17.29 - //xchg eax, edx
17.30 - IA32_Xchg_Eax_Reg(jit, AMX_REG_ALT);
17.31 -}
17.32 -
17.33 -inline void WriteOp_Push(JitWriter *jit)
17.34 -{
17.35 - //push stack, DAT offset based
17.36 - //sub edi, 4
17.37 - //mov ecx, [ebp+<val>]
17.38 - //mov [edi], ecx
17.39 - cell_t val = jit->read_cell();
17.40 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.41 - //optimize encoding a bit...
17.42 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.43 - {
17.44 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
17.45 - } else {
17.46 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
17.47 - }
17.48 - IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
17.49 -}
17.50 -
17.51 -inline void WriteOp_Push_C(JitWriter *jit)
17.52 -{
17.53 - //push stack
17.54 - //mov [edi-4], <val>
17.55 - //sub edi, 4
17.56 - cell_t val = jit->read_cell();
17.57 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, val, -4);
17.58 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.59 -}
17.60 -
17.61 -inline void WriteOp_Zero(JitWriter *jit)
17.62 -{
17.63 - //mov [ebp+<val>], 0
17.64 - cell_t val = jit->read_cell();
17.65 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.66 - {
17.67 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, 0, (jit_int8_t)val);
17.68 - } else {
17.69 - IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, 0, val);
17.70 - }
17.71 -}
17.72 -
17.73 -inline void WriteOp_Zero_S(JitWriter *jit)
17.74 -{
17.75 - //mov [ebx+<val>], 0
17.76 - cell_t val = jit->read_cell();
17.77 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.78 - {
17.79 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, 0, (jit_int8_t)val);
17.80 - } else {
17.81 - IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, 0, val);
17.82 - }
17.83 -}
17.84 -
17.85 -inline void WriteOp_Push_S(JitWriter *jit)
17.86 -{
17.87 - //push stack, FRM offset based
17.88 - //sub edi, 4
17.89 - //mov ecx, [ebx+<val>]
17.90 - //mov [edi], ecx
17.91 - cell_t val = jit->read_cell();
17.92 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.93 - //optimize encoding a bit...
17.94 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.95 - {
17.96 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
17.97 - } else {
17.98 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
17.99 - }
17.100 - IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
17.101 -}
17.102 -
17.103 -inline void WriteOp_Push_Pri(JitWriter *jit)
17.104 -{
17.105 - //mov [edi-4], eax
17.106 - //sub edi, 4
17.107 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_PRI, -4);
17.108 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.109 -}
17.110 -
17.111 -inline void WriteOp_Push_Alt(JitWriter *jit)
17.112 -{
17.113 - //mov [edi-4], edx
17.114 - //sub edi, 4
17.115 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_ALT, -4);
17.116 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.117 -}
17.118 -
17.119 -inline void WriteOp_Push2_C(JitWriter *jit)
17.120 -{
17.121 - Macro_PushN_C(jit, 2);
17.122 -}
17.123 -
17.124 -inline void WriteOp_Push3_C(JitWriter *jit)
17.125 -{
17.126 - Macro_PushN_C(jit, 3);
17.127 -}
17.128 -
17.129 -inline void WriteOp_Push4_C(JitWriter *jit)
17.130 -{
17.131 - Macro_PushN_C(jit, 4);
17.132 -}
17.133 -
17.134 -inline void WriteOp_Push5_C(JitWriter *jit)
17.135 -{
17.136 - Macro_PushN_C(jit, 5);
17.137 -}
17.138 -
17.139 -inline void WriteOp_Push2_Adr(JitWriter *jit)
17.140 -{
17.141 - Macro_PushN_Addr(jit, 2);
17.142 -}
17.143 -
17.144 -inline void WriteOp_Push3_Adr(JitWriter *jit)
17.145 -{
17.146 - Macro_PushN_Addr(jit, 3);
17.147 -}
17.148 -
17.149 -inline void WriteOp_Push4_Adr(JitWriter *jit)
17.150 -{
17.151 - Macro_PushN_Addr(jit, 4);
17.152 -}
17.153 -
17.154 -inline void WriteOp_Push5_Adr(JitWriter *jit)
17.155 -{
17.156 - Macro_PushN_Addr(jit, 5);
17.157 -}
17.158 -
17.159 -inline void WriteOp_Push2_S(JitWriter *jit)
17.160 -{
17.161 - Macro_PushN_S(jit, 2);
17.162 -}
17.163 -
17.164 -inline void WriteOp_Push3_S(JitWriter *jit)
17.165 -{
17.166 - Macro_PushN_S(jit, 3);
17.167 -}
17.168 -
17.169 -inline void WriteOp_Push4_S(JitWriter *jit)
17.170 -{
17.171 - Macro_PushN_S(jit, 4);
17.172 -}
17.173 -
17.174 -inline void WriteOp_Push5_S(JitWriter *jit)
17.175 -{
17.176 - Macro_PushN_S(jit, 5);
17.177 -}
17.178 -
17.179 -inline void WriteOp_Push5(JitWriter *jit)
17.180 -{
17.181 - Macro_PushN(jit, 5);
17.182 -}
17.183 -
17.184 -inline void WriteOp_Push4(JitWriter *jit)
17.185 -{
17.186 - Macro_PushN(jit, 4);
17.187 -}
17.188 -
17.189 -inline void WriteOp_Push3(JitWriter *jit)
17.190 -{
17.191 - Macro_PushN(jit, 3);
17.192 -}
17.193 -
17.194 -inline void WriteOp_Push2(JitWriter *jit)
17.195 -{
17.196 - Macro_PushN(jit, 2);
17.197 -}
17.198 -
17.199 -inline void WriteOp_Zero_Pri(JitWriter *jit)
17.200 -{
17.201 - //xor eax, eax
17.202 - IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
17.203 -}
17.204 -
17.205 -inline void WriteOp_Zero_Alt(JitWriter *jit)
17.206 -{
17.207 - //xor edx, edx
17.208 - IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
17.209 -}
17.210 -
17.211 -inline void WriteOp_Add(JitWriter *jit)
17.212 -{
17.213 - //add eax, edx
17.214 - IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.215 -}
17.216 -
17.217 -inline void WriteOp_Sub(JitWriter *jit)
17.218 -{
17.219 - //sub eax, edx
17.220 - IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.221 -}
17.222 -
17.223 -inline void WriteOp_Sub_Alt(JitWriter *jit)
17.224 -{
17.225 - //neg eax
17.226 - //add eax, edx
17.227 - IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
17.228 - IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.229 -}
17.230 -
17.231 -inline void WriteOp_Proc(JitWriter *jit)
17.232 -{
17.233 - /* align this to four byte boundaries!
17.234 - * This is a decent optimization - x86 likes calls to be properly aligned, otherwise there's an alignment exception
17.235 - * Since all calls are jumped to by relocation, the nops/garbage will never be hit by the runtime process.
17.236 - * Just in case, we guard this memory with INT3 to break into the debugger.
17.237 - */
17.238 - jitoffs_t cur_offs = jit->get_outputpos();
17.239 - if (cur_offs % 4)
17.240 - {
17.241 - cur_offs = 4 - (cur_offs % 4);
17.242 - for (unsigned int i=0; i<cur_offs; i++)
17.243 - {
17.244 - jit->write_ubyte(IA32_INT3);
17.245 - }
17.246 - /* add this amt to the offset we relocated */
17.247 - jitoffs_t offs = jit->get_inputpos() - sizeof(cell_t);
17.248 - jitcode_t rebase = ((CompData *)jit->data)->rebase;
17.249 - *(jitoffs_t *)((unsigned char *)rebase + offs) = jit->get_outputpos();
17.250 - }
17.251 - //push old frame on stack:
17.252 - //mov ecx, [esi+frm]
17.253 - //mov [edi-4], ecx
17.254 - //sub edi, 8 ;extra un-used slot for non-existant CIP
17.255 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_INFO, MOD_MEM_REG);
17.256 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4);
17.257 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
17.258 - //save frame:
17.259 - //mov ecx, edi - get new frame
17.260 - //mov ebx, edi - store frame back
17.261 - //sub ecx, ebp - relocate local frame
17.262 - //mov [esi+frm], ecx
17.263 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
17.264 - IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
17.265 - IA32_Sub_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
17.266 - IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_TMP, MOD_MEM_REG);
17.267 -}
17.268 -
17.269 -inline void WriteOp_Lidx_B(JitWriter *jit)
17.270 -{
17.271 - cell_t val = jit->read_cell();
17.272 - //shl eax, <val>
17.273 - //add eax, edx
17.274 - //mov eax, [ebp+eax]
17.275 - IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
17.276 - IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.277 - Write_Check_VerifyAddr(jit, AMX_REG_PRI);
17.278 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.279 -}
17.280 -
17.281 -inline void WriteOp_Idxaddr_B(JitWriter *jit)
17.282 -{
17.283 - //shl eax, <val>
17.284 - //add eax, edx
17.285 - cell_t val = jit->read_cell();
17.286 - IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, (jit_uint8_t)val, MOD_REG);
17.287 - IA32_Add_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.288 -}
17.289 -
17.290 -inline void WriteOp_Shl(JitWriter *jit)
17.291 -{
17.292 - //mov ecx, edx
17.293 - //shl eax, cl
17.294 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
17.295 - IA32_Shl_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
17.296 -}
17.297 -
17.298 -inline void WriteOp_Shr(JitWriter *jit)
17.299 -{
17.300 - //mov ecx, edx
17.301 - //shr eax, cl
17.302 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
17.303 - IA32_Shr_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
17.304 -}
17.305 -
17.306 -inline void WriteOp_Sshr(JitWriter *jit)
17.307 -{
17.308 - //mov ecx, edx
17.309 - //sar eax, cl
17.310 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
17.311 - IA32_Sar_Rm_CL(jit, AMX_REG_PRI, MOD_REG);
17.312 -}
17.313 -
17.314 -inline void WriteOp_Shl_C_Pri(JitWriter *jit)
17.315 -{
17.316 - //shl eax, <val>
17.317 - jit_uint8_t val = (jit_uint8_t)jit->read_cell();
17.318 - if (val == 1)
17.319 - {
17.320 - IA32_Shl_Rm_1(jit, AMX_REG_PRI, MOD_REG);
17.321 - } else {
17.322 - IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG);
17.323 - }
17.324 -}
17.325 -
17.326 -inline void WriteOp_Shl_C_Alt(JitWriter *jit)
17.327 -{
17.328 - //shl edx, <val>
17.329 - jit_uint8_t val = (jit_uint8_t)jit->read_cell();
17.330 - if (val == 1)
17.331 - {
17.332 - IA32_Shl_Rm_1(jit, AMX_REG_ALT, MOD_REG);
17.333 - } else {
17.334 - IA32_Shl_Rm_Imm8(jit, AMX_REG_ALT, val, MOD_REG);
17.335 - }
17.336 -}
17.337 -
17.338 -inline void WriteOp_Shr_C_Pri(JitWriter *jit)
17.339 -{
17.340 - //shr eax, <val>
17.341 - jit_uint8_t val = (jit_uint8_t)jit->read_cell();
17.342 - if (val == 1)
17.343 - {
17.344 - IA32_Shr_Rm_1(jit, AMX_REG_PRI, MOD_REG);
17.345 - } else {
17.346 - IA32_Shr_Rm_Imm8(jit, AMX_REG_PRI, val, MOD_REG);
17.347 - }
17.348 -}
17.349 -
17.350 -inline void WriteOp_Shr_C_Alt(JitWriter *jit)
17.351 -{
17.352 - //shr edx, <val>
17.353 - jit_uint8_t val = (jit_uint8_t)jit->read_cell();
17.354 - if (val == 1)
17.355 - {
17.356 - IA32_Shr_Rm_1(jit, AMX_REG_ALT, MOD_REG);
17.357 - } else {
17.358 - IA32_Shr_Rm_Imm8(jit, AMX_REG_ALT, val, MOD_REG);
17.359 - }
17.360 -}
17.361 -
17.362 -inline void WriteOp_SMul(JitWriter *jit)
17.363 -{
17.364 - //mov ecx, edx
17.365 - //imul edx
17.366 - //mov edx, ecx
17.367 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
17.368 - IA32_IMul_Rm(jit, AMX_REG_ALT, MOD_REG);
17.369 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
17.370 -}
17.371 -
17.372 -inline void WriteOp_Not(JitWriter *jit)
17.373 -{
17.374 - //test eax, eax
17.375 - //mov eax, 0
17.376 - //sete al
17.377 - IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
17.378 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.379 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
17.380 -}
17.381 -
17.382 -inline void WriteOp_Neg(JitWriter *jit)
17.383 -{
17.384 - //neg eax
17.385 - IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
17.386 -}
17.387 -
17.388 -inline void WriteOp_Xor(JitWriter *jit)
17.389 -{
17.390 - //xor eax, edx
17.391 - IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.392 -}
17.393 -
17.394 -inline void WriteOp_Or(JitWriter *jit)
17.395 -{
17.396 - //or eax, edx
17.397 - IA32_Or_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.398 -}
17.399 -
17.400 -inline void WriteOp_And(JitWriter *jit)
17.401 -{
17.402 - //and eax, edx
17.403 - IA32_And_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.404 -}
17.405 -
17.406 -inline void WriteOp_Invert(JitWriter *jit)
17.407 -{
17.408 - //not eax
17.409 - IA32_Not_Rm(jit, AMX_REG_PRI, MOD_REG);
17.410 -}
17.411 -
17.412 -inline void WriteOp_Add_C(JitWriter *jit)
17.413 -{
17.414 - //add eax, <val>
17.415 - cell_t val = jit->read_cell();
17.416 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.417 - IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, (jit_int8_t)val, MOD_REG);
17.418 - else
17.419 - IA32_Add_Eax_Imm32(jit, val);
17.420 -}
17.421 -
17.422 -inline void WriteOp_SMul_C(JitWriter *jit)
17.423 -{
17.424 - //imul eax, <val>
17.425 - cell_t val = jit->read_cell();
17.426 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.427 - IA32_IMul_Reg_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
17.428 - else
17.429 - IA32_IMul_Reg_Imm32(jit, AMX_REG_PRI, MOD_REG, val);
17.430 -}
17.431 -
17.432 -inline void WriteOp_Sign_Pri(JitWriter *jit)
17.433 -{
17.434 - //shl eax, 24
17.435 - //sar eax, 24
17.436 - IA32_Shl_Rm_Imm8(jit, AMX_REG_PRI, 24, MOD_REG);
17.437 - IA32_Sar_Rm_Imm8(jit, AMX_REG_PRI, 24, MOD_REG);
17.438 -}
17.439 -
17.440 -inline void WriteOp_Sign_Alt(JitWriter *jit)
17.441 -{
17.442 - //shl edx, 24
17.443 - //sar edx, 24
17.444 - IA32_Shl_Rm_Imm8(jit, AMX_REG_ALT, 24, MOD_REG);
17.445 - IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 24, MOD_REG);
17.446 -}
17.447 -
17.448 -inline void WriteOp_Eq(JitWriter *jit)
17.449 -{
17.450 - //cmp eax, edx ; PRI == ALT ?
17.451 - //mov eax, 0
17.452 - //sete al
17.453 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.454 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.455 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
17.456 -}
17.457 -
17.458 -inline void WriteOp_Neq(JitWriter *jit)
17.459 -{
17.460 - //cmp eax, edx ; PRI != ALT ?
17.461 - //mov eax, 0
17.462 - //setne al
17.463 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.464 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.465 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_NE);
17.466 -}
17.467 -
17.468 -inline void WriteOp_Sless(JitWriter *jit)
17.469 -{
17.470 - //cmp eax, edx ; PRI < ALT ? (signed)
17.471 - //mov eax, 0
17.472 - //setl al
17.473 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.474 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.475 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_L);
17.476 -}
17.477 -
17.478 -inline void WriteOp_Sleq(JitWriter *jit)
17.479 -{
17.480 - //cmp eax, edx ; PRI <= ALT ? (signed)
17.481 - //mov eax, 0
17.482 - //setle al
17.483 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.484 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.485 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_LE);
17.486 -}
17.487 -
17.488 -inline void WriteOp_Sgrtr(JitWriter *jit)
17.489 -{
17.490 - //cmp eax, edx ; PRI > ALT ? (signed)
17.491 - //mov eax, 0
17.492 - //setg al
17.493 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.494 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.495 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_G);
17.496 -}
17.497 -
17.498 -inline void WriteOp_Sgeq(JitWriter *jit)
17.499 -{
17.500 - //cmp eax, edx ; PRI >= ALT ? (signed)
17.501 - //mov eax, 0
17.502 - //setge al
17.503 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.504 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.505 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_GE);
17.506 -}
17.507 -
17.508 -inline void WriteOp_Eq_C_Pri(JitWriter *jit)
17.509 -{
17.510 - //cmp eax, <val> ; PRI == value ?
17.511 - //mov eax, 0
17.512 - //sete al
17.513 - cell_t val = jit->read_cell();
17.514 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.515 - IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
17.516 - else
17.517 - IA32_Cmp_Eax_Imm32(jit, val);
17.518 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
17.519 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
17.520 -}
17.521 -
17.522 -inline void WriteOp_Eq_C_Alt(JitWriter *jit)
17.523 -{
17.524 - //xor eax, eax
17.525 - //cmp edx, <val> ; ALT == value ?
17.526 - //sete al
17.527 - cell_t val = jit->read_cell();
17.528 - IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
17.529 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.530 - IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_ALT, (jit_int8_t)val);
17.531 - else
17.532 - IA32_Cmp_Rm_Imm32(jit, MOD_REG, AMX_REG_ALT, val);
17.533 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_E);
17.534 -}
17.535 -
17.536 -inline void WriteOp_Inc_Pri(JitWriter *jit)
17.537 -{
17.538 - //add eax, 1
17.539 - IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, 1, MOD_REG);
17.540 -}
17.541 -
17.542 -inline void WriteOp_Inc_Alt(JitWriter *jit)
17.543 -{
17.544 - //add edx, 1
17.545 - IA32_Add_Rm_Imm8(jit, AMX_REG_ALT, 1, MOD_REG);
17.546 -}
17.547 -
17.548 -inline void WriteOp_Inc(JitWriter *jit)
17.549 -{
17.550 - //add [ebp+<val>], 1
17.551 - cell_t val = jit->read_cell();
17.552 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.553 - IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_DAT, 1, (jit_int8_t)val);
17.554 - else
17.555 - IA32_Add_Rm_Imm8_Disp32(jit, AMX_REG_DAT, 1, val);
17.556 -}
17.557 -
17.558 -inline void WriteOp_Inc_S(JitWriter *jit)
17.559 -{
17.560 - //add [ebx+<val>], 1
17.561 - cell_t val = jit->read_cell();
17.562 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.563 - IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_FRM, 1, (jit_int8_t)val);
17.564 - else
17.565 - IA32_Add_Rm_Imm8_Disp32(jit, AMX_REG_FRM, 1, val);
17.566 -}
17.567 -
17.568 -inline void WriteOp_Inc_I(JitWriter *jit)
17.569 -{
17.570 - //add [ebp+eax], 1
17.571 - IA32_Add_RmEBP_Imm8_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_PRI, NOSCALE, 1);
17.572 -}
17.573 -
17.574 -inline void WriteOp_Dec_Pri(JitWriter *jit)
17.575 -{
17.576 - //sub eax, 1
17.577 - IA32_Sub_Rm_Imm8(jit, AMX_REG_PRI, 1, MOD_REG);
17.578 -}
17.579 -
17.580 -inline void WriteOp_Dec_Alt(JitWriter *jit)
17.581 -{
17.582 - //sub edx, 1
17.583 - IA32_Sub_Rm_Imm8(jit, AMX_REG_ALT, 1, MOD_REG);
17.584 -}
17.585 -
17.586 -inline void WriteOp_Dec(JitWriter *jit)
17.587 -{
17.588 - //sub [ebp+<val>], 1
17.589 - cell_t val = jit->read_cell();
17.590 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.591 - {
17.592 - IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_DAT, 1, (jit_int8_t)val);
17.593 - } else {
17.594 - IA32_Sub_Rm_Imm8_Disp32(jit, AMX_REG_DAT, 1, val);
17.595 - }
17.596 -}
17.597 -
17.598 -inline void WriteOp_Dec_S(JitWriter *jit)
17.599 -{
17.600 - //sub [ebx+<val>], 1
17.601 - cell_t val = jit->read_cell();
17.602 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.603 - {
17.604 - IA32_Sub_Rm_Imm8_Disp8(jit, AMX_REG_FRM, 1, (jit_int8_t)val);
17.605 - } else {
17.606 - IA32_Sub_Rm_Imm8_Disp32(jit, AMX_REG_FRM, 1, val);
17.607 - }
17.608 -}
17.609 -
17.610 -inline void WriteOp_Dec_I(JitWriter *jit)
17.611 -{
17.612 - //sub [ebp+eax], 1
17.613 - IA32_Sub_RmEBP_Imm8_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_PRI, NOSCALE, 1);
17.614 -}
17.615 -
17.616 -inline void WriteOp_Load_Pri(JitWriter *jit)
17.617 -{
17.618 - //mov eax, [ebp+<val>]
17.619 - cell_t val = jit->read_cell();
17.620 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.621 - {
17.622 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_DAT, (jit_int8_t)val);
17.623 - } else {
17.624 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
17.625 - }
17.626 -}
17.627 -
17.628 -inline void WriteOp_Load_Alt(JitWriter *jit)
17.629 -{
17.630 - //mov edx, [ebp+<val>]
17.631 - cell_t val = jit->read_cell();
17.632 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.633 - {
17.634 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_DAT, (jit_int8_t)val);
17.635 - } else {
17.636 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
17.637 - }
17.638 -}
17.639 -
17.640 -inline void WriteOp_Load_S_Pri(JitWriter *jit)
17.641 -{
17.642 - //mov eax, [ebx+<val>]
17.643 - cell_t val = jit->read_cell();
17.644 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.645 - {
17.646 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_FRM, (jit_int8_t)val);
17.647 - } else {
17.648 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
17.649 - }
17.650 -}
17.651 -
17.652 -inline void WriteOp_Load_S_Alt(JitWriter *jit)
17.653 -{
17.654 - //mov edx, [ebx+<val>]
17.655 - cell_t val = jit->read_cell();
17.656 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.657 - {
17.658 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_FRM, (jit_int8_t)val);
17.659 - } else {
17.660 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
17.661 - }
17.662 -}
17.663 -
17.664 -inline void WriteOp_Lref_Pri(JitWriter *jit)
17.665 -{
17.666 - //mov eax, [ebp+<val>]
17.667 - //mov eax, [ebp+eax]
17.668 - cell_t val = jit->read_cell();
17.669 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.670 - {
17.671 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_DAT, (jit_int8_t)val);
17.672 - } else {
17.673 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_DAT, val);
17.674 - }
17.675 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.676 -}
17.677 -
17.678 -inline void WriteOp_Lref_Alt(JitWriter *jit)
17.679 -{
17.680 - //mov edx, [ebp+<val>]
17.681 - //mov edx, [ebp+edx]
17.682 - cell_t val = jit->read_cell();
17.683 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.684 - {
17.685 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_DAT, (jit_int8_t)val);
17.686 - } else {
17.687 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_DAT, val);
17.688 - }
17.689 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
17.690 -}
17.691 -
17.692 -inline void WriteOp_Lref_S_Pri(JitWriter *jit)
17.693 -{
17.694 - //mov eax, [ebx+<val>]
17.695 - //mov eax, [ebp+eax]
17.696 - cell_t val = jit->read_cell();
17.697 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.698 - {
17.699 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_FRM, (jit_int8_t)val);
17.700 - } else {
17.701 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_PRI, AMX_REG_FRM, val);
17.702 - }
17.703 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.704 -}
17.705 -
17.706 -inline void WriteOp_Lref_S_Alt(JitWriter *jit)
17.707 -{
17.708 - //mov edx, [ebx+<val>]
17.709 - //mov edx, [ebp+edx]
17.710 - cell_t val = jit->read_cell();
17.711 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.712 - {
17.713 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_FRM, (jit_int8_t)val);
17.714 - } else {
17.715 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_ALT, AMX_REG_FRM, val);
17.716 - }
17.717 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_ALT, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
17.718 -}
17.719 -
17.720 -inline void WriteOp_Const_Pri(JitWriter *jit)
17.721 -{
17.722 - //mov eax, <val>
17.723 - cell_t val = jit->read_cell();
17.724 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, val);
17.725 -}
17.726 -
17.727 -inline void WriteOp_Const_Alt(JitWriter *jit)
17.728 -{
17.729 - //mov edx, <val>
17.730 - cell_t val = jit->read_cell();
17.731 - IA32_Mov_Reg_Imm32(jit, AMX_REG_ALT, val);
17.732 -}
17.733 -
17.734 -inline void WriteOp_Addr_Pri(JitWriter *jit)
17.735 -{
17.736 - //mov eax, [esi+frm]
17.737 - //add eax, <val>
17.738 - cell_t val = jit->read_cell();
17.739 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
17.740 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.741 - {
17.742 - IA32_Add_Rm_Imm8(jit, AMX_REG_PRI, (jit_int8_t)val, MOD_REG);
17.743 - } else {
17.744 - IA32_Add_Eax_Imm32(jit, val);
17.745 - }
17.746 -}
17.747 -
17.748 -inline void WriteOp_Addr_Alt(JitWriter *jit)
17.749 -{
17.750 - //mov edx, [esi+frm]
17.751 - //add edx, <val>
17.752 - cell_t val = jit->read_cell();
17.753 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_INFO, MOD_MEM_REG);
17.754 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.755 - {
17.756 - IA32_Add_Rm_Imm8(jit, AMX_REG_ALT, (jit_int8_t)val, MOD_REG);
17.757 - } else {
17.758 - IA32_Add_Rm_Imm32(jit, AMX_REG_ALT, val, MOD_REG);
17.759 - }
17.760 -}
17.761 -
17.762 -inline void WriteOp_Stor_Pri(JitWriter *jit)
17.763 -{
17.764 - //mov [ebp+<val>], eax
17.765 - cell_t val = jit->read_cell();
17.766 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.767 - {
17.768 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_DAT, AMX_REG_PRI, (jit_int8_t)val);
17.769 - } else {
17.770 - IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_DAT, AMX_REG_PRI, val);
17.771 - }
17.772 -}
17.773 -
17.774 -inline void WriteOp_Stor_Alt(JitWriter *jit)
17.775 -{
17.776 - //mov [ebp+<val>], edx
17.777 - cell_t val = jit->read_cell();
17.778 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.779 - {
17.780 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_DAT, AMX_REG_ALT, (jit_int8_t)val);
17.781 - } else {
17.782 - IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_DAT, AMX_REG_ALT, val);
17.783 - }
17.784 -}
17.785 -
17.786 -inline void WriteOp_Stor_S_Pri(JitWriter *jit)
17.787 -{
17.788 - //mov [ebx+<val>], eax
17.789 - cell_t val = jit->read_cell();
17.790 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.791 - {
17.792 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_FRM, AMX_REG_PRI, (jit_int8_t)val);
17.793 - } else {
17.794 - IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_FRM, AMX_REG_PRI, val);
17.795 - }
17.796 -}
17.797 -
17.798 -inline void WriteOp_Stor_S_Alt(JitWriter *jit)
17.799 -{
17.800 - //mov [ebx+<val>], edx
17.801 - cell_t val = jit->read_cell();
17.802 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.803 - {
17.804 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_FRM, AMX_REG_ALT, (jit_int8_t)val);
17.805 - } else {
17.806 - IA32_Mov_Rm_Reg_Disp32(jit, AMX_REG_FRM, AMX_REG_ALT, val);
17.807 - }
17.808 -}
17.809 -
17.810 -inline void WriteOp_Idxaddr(JitWriter *jit)
17.811 -{
17.812 - //lea eax, [edx+4*eax]
17.813 - IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
17.814 -}
17.815 -
17.816 -inline void WriteOp_Sref_Pri(JitWriter *jit)
17.817 -{
17.818 - //mov ecx, [ebp+<val>]
17.819 - //mov [ebp+ecx], eax
17.820 - cell_t val = jit->read_cell();
17.821 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.822 - {
17.823 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
17.824 - } else {
17.825 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
17.826 - }
17.827 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
17.828 -}
17.829 -
17.830 -inline void WriteOp_Sref_Alt(JitWriter *jit)
17.831 -{
17.832 - //mov ecx, [ebp+<val>]
17.833 - //mov [ebp+ecx], edx
17.834 - cell_t val = jit->read_cell();
17.835 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.836 - {
17.837 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
17.838 - } else {
17.839 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
17.840 - }
17.841 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
17.842 -}
17.843 -
17.844 -inline void WriteOp_Sref_S_Pri(JitWriter *jit)
17.845 -{
17.846 - //mov ecx, [ebx+<val>]
17.847 - //mov [ebp+ecx], eax
17.848 - cell_t val = jit->read_cell();
17.849 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.850 - {
17.851 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
17.852 - } else {
17.853 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
17.854 - }
17.855 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_PRI);
17.856 -}
17.857 -
17.858 -inline void WriteOp_Sref_S_Alt(JitWriter *jit)
17.859 -{
17.860 - //mov ecx, [ebx+<val>]
17.861 - //mov [ebp+ecx], edx
17.862 - cell_t val = jit->read_cell();
17.863 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.864 - {
17.865 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
17.866 - } else {
17.867 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
17.868 - }
17.869 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, AMX_REG_ALT);
17.870 -}
17.871 -
17.872 -inline void WriteOp_Pop_Pri(JitWriter *jit)
17.873 -{
17.874 - //mov eax, [edi]
17.875 - //add edi, 4
17.876 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_MEM_REG);
17.877 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.878 -}
17.879 -
17.880 -inline void WriteOp_Pop_Alt(JitWriter *jit)
17.881 -{
17.882 - //mov edx, [edi]
17.883 - //add edi, 4
17.884 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_MEM_REG);
17.885 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.886 -}
17.887 -
17.888 -inline void WriteOp_Swap_Pri(JitWriter *jit)
17.889 -{
17.890 - //add [edi], eax
17.891 - //sub eax, [edi]
17.892 - //add [edi], eax
17.893 - //neg eax
17.894 - IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_PRI, MOD_MEM_REG);
17.895 - IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_MEM_REG);
17.896 - IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_PRI, MOD_MEM_REG);
17.897 - IA32_Neg_Rm(jit, AMX_REG_PRI, MOD_REG);
17.898 -}
17.899 -
17.900 -inline void WriteOp_Swap_Alt(JitWriter *jit)
17.901 -{
17.902 - //add [edi], edx
17.903 - //sub edx, [edi]
17.904 - //add [edi], edx
17.905 - //neg edx
17.906 - IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
17.907 - IA32_Sub_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_MEM_REG);
17.908 - IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
17.909 - IA32_Neg_Rm(jit, AMX_REG_ALT, MOD_REG);
17.910 -}
17.911 -
17.912 -inline void WriteOp_PushAddr(JitWriter *jit)
17.913 -{
17.914 - //mov ecx, [esi+frm] ;get address (offset from frame)
17.915 - //sub edi, 4
17.916 - //add ecx, <val>
17.917 - //mov [edi], ecx
17.918 - cell_t val = jit->read_cell();
17.919 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_INFO, MOD_MEM_REG);
17.920 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.921 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.922 - {
17.923 - IA32_Add_Rm_Imm8(jit, AMX_REG_TMP, (jit_int8_t)val, MOD_REG);
17.924 - } else {
17.925 - IA32_Add_Rm_Imm32(jit, AMX_REG_TMP, val, MOD_REG);
17.926 - }
17.927 - IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_TMP, MOD_MEM_REG);
17.928 -}
17.929 -
17.930 -inline void WriteOp_Movs(JitWriter *jit)
17.931 -{
17.932 - //cld
17.933 - //push esi
17.934 - //push edi
17.935 - //lea esi, [ebp+eax]
17.936 - //lea edi, [ebp+edx]
17.937 - //if dword:
17.938 - // mov ecx, dword
17.939 - // rep movsd
17.940 - //if byte:
17.941 - // mov ecx, byte
17.942 - // rep movsb
17.943 - //pop edi
17.944 - //pop esi
17.945 - cell_t val = jit->read_cell();
17.946 - unsigned int dwords = val >> 2;
17.947 - unsigned int bytes = val & 0x3;
17.948 -
17.949 - IA32_Cld(jit);
17.950 - IA32_Push_Reg(jit, REG_ESI);
17.951 - IA32_Push_Reg(jit, REG_EDI);
17.952 - IA32_Lea_Reg_DispEBPRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.953 - IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
17.954 - if (dwords)
17.955 - {
17.956 - IA32_Mov_Reg_Imm32(jit, REG_ECX, dwords);
17.957 - IA32_Rep(jit);
17.958 - IA32_Movsd(jit);
17.959 - }
17.960 - if (bytes)
17.961 - {
17.962 - IA32_Mov_Reg_Imm32(jit, REG_ECX, bytes);
17.963 - IA32_Rep(jit);
17.964 - IA32_Movsb(jit);
17.965 - }
17.966 - IA32_Pop_Reg(jit, REG_EDI);
17.967 - IA32_Pop_Reg(jit, REG_ESI);
17.968 -}
17.969 -
17.970 -inline void WriteOp_Fill(JitWriter *jit)
17.971 -{
17.972 - //push edi
17.973 - //lea edi, [ebp+edx]
17.974 - //mov ecx, <val> >> 2
17.975 - //cld
17.976 - //rep stosd
17.977 - //pop edi
17.978 - unsigned int val = jit->read_cell() >> 2;
17.979 -
17.980 - IA32_Push_Reg(jit, REG_EDI);
17.981 - IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
17.982 - IA32_Mov_Reg_Imm32(jit, REG_ECX, val);
17.983 - IA32_Cld(jit);
17.984 - IA32_Rep(jit);
17.985 - IA32_Stosd(jit);
17.986 - IA32_Pop_Reg(jit, REG_EDI);
17.987 -}
17.988 -
17.989 -inline void WriteOp_GenArray(JitWriter *jit, bool autozero)
17.990 -{
17.991 - cell_t val = jit->read_cell();
17.992 - if (val == 1)
17.993 - {
17.994 - /* flat array. we can generate this without indirection tables. */
17.995 - /* Note that we can overwrite ALT because technically STACK should be destroying ALT */
17.996 - //mov edx, [esi+info.heap]
17.997 - //mov ecx, [edi]
17.998 - //mov [edi], edx ;store base of array into stack
17.999 - //lea edx, [edx+ecx*4] ;get the final new heap pointer
17.1000 - //mov [esi+info.heap], edx ;store heap pointer back
17.1001 - //add edx, ebp ;relocate
17.1002 - //cmp edx, edi ;compare against stack pointer
17.1003 - //jae :error ;error out if not enough space
17.1004 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
17.1005 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_MEM_REG);
17.1006 - IA32_Mov_Rm_Reg(jit, AMX_REG_STK, AMX_REG_ALT, MOD_MEM_REG);
17.1007 - IA32_Lea_Reg_DispRegMult(jit, AMX_REG_ALT, AMX_REG_ALT, AMX_REG_TMP, SCALE4);
17.1008 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_ALT, AMX_INFO_HEAP);
17.1009 - IA32_Add_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_DAT, MOD_REG);
17.1010 - IA32_Cmp_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_STK, MOD_REG);
17.1011 - IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_heaplow);
17.1012 -
17.1013 - WriteOp_Tracker_Push_Reg(jit, REG_ECX);
17.1014 -
17.1015 - if (autozero)
17.1016 - {
17.1017 - /* Zero out the array - inline a quick fill */
17.1018 - //push eax ;save pri
17.1019 - //push edi ;save stk
17.1020 - //xor eax, eax ;zero source
17.1021 - //mov edi, [edi] ;get heap ptr out of the stack
17.1022 - //add edi, ebp ;relocate
17.1023 - //cld ;clear direction flag
17.1024 - //rep stosd ;copy (note: ECX is sane from above)
17.1025 - //pop edi ;pop stk
17.1026 - //pop eax ;pop pri
17.1027 - IA32_Push_Reg(jit, REG_EAX);
17.1028 - IA32_Push_Reg(jit, REG_EDI);
17.1029 - IA32_Xor_Reg_Rm(jit, REG_EAX, REG_EAX, MOD_REG);
17.1030 - IA32_Mov_Reg_Rm(jit, REG_EDI, REG_EDI, MOD_MEM_REG);
17.1031 - IA32_Add_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG);
17.1032 - IA32_Cld(jit);
17.1033 - IA32_Rep(jit);
17.1034 - IA32_Stosd(jit);
17.1035 - IA32_Pop_Reg(jit, REG_EDI);
17.1036 - IA32_Pop_Reg(jit, REG_EAX);
17.1037 - }
17.1038 - } else {
17.1039 - //mov ecx, num_dims
17.1040 - //mov edx, 0/1
17.1041 - //call [genarray]
17.1042 - IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, val);
17.1043 - if (autozero)
17.1044 - {
17.1045 - IA32_Mov_Reg_Imm32(jit, REG_EDX, 1);
17.1046 - } else {
17.1047 - IA32_Mov_Reg_Imm32(jit, REG_EDX, 0);
17.1048 - }
17.1049 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1050 - IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_genarray);
17.1051 - }
17.1052 -}
17.1053 -
17.1054 -inline void WriteOp_Load_Both(JitWriter *jit)
17.1055 -{
17.1056 - WriteOp_Load_Pri(jit);
17.1057 - WriteOp_Load_Alt(jit);
17.1058 -}
17.1059 -
17.1060 -inline void WriteOp_Load_S_Both(JitWriter *jit)
17.1061 -{
17.1062 - WriteOp_Load_S_Pri(jit);
17.1063 - WriteOp_Load_S_Alt(jit);
17.1064 -}
17.1065 -
17.1066 -inline void WriteOp_Const(JitWriter *jit)
17.1067 -{
17.1068 - //mov [ebp+<addr>], <val>
17.1069 - cell_t addr = jit->read_cell();
17.1070 - cell_t val = jit->read_cell();
17.1071 - if (addr < SCHAR_MAX && addr > SCHAR_MIN)
17.1072 - {
17.1073 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_DAT, val, (jit_int8_t)addr);
17.1074 - } else {
17.1075 - IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_DAT, val, addr);
17.1076 - }
17.1077 -}
17.1078 -
17.1079 -inline void WriteOp_Const_S(JitWriter *jit)
17.1080 -{
17.1081 - //mov [ebx+<offs>], <val>
17.1082 - cell_t offs = jit->read_cell();
17.1083 - cell_t val = jit->read_cell();
17.1084 - if (offs < SCHAR_MAX && offs > SCHAR_MIN)
17.1085 - {
17.1086 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_FRM, val, (jit_int8_t)offs);
17.1087 - } else {
17.1088 - IA32_Mov_Rm_Imm32_Disp32(jit, AMX_REG_FRM, val, offs);
17.1089 - }
17.1090 -}
17.1091 -
17.1092 -inline void WriteOp_Load_I(JitWriter *jit)
17.1093 -{
17.1094 - //mov eax, [ebp+eax]
17.1095 - Write_Check_VerifyAddr(jit, AMX_REG_PRI);
17.1096 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.1097 -}
17.1098 -
17.1099 -inline void WriteOp_Lodb_I(JitWriter *jit)
17.1100 -{
17.1101 - Write_Check_VerifyAddr(jit, AMX_REG_PRI);
17.1102 -
17.1103 - //mov eax, [ebp+eax]
17.1104 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.1105 -
17.1106 - //and eax, <bitmask>
17.1107 - cell_t val = jit->read_cell();
17.1108 - switch(val)
17.1109 - {
17.1110 - case 1:
17.1111 - {
17.1112 - IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x000000FF);
17.1113 - break;
17.1114 - }
17.1115 - case 2:
17.1116 - {
17.1117 - IA32_And_Rm_Imm32(jit, AMX_REG_PRI, 0x0000FFFF);
17.1118 - break;
17.1119 - }
17.1120 - }
17.1121 -}
17.1122 -
17.1123 -inline void WriteOp_Stor_I(JitWriter *jit)
17.1124 -{
17.1125 - //mov [ebp+edx], eax
17.1126 - Write_Check_VerifyAddr(jit, AMX_REG_ALT);
17.1127 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
17.1128 -}
17.1129 -
17.1130 -inline void WriteOp_Strb_I(JitWriter *jit)
17.1131 -{
17.1132 - Write_Check_VerifyAddr(jit, AMX_REG_ALT);
17.1133 - //mov [ebp+edx], eax
17.1134 - cell_t val = jit->read_cell();
17.1135 - switch (val)
17.1136 - {
17.1137 - case 1:
17.1138 - {
17.1139 - IA32_Mov_Rm8EBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
17.1140 - break;
17.1141 - }
17.1142 - case 2:
17.1143 - {
17.1144 - IA32_Mov_Rm16EBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
17.1145 - break;
17.1146 - }
17.1147 - case 4:
17.1148 - {
17.1149 - IA32_Mov_RmEBP_Reg_Disp_Reg(jit, AMX_REG_DAT, AMX_REG_ALT, NOSCALE, AMX_REG_PRI);
17.1150 - break;
17.1151 - }
17.1152 - }
17.1153 -}
17.1154 -
17.1155 -inline void WriteOp_Lidx(JitWriter *jit)
17.1156 -{
17.1157 - //lea eax, [edx+4*eax]
17.1158 - //mov eax, [ebp+eax]
17.1159 - IA32_Lea_Reg_DispRegMult(jit, AMX_REG_PRI, AMX_REG_ALT, AMX_REG_PRI, SCALE4);
17.1160 - Write_Check_VerifyAddr(jit, AMX_REG_PRI);
17.1161 - IA32_Mov_Reg_RmEBP_Disp_Reg(jit, AMX_REG_PRI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
17.1162 -}
17.1163 -
17.1164 -inline void WriteOp_Stack(JitWriter *jit)
17.1165 -{
17.1166 - //add edi, <val>
17.1167 - cell_t val = jit->read_cell();
17.1168 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.1169 - {
17.1170 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)val, MOD_REG);
17.1171 - } else {
17.1172 - IA32_Add_Rm_Imm32(jit, AMX_REG_STK, val, MOD_REG);
17.1173 - }
17.1174 -
17.1175 - if (val > 0)
17.1176 - {
17.1177 - Write_CheckStack_Min(jit);
17.1178 - } else if (val < 0) {
17.1179 - Write_CheckStack_Low(jit);
17.1180 - }
17.1181 -}
17.1182 -
17.1183 -inline void WriteOp_Heap(JitWriter *jit)
17.1184 -{
17.1185 - //mov edx, [esi+hea]
17.1186 - //add [esi+hea], <val>
17.1187 - cell_t val = jit->read_cell();
17.1188 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_ALT, AMX_REG_INFO, AMX_INFO_HEAP);
17.1189 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.1190 - {
17.1191 - IA32_Add_Rm_Imm8_Disp8(jit, AMX_REG_INFO, (jit_int8_t)val, AMX_INFO_HEAP);
17.1192 - } else {
17.1193 - IA32_Add_Rm_Imm32_Disp8(jit, AMX_REG_INFO, val, AMX_INFO_HEAP);
17.1194 - }
17.1195 -
17.1196 - /* NOTE: Backwards from op.stack */
17.1197 - if (val > 0)
17.1198 - {
17.1199 - Write_CheckHeap_Low(jit);
17.1200 - } else if (val < 0) {
17.1201 - Write_CheckHeap_Min(jit);
17.1202 - }
17.1203 -}
17.1204 -
17.1205 -inline void WriteOp_SDiv(JitWriter *jit)
17.1206 -{
17.1207 - //mov ecx, edx
17.1208 - //mov edx, eax
17.1209 - //sar edx, 31
17.1210 - //idiv ecx
17.1211 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
17.1212 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_PRI, MOD_REG);
17.1213 - IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 31, MOD_REG);
17.1214 - Write_Check_DivZero(jit, AMX_REG_TMP);
17.1215 - IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
17.1216 -}
17.1217 -
17.1218 -inline void WriteOp_SDiv_Alt(JitWriter *jit)
17.1219 -{
17.1220 - //mov ecx, eax
17.1221 - //mov eax, edx
17.1222 - //sar edx, 31
17.1223 - //idiv ecx
17.1224 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
17.1225 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1226 - IA32_Sar_Rm_Imm8(jit, AMX_REG_ALT, 31, MOD_REG);
17.1227 - Write_Check_DivZero(jit, AMX_REG_TMP);
17.1228 - IA32_IDiv_Rm(jit, AMX_REG_TMP, MOD_REG);
17.1229 -}
17.1230 -
17.1231 -inline void WriteOp_Retn(JitWriter *jit)
17.1232 -{
17.1233 - //mov ebx, [edi+4] - get old frm
17.1234 - //add edi, 8 - pop stack
17.1235 - //mov [esi+frm], ebx - restore frame pointer
17.1236 - //add ebx, ebp - relocate
17.1237 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_FRM, AMX_REG_STK, 4);
17.1238 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 8, MOD_REG);
17.1239 - IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_FRM, MOD_MEM_REG);
17.1240 - IA32_Add_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
17.1241 -
17.1242 - /* pop params */
17.1243 - //mov ecx, [edi]
17.1244 - //lea edi, [edi+ecx*4+4]
17.1245 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_MEM_REG);
17.1246 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, AMX_REG_TMP, SCALE4, 4);
17.1247 -
17.1248 - //ret - return (EIP on real stack!)
17.1249 - IA32_Return(jit);
17.1250 -}
17.1251 -
17.1252 -inline void WriteOp_Call(JitWriter *jit)
17.1253 -{
17.1254 - cell_t offs = jit->read_cell();
17.1255 -
17.1256 - jitoffs_t jmp = IA32_Call_Imm32(jit, 0);
17.1257 - IA32_Write_Jump32(jit, jmp, RelocLookup(jit, offs, false));
17.1258 -}
17.1259 -
17.1260 -inline void WriteOp_Bounds(JitWriter *jit)
17.1261 -{
17.1262 - cell_t val = jit->read_cell();
17.1263 -
17.1264 - //cmp eax, <val>
17.1265 - //ja :error
17.1266 - if (val < SCHAR_MAX && val > SCHAR_MIN)
17.1267 - {
17.1268 - IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_PRI, (jit_int8_t)val);
17.1269 - } else {
17.1270 - IA32_Cmp_Eax_Imm32(jit, val);
17.1271 - }
17.1272 - IA32_Jump_Cond_Imm32_Abs(jit, CC_A, ((CompData *)jit->data)->jit_error_bounds);
17.1273 -}
17.1274 -
17.1275 -inline void WriteOp_Halt(JitWriter *jit)
17.1276 -{
17.1277 - //mov ecx, [esi+ret]
17.1278 - //mov [ecx], eax
17.1279 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_RETVAL);
17.1280 - IA32_Mov_Rm_Reg(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_MEM_REG);
17.1281 -
17.1282 - /* :TODO:
17.1283 - * We don't support sleeping or halting with weird values.
17.1284 - * So we're omitting the mov eax <val> that was here.
17.1285 - */
17.1286 - jit->read_cell();
17.1287 -
17.1288 - CompData *data = (CompData *)jit->data;
17.1289 - IA32_Jump_Imm32_Abs(jit, data->jit_return);
17.1290 -}
17.1291 -
17.1292 -inline void WriteOp_Break(JitWriter *jit)
17.1293 -{
17.1294 - CompData *data = (CompData *)jit->data;
17.1295 - if (data->debug)
17.1296 - {
17.1297 - //mov ecx, <cip>
17.1298 - jitoffs_t wr = IA32_Mov_Reg_Imm32(jit, AMX_REG_TMP, 0);
17.1299 - jitoffs_t save = jit->get_outputpos();
17.1300 - jit->set_outputpos(wr);
17.1301 - jit->write_uint32((uint32_t)(jit->outbase + wr));
17.1302 - jit->set_outputpos(save);
17.1303 -
17.1304 - wr = IA32_Call_Imm32(jit, 0);
17.1305 - IA32_Write_Jump32(jit, wr, data->jit_break);
17.1306 - }
17.1307 -}
17.1308 -
17.1309 -inline void WriteOp_Jump(JitWriter *jit)
17.1310 -{
17.1311 - //jmp <offs>
17.1312 - cell_t amx_offs = jit->read_cell();
17.1313 - IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, amx_offs, false));
17.1314 -}
17.1315 -
17.1316 -inline void WriteOp_Jzer(JitWriter *jit)
17.1317 -{
17.1318 - //test eax, eax
17.1319 - //jz <target>
17.1320 - cell_t target = jit->read_cell();
17.1321 - IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
17.1322 - IA32_Jump_Cond_Imm32_Abs(jit, CC_Z, RelocLookup(jit, target, false));
17.1323 -}
17.1324 -
17.1325 -inline void WriteOp_Jnz(JitWriter *jit)
17.1326 -{
17.1327 - //test eax, eax
17.1328 - //jnz <target>
17.1329 - cell_t target = jit->read_cell();
17.1330 - IA32_Test_Rm_Reg(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
17.1331 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, RelocLookup(jit, target, false));
17.1332 -}
17.1333 -
17.1334 -inline void WriteOp_Jeq(JitWriter *jit)
17.1335 -{
17.1336 - //cmp eax, edx
17.1337 - //je <target>
17.1338 - cell_t target = jit->read_cell();
17.1339 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1340 - IA32_Jump_Cond_Imm32_Abs(jit, CC_E, RelocLookup(jit, target, false));
17.1341 -}
17.1342 -
17.1343 -inline void WriteOp_Jneq(JitWriter *jit)
17.1344 -{
17.1345 - //cmp eax, edx
17.1346 - //jne <target>
17.1347 - cell_t target = jit->read_cell();
17.1348 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1349 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NE, RelocLookup(jit, target, false));
17.1350 -}
17.1351 -
17.1352 -inline void WriteOp_Jsless(JitWriter *jit)
17.1353 -{
17.1354 - //cmp eax, edx
17.1355 - //jl <target>
17.1356 - cell_t target = jit->read_cell();
17.1357 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1358 - IA32_Jump_Cond_Imm32_Abs(jit, CC_L, RelocLookup(jit, target, false));
17.1359 -}
17.1360 -
17.1361 -inline void WriteOp_Jsleq(JitWriter *jit)
17.1362 -{
17.1363 - //cmp eax, edx
17.1364 - //jle <target>
17.1365 - cell_t target = jit->read_cell();
17.1366 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1367 - IA32_Jump_Cond_Imm32_Abs(jit, CC_LE, RelocLookup(jit, target, false));
17.1368 -}
17.1369 -
17.1370 -inline void WriteOp_JsGrtr(JitWriter *jit)
17.1371 -{
17.1372 - //cmp eax, edx
17.1373 - //jg <target>
17.1374 - cell_t target = jit->read_cell();
17.1375 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1376 - IA32_Jump_Cond_Imm32_Abs(jit, CC_G, RelocLookup(jit, target, false));
17.1377 -}
17.1378 -
17.1379 -inline void WriteOp_JsGeq(JitWriter *jit)
17.1380 -{
17.1381 - //cmp eax, edx
17.1382 - //jge <target>
17.1383 - cell_t target = jit->read_cell();
17.1384 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
17.1385 - IA32_Jump_Cond_Imm32_Abs(jit, CC_GE, RelocLookup(jit, target, false));
17.1386 -}
17.1387 -
17.1388 -inline void WriteOp_Switch(JitWriter *jit)
17.1389 -{
17.1390 - cell_t offs = jit->read_cell();
17.1391 - cell_t *tbl = (cell_t *)((char *)jit->inbase + offs + sizeof(cell_t));
17.1392 -
17.1393 - struct casetbl
17.1394 - {
17.1395 - cell_t val;
17.1396 - cell_t offs;
17.1397 - };
17.1398 -
17.1399 - /* Read the number of cases, then advance by one */
17.1400 - cell_t num_cases = *tbl++;
17.1401 - if (!num_cases)
17.1402 - {
17.1403 - /* Special treatment for 0 cases */
17.1404 - //jmp <default>
17.1405 - IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, *tbl, false));
17.1406 - } else {
17.1407 - /* Check if the case layout is fully sequential */
17.1408 - casetbl *iter = (casetbl *)(tbl + 1);
17.1409 - casetbl *cases = iter;
17.1410 - cell_t first = iter[0].val;
17.1411 - cell_t last = first;
17.1412 - bool sequential = true;
17.1413 - for (cell_t i=1; i<num_cases; i++)
17.1414 - {
17.1415 - if (iter[i].val != ++last)
17.1416 - {
17.1417 - sequential = false;
17.1418 - break;
17.1419 - }
17.1420 - }
17.1421 - /* Time to generate.
17.1422 - * First check whether the bounds are correct: if (a < LOW || a > HIGH)
17.1423 - * This check is valid for both sequential and non-sequential.
17.1424 - */
17.1425 - cell_t low_bound = cases[0].val;
17.1426 - if (low_bound != 0)
17.1427 - {
17.1428 - /* negate it so we'll get a lower bound of 0 */
17.1429 - //lea ecx, [eax-<LOWER_BOUND>]
17.1430 - low_bound = -low_bound;
17.1431 - if (low_bound > SCHAR_MIN && low_bound < SCHAR_MAX)
17.1432 - {
17.1433 - IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, low_bound);
17.1434 - } else {
17.1435 - IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, low_bound);
17.1436 - }
17.1437 - }
17.1438 - cell_t high_bound = abs(cases[0].val - cases[num_cases-1].val);
17.1439 - //cmp ecx, <UPPER BOUND BOUND>
17.1440 - if (high_bound > SCHAR_MIN && high_bound < SCHAR_MAX)
17.1441 - {
17.1442 - IA32_Cmp_Rm_Imm8(jit, MOD_REG, AMX_REG_TMP, high_bound);
17.1443 - } else {
17.1444 - IA32_Cmp_Rm_Imm32(jit, MOD_REG, AMX_REG_TMP, high_bound);
17.1445 - }
17.1446 - //ja <default case>
17.1447 - IA32_Jump_Cond_Imm32_Abs(jit, CC_A, RelocLookup(jit, *tbl, false));
17.1448 -
17.1449 - /**
17.1450 - * Now we've taken the default case out of the way, it's time to do the
17.1451 - * full check, which is different for sequential vs. non-sequential.
17.1452 - */
17.1453 - if (sequential)
17.1454 - {
17.1455 - /* we're now theoretically guaranteed to be jumping to a correct offset.
17.1456 - * ECX still has the correctly bound offset in it, luckily!
17.1457 - * thus, we simply need to relocate ECX and store the cases.
17.1458 - */
17.1459 - //lea ecx, [ecx*4]
17.1460 - //add ecx, <case table start>
17.1461 - IA32_Lea_Reg_RegMultImm32(jit, AMX_REG_TMP, AMX_REG_TMP, SCALE4, 0);
17.1462 - jitoffs_t tbl_offs = IA32_Add_Rm_Imm32_Later(jit, AMX_REG_TMP, MOD_REG);
17.1463 - IA32_Jump_Rm(jit, AMX_REG_TMP, MOD_MEM_REG);
17.1464 - /* The case table starts here. Go back and write the output pointer. */
17.1465 - jitoffs_t cur_pos = jit->get_outputpos();
17.1466 - jit->set_outputpos(tbl_offs);
17.1467 - jit->write_uint32((jit_uint32_t)(jit->outbase + cur_pos));
17.1468 - jit->set_outputpos(cur_pos);
17.1469 - //now we can write the case table, finally!
17.1470 - jit_uint32_t base = (jit_uint32_t)jit->outbase;
17.1471 - for (cell_t i=0; i<num_cases; i++)
17.1472 - {
17.1473 - jit->write_uint32(base + RelocLookup(jit, cases[i].offs, false));
17.1474 - }
17.1475 - } else {
17.1476 - /* The slow version. Go through each case and generate a check.
17.1477 - * In the future we should replace case tables of more than ~8 cases with a
17.1478 - * hash table lookup.
17.1479 - * :THOUGHT: Another method of optimizing this - fill in the gaps with jumps to the default case,
17.1480 - * but only if we're under N cases or so!
17.1481 - * :THOUGHT: Write out a static btree lookup :)
17.1482 - */
17.1483 - cell_t val;
17.1484 - for (cell_t i=0; i<num_cases; i++)
17.1485 - {
17.1486 - val = cases[i].val;
17.1487 - //cmp eax, <val> OR cmp al, <val>
17.1488 - if (val > SCHAR_MIN && val < SCHAR_MAX)
17.1489 - {
17.1490 - IA32_Cmp_Al_Imm8(jit, val);
17.1491 - } else {
17.1492 - IA32_Cmp_Eax_Imm32(jit, cases[i].val);
17.1493 - }
17.1494 - IA32_Jump_Cond_Imm32_Abs(jit, CC_E, RelocLookup(jit, cases[i].offs, false));
17.1495 - }
17.1496 - /* After all this, jump to the default case! */
17.1497 - IA32_Jump_Imm32_Abs(jit, RelocLookup(jit, *tbl, false));
17.1498 - }
17.1499 - }
17.1500 -}
17.1501 -
17.1502 -inline void WriteOp_Casetbl(JitWriter *jit)
17.1503 -{
17.1504 - /* do nothing here, switch does all ze work */
17.1505 - cell_t num_cases = jit->read_cell();
17.1506 -
17.1507 - /* Two cells per case, one extra case for the default jump */
17.1508 - num_cases = (num_cases * 2) + 1;
17.1509 - jit->inptr += num_cases;
17.1510 -}
17.1511 -
17.1512 -inline void WriteOp_Sysreq_C(JitWriter *jit)
17.1513 -{
17.1514 - /* store the number of parameters on the stack,
17.1515 - * and store the native index as well.
17.1516 - */
17.1517 - cell_t native_index = jit->read_cell();
17.1518 -
17.1519 - if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
17.1520 - {
17.1521 - ((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
17.1522 - return;
17.1523 - }
17.1524 -
17.1525 - //mov ecx, <native_index>
17.1526 - IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
17.1527 -
17.1528 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1529 - IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_c);
17.1530 -}
17.1531 -
17.1532 -inline void WriteOp_Sysreq_N_NoInline(JitWriter *jit)
17.1533 -{
17.1534 - /* store the number of parameters on the stack,
17.1535 - * and store the native index as well.
17.1536 - */
17.1537 - cell_t native_index = jit->read_cell();
17.1538 - cell_t num_params = jit->read_cell();
17.1539 -
17.1540 - if ((uint32_t)native_index >= ((CompData*)jit->data)->plugin->info.natives_num)
17.1541 - {
17.1542 - ((CompData *)jit->data)->error_set = SP_ERROR_INSTRUCTION_PARAM;
17.1543 - return;
17.1544 - }
17.1545 -
17.1546 - //mov eax, <num_params>
17.1547 - //mov ecx, <native_index>
17.1548 - IA32_Mov_Reg_Imm32(jit, REG_EAX, num_params);
17.1549 - IA32_Mov_Reg_Imm32(jit, REG_ECX, native_index);
17.1550 -
17.1551 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1552 - IA32_Write_Jump32(jit, call, ((CompData *)jit->data)->jit_sysreq_n);
17.1553 -}
17.1554 -
17.1555 -inline void WriteOp_Sysreq_N(JitWriter *jit)
17.1556 -{
17.1557 - /* The big daddy of opcodes. */
17.1558 - cell_t native_index = jit->read_cell();
17.1559 - cell_t num_params = jit->read_cell();
17.1560 - CompData *data = (CompData *)jit->data;
17.1561 -
17.1562 - if ((uint32_t)native_index >= data->plugin->info.natives_num)
17.1563 - {
17.1564 - data->error_set = SP_ERROR_INSTRUCTION_PARAM;
17.1565 - return;
17.1566 - }
17.1567 -
17.1568 - /* store the number of parameters on the stack */
17.1569 - //mov [edi-4], num_params
17.1570 - //sub edi, 4
17.1571 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, num_params, -4);
17.1572 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
17.1573 -
17.1574 - /* save registers we will need */
17.1575 - //push edx
17.1576 - IA32_Push_Reg(jit, AMX_REG_ALT);
17.1577 -
17.1578 - /* push some callback stuff */
17.1579 - //push edi ; stack
17.1580 - //push <native> ; native index
17.1581 - IA32_Push_Reg(jit, AMX_REG_STK);
17.1582 - if (native_index < SCHAR_MAX && native_index > SCHAR_MIN)
17.1583 - {
17.1584 - IA32_Push_Imm8(jit, (jit_int8_t)native_index);
17.1585 - } else {
17.1586 - IA32_Push_Imm32(jit, native_index);
17.1587 - }
17.1588 -
17.1589 - /* Relocate stack, heap, frm information, then store back */
17.1590 - //mov eax, [esi+context]
17.1591 - //mov ecx, [esi+hea]
17.1592 - //sub edi, ebp
17.1593 - //mov [eax+hp], ecx
17.1594 - //mov ecx, [esi]
17.1595 - //mov [eax+sp], edi
17.1596 - //mov [eax+frm], ecx
17.1597 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
17.1598 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
17.1599 - IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
17.1600 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
17.1601 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
17.1602 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
17.1603 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
17.1604 -
17.1605 - /* finally, push the last parameter and make the call */
17.1606 - //push eax ; context
17.1607 - //call NativeCallback
17.1608 - IA32_Push_Reg(jit, REG_EAX);
17.1609 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1610 - if (!data->debug)
17.1611 - {
17.1612 - IA32_Write_Jump32_Abs(jit, call, NativeCallback);
17.1613 - } else {
17.1614 - IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
17.1615 - }
17.1616 -
17.1617 - /* check for errors */
17.1618 - //mov ecx, [esi+context]
17.1619 - //cmp [ecx+err], 0
17.1620 - //jnz :error
17.1621 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
17.1622 - IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
17.1623 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
17.1624 -
17.1625 - /* restore what we damaged */
17.1626 - //add esp, 4*3
17.1627 - //add edi, ebp
17.1628 - //pop edx
17.1629 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
17.1630 - IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
17.1631 - IA32_Pop_Reg(jit, AMX_REG_ALT);
17.1632 -
17.1633 - /* pop the stack. do not check the margins.
17.1634 - * Note that this is not a true macro - we don't bother to
17.1635 - * set ALT here because nothing will be using it.
17.1636 - */
17.1637 - num_params++;
17.1638 - num_params *= 4;
17.1639 - //add edi, <val*4+4>
17.1640 - if (num_params < SCHAR_MAX && num_params > SCHAR_MIN)
17.1641 - {
17.1642 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, (jit_int8_t)num_params, MOD_REG);
17.1643 - } else {
17.1644 - IA32_Add_Rm_Imm32(jit, AMX_REG_STK, num_params, MOD_REG);
17.1645 - }
17.1646 -}
17.1647 -
17.1648 -inline void WriteOp_Tracker_Push_C(JitWriter *jit)
17.1649 -{
17.1650 - CompData *data = (CompData *)jit->data;
17.1651 - cell_t val = jit->read_cell();
17.1652 -
17.1653 - /* Save registers that may be damaged by the call */
17.1654 - //push eax
17.1655 - //push edx
17.1656 - IA32_Push_Reg(jit, AMX_REG_PRI);
17.1657 - IA32_Push_Reg(jit, AMX_REG_ALT);
17.1658 -
17.1659 - /* Get the context ptr, push it and call the check */
17.1660 - //mov eax, [esi+context]
17.1661 - //push eax
17.1662 - //call JIT_VerifyOrAllocateTracker
17.1663 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
17.1664 - IA32_Push_Reg(jit, REG_EAX);
17.1665 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1666 - IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
17.1667 -
17.1668 - /* Check for errors */
17.1669 - //pop eax
17.1670 - //cmp [eax+err], 0
17.1671 - //jnz :error
17.1672 - IA32_Pop_Reg(jit, REG_EAX);
17.1673 - IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
17.1674 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
17.1675 -
17.1676 - /* Push the value into the stack and increment pCur */
17.1677 - //mov edx, [eax+vm[]]
17.1678 - //mov ecx, [edx+pcur]
17.1679 - //add [edx+pcur], 4
17.1680 - //mov [ecx], <val>*4 ; we want the count in bytes not in cells
17.1681 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
17.1682 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
17.1683 - IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
17.1684 - IA32_Mov_Rm_Imm32(jit, AMX_REG_TMP, val*4, MOD_MEM_REG);
17.1685 -
17.1686 - /* Restore PRI & ALT */
17.1687 - //pop edx
17.1688 - //pop eax
17.1689 - IA32_Pop_Reg(jit, AMX_REG_ALT);
17.1690 - IA32_Pop_Reg(jit, AMX_REG_PRI);
17.1691 -}
17.1692 -
17.1693 -inline void WriteOp_Tracker_Pop_SetHeap(JitWriter *jit)
17.1694 -{
17.1695 - CompData *data = (CompData *)jit->data;
17.1696 -
17.1697 - /* Save registers that may be damaged by the call */
17.1698 - //push eax
17.1699 - //push edx
17.1700 - IA32_Push_Reg(jit, AMX_REG_PRI);
17.1701 - IA32_Push_Reg(jit, AMX_REG_ALT);
17.1702 -
17.1703 - /* Get the context ptr, push it and call the check */
17.1704 - //mov eax, [esi+context]
17.1705 - //push eax
17.1706 - //call JIT_VerifyLowBoundTracker
17.1707 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
17.1708 - IA32_Push_Reg(jit, REG_EAX);
17.1709 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
17.1710 - IA32_Write_Jump32_Abs(jit, call, JIT_VerifyLowBoundTracker);
17.1711 -
17.1712 - /* Check for errors */
17.1713 - //pop eax
17.1714 - //cmp [eax+err], 0
17.1715 - //jnz :error
17.1716 - IA32_Pop_Reg(jit, REG_EAX);
17.1717 - IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
17.1718 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
17.1719 -
17.1720 - /* Pop the value from the stack and decrease the heap by it*/
17.1721 - //mov edx, [eax+vm[]]
17.1722 - //sub [edx+pcur], 4
17.1723 - //mov ecx, [edx+pcur]
17.1724 - //mov ecx, [ecx]
17.1725 - //sub [esi+hea], ecx
17.1726 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
17.1727 - IA32_Sub_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
17.1728 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, REG_EDX, offsetof(tracker_t, pCur));
17.1729 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_TMP, MOD_MEM_REG);
17.1730 - IA32_Sub_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_TMP, AMX_INFO_HEAP);
17.1731 -
17.1732 - Write_CheckHeap_Min(jit);
17.1733 -
17.1734 - /* Restore PRI & ALT */
17.1735 - //pop edx
17.1736 - //pop eax
17.1737 - IA32_Pop_Reg(jit, AMX_REG_ALT);
17.1738 - IA32_Pop_Reg(jit, AMX_REG_PRI);
17.1739 -}
17.1740 -
17.1741 -/*************************************************
17.1742 - *************************************************
17.1743 - * JIT PROPER ************************************
17.1744 - * The rest from now on is the JIT engine *
17.1745 - *************************************************
17.1746 - *************************************************/
17.1747 -
17.1748 -cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
17.1749 -{
17.1750 - sp_native_t *native = &ctx->natives[native_idx];
17.1751 -
17.1752 - /* Technically both aren't needed, I guess */
17.1753 - if (native->status == SP_NATIVE_NONE)
17.1754 - {
17.1755 - ctx->err = SP_ERROR_NATIVE_PENDING;
17.1756 - return 0;
17.1757 - }
17.1758 -
17.1759 - return native->pfn(ctx, params);
17.1760 -}
17.1761 -
17.1762 -cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params)
17.1763 -{
17.1764 - cell_t save_sp = ctx->sp;
17.1765 - cell_t save_hp = ctx->hp;
17.1766 -
17.1767 - if (ctx->hp < ctx->heap_base)
17.1768 - {
17.1769 - ctx->err = SP_ERROR_HEAPMIN;
17.1770 - return 0;
17.1771 - }
17.1772 -
17.1773 - if (ctx->hp + STACK_MARGIN > ctx->sp)
17.1774 - {
17.1775 - ctx->err = SP_ERROR_STACKLOW;
17.1776 - return 0;
17.1777 - }
17.1778 -
17.1779 - if ((uint32_t)ctx->sp >= ctx->mem_size)
17.1780 - {
17.1781 - ctx->err = SP_ERROR_STACKMIN;
17.1782 - return 0;
17.1783 - }
17.1784 -
17.1785 - cell_t result = NativeCallback(ctx, native_idx, params);
17.1786 -
17.1787 - if (ctx->err != SP_ERROR_NONE)
17.1788 - {
17.1789 - return result;
17.1790 - }
17.1791 -
17.1792 - if (save_sp != ctx->sp)
17.1793 - {
17.1794 - ctx->err = SP_ERROR_STACKLEAK;
17.1795 - return result;
17.1796 - } else if (save_hp != ctx->hp) {
17.1797 - ctx->err = SP_ERROR_HEAPLEAK;
17.1798 - return result;
17.1799 - }
17.1800 -
17.1801 - return result;
17.1802 -}
17.1803 -
17.1804 -jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative)
17.1805 -{
17.1806 - if (jit->outptr)
17.1807 - {
17.1808 - CompData *data = (CompData *)jit->data;
17.1809 - if (relative)
17.1810 - {
17.1811 - /* The actual offset is EIP relative. We need to relocate it.
17.1812 - * Note that this assumes that we're pointing to the next op.
17.1813 - */
17.1814 - pcode_offs += jit->get_inputpos();
17.1815 - }
17.1816 - /* Offset must always be 1)positive and 2)less than the codesize */
17.1817 - assert(pcode_offs >= 0 && (uint32_t)pcode_offs < data->codesize);
17.1818 - /* Do the lookup in the native dictionary. */
17.1819 - return *(jitoffs_t *)(data->rebase + pcode_offs);
17.1820 - } else {
17.1821 - return 0;
17.1822 - }
17.1823 -}
17.1824 -
17.1825 -void WriteErrorRoutines(CompData *data, JitWriter *jit)
17.1826 -{
17.1827 - data->jit_error_divzero = jit->get_outputpos();
17.1828 - Write_SetError(jit, SP_ERROR_DIVIDE_BY_ZERO);
17.1829 -
17.1830 - data->jit_error_stacklow = jit->get_outputpos();
17.1831 - Write_SetError(jit, SP_ERROR_STACKLOW);
17.1832 -
17.1833 - data->jit_error_stackmin = jit->get_outputpos();
17.1834 - Write_SetError(jit, SP_ERROR_STACKMIN);
17.1835 -
17.1836 - data->jit_error_bounds = jit->get_outputpos();
17.1837 - Write_SetError(jit, SP_ERROR_ARRAY_BOUNDS);
17.1838 -
17.1839 - data->jit_error_memaccess = jit->get_outputpos();
17.1840 - Write_SetError(jit, SP_ERROR_MEMACCESS);
17.1841 -
17.1842 - data->jit_error_heaplow = jit->get_outputpos();
17.1843 - Write_SetError(jit, SP_ERROR_HEAPLOW);
17.1844 -
17.1845 - data->jit_error_heapmin = jit->get_outputpos();
17.1846 - Write_SetError(jit, SP_ERROR_HEAPMIN);
17.1847 -
17.1848 - data->jit_error_array_too_big = jit->get_outputpos();
17.1849 - Write_SetError(jit, SP_ERROR_ARRAY_TOO_BIG);
17.1850 -
17.1851 - data->jit_error_tracker_bounds = jit->get_outputpos();
17.1852 - Write_SetError(jit, SP_ERROR_TRACKER_BOUNDS);
17.1853 -
17.1854 - data->jit_extern_error = jit->get_outputpos();
17.1855 - Write_GetError(jit);
17.1856 -}
17.1857 -
17.1858 -sp_context_t *JITX86::CompileToContext(ICompilation *co, int *err)
17.1859 -{
17.1860 - CompData *data = (CompData *)co;
17.1861 - sp_plugin_t *plugin = data->plugin;
17.1862 -
17.1863 - /* The first phase is to browse */
17.1864 - uint8_t *code = plugin->pcode;
17.1865 - uint8_t *end_cip = plugin->pcode + plugin->pcode_size;
17.1866 - OPCODE op;
17.1867 -
17.1868 - /*********************************************
17.1869 - * FIRST PASS (medium load): writer.outbase is NULL, getting size only
17.1870 - * SECOND PASS (heavy load!!): writer.outbase is valid and output is written
17.1871 - *********************************************/
17.1872 -
17.1873 - JitWriter writer;
17.1874 - JitWriter *jit = &writer;
17.1875 - cell_t *endptr = (cell_t *)(end_cip);
17.1876 -
17.1877 - /* Initial code is written "blank,"
17.1878 - * so we can check the exact memory usage.
17.1879 - */
17.1880 - data->codesize = plugin->pcode_size;
17.1881 - writer.data = data;
17.1882 - writer.inbase = (cell_t *)code;
17.1883 - writer.outptr = NULL;
17.1884 - writer.outbase = NULL;
17.1885 - data->rebase = (jitcode_t)engine->BaseAlloc(plugin->pcode_size);
17.1886 -
17.1887 - /* We will jump back here for second pass */
17.1888 -jit_rewind:
17.1889 - /* Initialize pass vars */
17.1890 - writer.inptr = writer.inbase;
17.1891 - data->jit_verify_addr_eax = 0;
17.1892 - data->jit_verify_addr_edx = 0;
17.1893 -
17.1894 - /* Write the prologue of the JIT */
17.1895 - data->jit_return = Write_Execute_Function(jit);
17.1896 -
17.1897 - /* Write the SYSREQ.N opcode if we need to */
17.1898 - if (!(data->inline_level & JIT_INLINE_NATIVES))
17.1899 - {
17.1900 - data->jit_sysreq_n = jit->get_outputpos();
17.1901 - WriteOp_Sysreq_N_Function(jit);
17.1902 - }
17.1903 -
17.1904 - /* Plugins compiled with -O0 will need this! */
17.1905 - data->jit_sysreq_c = jit->get_outputpos();
17.1906 - WriteOp_Sysreq_C_Function(jit);
17.1907 -
17.1908 - data->jit_genarray = jit->get_outputpos();
17.1909 - WriteIntrinsic_GenArray(jit);
17.1910 -
17.1911 - /* Write error checking routines that are called to */
17.1912 - if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
17.1913 - {
17.1914 - data->jit_verify_addr_eax = jit->get_outputpos();
17.1915 - Write_Check_VerifyAddr(jit, REG_EAX);
17.1916 -
17.1917 - data->jit_verify_addr_edx = jit->get_outputpos();
17.1918 - Write_Check_VerifyAddr(jit, REG_EDX);
17.1919 - }
17.1920 -
17.1921 - /* Actual code generation! */
17.1922 - if (writer.outbase == NULL)
17.1923 - {
17.1924 - /* First Pass - find codesize and resolve relocation */
17.1925 - jitoffs_t pcode_offs;
17.1926 - jitoffs_t native_offs;
17.1927 -
17.1928 - for (; writer.inptr < endptr;)
17.1929 - {
17.1930 - /* Store the native offset into the rebase memory.
17.1931 - * This large chunk of memory lets us do an instant lookup
17.1932 - * based on an original pcode offset.
17.1933 - */
17.1934 - pcode_offs = (jitoffs_t)((uint8_t *)writer.inptr - code);
17.1935 - native_offs = jit->get_outputpos();
17.1936 - *((jitoffs_t *)(data->rebase + pcode_offs)) = native_offs;
17.1937 -
17.1938 - /* Now read the opcode and continue. */
17.1939 - op = (OPCODE)writer.read_cell();
17.1940 - switch (op)
17.1941 - {
17.1942 - #include "opcode_switch.inc"
17.1943 - }
17.1944 - /* Check for errors. This should only happen in the first pass. */
17.1945 - if (data->error_set != SP_ERROR_NONE)
17.1946 - {
17.1947 - *err = data->error_set;
17.1948 - AbortCompilation(co);
17.1949 - return NULL;
17.1950 - }
17.1951 - }
17.1952 - /* Write these last because error jumps should be unpredicted, and thus forward */
17.1953 - WriteErrorRoutines(data, jit);
17.1954 -
17.1955 - /* the total codesize is now known! */
17.1956 - uint32_t mem = writer.get_outputpos();
17.1957 - writer.outbase = (jitcode_t)engine->ExecAlloc(mem);
17.1958 - writer.outptr = writer.outbase;
17.1959 - /* go back for third pass */
17.1960 - goto jit_rewind;
17.1961 - } else {
17.1962 - /*******
17.1963 - * THIRD PASS - write opcode info
17.1964 - *******/
17.1965 - for (; writer.inptr < endptr;)
17.1966 - {
17.1967 - op = (OPCODE)writer.read_cell();
17.1968 - switch (op)
17.1969 - {
17.1970 - #include "opcode_switch.inc"
17.1971 - }
17.1972 - }
17.1973 - /* Write these last because error jumps should be unpredicted, and thus forward */
17.1974 - WriteErrorRoutines(data, jit);
17.1975 - }
17.1976 -
17.1977 - /*************
17.1978 - * FOURTH PASS - Context Setup
17.1979 - *************/
17.1980 -
17.1981 - sp_context_t *ctx = new sp_context_t;
17.1982 - memset(ctx, 0, sizeof(sp_context_t));
17.1983 -
17.1984 - /* setup basics */
17.1985 - ctx->codebase = writer.outbase;
17.1986 - ctx->plugin = plugin;
17.1987 - ctx->vmbase = this;
17.1988 - ctx->flags = (data->debug ? SPFLAG_PLUGIN_DEBUG : 0);
17.1989 -
17.1990 - /* setup memory */
17.1991 - ctx->memory = new uint8_t[plugin->memory];
17.1992 - memcpy(ctx->memory, plugin->data, plugin->data_size);
17.1993 - ctx->mem_size = plugin->memory;
17.1994 - ctx->heap_base = plugin->data_size;
17.1995 - ctx->hp = ctx->heap_base;
17.1996 - ctx->sp = ctx->mem_size - sizeof(cell_t);
17.1997 -
17.1998 - const char *strbase = plugin->info.stringbase;
17.1999 - uint32_t max, iter;
17.2000 -
17.2001 - /* relocate public info */
17.2002 - if ((max = plugin->info.publics_num))
17.2003 - {
17.2004 - ctx->publics = new sp_public_t[max];
17.2005 - for (iter=0; iter<max; iter++)
17.2006 - {
17.2007 - ctx->publics[iter].name = strbase + plugin->info.publics[iter].name;
17.2008 - ctx->publics[iter].offs = RelocLookup(jit, plugin->info.publics[iter].address, false);
17.2009 - }
17.2010 - }
17.2011 -
17.2012 - /* relocate pubvar info */
17.2013 - if ((max = plugin->info.pubvars_num))
17.2014 - {
17.2015 - uint8_t *dat = ctx->memory;
17.2016 - ctx->pubvars = new sp_pubvar_t[max];
17.2017 - for (iter=0; iter<max; iter++)
17.2018 - {
17.2019 - ctx->pubvars[iter].name = strbase + plugin->info.pubvars[iter].name;
17.2020 - ctx->pubvars[iter].offs = (cell_t *)(dat + plugin->info.pubvars[iter].address);
17.2021 - }
17.2022 - }
17.2023 -
17.2024 - /* relocate native info */
17.2025 - if ((max = plugin->info.natives_num))
17.2026 - {
17.2027 - ctx->natives = new sp_native_t[max];
17.2028 - for (iter=0; iter<max; iter++)
17.2029 - {
17.2030 - ctx->natives[iter].name = strbase + plugin->info.natives[iter].name;
17.2031 - ctx->natives[iter].pfn = NULL;
17.2032 - ctx->natives[iter].status = SP_NATIVE_NONE;
17.2033 - }
17.2034 - }
17.2035 -
17.2036 - /**
17.2037 - * If we're debugging, make sure we copy the necessary info.
17.2038 - */
17.2039 - if (data->debug)
17.2040 - {
17.2041 - strbase = plugin->debug.stringbase;
17.2042 -
17.2043 - /* relocate files */
17.2044 - max = plugin->debug.files_num;
17.2045 - ctx->files = new sp_debug_file_t[max];
17.2046 - for (iter=0; iter<max; iter++)
17.2047 - {
17.2048 - ctx->files[iter].addr = RelocLookup(jit, plugin->debug.files[iter].addr, false);
17.2049 - ctx->files[iter].name = strbase + plugin->debug.files[iter].name;
17.2050 - }
17.2051 -
17.2052 - /* relocate lines */
17.2053 - max = plugin->debug.lines_num;
17.2054 - ctx->lines = new sp_debug_line_t[max];
17.2055 - for (iter=0; iter<max; iter++)
17.2056 - {
17.2057 - ctx->lines[iter].addr = RelocLookup(jit, plugin->debug.lines[iter].addr, false);
17.2058 - ctx->lines[iter].line = plugin->debug.lines[iter].line;
17.2059 - }
17.2060 -
17.2061 - /* relocate arrays */
17.2062 - sp_fdbg_symbol_t *sym;
17.2063 - sp_fdbg_arraydim_t *arr;
17.2064 - uint8_t *cursor = (uint8_t *)(plugin->debug.symbols);
17.2065 -
17.2066 - max = plugin->debug.syms_num;
17.2067 - ctx->symbols = new sp_debug_symbol_t[max];
17.2068 - for (iter=0; iter<max; iter++)
17.2069 - {
17.2070 - sym = (sp_fdbg_symbol_t *)cursor;
17.2071 -
17.2072 - ctx->symbols[iter].codestart = RelocLookup(jit, sym->codestart, false);
17.2073 - ctx->symbols[iter].codeend = RelocLookup(jit, sym->codeend, false);
17.2074 - ctx->symbols[iter].name = strbase + sym->name;
17.2075 - ctx->symbols[iter].sym = sym;
17.2076 -
17.2077 - if (sym->dimcount > 0)
17.2078 - {
17.2079 - cursor += sizeof(sp_fdbg_symbol_t);
17.2080 - arr = (sp_fdbg_arraydim_t *)cursor;
17.2081 - ctx->symbols[iter].dims = arr;
17.2082 - cursor += sizeof(sp_fdbg_arraydim_t) * sym->dimcount;
17.2083 - continue;
17.2084 - }
17.2085 -
17.2086 - ctx->symbols[iter].dims = NULL;
17.2087 - cursor += sizeof(sp_fdbg_symbol_t);
17.2088 - }
17.2089 - }
17.2090 -
17.2091 - tracker_t *trk = new tracker_t;
17.2092 - ctx->vm[JITVARS_TRACKER] = trk;
17.2093 - trk->pBase = (ucell_t *)malloc(1024);
17.2094 - trk->pCur = trk->pBase;
17.2095 - trk->size = 1024 / sizeof(cell_t);
17.2096 -
17.2097 - /* clean up relocation+compilation memory */
17.2098 - AbortCompilation(co);
17.2099 -
17.2100 - *err = SP_ERROR_NONE;
17.2101 -
17.2102 - return ctx;
17.2103 -}
17.2104 -
17.2105 -const char *JITX86::GetVMName()
17.2106 -{
17.2107 - return "JIT (x86)";
17.2108 -}
17.2109 -
17.2110 -int JITX86::ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result)
17.2111 -{
17.2112 - typedef int (*CONTEXT_EXECUTE)(sp_context_t *, uint32_t, cell_t *);
17.2113 - CONTEXT_EXECUTE fn = (CONTEXT_EXECUTE)ctx->codebase;
17.2114 - return fn(ctx, code_idx, result);
17.2115 -}
17.2116 -
17.2117 -void JITX86::FreeContext(sp_context_t *ctx)
17.2118 -{
17.2119 - engine->ExecFree(ctx->codebase);
17.2120 - delete [] ctx->memory;
17.2121 - delete [] ctx->files;
17.2122 - delete [] ctx->lines;
17.2123 - delete [] ctx->natives;
17.2124 - delete [] ctx->publics;
17.2125 - delete [] ctx->pubvars;
17.2126 - delete [] ctx->symbols;
17.2127 - free(((tracker_t *)(ctx->vm[JITVARS_TRACKER]))->pBase);
17.2128 - delete ctx->vm[JITVARS_TRACKER];
17.2129 - delete ctx;
17.2130 -}
17.2131 -
17.2132 -ICompilation *JITX86::StartCompilation(sp_plugin_t *plugin)
17.2133 -{
17.2134 - CompData *data = new CompData;
17.2135 -
17.2136 - data->plugin = plugin;
17.2137 - data->inline_level = JIT_INLINE_ERRORCHECKS|JIT_INLINE_NATIVES;
17.2138 - data->error_set = SP_ERROR_NONE;
17.2139 -
17.2140 - return data;
17.2141 -}
17.2142 -
17.2143 -void JITX86::AbortCompilation(ICompilation *co)
17.2144 -{
17.2145 - if (((CompData *)co)->rebase)
17.2146 - {
17.2147 - engine->BaseFree(((CompData *)co)->rebase);
17.2148 - }
17.2149 - delete (CompData *)co;
17.2150 -}
17.2151 -
17.2152 -bool JITX86::SetCompilationOption(ICompilation *co, const char *key, const char *val)
17.2153 -{
17.2154 - CompData *data = (CompData *)co;
17.2155 -
17.2156 - if (strcmp(key, "debug") == 0)
17.2157 - {
17.2158 - data->debug = (atoi(val) == 1);
17.2159 - if (data->debug && !(data->plugin->flags & SP_FLAG_DEBUG))
17.2160 - {
17.2161 - data->debug = false;
17.2162 - return false;
17.2163 - }
17.2164 - return true;
17.2165 - }
17.2166 -
17.2167 - return false;
17.2168 -}
18.1 --- a/sourcepawn/vm/jit/x86/jit_x86.h Tue Nov 07 23:26:40 2006 +0000
18.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
18.3 @@ -1,90 +0,0 @@
18.4 -#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_H_
18.5 -#define _INCLUDE_SOURCEPAWN_JIT_X86_H_
18.6 -
18.7 -#include <sp_vm_types.h>
18.8 -#include <sp_vm_api.h>
18.9 -#include "..\jit_helpers.h"
18.10 -
18.11 -using namespace SourcePawn;
18.12 -
18.13 -#define JIT_INLINE_ERRORCHECKS (1<<0)
18.14 -#define JIT_INLINE_NATIVES (1<<1)
18.15 -#define STACK_MARGIN 64 //8 parameters of safety, I guess
18.16 -
18.17 -#define JITVARS_TRACKER 0 //important: don't change this to avoid trouble
18.18 -
18.19 -typedef struct tracker_s
18.20 -{
18.21 - size_t size;
18.22 - ucell_t *pBase;
18.23 - ucell_t *pCur;
18.24 -} tracker_t;
18.25 -
18.26 -class CompData : public ICompilation
18.27 -{
18.28 -public:
18.29 - CompData() : plugin(NULL),
18.30 - debug(false), inline_level(0), rebase(NULL),
18.31 - error_set(SP_ERROR_NONE)
18.32 - {
18.33 - };
18.34 -public:
18.35 - sp_plugin_t *plugin; /* plugin handle */
18.36 - jitcode_t rebase; /* relocation map */
18.37 - jitoffs_t jit_return; /* point in main call to return to */
18.38 - jitoffs_t jit_verify_addr_eax;
18.39 - jitoffs_t jit_verify_addr_edx;
18.40 - jitoffs_t jit_break; /* call to op.break */
18.41 - jitoffs_t jit_sysreq_n; /* call version of op.sysreq.n */
18.42 - jitoffs_t jit_genarray; /* call to genarray intrinsic */
18.43 - jitoffs_t jit_error_bounds;
18.44 - jitoffs_t jit_error_divzero;
18.45 - jitoffs_t jit_error_stacklow;
18.46 - jitoffs_t jit_error_stackmin;
18.47 - jitoffs_t jit_error_memaccess;
18.48 - jitoffs_t jit_error_heaplow;
18.49 - jitoffs_t jit_error_heapmin;
18.50 - jitoffs_t jit_error_array_too_big;
18.51 - jitoffs_t jit_error_tracker_bounds;
18.52 - jitoffs_t jit_extern_error; /* returning generic error */
18.53 - jitoffs_t jit_sysreq_c; /* old version! */
18.54 - uint32_t codesize; /* total codesize */
18.55 - int inline_level; /* inline optimization level */
18.56 - int error_set; /* error code to halt process */
18.57 - bool debug; /* whether to compile debug mode */
18.58 -};
18.59 -
18.60 -class JITX86 : public IVirtualMachine
18.61 -{
18.62 -public:
18.63 - const char *GetVMName();
18.64 - ICompilation *StartCompilation(sp_plugin_t *plugin);
18.65 - bool SetCompilationOption(ICompilation *co, const char *key, const char *val);
18.66 - sp_context_t *CompileToContext(ICompilation *co, int *err);
18.67 - void AbortCompilation(ICompilation *co);
18.68 - void FreeContext(sp_context_t *ctx);
18.69 - int ContextExecute(sp_context_t *ctx, uint32_t code_idx, cell_t *result);
18.70 -};
18.71 -
18.72 -cell_t NativeCallback(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
18.73 -cell_t NativeCallback_Debug(sp_context_t *ctx, ucell_t native_idx, cell_t *params);
18.74 -jitoffs_t RelocLookup(JitWriter *jit, cell_t pcode_offs, bool relative=false);
18.75 -
18.76 -#define AMX_REG_PRI REG_EAX
18.77 -#define AMX_REG_ALT REG_EDX
18.78 -#define AMX_REG_STK REG_EDI
18.79 -#define AMX_REG_DAT REG_EBP
18.80 -#define AMX_REG_TMP REG_ECX
18.81 -#define AMX_REG_INFO REG_ESI
18.82 -#define AMX_REG_FRM REG_EBX
18.83 -
18.84 -#define AMX_INFO_FRM AMX_REG_INFO //not relocated
18.85 -#define AMX_INFO_FRAME 0 //(same thing as above)
18.86 -#define AMX_INFO_HEAP 4 //not relocated
18.87 -#define AMX_INFO_RETVAL 8 //physical
18.88 -#define AMX_INFO_CONTEXT 12 //physical
18.89 -#define AMX_INFO_STACKTOP 16 //relocated
18.90 -
18.91 -extern ISourcePawnEngine *engine;
18.92 -
18.93 -#endif //_INCLUDE_SOURCEPAWN_JIT_X86_H_
19.1 --- a/sourcepawn/vm/jit/x86/msvc8/jit-x86.sln Tue Nov 07 23:26:40 2006 +0000
19.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
19.3 @@ -1,20 +0,0 @@
19.4 -
19.5 -Microsoft Visual Studio Solution File, Format Version 9.00
19.6 -# Visual Studio 2005
19.7 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "jit-x86", "jit-x86.vcproj", "{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
19.8 -EndProject
19.9 -Global
19.10 - GlobalSection(SolutionConfigurationPlatforms) = preSolution
19.11 - Debug|Win32 = Debug|Win32
19.12 - Release|Win32 = Release|Win32
19.13 - EndGlobalSection
19.14 - GlobalSection(ProjectConfigurationPlatforms) = postSolution
19.15 - {6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.ActiveCfg = Debug|Win32
19.16 - {6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Debug|Win32.Build.0 = Debug|Win32
19.17 - {6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.ActiveCfg = Release|Win32
19.18 - {6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}.Release|Win32.Build.0 = Release|Win32
19.19 - EndGlobalSection
19.20 - GlobalSection(SolutionProperties) = preSolution
19.21 - HideSolutionNode = FALSE
19.22 - EndGlobalSection
19.23 -EndGlobal
20.1 --- a/sourcepawn/vm/jit/x86/msvc8/jit-x86.vcproj Tue Nov 07 23:26:40 2006 +0000
20.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
20.3 @@ -1,270 +0,0 @@
20.4 -<?xml version="1.0" encoding="Windows-1252"?>
20.5 -<VisualStudioProject
20.6 - ProjectType="Visual C++"
20.7 - Version="8.00"
20.8 - Name="jit-x86"
20.9 - ProjectGUID="{6EF06E6E-0ED5-4E2D-A8F3-01DD1EC25BA7}"
20.10 - RootNamespace="jitx86"
20.11 - Keyword="Win32Proj"
20.12 - >
20.13 - <Platforms>
20.14 - <Platform
20.15 - Name="Win32"
20.16 - />
20.17 - </Platforms>
20.18 - <ToolFiles>
20.19 - </ToolFiles>
20.20 - <Configurations>
20.21 - <Configuration
20.22 - Name="Debug|Win32"
20.23 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
20.24 - IntermediateDirectory="$(ConfigurationName)"
20.25 - ConfigurationType="2"
20.26 - CharacterSet="2"
20.27 - >
20.28 - <Tool
20.29 - Name="VCPreBuildEventTool"
20.30 - />
20.31 - <Tool
20.32 - Name="VCCustomBuildTool"
20.33 - />
20.34 - <Tool
20.35 - Name="VCXMLDataGeneratorTool"
20.36 - />
20.37 - <Tool
20.38 - Name="VCWebServiceProxyGeneratorTool"
20.39 - />
20.40 - <Tool
20.41 - Name="VCMIDLTool"
20.42 - />
20.43 - <Tool
20.44 - Name="VCCLCompilerTool"
20.45 - Optimization="0"
20.46 - AdditionalIncludeDirectories="..\..\..\..\include"
20.47 - PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS;_CRT_SECURE_NO_DEPRECATE"
20.48 - MinimalRebuild="true"
20.49 - BasicRuntimeChecks="3"
20.50 - RuntimeLibrary="1"
20.51 - UsePrecompiledHeader="0"
20.52 - WarningLevel="3"
20.53 - Detect64BitPortabilityProblems="false"
20.54 - DebugInformationFormat="4"
20.55 - />
20.56 - <Tool
20.57 - Name="VCManagedResourceCompilerTool"
20.58 - />
20.59 - <Tool
20.60 - Name="VCResourceCompilerTool"
20.61 - />
20.62 - <Tool
20.63 - Name="VCPreLinkEventTool"
20.64 - />
20.65 - <Tool
20.66 - Name="VCLinkerTool"
20.67 - LinkIncremental="2"
20.68 - GenerateDebugInformation="true"
20.69 - SubSystem="2"
20.70 - TargetMachine="1"
20.71 - />
20.72 - <Tool
20.73 - Name="VCALinkTool"
20.74 - />
20.75 - <Tool
20.76 - Name="VCManifestTool"
20.77 - />
20.78 - <Tool
20.79 - Name="VCXDCMakeTool"
20.80 - />
20.81 - <Tool
20.82 - Name="VCBscMakeTool"
20.83 - />
20.84 - <Tool
20.85 - Name="VCFxCopTool"
20.86 - />
20.87 - <Tool
20.88 - Name="VCAppVerifierTool"
20.89 - />
20.90 - <Tool
20.91 - Name="VCWebDeploymentTool"
20.92 - />
20.93 - <Tool
20.94 - Name="VCPostBuildEventTool"
20.95 - />
20.96 - </Configuration>
20.97 - <Configuration
20.98 - Name="Release|Win32"
20.99 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
20.100 - IntermediateDirectory="$(ConfigurationName)"
20.101 - ConfigurationType="2"
20.102 - CharacterSet="1"
20.103 - WholeProgramOptimization="1"
20.104 - >
20.105 - <Tool
20.106 - Name="VCPreBuildEventTool"
20.107 - />
20.108 - <Tool
20.109 - Name="VCCustomBuildTool"
20.110 - />
20.111 - <Tool
20.112 - Name="VCXMLDataGeneratorTool"
20.113 - />
20.114 - <Tool
20.115 - Name="VCWebServiceProxyGeneratorTool"
20.116 - />
20.117 - <Tool
20.118 - Name="VCMIDLTool"
20.119 - />
20.120 - <Tool
20.121 - Name="VCCLCompilerTool"
20.122 - PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS;_USRDLL;JITX86_EXPORTS"
20.123 - RuntimeLibrary="2"
20.124 - UsePrecompiledHeader="0"
20.125 - WarningLevel="3"
20.126 - Detect64BitPortabilityProblems="true"
20.127 - DebugInformationFormat="3"
20.128 - />
20.129 - <Tool
20.130 - Name="VCManagedResourceCompilerTool"
20.131 - />
20.132 - <Tool
20.133 - Name="VCResourceCompilerTool"
20.134 - />
20.135 - <Tool
20.136 - Name="VCPreLinkEventTool"
20.137 - />
20.138 - <Tool
20.139 - Name="VCLinkerTool"
20.140 - LinkIncremental="1"
20.141 - GenerateDebugInformation="true"
20.142 - SubSystem="2"
20.143 - OptimizeReferences="2"
20.144 - EnableCOMDATFolding="2"
20.145 - TargetMachine="1"
20.146 - />
20.147 - <Tool
20.148 - Name="VCALinkTool"
20.149 - />
20.150 - <Tool
20.151 - Name="VCManifestTool"
20.152 - />
20.153 - <Tool
20.154 - Name="VCXDCMakeTool"
20.155 - />
20.156 - <Tool
20.157 - Name="VCBscMakeTool"
20.158 - />
20.159 - <Tool
20.160 - Name="VCFxCopTool"
20.161 - />
20.162 - <Tool
20.163 - Name="VCAppVerifierTool"
20.164 - />
20.165 - <Tool
20.166 - Name="VCWebDeploymentTool"
20.167 - />
20.168 - <Tool
20.169 - Name="VCPostBuildEventTool"
20.170 - />
20.171 - </Configuration>
20.172 - </Configurations>
20.173 - <References>
20.174 - </References>
20.175 - <Files>
20.176 - <Filter
20.177 - Name="Source Files"
20.178 - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
20.179 - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
20.180 - >
20.181 - <File
20.182 - RelativePath="..\dll_exports.cpp"
20.183 - >
20.184 - <FileConfiguration
20.185 - Name="Debug|Win32"
20.186 - >
20.187 - <Tool
20.188 - Name="VCCLCompilerTool"
20.189 - AdditionalIncludeDirectories=""
20.190 - />
20.191 - </FileConfiguration>
20.192 - </File>
20.193 - <File
20.194 - RelativePath="..\jit_x86.cpp"
20.195 - >
20.196 - </File>
20.197 - <File
20.198 - RelativePath="..\opcode_helpers.cpp"
20.199 - >
20.200 - </File>
20.201 - </Filter>
20.202 - <Filter
20.203 - Name="Header Files"
20.204 - Filter="h;hpp;hxx;hm;inl;inc;xsd"
20.205 - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
20.206 - >
20.207 - <File
20.208 - RelativePath="..\dll_exports.h"
20.209 - >
20.210 - </File>
20.211 - <File
20.212 - RelativePath="..\jit_x86.h"
20.213 - >
20.214 - </File>
20.215 - <File
20.216 - RelativePath="..\opcode_helpers.h"
20.217 - >
20.218 - </File>
20.219 - <File
20.220 - RelativePath="..\ungen_opcodes.h"
20.221 - >
20.222 - </File>
20.223 - <File
20.224 - RelativePath="..\x86_macros.h"
20.225 - >
20.226 - </File>
20.227 - </Filter>
20.228 - <Filter
20.229 - Name="Resource Files"
20.230 - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
20.231 - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
20.232 - >
20.233 - <File
20.234 - RelativePath="..\opcode_switch.inc"
20.235 - >
20.236 - </File>
20.237 - <File
20.238 - RelativePath="..\ungen_opcode_switch.inc"
20.239 - >
20.240 - </File>
20.241 - </Filter>
20.242 - <Filter
20.243 - Name="SDK"
20.244 - >
20.245 - <File
20.246 - RelativePath="..\..\jit_helpers.h"
20.247 - >
20.248 - </File>
20.249 - <File
20.250 - RelativePath="..\..\..\..\include\sp_file_headers.h"
20.251 - >
20.252 - </File>
20.253 - <File
20.254 - RelativePath="..\..\..\..\include\sp_vm_api.h"
20.255 - >
20.256 - </File>
20.257 - <File
20.258 - RelativePath="..\..\..\..\include\sp_vm_base.h"
20.259 - >
20.260 - </File>
20.261 - <File
20.262 - RelativePath="..\..\..\..\include\sp_vm_context.h"
20.263 - >
20.264 - </File>
20.265 - <File
20.266 - RelativePath="..\..\..\..\include\sp_vm_types.h"
20.267 - >
20.268 - </File>
20.269 - </Filter>
20.270 - </Files>
20.271 - <Globals>
20.272 - </Globals>
20.273 -</VisualStudioProject>
21.1 --- a/sourcepawn/vm/jit/x86/opcode_helpers.cpp Tue Nov 07 23:26:40 2006 +0000
21.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
21.3 @@ -1,779 +0,0 @@
21.4 -#include <limits.h>
21.5 -#include <string.h>
21.6 -#include <malloc.h>
21.7 -#include "jit_x86.h"
21.8 -#include "opcode_helpers.h"
21.9 -#include "x86_macros.h"
21.10 -
21.11 -#define NUM_INFO_PARAMS 5
21.12 -
21.13 -jitoffs_t Write_Execute_Function(JitWriter *jit)
21.14 -{
21.15 - /**
21.16 - * The variables we're passed in:
21.17 - * sp_context_t *ctx, uint32_t code_idx, cell_t *result
21.18 - */
21.19 -
21.20 - /**
21.21 - * !NOTE!
21.22 - * Currently, we do not accept ctx->frm as the new frame pointer.
21.23 - * Instead, we copy the frame from the stack pointer.
21.24 - * This is because we do not support resuming or sleeping!
21.25 - */
21.26 -
21.27 - //push ebp
21.28 - //mov ebp, esp
21.29 - IA32_Push_Reg(jit, REG_EBP);
21.30 - IA32_Mov_Reg_Rm(jit, REG_EBP, REG_ESP, MOD_REG);
21.31 -
21.32 - //push esi
21.33 - //push edi
21.34 - //push ebx
21.35 - IA32_Push_Reg(jit, REG_ESI);
21.36 - IA32_Push_Reg(jit, REG_EDI);
21.37 - IA32_Push_Reg(jit, REG_EBX);
21.38 -
21.39 - //sub esp, 4*n - reserve info array
21.40 - //mov esi, esp - save info pointer
21.41 - IA32_Sub_Rm_Imm8(jit, REG_ESP, 4*NUM_INFO_PARAMS, MOD_REG);
21.42 - IA32_Mov_Reg_Rm(jit, AMX_REG_INFO, REG_ESP, MOD_REG);
21.43 -
21.44 - /* Initial memory setup */
21.45 - //mov eax, [ebp+16] - get result pointer
21.46 - //mov [esi+8], eax - store into info pointer
21.47 - //mov eax, [ebp+8] - get context
21.48 - //mov [esi+12], eax - store context into info pointer
21.49 - //mov ecx, [eax+<offs>] - get heap pointer
21.50 - //mov [esi+4], ecx - store heap into info pointer
21.51 - //mov ebp, [eax+<offs>] - get data pointer
21.52 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 16);
21.53 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_RETVAL);
21.54 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EBP, 8);
21.55 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EAX, AMX_INFO_CONTEXT);
21.56 - IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, hp));
21.57 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_HEAP);
21.58 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_DAT, REG_EAX, offsetof(sp_context_t, memory));
21.59 -
21.60 - /* Frame setup */
21.61 - //mov edi, [eax+<offs>] - get stack pointer
21.62 - //add edi, ebp - relocate to data section
21.63 - //mov ebx, edi - copy sp to frm
21.64 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_STK, REG_EAX, offsetof(sp_context_t, sp));
21.65 - IA32_Add_Rm_Reg(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
21.66 - IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_REG);
21.67 -
21.68 - /* Info memory setup */
21.69 - //mov ecx, [eax+<offs>] - copy memsize to temp var
21.70 - //add ecx, ebp - relocate
21.71 - //mov [esi+x], ecx - store relocated
21.72 - IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, memory));
21.73 - IA32_Add_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_DAT, MOD_REG);
21.74 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_ECX, AMX_INFO_STACKTOP);
21.75 -
21.76 - /* Remaining needed vars */
21.77 - //mov ecx, [esp+(4*(NUM_INFO_PARAMS+3))+12] - get code index (normally esp+12, but we have another array on the stack)
21.78 - //add ecx, [eax+<offs>] - add code base to index
21.79 - IA32_Mov_Reg_Esp_Disp8(jit, REG_ECX, 12+(4*(NUM_INFO_PARAMS+3)));
21.80 - IA32_Add_Reg_Rm_Disp8(jit, REG_ECX, REG_EAX, offsetof(sp_context_t, codebase));
21.81 -
21.82 - /* by now, everything is set up, so we can call into the plugin */
21.83 - //call ecx
21.84 - IA32_Call_Reg(jit, REG_ECX);
21.85 -
21.86 - /* if the code flow gets to here, there was a normal return */
21.87 - //mov ecx, [esi+8] - get retval pointer
21.88 - //mov [ecx], eax - store retval from PRI
21.89 - //mov eax, SP_ERROR_NONE - set no error
21.90 - IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, AMX_REG_INFO, AMX_INFO_RETVAL);
21.91 - IA32_Mov_Rm_Reg(jit, REG_ECX, AMX_REG_PRI, MOD_MEM_REG);
21.92 - IA32_Mov_Reg_Imm32(jit, REG_EAX, SP_ERROR_NONE);
21.93 -
21.94 - /* save where error checking/halting functions should go to */
21.95 - jitoffs_t offs_return = jit->get_outputpos();
21.96 - //mov esp, esi - restore stack pointer
21.97 - IA32_Mov_Reg_Rm(jit, REG_ESP, REG_ESI, MOD_REG);
21.98 -
21.99 - /* _FOR NOW_ ...
21.100 - * We are going to restore SP, HP, and FRM for now. This is for
21.101 - * debugging only, to check for alignment errors. As such:
21.102 - * :TODO: probably remove this.
21.103 - */
21.104 - //mov ecx, [esi+context]
21.105 - //sub edi, ebp
21.106 - //mov edx, [esi+heap]
21.107 - //mov [ecx+sp], edi
21.108 - //mov [ecx+hp], edx
21.109 - IA32_Mov_Reg_Rm_Disp8(jit, REG_ECX, REG_ESI, AMX_INFO_CONTEXT);
21.110 - IA32_Sub_Reg_Rm(jit, REG_EDI, REG_EBP, MOD_REG);
21.111 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_ESI, AMX_INFO_HEAP);
21.112 - IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDI, offsetof(sp_context_t, sp));
21.113 - IA32_Mov_Rm_Reg_Disp8(jit, REG_ECX, REG_EDX, offsetof(sp_context_t, hp));
21.114 -
21.115 - //add esp, 4*NUM_INFO_PARAMS
21.116 - //pop ebx
21.117 - //pop edi
21.118 - //pop esi
21.119 - //pop ebp
21.120 - //ret
21.121 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*NUM_INFO_PARAMS, MOD_REG);
21.122 - IA32_Pop_Reg(jit, REG_EBX);
21.123 - IA32_Pop_Reg(jit, REG_EDI);
21.124 - IA32_Pop_Reg(jit, REG_ESI);
21.125 - IA32_Pop_Reg(jit, REG_EBP);
21.126 - IA32_Return(jit);
21.127 -
21.128 - return offs_return;
21.129 -}
21.130 -
21.131 -void Write_BreakDebug(JitWriter *jit)
21.132 -{
21.133 - //push ecx
21.134 - //mov ecx, [esi+ctx]
21.135 - //cmp [ecx+dbreak], 0
21.136 - //jnz :nocall
21.137 - IA32_Push_Reg(jit, AMX_REG_TMP);
21.138 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.139 - IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, dbreak), 0);
21.140 - jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_NZ, 0);
21.141 -
21.142 - //pushad
21.143 - IA32_Pushad(jit);
21.144 -
21.145 - //push [esi+frm]
21.146 - //push [ecx+context]
21.147 - //mov ecx, [ecx+dbreak]
21.148 - //call ecx
21.149 - //add esp, 8
21.150 - //popad
21.151 - IA32_Push_Rm_Disp8(jit, AMX_REG_INFO, AMX_INFO_FRAME); //:TODO: move to regs and push? and dont disp for 0
21.152 - IA32_Push_Rm_Disp8(jit, AMX_REG_TMP, offsetof(sp_context_t, context));
21.153 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_TMP, offsetof(sp_context_t, dbreak));
21.154 - IA32_Call_Reg(jit, AMX_REG_TMP);
21.155 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*2, MOD_REG);
21.156 - IA32_Popad(jit);
21.157 -
21.158 - //:nocall
21.159 - IA32_Send_Jump8_Here(jit, jmp);
21.160 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*1, MOD_REG);
21.161 - IA32_Return(jit);
21.162 -}
21.163 -
21.164 -void Write_GetError(JitWriter *jit)
21.165 -{
21.166 - CompData *data = (CompData *)jit->data;
21.167 -
21.168 - //mov eax, [esi+info.context]
21.169 - //mov eax, [eax+ctx.error]
21.170 - //jmp [jit_return]
21.171 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.172 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EAX, offsetof(sp_context_t, err));
21.173 - IA32_Jump_Imm32_Abs(jit, data->jit_return);
21.174 -}
21.175 -
21.176 -void Write_SetError(JitWriter *jit, int error)
21.177 -{
21.178 - CompData *data = (CompData *)jit->data;
21.179 -
21.180 - //mov eax, <error>
21.181 - //jmp [jit_return]
21.182 - IA32_Mov_Reg_Imm32(jit, REG_EAX, error);
21.183 - IA32_Jump_Imm32_Abs(jit, data->jit_return);
21.184 -}
21.185 -
21.186 -void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg)
21.187 -{
21.188 - //test reg, reg
21.189 - //jz :error
21.190 - IA32_Test_Rm_Reg(jit, reg, reg, MOD_REG);
21.191 - IA32_Jump_Cond_Imm32_Abs(jit, CC_Z, ((CompData *)jit->data)->jit_error_divzero);
21.192 -}
21.193 -
21.194 -void Write_CheckHeap_Min(JitWriter *jit)
21.195 -{
21.196 - /* Check if the stack went beyond the heap low.
21.197 - * This usually means there was a compiler error.
21.198 - * NOTE: Special optimization here.
21.199 - * The heap low is always known ahead of time! :)
21.200 - */
21.201 - CompData *data = (CompData *)jit->data;
21.202 - //cmp [esi+info.heap], <heaplow>
21.203 - //jb :error
21.204 - IA32_Cmp_Rm_Imm32_Disp8(jit, AMX_REG_INFO, AMX_INFO_HEAP, data->plugin->data_size);
21.205 - IA32_Jump_Cond_Imm32_Abs(jit, CC_B, data->jit_error_heapmin);
21.206 -}
21.207 -
21.208 -void Write_CheckHeap_Low(JitWriter *jit)
21.209 -{
21.210 - /* Check if the heap is trying to grow beyond the stack.
21.211 - */
21.212 - //mov ecx, [esi+info.heap]
21.213 - //lea ecx, [ebp+ecx+STACK_MARGIN]
21.214 - //cmp ecx, edi
21.215 - //ja :error ; I think this is right
21.216 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
21.217 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, STACK_MARGIN);
21.218 - IA32_Cmp_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
21.219 - IA32_Jump_Cond_Imm32_Abs(jit, CC_A, ((CompData *)jit->data)->jit_error_heaplow);
21.220 -}
21.221 -
21.222 -void Write_CheckStack_Min(JitWriter *jit)
21.223 -{
21.224 - /* Check if the stack went beyond the stack top
21.225 - * This usually means there was a compiler error.
21.226 - */
21.227 - //cmp edi, [esi+info.stacktop]
21.228 - //jae :error
21.229 - IA32_Cmp_Reg_Rm_Disp8(jit, AMX_REG_STK, AMX_REG_INFO, AMX_INFO_STACKTOP);
21.230 - IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_stackmin);
21.231 -}
21.232 -
21.233 -void Write_CheckStack_Low(JitWriter *jit)
21.234 -{
21.235 - /* Check if the stack went beyond the heap boundary.
21.236 - * Unfortunately this one isn't as quick as the other check.
21.237 - * The stack margin check is important for sysreq.n having space.
21.238 - */
21.239 - //mov ecx, [esi+info.heap]
21.240 - //lea ecx, [ebp+ecx+STACK_MARGIN]
21.241 - //cmp edi, ecx
21.242 - //jb :error ; I think this is right
21.243 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
21.244 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, AMX_REG_TMP, NOSCALE, STACK_MARGIN);
21.245 - IA32_Cmp_Reg_Rm(jit, AMX_REG_STK, AMX_REG_TMP, MOD_REG);
21.246 - IA32_Jump_Cond_Imm32_Abs(jit, CC_B, ((CompData *)jit->data)->jit_error_stacklow);
21.247 -}
21.248 -
21.249 -void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg)
21.250 -{
21.251 - CompData *data = (CompData *)jit->data;
21.252 -
21.253 - /* :TODO: Should this be checking for below heaplow?
21.254 - * The old JIT did not.
21.255 - */
21.256 -
21.257 - bool call = false;
21.258 - if (!(data->inline_level & JIT_INLINE_ERRORCHECKS))
21.259 - {
21.260 - /* If we're not in the initial generation phase,
21.261 - * Write a call to the actual routine instead.
21.262 - */
21.263 - if ((reg == REG_EAX) && data->jit_verify_addr_eax)
21.264 - {
21.265 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
21.266 - IA32_Write_Jump32(jit, call, data->jit_verify_addr_eax);
21.267 - return;
21.268 - } else if ((reg == REG_EDX) && data->jit_verify_addr_edx) {
21.269 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
21.270 - IA32_Write_Jump32(jit, call, data->jit_verify_addr_edx);
21.271 - return;
21.272 - }
21.273 - call = true;
21.274 - }
21.275 -
21.276 - /**
21.277 - * :TODO: If we can't find a nicer way of doing this,
21.278 - * then scrap it on high optimizations. The second portion is not needed at all!
21.279 - */
21.280 -
21.281 - /* Part 1: Check if we're in the memory bounds */
21.282 - //cmp <reg>, <stpu>
21.283 - //jae :error
21.284 - IA32_Cmp_Rm_Imm32(jit, MOD_REG, reg, ((CompData *)jit->data)->plugin->memory);
21.285 - IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_memaccess);
21.286 -
21.287 - /* Part 2: Check if we're in the invalid region between HP and SP */
21.288 - jitoffs_t jmp;
21.289 - //cmp <reg>, [esi+info.heap]
21.290 - //jb :continue
21.291 - //lea ecx, [ebp+<reg>]
21.292 - //cmp edi, ecx
21.293 - //jb :error
21.294 - //:continue
21.295 - IA32_Cmp_Reg_Rm_Disp8(jit, reg, AMX_REG_INFO, AMX_INFO_HEAP);
21.296 - jmp = IA32_Jump_Cond_Imm8(jit, CC_B, 0);
21.297 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_TMP, AMX_REG_DAT, reg, NOSCALE, 0);
21.298 - IA32_Cmp_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_STK, MOD_REG);
21.299 - IA32_Jump_Cond_Imm32_Abs(jit, CC_B, ((CompData *)jit->data)->jit_error_memaccess);
21.300 - IA32_Send_Jump8_Here(jit, jmp);
21.301 -
21.302 - if (call)
21.303 - {
21.304 - IA32_Return(jit);
21.305 - }
21.306 -}
21.307 -
21.308 -void Macro_PushN_Addr(JitWriter *jit, int i)
21.309 -{
21.310 - //push eax
21.311 - //mov eax, [esi+frm]
21.312 - //loop i times:
21.313 - // lea ecx, [eax+<val>]
21.314 - // mov [edi-4*i], ecx
21.315 - //sub edi, 4*N
21.316 - //pop eax
21.317 -
21.318 - cell_t val;
21.319 - int n = 1;
21.320 - IA32_Push_Reg(jit, AMX_REG_PRI);
21.321 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
21.322 - do
21.323 - {
21.324 - val = jit->read_cell();
21.325 - if (val < SCHAR_MAX && val > SCHAR_MIN)
21.326 - IA32_Lea_DispRegImm8(jit, AMX_REG_TMP, AMX_REG_PRI, (jit_int8_t)val);
21.327 - else
21.328 - IA32_Lea_DispRegImm32(jit, AMX_REG_TMP, AMX_REG_PRI, val);
21.329 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
21.330 - } while (n++ < i);
21.331 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
21.332 - IA32_Pop_Reg(jit, AMX_REG_PRI);
21.333 -}
21.334 -
21.335 -void Macro_PushN_S(JitWriter *jit, int i)
21.336 -{
21.337 - //loop i times:
21.338 - // mov ecx, [ebx+<val>]
21.339 - // mov [edi-4*i], ecx
21.340 - //sub edi, 4*N
21.341 -
21.342 - cell_t val;
21.343 - int n = 1;
21.344 - do
21.345 - {
21.346 - val = jit->read_cell();
21.347 - if (val < SCHAR_MAX && val > SCHAR_MIN)
21.348 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_FRM, (jit_int8_t)val);
21.349 - else
21.350 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_FRM, val);
21.351 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
21.352 - } while (n++ < i);
21.353 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
21.354 -}
21.355 -
21.356 -void Macro_PushN_C(JitWriter *jit, int i)
21.357 -{
21.358 - //loop i times:
21.359 - // mov [edi-4*i], <val>
21.360 - //sub edi, 4*N
21.361 -
21.362 - int n = 1;
21.363 - do
21.364 - {
21.365 - IA32_Mov_Rm_Imm32_Disp8(jit, AMX_REG_STK, jit->read_cell(), -4*n);
21.366 - } while (n++ < i);
21.367 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
21.368 -}
21.369 -
21.370 -void Macro_PushN(JitWriter *jit, int i)
21.371 -{
21.372 - //loop i times:
21.373 - // mov ecx, [ebp+<val>]
21.374 - // mov [edi-4*i], ecx
21.375 - //sub edi, 4*N
21.376 -
21.377 - cell_t val;
21.378 - int n = 1;
21.379 - do
21.380 - {
21.381 - val = jit->read_cell();
21.382 - if (val < SCHAR_MAX && val > SCHAR_MIN)
21.383 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_DAT, (jit_int8_t)val);
21.384 - else
21.385 - IA32_Mov_Reg_Rm_Disp32(jit, AMX_REG_TMP, AMX_REG_DAT, val);
21.386 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, AMX_REG_TMP, -4*n);
21.387 - } while (n++ < i);
21.388 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4*i, MOD_REG);
21.389 -}
21.390 -
21.391 -void WriteOp_Sysreq_C_Function(JitWriter *jit)
21.392 -{
21.393 - /* The small daddy of the big daddy of opcodes.
21.394 - * ecx - native index
21.395 - */
21.396 - CompData *data = (CompData *)jit->data;
21.397 -
21.398 - /* save registers we will need */
21.399 - //push edx
21.400 - IA32_Push_Reg(jit, AMX_REG_ALT);
21.401 -
21.402 - /* push some callback stuff */
21.403 - //push edi ; stack
21.404 - //push ecx ; native index
21.405 - IA32_Push_Reg(jit, AMX_REG_STK);
21.406 - IA32_Push_Reg(jit, REG_ECX);
21.407 -
21.408 - /* Relocate stack, heap, frm information, then store back */
21.409 - //mov eax, [esi+context]
21.410 - //mov ecx, [esi+hea]
21.411 - //sub edi, ebp
21.412 - //mov [eax+hp], ecx
21.413 - //mov ecx, [esi]
21.414 - //mov [eax+sp], edi
21.415 - //mov [eax+frm], ecx
21.416 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.417 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
21.418 - IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
21.419 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
21.420 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
21.421 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
21.422 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
21.423 -
21.424 - /* finally, push the last parameter and make the call */
21.425 - //push eax ; context
21.426 - //call NativeCallback
21.427 - IA32_Push_Reg(jit, REG_EAX);
21.428 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
21.429 - if (!data->debug)
21.430 - {
21.431 - IA32_Write_Jump32_Abs(jit, call, NativeCallback);
21.432 - } else {
21.433 - IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
21.434 - }
21.435 -
21.436 - /* Test for error */
21.437 - //mov ecx, [esi+context]
21.438 - //cmp [ecx+err], 0
21.439 - //jnz :error
21.440 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.441 - IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
21.442 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
21.443 -
21.444 - /* restore what we damaged */
21.445 - //add esp, 4*3
21.446 - //add edi, ebp
21.447 - //pop edx
21.448 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
21.449 - IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
21.450 - IA32_Pop_Reg(jit, AMX_REG_ALT);
21.451 -
21.452 - //ret
21.453 - IA32_Return(jit);
21.454 -}
21.455 -
21.456 -void GenerateArrayIndirectionVectors(cell_t *arraybase, cell_t dims[], ucell_t _dimcount, bool autozero)
21.457 -{
21.458 - cell_t vectors = 1; /* we need one vector to start off with */
21.459 - cell_t cur_offs = 0;
21.460 - cell_t cur_write = 0;
21.461 - cell_t dimcount = _dimcount;
21.462 -
21.463 - /* Initialize rotation */
21.464 - cur_write = dims[dimcount-1];
21.465 -
21.466 - while (--dimcount >= 1)
21.467 - {
21.468 - cell_t cur_dim = dims[dimcount];
21.469 - cell_t sub_dim = dims[dimcount-1];
21.470 - for (cell_t i=0; i<vectors; i++)
21.471 - {
21.472 - for (cell_t j=0; j<cur_dim; j++)
21.473 - {
21.474 - arraybase[cur_offs] = (cur_write - cur_offs)*sizeof(cell_t);
21.475 - cur_offs++;
21.476 - cur_write += sub_dim;
21.477 - }
21.478 - }
21.479 - vectors = cur_dim;
21.480 - }
21.481 -
21.482 - /* everything after cur_offs can be zeroed */
21.483 - if (autozero)
21.484 - {
21.485 - size_t size = 1;
21.486 - for (ucell_t i=0; i<_dimcount; i++)
21.487 - {
21.488 - size *= dims[i];
21.489 - }
21.490 - memset(&arraybase[cur_offs], 0, size*sizeof(cell_t));
21.491 - }
21.492 -
21.493 - return;
21.494 -}
21.495 -
21.496 -/**
21.497 - * A few notes about this function.
21.498 - * I was more concerned about efficient use of registers here, rather than
21.499 - * fine-tuned optimization. The reason is that the code is already complicated,
21.500 - * and it is very easy to mess up.
21.501 - */
21.502 -void WriteIntrinsic_GenArray(JitWriter *jit)
21.503 -{
21.504 - /**
21.505 - * save important values
21.506 - */
21.507 - //push ebx
21.508 - //push eax
21.509 - //push edx
21.510 - //push ecx ;value is referenced on stack
21.511 - IA32_Push_Reg(jit, REG_EBX);
21.512 - IA32_Push_Reg(jit, REG_EAX);
21.513 - IA32_Push_Reg(jit, REG_EDX);
21.514 - IA32_Push_Reg(jit, REG_ECX);
21.515 -
21.516 - /**
21.517 - * Calculate how many cells will be needed.
21.518 - */
21.519 - //mov edx, [edi] ;get last dimension's count
21.520 - //mov eax, 1 ;position at second to last dimension
21.521 - //:loop
21.522 - //cmp eax, [esp] ;compare to # of params
21.523 - //jae :done ;end loop if done
21.524 - //mov ecx, [edi+eax*4] ;get dimension size
21.525 - //imul edx, ecx ;multiply by size
21.526 - //add eax, 1 ;increment
21.527 - //add edx, ecx ;add size (indirection vector)
21.528 - //jmp :loop ;jump back
21.529 - //:done
21.530 - IA32_Mov_Reg_Rm(jit, REG_EDX, AMX_REG_STK, MOD_MEM_REG);
21.531 - IA32_Mov_Reg_Imm32(jit, REG_EAX, 1);
21.532 - jitoffs_t loop1 = jit->get_outputpos();
21.533 - IA32_Cmp_Reg_Rm_ESP(jit, REG_EAX);
21.534 - jitoffs_t done1 = IA32_Jump_Cond_Imm8(jit, CC_AE, 0);
21.535 - IA32_Mov_Reg_Rm_Disp_Reg(jit, REG_ECX, AMX_REG_STK, REG_EAX, SCALE4);
21.536 - IA32_IMul_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG);
21.537 - IA32_Add_Rm_Imm8(jit, REG_EAX, 1, MOD_REG);
21.538 - IA32_Add_Reg_Rm(jit, REG_EDX, REG_ECX, MOD_REG);
21.539 - IA32_Write_Jump8(jit, IA32_Jump_Imm8(jit, loop1), loop1);
21.540 - IA32_Send_Jump8_Here(jit, done1);
21.541 -
21.542 - /* Test if we have heap space for this */
21.543 - //mov eax, [esi+info.heap] ;get heap pointer
21.544 - //lea eax, [eax+edx*4] ;new heap pointer
21.545 - //cmp eax, <hlw> ;compare to heap low
21.546 - //jbe :error ;die if we hit this (it should always be >)
21.547 - //add eax, ebp ;relocate to stack
21.548 - //cmp eax, edi ;die if above the stack pointer
21.549 - //jae :error
21.550 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
21.551 - IA32_Lea_Reg_DispRegMult(jit, REG_EAX, REG_EAX, REG_EDX, SCALE4);
21.552 - IA32_Cmp_Rm_Imm32(jit, MOD_REG, REG_EAX, ((CompData *)jit->data)->plugin->data_size);
21.553 - IA32_Jump_Cond_Imm32_Abs(jit, CC_BE, ((CompData *)jit->data)->jit_error_array_too_big);
21.554 - IA32_Add_Reg_Rm(jit, REG_EAX, AMX_REG_DAT, MOD_REG);
21.555 - IA32_Cmp_Reg_Rm(jit, REG_EAX, AMX_REG_STK, MOD_REG);
21.556 - IA32_Jump_Cond_Imm32_Abs(jit, CC_AE, ((CompData *)jit->data)->jit_error_array_too_big);
21.557 -
21.558 - /* Prepare for indirection iteration */
21.559 - //mov eax, [esi+info.heap] ;get heap pointer
21.560 - //lea ebx, [eax+edx*4] ;new heap pointer
21.561 - //mov [esi+info.heap], ebx ;store back
21.562 - //push eax ;save heap pointer - we need it
21.563 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_HEAP);
21.564 - IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EDX, SCALE4);
21.565 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, REG_EBX, AMX_INFO_HEAP);
21.566 - IA32_Push_Reg(jit, REG_EAX);
21.567 -
21.568 - WriteOp_Tracker_Push_Reg(jit, REG_EDX);
21.569 -
21.570 - /* This part is too messy to do in straight assembly.
21.571 - * I'm letting the compiler handle it and thus it's in C.
21.572 - */
21.573 - //lea ebx, [ebp+eax] ;get base pointer
21.574 - //push dword [esp-8] ;push autozero
21.575 - //push dword [esp-8] ;push dimension count
21.576 - //push edi ;push dim array
21.577 - //push ebx
21.578 - //call GenerateArrayIndirectionVectors
21.579 - //add esp, 4*4
21.580 - IA32_Lea_Reg_DispRegMult(jit, REG_EBX, REG_EAX, REG_EBP, NOSCALE);
21.581 - IA32_Push_Rm_Disp8_ESP(jit, 8);
21.582 - IA32_Push_Rm_Disp8_ESP(jit, 8);
21.583 - IA32_Push_Reg(jit, REG_EDI);
21.584 - IA32_Push_Reg(jit, REG_EBX);
21.585 - IA32_Write_Jump32_Abs(jit, IA32_Call_Imm32(jit, 0), (void *)&GenerateArrayIndirectionVectors);
21.586 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*4, MOD_REG);
21.587 -
21.588 - /* Store the heap pointer back into the stack */
21.589 - //pop eax ;restore heap pointer
21.590 - //pop ecx ;restore param count
21.591 - //lea edi, [edi+ecx*4-4] ;pop params-4 off the stack
21.592 - //mov [edi], eax ;store back the heap pointer
21.593 - IA32_Pop_Reg(jit, REG_EAX);
21.594 - IA32_Pop_Reg(jit, REG_ECX);
21.595 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, REG_ECX, SCALE4, -4);
21.596 - IA32_Mov_Rm_Reg(jit, AMX_REG_STK, REG_EAX, MOD_MEM_REG);
21.597 -
21.598 - /* Return to caller */
21.599 - //pop edx
21.600 - //pop eax
21.601 - //pop ebx
21.602 - //ret
21.603 - IA32_Pop_Reg(jit, REG_ECX);
21.604 - IA32_Pop_Reg(jit, REG_EAX);
21.605 - IA32_Pop_Reg(jit, REG_EBX);
21.606 - IA32_Return(jit);
21.607 -}
21.608 -
21.609 -void WriteOp_Sysreq_N_Function(JitWriter *jit)
21.610 -{
21.611 - /* The big daddy of opcodes.
21.612 - * eax - num_params
21.613 - * ecx - native index
21.614 - */
21.615 - CompData *data = (CompData *)jit->data;
21.616 -
21.617 - /* store the number of parameters on the stack */
21.618 - //mov [edi-4], eax
21.619 - //sub edi, 4
21.620 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_STK, REG_EAX, -4);
21.621 - IA32_Sub_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
21.622 -
21.623 - /* save registers we will need */
21.624 - //push eax ; num_params for stack popping
21.625 - //push edx
21.626 - IA32_Push_Reg(jit, REG_EAX);
21.627 - IA32_Push_Reg(jit, AMX_REG_ALT);
21.628 -
21.629 - /* push some callback stuff */
21.630 - //push edi ; stack
21.631 - //push ecx ; native index
21.632 - IA32_Push_Reg(jit, AMX_REG_STK);
21.633 - IA32_Push_Reg(jit, REG_ECX);
21.634 -
21.635 - /* Relocate stack, heap, frm information, then store back */
21.636 - //mov eax, [esi+context]
21.637 - //mov ecx, [esi+hea]
21.638 - //sub edi, ebp
21.639 - //mov [eax+hp], ecx
21.640 - //mov ecx, [esi]
21.641 - //mov [eax+sp], edi
21.642 - //mov [eax+frm], ecx
21.643 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.644 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_HEAP);
21.645 - IA32_Sub_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
21.646 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, hp));
21.647 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_INFO_FRM, MOD_MEM_REG);
21.648 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_STK, offsetof(sp_context_t, sp));
21.649 - IA32_Mov_Rm_Reg_Disp8(jit, REG_EAX, AMX_REG_TMP, offsetof(sp_context_t, frm));
21.650 -
21.651 - /* finally, push the last parameter and make the call */
21.652 - //push eax ; context
21.653 - //call NativeCallback
21.654 - IA32_Push_Reg(jit, REG_EAX);
21.655 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
21.656 - if (!data->debug)
21.657 - {
21.658 - IA32_Write_Jump32_Abs(jit, call, NativeCallback);
21.659 - } else {
21.660 - IA32_Write_Jump32_Abs(jit, call, NativeCallback_Debug);
21.661 - }
21.662 -
21.663 - /* Test for error */
21.664 - //mov ecx, [esi+context]
21.665 - //cmp [ecx+err], 0
21.666 - //jnz :error
21.667 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.668 - IA32_Cmp_Rm_Disp8_Imm8(jit, AMX_REG_TMP, offsetof(sp_context_t, err), 0);
21.669 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_extern_error);
21.670 -
21.671 - /* restore what we damaged */
21.672 - //add esp, 4*3
21.673 - //add edi, ebp
21.674 - //pop edx
21.675 - //pop ecx ; num_params
21.676 - IA32_Add_Rm_Imm8(jit, REG_ESP, 4*3, MOD_REG);
21.677 - IA32_Add_Reg_Rm(jit, AMX_REG_STK, AMX_REG_DAT, MOD_REG);
21.678 - IA32_Pop_Reg(jit, AMX_REG_ALT);
21.679 - IA32_Pop_Reg(jit, REG_ECX);
21.680 -
21.681 - /* pop the AMX stack. do not check the margins.
21.682 - * Note that this is not a true macro - we don't bother to
21.683 - * set ALT here because nothing will be using it.
21.684 - */
21.685 - //lea edi, [edi+ecx*4+4]
21.686 - IA32_Lea_Reg_DispRegMultImm8(jit, AMX_REG_STK, AMX_REG_STK, REG_ECX, SCALE4, 4);
21.687 -
21.688 - //ret
21.689 - IA32_Return(jit);
21.690 -}
21.691 -
21.692 -void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg)
21.693 -{
21.694 - CompData *data = (CompData *)jit->data;
21.695 -
21.696 - /* Save registers that may be damaged by the call */
21.697 - //push eax
21.698 - //push ecx
21.699 - //push edi
21.700 - //lea edi, [<reg>*4] ; we want the count in bytes not in cells
21.701 - IA32_Push_Reg(jit, AMX_REG_PRI);
21.702 - if (reg == REG_ECX)
21.703 - {
21.704 - IA32_Push_Reg(jit, AMX_REG_TMP);
21.705 - }
21.706 - IA32_Push_Reg(jit, AMX_REG_STK);
21.707 - IA32_Lea_Reg_RegMultImm32(jit, REG_EDI, reg, SCALE4, 0);
21.708 -
21.709 - /* Get the context ptr, push it and call the check */
21.710 - //mov eax, [esi+context]
21.711 - //push eax
21.712 - //call JIT_VerifyOrAllocateTracker
21.713 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, AMX_REG_INFO, AMX_INFO_CONTEXT);
21.714 - IA32_Push_Reg(jit, REG_EAX);
21.715 - jitoffs_t call = IA32_Call_Imm32(jit, 0);
21.716 - IA32_Write_Jump32_Abs(jit, call, JIT_VerifyOrAllocateTracker);
21.717 -
21.718 - /* Check for errors */
21.719 - //pop eax
21.720 - //cmp [eax+err], 0
21.721 - //jnz :error
21.722 - IA32_Pop_Reg(jit, REG_EAX);
21.723 - IA32_Cmp_Rm_Disp8_Imm8(jit, REG_EAX, offsetof(sp_context_t, err), 0);
21.724 - IA32_Jump_Cond_Imm32_Abs(jit, CC_NZ, data->jit_error_tracker_bounds);
21.725 -
21.726 - /* Push the register into the stack and increment pCur */
21.727 - //mov edx, [eax+vm[]]
21.728 - //mov eax, [edx+pcur]
21.729 - //add [edx+pcur], 4
21.730 - //mov [eax], edi
21.731 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EDX, REG_EAX, offsetof(sp_context_t, vm[JITVARS_TRACKER]));
21.732 - IA32_Mov_Reg_Rm_Disp8(jit, REG_EAX, REG_EDX, offsetof(tracker_t, pCur));
21.733 - IA32_Add_Rm_Imm8_Disp8(jit, REG_EDX, 4, offsetof(tracker_t, pCur));
21.734 - IA32_Mov_Rm_Reg(jit, REG_EAX, REG_EDI, MOD_MEM_REG);
21.735 -
21.736 - /* Restore PRI, ALT and STK */
21.737 - //pop edi
21.738 - //pop ecx
21.739 - //pop eax
21.740 - IA32_Pop_Reg(jit, AMX_REG_STK);
21.741 - if (reg == REG_ECX)
21.742 - {
21.743 - IA32_Pop_Reg(jit, AMX_REG_TMP);
21.744 - }
21.745 - IA32_Pop_Reg(jit, AMX_REG_PRI);
21.746 -}
21.747 -
21.748 -void JIT_VerifyOrAllocateTracker(sp_context_t *ctx)
21.749 -{
21.750 - tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
21.751 -
21.752 - if ((size_t)(trk->pCur - trk->pBase) >= trk->size)
21.753 - {
21.754 - ctx->err = SP_ERROR_TRACKER_BOUNDS;
21.755 - return;
21.756 - }
21.757 -
21.758 - if (trk->pCur+1 - (trk->pBase + trk->size) == 0)
21.759 - {
21.760 - size_t disp = trk->size - 1;
21.761 - trk->size *= 2;
21.762 - trk->pBase = (ucell_t *)realloc(trk->pBase, trk->size * sizeof(cell_t));
21.763 -
21.764 - if (!trk->pBase)
21.765 - {
21.766 - ctx->err = SP_ERROR_TRACKER_BOUNDS;
21.767 - return;
21.768 - }
21.769 -
21.770 - trk->pCur = trk->pBase + disp;
21.771 - }
21.772 -}
21.773 -
21.774 -void JIT_VerifyLowBoundTracker(sp_context_t *ctx)
21.775 -{
21.776 - tracker_t *trk = (tracker_t *)(ctx->vm[JITVARS_TRACKER]);
21.777 -
21.778 - if (trk->pCur <= trk->pBase)
21.779 - {
21.780 - ctx->err = SP_ERROR_TRACKER_BOUNDS;
21.781 - }
21.782 -}
21.783 \ No newline at end of file
22.1 --- a/sourcepawn/vm/jit/x86/opcode_helpers.h Tue Nov 07 23:26:40 2006 +0000
22.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
22.3 @@ -1,285 +0,0 @@
22.4 -#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
22.5 -#define _INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
22.6 -
22.7 -#include "..\jit_helpers.h"
22.8 -
22.9 -/**
22.10 - * This outputs the execution function for a plugin.
22.11 - * It also returns the 'return' offset, which is used for
22.12 - * breaking out of the JIT during runtime.
22.13 - */
22.14 -jitoffs_t Write_Execute_Function(JitWriter *jit);
22.15 -
22.16 -/**
22.17 - * Writes the Sysreq.* opcodes as a function call.
22.18 - */
22.19 -void WriteOp_Sysreq_N_Function(JitWriter *jit);
22.20 -void WriteOp_Sysreq_C_Function(JitWriter *jit);
22.21 -
22.22 -/**
22.23 - * Write the GENARRAY intrinsic function.
22.24 - */
22.25 -void WriteIntrinsic_GenArray(JitWriter *jit);
22.26 -
22.27 -/**
22.28 - * Generates code to set an error state in the VM and return.
22.29 - * This is used for generating the error set points in the VM.
22.30 - * GetError writes the error from the context. SetError hardcodes.
22.31 - */
22.32 -void Write_GetError(JitWriter *jit);
22.33 -void Write_SetError(JitWriter *jit, int error);
22.34 -
22.35 -/**
22.36 - * Checks the stacks for min and low errors.
22.37 - * :TODO: Should a variation of this go in the pushN opcodes?
22.38 - */
22.39 -void Write_CheckStack_Min(JitWriter *jit);
22.40 -void Write_CheckStack_Low(JitWriter *jit);
22.41 -
22.42 -/**
22.43 - * Checks the heap for min and low errors.
22.44 - */
22.45 -void Write_CheckHeap_Min(JitWriter *jit);
22.46 -void Write_CheckHeap_Low(JitWriter *jit);
22.47 -
22.48 -/**
22.49 - * Verifies an address by register. The address must reside
22.50 - * between DAT and HP and SP and STP.
22.51 - */
22.52 -void Write_Check_VerifyAddr(JitWriter *jit, jit_uint8_t reg);
22.53 -
22.54 -/**
22.55 - * Checks for division by zero.
22.56 - */
22.57 -void Write_Check_DivZero(JitWriter *jit, jit_uint8_t reg);
22.58 -
22.59 -/**
22.60 - * Writes the break debug function.
22.61 - */
22.62 -void Write_BreakDebug(JitWriter *jit);
22.63 -
22.64 -/**
22.65 - * These are for writing the PushN opcodes.
22.66 - */
22.67 -void Macro_PushN_Addr(JitWriter *jit, int i);
22.68 -void Macro_PushN_S(JitWriter *jit, int i);
22.69 -void Macro_PushN_C(JitWriter *jit, int i);
22.70 -void Macro_PushN(JitWriter *jit, int i);
22.71 -
22.72 -/**
22.73 -* Bound checking for the tracker stack,
22.74 -*/
22.75 -void JIT_VerifyLowBoundTracker(sp_context_t *ctx);
22.76 -void JIT_VerifyOrAllocateTracker(sp_context_t *ctx);
22.77 -
22.78 -/**
22.79 -* Writes the push into tracker function.
22.80 -*/
22.81 -void WriteOp_Tracker_Push_Reg(JitWriter *jit, uint8_t reg);
22.82 -
22.83 -/**
22.84 - * Legend for Statuses:
22.85 - * ****** *** ********
22.86 - * DONE -> code generation is done
22.87 - * !GEN -> code generation is deliberate skipped because:
22.88 - * (default): compiler does not generate
22.89 - * DEPRECATED: this feature no longer exists/supported
22.90 - * UNSUPPORTED: this opcode is not supported
22.91 - * TODO: done in case needed
22.92 - * VERIFIED -> code generation is checked as run-time working. prefixes:
22.93 - * ! errors are not checked yet.
22.94 - * - non-inline errors are not checked yet.
22.95 - * ~ assumed checked because of related variation, but not actually checked
22.96 - */
22.97 -
22.98 -typedef enum
22.99 -{
22.100 - OP_NONE, /* invalid opcode */
22.101 - OP_LOAD_PRI, //!VERIFIED
22.102 - OP_LOAD_ALT, //~!VERIFIED (load.pri)
22.103 - OP_LOAD_S_PRI, //VERIFIED
22.104 - OP_LOAD_S_ALT, //VERIFIED
22.105 - OP_LREF_PRI, // !GEN :TODO: we will need this for dynarrays
22.106 - OP_LREF_ALT, // !GEN :TODO: we will need this for dynarrays
22.107 - OP_LREF_S_PRI, //VERIFIED
22.108 - OP_LREF_S_ALT, //~VERIFIED (lref.s.pri)
22.109 - OP_LOAD_I, //VERIFIED
22.110 - OP_LODB_I, //VERIFIED
22.111 - OP_CONST_PRI, //VERIFIED
22.112 - OP_CONST_ALT, //~VERIFIED (const.pri)
22.113 - OP_ADDR_PRI, //VERIFIED
22.114 - OP_ADDR_ALT, //VERIFIED
22.115 - OP_STOR_PRI, //VERIFIED
22.116 - OP_STOR_ALT, //~VERIFIED (stor.pri)
22.117 - OP_STOR_S_PRI, //VERIFIED
22.118 - OP_STOR_S_ALT, //~VERIFIED (stor.s.pri)
22.119 - OP_SREF_PRI, // !GEN :TODO: we will need this for dynarrays
22.120 - OP_SREF_ALT, // !GEN :TODO: we will need this for dynarrays
22.121 - OP_SREF_S_PRI, //VERIFIED
22.122 - OP_SREF_S_ALT, //~VERIFIED (stor.s.alt)
22.123 - OP_STOR_I, //VERIFIED
22.124 - OP_STRB_I, //VERIFIED
22.125 - OP_LIDX, //VERIFIED
22.126 - OP_LIDX_B, //DONE
22.127 - OP_IDXADDR, //VERIFIED
22.128 - OP_IDXADDR_B, //DONE
22.129 - OP_ALIGN_PRI, // !GEN :TODO: - only used for pack access, drop support in compiler first
22.130 - OP_ALIGN_ALT, // !GEN :TODO: - only used for pack access, drop support in compiler first
22.131 - OP_LCTRL, // !GEN
22.132 - OP_SCTRL, // !GEN
22.133 - OP_MOVE_PRI, //~VERIFIED (move.alt)
22.134 - OP_MOVE_ALT, //VERIFIED
22.135 - OP_XCHG, //DONE
22.136 - OP_PUSH_PRI, //DONE
22.137 - OP_PUSH_ALT, //DONE
22.138 - OP_PUSH_R, // !GEN DEPRECATED
22.139 - OP_PUSH_C, //VERIFIED
22.140 - OP_PUSH, //DONE
22.141 - OP_PUSH_S, //VERIFIED
22.142 - OP_POP_PRI, //VERIFIED
22.143 - OP_POP_ALT, //VERIFIED
22.144 - OP_STACK, //VERIFIED
22.145 - OP_HEAP, //VERIFIED
22.146 - OP_PROC, //VERIFIED
22.147 - OP_RET, // !GEN
22.148 - OP_RETN, //VERIFIED
22.149 - OP_CALL, //VERIFIED
22.150 - OP_CALL_PRI, // !GEN
22.151 - OP_JUMP, //VERIFIED
22.152 - OP_JREL, // !GEN
22.153 - OP_JZER, //VERIFIED
22.154 - OP_JNZ, //DONE
22.155 - OP_JEQ, //VERIFIED
22.156 - OP_JNEQ, //VERIFIED
22.157 - OP_JLESS, // !GEN
22.158 - OP_JLEQ, // !GEN
22.159 - OP_JGRTR, // !GEN
22.160 - OP_JGEQ, // !GEN
22.161 - OP_JSLESS, //VERIFIED
22.162 - OP_JSLEQ, //VERIFIED
22.163 - OP_JSGRTR, //VERIFIED
22.164 - OP_JSGEQ, //VERIFIED
22.165 - OP_SHL, //VERIFIED
22.166 - OP_SHR, //VERIFIED (Note: operator >>>)
22.167 - OP_SSHR, //VERIFIED (Note: operator >>)
22.168 - OP_SHL_C_PRI, //DONE
22.169 - OP_SHL_C_ALT, //DONE
22.170 - OP_SHR_C_PRI, //DONE
22.171 - OP_SHR_C_ALT, //DONE
22.172 - OP_SMUL, //VERIFIED
22.173 - OP_SDIV, //DONE
22.174 - OP_SDIV_ALT, //VERIFIED
22.175 - OP_UMUL, // !GEN
22.176 - OP_UDIV, // !GEN
22.177 - OP_UDIV_ALT, // !GEN
22.178 - OP_ADD, //VERIFIED
22.179 - OP_SUB, //DONE
22.180 - OP_SUB_ALT, //VERIFIED
22.181 - OP_AND, //VERIFIED
22.182 - OP_OR, //VERIFIED
22.183 - OP_XOR, //VERIFIED
22.184 - OP_NOT, //VERIFIED
22.185 - OP_NEG, //VERIFIED
22.186 - OP_INVERT, //VERIFIED
22.187 - OP_ADD_C, //VERIFIED
22.188 - OP_SMUL_C, //VERIFIED
22.189 - OP_ZERO_PRI, //VERIFIED
22.190 - OP_ZERO_ALT, //~VERIFIED
22.191 - OP_ZERO, //VERIFIED
22.192 - OP_ZERO_S, //VERIFIED
22.193 - OP_SIGN_PRI, //DONE
22.194 - OP_SIGN_ALT, //DONE
22.195 - OP_EQ, //VERIFIED
22.196 - OP_NEQ, //VERIFIED
22.197 - OP_LESS, // !GEN
22.198 - OP_LEQ, // !GEN
22.199 - OP_GRTR, // !GEN
22.200 - OP_GEQ, // !GEN
22.201 - OP_SLESS, //VERIFIED
22.202 - OP_SLEQ, //VERIFIED
22.203 - OP_SGRTR, //VERIFIED
22.204 - OP_SGEQ, //VERIFIED
22.205 - OP_EQ_C_PRI, //DONE
22.206 - OP_EQ_C_ALT, //DONE
22.207 - OP_INC_PRI, //VERIFIED
22.208 - OP_INC_ALT, //~VERIFIED (inc.pri)
22.209 - OP_INC, //VERIFIED
22.210 - OP_INC_S, //VERIFIED
22.211 - OP_INC_I, //VERIFIED
22.212 - OP_DEC_PRI, //VERIFIED
22.213 - OP_DEC_ALT, //~VERIFIED (dec.pri)
22.214 - OP_DEC, //VERIFIED
22.215 - OP_DEC_S, //VERIFIED
22.216 - OP_DEC_I, //VERIFIED
22.217 - OP_MOVS, //VERIFIED
22.218 - OP_CMPS, // !GEN
22.219 - OP_FILL, //VERIFIED
22.220 - OP_HALT, //DONE
22.221 - OP_BOUNDS, //VERIFIED
22.222 - OP_SYSREQ_PRI, // !GEN
22.223 - OP_SYSREQ_C, //VERIFIED
22.224 - OP_FILE, // !GEN DEPRECATED
22.225 - OP_LINE, // !GEN DEPRECATED
22.226 - OP_SYMBOL, // !GEN DEPRECATED
22.227 - OP_SRANGE, // !GEN DEPRECATED
22.228 - OP_JUMP_PRI, // !GEN
22.229 - OP_SWITCH, //VERIFIED
22.230 - OP_CASETBL, //VERIFIED
22.231 - OP_SWAP_PRI, //VERIFIED
22.232 - OP_SWAP_ALT, //~VERIFIED (swap.alt)
22.233 - OP_PUSH_ADR, //VERIFIED
22.234 - OP_NOP, //VERIFIED (lol)
22.235 - OP_SYSREQ_N, //VERIFIED
22.236 - OP_SYMTAG, // !GEN DEPRECATED
22.237 - OP_BREAK, //DONE
22.238 - OP_PUSH2_C, //~VERIFIED (push3.c)
22.239 - OP_PUSH2, //VERIFIED
22.240 - OP_PUSH2_S, //VERIFIED
22.241 - OP_PUSH2_ADR, //VERIFIED
22.242 - OP_PUSH3_C, //VERIFIED
22.243 - OP_PUSH3, //~VERIFIED (push2)
22.244 - OP_PUSH3_S, //~VERIFIED (push2.s)
22.245 - OP_PUSH3_ADR, //~VERIFIED (push2.adr)
22.246 - OP_PUSH4_C, //~VERIFIED (push3.c)
22.247 - OP_PUSH4, //~VERIFIED (push2)
22.248 - OP_PUSH4_S, //~VERIFIED (push2.s)
22.249 - OP_PUSH4_ADR, //~VERIFIED (push2.adr)
22.250 - OP_PUSH5_C, //~VERIFIED (push3.c)
22.251 - OP_PUSH5, //~VERIFIED (push2)
22.252 - OP_PUSH5_S, //~VERIFIED (push2.s)
22.253 - OP_PUSH5_ADR, //~VERIFIED (push2.adr)
22.254 - OP_LOAD_BOTH, //VERIFIED
22.255 - OP_LOAD_S_BOTH, //VERIFIED
22.256 - OP_CONST, //VERIFIED
22.257 - OP_CONST_S, //DONE
22.258 - /* ----- */
22.259 - OP_SYSREQ_D, // !GEN UNSUPPORT
22.260 - OP_SYSREQ_ND, // !GEN UNSUPPORT
22.261 - /* ----- */
22.262 - OP_TRACKER_PUSH_C, //DONE
22.263 - OP_TRACKER_POP_SETHEAP, //VERIFIED
22.264 - OP_GENARRAY, //VERIFIED
22.265 - OP_GENARRAY_Z, //-VERIFIED (not tested for 1D arrays)
22.266 - /* ----- */
22.267 - OP_NUM_OPCODES
22.268 -} OPCODE;
22.269 -
22.270 -/*
22.271 -* :TODO: List of ASM Opts
22.272 -* from jit_x86.cpp
22.273 -* DONE: Rest of opcodes including the SYSREQ.N inlined version (rev2)
22.274 -* Including genarray and the 2 tracker ones
22.275 -* DONE: ALL ungen opcodes (rev1)
22.276 -* from opcode_helpers.cpp
22.277 -* DONE: SYSREQ.N .C (rev2)
22.278 -* MACRO OPCODES (rev2)
22.279 -* ERROR CHECKS\{VERIFY ADDR} (rev2)
22.280 -* ARRAY STUFF
22.281 -* TODO: BrkDebug
22.282 -* EXEC FUNCTION
22.283 -* VERIFY ADDR
22.284 -*
22.285 -* Oh and ALIGN all stuff that is called via CALL like what's done with PROC.
22.286 -*/
22.287 -
22.288 -#endif //_INCLUDE_SOURCEPAWN_JIT_X86_OPCODE_INFO_H_
23.1 --- a/sourcepawn/vm/jit/x86/opcode_switch.inc Tue Nov 07 23:26:40 2006 +0000
23.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
23.3 @@ -1,684 +0,0 @@
23.4 - case OP_MOVE_PRI:
23.5 - {
23.6 - WriteOp_Move_Pri(jit);
23.7 - break;
23.8 - }
23.9 - case OP_MOVE_ALT:
23.10 - {
23.11 - WriteOp_Move_Alt(jit);
23.12 - break;
23.13 - }
23.14 - case OP_XCHG:
23.15 - {
23.16 - WriteOp_Xchg(jit);
23.17 - break;
23.18 - }
23.19 - case OP_PUSH:
23.20 - {
23.21 - WriteOp_Push(jit);
23.22 - break;
23.23 - }
23.24 - case OP_PUSH_S:
23.25 - {
23.26 - WriteOp_Push_S(jit);
23.27 - break;
23.28 - }
23.29 - case OP_PUSH2_C:
23.30 - {
23.31 - WriteOp_Push2_C(jit);
23.32 - break;
23.33 - }
23.34 - case OP_PUSH3_C:
23.35 - {
23.36 - WriteOp_Push3_C(jit);
23.37 - break;
23.38 - }
23.39 - case OP_PUSH4_C:
23.40 - {
23.41 - WriteOp_Push4_C(jit);
23.42 - break;
23.43 - }
23.44 - case OP_PUSH5_C:
23.45 - {
23.46 - WriteOp_Push5_C(jit);
23.47 - break;
23.48 - }
23.49 - case OP_PUSH2_ADR:
23.50 - {
23.51 - WriteOp_Push2_Adr(jit);
23.52 - break;
23.53 - }
23.54 - case OP_PUSH3_ADR:
23.55 - {
23.56 - WriteOp_Push3_Adr(jit);
23.57 - break;
23.58 - }
23.59 - case OP_PUSH4_ADR:
23.60 - {
23.61 - WriteOp_Push4_Adr(jit);
23.62 - break;
23.63 - }
23.64 - case OP_PUSH5_ADR:
23.65 - {
23.66 - WriteOp_Push5_Adr(jit);
23.67 - break;
23.68 - }
23.69 - case OP_PUSH2_S:
23.70 - {
23.71 - WriteOp_Push2_S(jit);
23.72 - break;
23.73 - }
23.74 - case OP_PUSH3_S:
23.75 - {
23.76 - WriteOp_Push3_S(jit);
23.77 - break;
23.78 - }
23.79 - case OP_PUSH4_S:
23.80 - {
23.81 - WriteOp_Push4_S(jit);
23.82 - break;
23.83 - }
23.84 - case OP_PUSH5_S:
23.85 - {
23.86 - WriteOp_Push5_S(jit);
23.87 - break;
23.88 - }
23.89 - case OP_PUSH5:
23.90 - {
23.91 - WriteOp_Push5(jit);
23.92 - break;
23.93 - }
23.94 - case OP_PUSH4:
23.95 - {
23.96 - WriteOp_Push4(jit);
23.97 - break;
23.98 - }
23.99 - case OP_PUSH3:
23.100 - {
23.101 - WriteOp_Push3(jit);
23.102 - break;
23.103 - }
23.104 - case OP_PUSH2:
23.105 - {
23.106 - WriteOp_Push2(jit);
23.107 - break;
23.108 - }
23.109 - case OP_ZERO_PRI:
23.110 - {
23.111 - WriteOp_Zero_Pri(jit);
23.112 - break;
23.113 - }
23.114 - case OP_ZERO_ALT:
23.115 - {
23.116 - WriteOp_Zero_Alt(jit);
23.117 - break;
23.118 - }
23.119 - case OP_PROC:
23.120 - {
23.121 - WriteOp_Proc(jit);
23.122 - break;
23.123 - }
23.124 - case OP_SHL:
23.125 - {
23.126 - WriteOp_Shl(jit);
23.127 - break;
23.128 - }
23.129 - case OP_SHR:
23.130 - {
23.131 - WriteOp_Shr(jit);
23.132 - break;
23.133 - }
23.134 - case OP_SSHR:
23.135 - {
23.136 - WriteOp_Sshr(jit);
23.137 - break;
23.138 - }
23.139 - case OP_SHL_C_PRI:
23.140 - {
23.141 - WriteOp_Shl_C_Pri(jit);
23.142 - break;
23.143 - }
23.144 - case OP_SHL_C_ALT:
23.145 - {
23.146 - WriteOp_Shl_C_Alt(jit);
23.147 - break;
23.148 - }
23.149 - case OP_SHR_C_PRI:
23.150 - {
23.151 - WriteOp_Shr_C_Pri(jit);
23.152 - break;
23.153 - }
23.154 - case OP_SHR_C_ALT:
23.155 - {
23.156 - WriteOp_Shr_C_Alt(jit);
23.157 - break;
23.158 - }
23.159 - case OP_SMUL:
23.160 - {
23.161 - WriteOp_SMul(jit);
23.162 - break;
23.163 - }
23.164 - case OP_ADD:
23.165 - {
23.166 - WriteOp_Add(jit);
23.167 - break;
23.168 - }
23.169 - case OP_SUB:
23.170 - {
23.171 - WriteOp_Sub(jit);
23.172 - break;
23.173 - }
23.174 - case OP_SUB_ALT:
23.175 - {
23.176 - WriteOp_Sub_Alt(jit);
23.177 - break;
23.178 - }
23.179 - case OP_NOP:
23.180 - {
23.181 - /* do nothing */
23.182 - break;
23.183 - }
23.184 - case OP_NOT:
23.185 - {
23.186 - WriteOp_Not(jit);
23.187 - break;
23.188 - }
23.189 - case OP_NEG:
23.190 - {
23.191 - WriteOp_Neg(jit);
23.192 - break;
23.193 - }
23.194 - case OP_XOR:
23.195 - {
23.196 - WriteOp_Xor(jit);
23.197 - break;
23.198 - }
23.199 - case OP_OR:
23.200 - {
23.201 - WriteOp_Or(jit);
23.202 - break;
23.203 - }
23.204 - case OP_AND:
23.205 - {
23.206 - WriteOp_And(jit);
23.207 - break;
23.208 - }
23.209 - case OP_INVERT:
23.210 - {
23.211 - WriteOp_Invert(jit);
23.212 - break;
23.213 - }
23.214 - case OP_ADD_C:
23.215 - {
23.216 - WriteOp_Add_C(jit);
23.217 - break;
23.218 - }
23.219 - case OP_SMUL_C:
23.220 - {
23.221 - WriteOp_SMul_C(jit);
23.222 - break;
23.223 - }
23.224 - case OP_SIGN_PRI:
23.225 - {
23.226 - WriteOp_Sign_Pri(jit);
23.227 - break;
23.228 - }
23.229 - case OP_SIGN_ALT:
23.230 - {
23.231 - WriteOp_Sign_Alt(jit);
23.232 - break;
23.233 - }
23.234 - case OP_EQ:
23.235 - {
23.236 - WriteOp_Eq(jit);
23.237 - break;
23.238 - }
23.239 - case OP_NEQ:
23.240 - {
23.241 - WriteOp_Neq(jit);
23.242 - break;
23.243 - }
23.244 - case OP_SLESS:
23.245 - {
23.246 - WriteOp_Sless(jit);
23.247 - break;
23.248 - }
23.249 - case OP_SLEQ:
23.250 - {
23.251 - WriteOp_Sleq(jit);
23.252 - break;
23.253 - }
23.254 - case OP_SGRTR:
23.255 - {
23.256 - WriteOp_Sgrtr(jit);
23.257 - break;
23.258 - }
23.259 - case OP_SGEQ:
23.260 - {
23.261 - WriteOp_Sgeq(jit);
23.262 - break;
23.263 - }
23.264 - case OP_EQ_C_PRI:
23.265 - {
23.266 - WriteOp_Eq_C_Pri(jit);
23.267 - break;
23.268 - }
23.269 - case OP_EQ_C_ALT:
23.270 - {
23.271 - WriteOp_Eq_C_Alt(jit);
23.272 - break;
23.273 - }
23.274 - case OP_INC_PRI:
23.275 - {
23.276 - WriteOp_Inc_Pri(jit);
23.277 - break;
23.278 - }
23.279 - case OP_INC_ALT:
23.280 - {
23.281 - WriteOp_Inc_Alt(jit);
23.282 - break;
23.283 - }
23.284 - case OP_INC:
23.285 - {
23.286 - WriteOp_Inc(jit);
23.287 - break;
23.288 - }
23.289 - case OP_INC_S:
23.290 - {
23.291 - WriteOp_Inc_S(jit);
23.292 - break;
23.293 - }
23.294 - case OP_INC_I:
23.295 - {
23.296 - WriteOp_Inc_I(jit);
23.297 - break;
23.298 - }
23.299 - case OP_DEC_PRI:
23.300 - {
23.301 - WriteOp_Dec_Pri(jit);
23.302 - break;
23.303 - }
23.304 - case OP_DEC_ALT:
23.305 - {
23.306 - WriteOp_Dec_Alt(jit);
23.307 - break;
23.308 - }
23.309 - case OP_DEC:
23.310 - {
23.311 - WriteOp_Dec(jit);
23.312 - break;
23.313 - }
23.314 - case OP_DEC_S:
23.315 - {
23.316 - WriteOp_Dec_S(jit);
23.317 - break;
23.318 - }
23.319 - case OP_DEC_I:
23.320 - {
23.321 - WriteOp_Dec_I(jit);
23.322 - break;
23.323 - }
23.324 - case OP_LOAD_PRI:
23.325 - {
23.326 - WriteOp_Load_Pri(jit);
23.327 - break;
23.328 - }
23.329 - case OP_LOAD_ALT:
23.330 - {
23.331 - WriteOp_Load_Alt(jit);
23.332 - break;
23.333 - }
23.334 - case OP_LOAD_S_PRI:
23.335 - {
23.336 - WriteOp_Load_S_Pri(jit);
23.337 - break;
23.338 - }
23.339 - case OP_LOAD_S_ALT:
23.340 - {
23.341 - WriteOp_Load_S_Alt(jit);
23.342 - break;
23.343 - }
23.344 - case OP_LREF_PRI:
23.345 - {
23.346 - WriteOp_Lref_Pri(jit);
23.347 - break;
23.348 - }
23.349 - case OP_LREF_ALT:
23.350 - {
23.351 - WriteOp_Lref_Alt(jit);
23.352 - break;
23.353 - }
23.354 - case OP_LREF_S_PRI:
23.355 - {
23.356 - WriteOp_Lref_S_Pri(jit);
23.357 - break;
23.358 - }
23.359 - case OP_LREF_S_ALT:
23.360 - {
23.361 - WriteOp_Lref_S_Alt(jit);
23.362 - break;
23.363 - }
23.364 - case OP_CONST_PRI:
23.365 - {
23.366 - WriteOp_Const_Pri(jit);
23.367 - break;
23.368 - }
23.369 - case OP_CONST_ALT:
23.370 - {
23.371 - WriteOp_Const_Alt(jit);
23.372 - break;
23.373 - }
23.374 - case OP_ADDR_PRI:
23.375 - {
23.376 - WriteOp_Addr_Pri(jit);
23.377 - break;
23.378 - }
23.379 - case OP_ADDR_ALT:
23.380 - {
23.381 - WriteOp_Addr_Alt(jit);
23.382 - break;
23.383 - }
23.384 - case OP_STOR_PRI:
23.385 - {
23.386 - WriteOp_Stor_Pri(jit);
23.387 - break;
23.388 - }
23.389 - case OP_STOR_ALT:
23.390 - {
23.391 - WriteOp_Stor_Alt(jit);
23.392 - break;
23.393 - }
23.394 - case OP_STOR_S_PRI:
23.395 - {
23.396 - WriteOp_Stor_S_Pri(jit);
23.397 - break;
23.398 - }
23.399 - case OP_STOR_S_ALT:
23.400 - {
23.401 - WriteOp_Stor_S_Alt(jit);
23.402 - break;
23.403 - }
23.404 - case OP_IDXADDR:
23.405 - {
23.406 - WriteOp_Idxaddr(jit);
23.407 - break;
23.408 - }
23.409 - case OP_SREF_PRI:
23.410 - {
23.411 - WriteOp_Sref_Pri(jit);
23.412 - break;
23.413 - }
23.414 - case OP_SREF_ALT:
23.415 - {
23.416 - WriteOp_Sref_Alt(jit);
23.417 - break;
23.418 - }
23.419 - case OP_SREF_S_PRI:
23.420 - {
23.421 - WriteOp_Sref_S_Pri(jit);
23.422 - break;
23.423 - }
23.424 - case OP_SREF_S_ALT:
23.425 - {
23.426 - WriteOp_Sref_S_Alt(jit);
23.427 - break;
23.428 - }
23.429 - case OP_POP_PRI:
23.430 - {
23.431 - WriteOp_Pop_Pri(jit);
23.432 - break;
23.433 - }
23.434 - case OP_POP_ALT:
23.435 - {
23.436 - WriteOp_Pop_Alt(jit);
23.437 - break;
23.438 - }
23.439 - case OP_SWAP_PRI:
23.440 - {
23.441 - WriteOp_Swap_Pri(jit);
23.442 - break;
23.443 - }
23.444 - case OP_SWAP_ALT:
23.445 - {
23.446 - WriteOp_Swap_Alt(jit);
23.447 - break;
23.448 - }
23.449 - case OP_PUSH_ADR:
23.450 - {
23.451 - WriteOp_PushAddr(jit);
23.452 - break;
23.453 - }
23.454 - case OP_MOVS:
23.455 - {
23.456 - WriteOp_Movs(jit);
23.457 - break;
23.458 - }
23.459 - case OP_FILL:
23.460 - {
23.461 - WriteOp_Fill(jit);
23.462 - break;
23.463 - }
23.464 - case OP_PUSH_C:
23.465 - {
23.466 - WriteOp_Push_C(jit);
23.467 - break;
23.468 - }
23.469 - case OP_ZERO:
23.470 - {
23.471 - WriteOp_Zero(jit);
23.472 - break;
23.473 - }
23.474 - case OP_ZERO_S:
23.475 - {
23.476 - WriteOp_Zero_S(jit);
23.477 - break;
23.478 - }
23.479 - case OP_PUSH_PRI:
23.480 - {
23.481 - WriteOp_Push_Pri(jit);
23.482 - break;
23.483 - }
23.484 - case OP_PUSH_ALT:
23.485 - {
23.486 - WriteOp_Push_Alt(jit);
23.487 - break;
23.488 - }
23.489 - case OP_LOAD_BOTH:
23.490 - {
23.491 - WriteOp_Load_Both(jit);
23.492 - break;
23.493 - }
23.494 - case OP_LOAD_S_BOTH:
23.495 - {
23.496 - WriteOp_Load_S_Both(jit);
23.497 - break;
23.498 - }
23.499 - case OP_CONST:
23.500 - {
23.501 - WriteOp_Const(jit);
23.502 - break;
23.503 - }
23.504 - case OP_CONST_S:
23.505 - {
23.506 - WriteOp_Const_S(jit);
23.507 - break;
23.508 - }
23.509 - case OP_LOAD_I:
23.510 - {
23.511 - WriteOp_Load_I(jit);
23.512 - break;
23.513 - }
23.514 - case OP_LODB_I:
23.515 - {
23.516 - WriteOp_Lodb_I(jit);
23.517 - break;
23.518 - }
23.519 - case OP_STOR_I:
23.520 - {
23.521 - WriteOp_Stor_I(jit);
23.522 - break;
23.523 - }
23.524 - case OP_STRB_I:
23.525 - {
23.526 - WriteOp_Strb_I(jit);
23.527 - break;
23.528 - }
23.529 - case OP_LIDX:
23.530 - {
23.531 - WriteOp_Lidx(jit);
23.532 - break;
23.533 - }
23.534 - case OP_LIDX_B:
23.535 - {
23.536 - WriteOp_Lidx_B(jit);
23.537 - break;
23.538 - }
23.539 - case OP_IDXADDR_B:
23.540 - {
23.541 - WriteOp_Idxaddr_B(jit);
23.542 - break;
23.543 - }
23.544 - case OP_STACK:
23.545 - {
23.546 - WriteOp_Stack(jit);
23.547 - break;
23.548 - }
23.549 - case OP_HEAP:
23.550 - {
23.551 - WriteOp_Heap(jit);
23.552 - break;
23.553 - }
23.554 - case OP_SDIV:
23.555 - {
23.556 - WriteOp_SDiv(jit);
23.557 - break;
23.558 - }
23.559 - case OP_SDIV_ALT:
23.560 - {
23.561 - WriteOp_SDiv_Alt(jit);
23.562 - break;
23.563 - }
23.564 - case OP_RETN:
23.565 - {
23.566 - WriteOp_Retn(jit);
23.567 - break;
23.568 - }
23.569 - case OP_BOUNDS:
23.570 - {
23.571 - WriteOp_Bounds(jit);
23.572 - break;
23.573 - }
23.574 - case OP_HALT:
23.575 - {
23.576 - WriteOp_Halt(jit);
23.577 - break;
23.578 - }
23.579 - case OP_BREAK:
23.580 - {
23.581 - WriteOp_Break(jit);
23.582 - break;
23.583 - }
23.584 - case OP_JUMP:
23.585 - {
23.586 - WriteOp_Jump(jit);
23.587 - break;
23.588 - }
23.589 - case OP_JZER:
23.590 - {
23.591 - WriteOp_Jzer(jit);
23.592 - break;
23.593 - }
23.594 - case OP_JNZ:
23.595 - {
23.596 - WriteOp_Jnz(jit);
23.597 - break;
23.598 - }
23.599 - case OP_JEQ:
23.600 - {
23.601 - WriteOp_Jeq(jit);
23.602 - break;
23.603 - }
23.604 - case OP_JNEQ:
23.605 - {
23.606 - WriteOp_Jneq(jit);
23.607 - break;
23.608 - }
23.609 - case OP_JSLESS:
23.610 - {
23.611 - WriteOp_Jsless(jit);
23.612 - break;
23.613 - }
23.614 - case OP_JSGRTR:
23.615 - {
23.616 - WriteOp_JsGrtr(jit);
23.617 - break;
23.618 - }
23.619 - case OP_JSGEQ:
23.620 - {
23.621 - WriteOp_JsGeq(jit);
23.622 - break;
23.623 - }
23.624 - case OP_JSLEQ:
23.625 - {
23.626 - WriteOp_Jsleq(jit);
23.627 - break;
23.628 - }
23.629 - case OP_SWITCH:
23.630 - {
23.631 - WriteOp_Switch(jit);
23.632 - break;
23.633 - }
23.634 - case OP_CASETBL:
23.635 - {
23.636 - WriteOp_Casetbl(jit);
23.637 - break;
23.638 - }
23.639 - case OP_CALL:
23.640 - {
23.641 - WriteOp_Call(jit);
23.642 - break;
23.643 - }
23.644 - case OP_SYSREQ_C:
23.645 - {
23.646 - WriteOp_Sysreq_C(jit);
23.647 - break;
23.648 - }
23.649 - case OP_SYSREQ_N:
23.650 - {
23.651 - if (data->inline_level & JIT_INLINE_NATIVES)
23.652 - {
23.653 - WriteOp_Sysreq_N(jit);
23.654 - } else {
23.655 - WriteOp_Sysreq_N_NoInline(jit);
23.656 - }
23.657 - break;
23.658 - }
23.659 - case OP_TRACKER_PUSH_C:
23.660 - {
23.661 - WriteOp_Tracker_Push_C(jit);
23.662 - break;
23.663 - }
23.664 - case OP_TRACKER_POP_SETHEAP:
23.665 - {
23.666 - WriteOp_Tracker_Pop_SetHeap(jit);
23.667 - break;
23.668 - }
23.669 - case OP_GENARRAY:
23.670 - {
23.671 - WriteOp_GenArray(jit, false);
23.672 - break;
23.673 - }
23.674 - case OP_GENARRAY_Z:
23.675 - {
23.676 - WriteOp_GenArray(jit, true);
23.677 - break;
23.678 - }
23.679 -#if defined USE_UNGEN_OPCODES
23.680 - #include "ungen_opcode_switch.inc"
23.681 -#endif
23.682 - default:
23.683 - {
23.684 - data->error_set = SP_ERROR_INVALID_INSTRUCTION;
23.685 - break;
23.686 - }
23.687 -
23.688 \ No newline at end of file
24.1 --- a/sourcepawn/vm/jit/x86/ungen_opcode_switch.inc Tue Nov 07 23:26:40 2006 +0000
24.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
24.3 @@ -1,90 +0,0 @@
24.4 - case OP_UMUL:
24.5 - {
24.6 - WriteOp_UMul(jit);
24.7 - break;
24.8 - }
24.9 - case OP_LESS:
24.10 - {
24.11 - WriteOp_Less(jit);
24.12 - break;
24.13 - }
24.14 - case OP_LEQ:
24.15 - {
24.16 - WriteOp_Leq(jit);
24.17 - break;
24.18 - }
24.19 - case OP_GRTR:
24.20 - {
24.21 - WriteOp_Grtr(jit);
24.22 - break;
24.23 - }
24.24 - case OP_GEQ:
24.25 - {
24.26 - WriteOp_Geq(jit);
24.27 - break;
24.28 - }
24.29 - case OP_ALIGN_PRI:
24.30 - {
24.31 - WriteOp_Align_Pri(jit);
24.32 - break;
24.33 - }
24.34 - case OP_ALIGN_ALT:
24.35 - {
24.36 - WriteOp_Align_Alt(jit);
24.37 - break;
24.38 - }
24.39 - case OP_LCTRL:
24.40 - {
24.41 - WriteOp_Lctrl(jit);
24.42 - break;
24.43 - }
24.44 - case OP_SCTRL:
24.45 - {
24.46 - WriteOp_Sctrl(jit);
24.47 - break;
24.48 - }
24.49 - case OP_UDIV:
24.50 - {
24.51 - WriteOp_UDiv(jit);
24.52 - break;
24.53 - }
24.54 - case OP_UDIV_ALT:
24.55 - {
24.56 - WriteOp_UDiv_Alt(jit);
24.57 - break;
24.58 - }
24.59 - case OP_RET:
24.60 - {
24.61 - WriteOp_Ret(jit);
24.62 - break;
24.63 - }
24.64 - case OP_CMPS:
24.65 - {
24.66 - WriteOp_Cmps(jit);
24.67 - break;
24.68 - }
24.69 - case OP_JREL:
24.70 - {
24.71 - WriteOp_JRel(jit);
24.72 - break;
24.73 - }
24.74 - case OP_JLESS:
24.75 - {
24.76 - WriteOp_Jless(jit);
24.77 - break;
24.78 - }
24.79 - case OP_JLEQ:
24.80 - {
24.81 - WriteOp_Jeq(jit);
24.82 - break;
24.83 - }
24.84 - case OP_JGRTR:
24.85 - {
24.86 - WriteOp_Jgrtr(jit);
24.87 - break;
24.88 - }
24.89 - case OP_JGEQ:
24.90 - {
24.91 - WriteOp_Jgeq(jit);
24.92 - break;
24.93 - }
24.94 \ No newline at end of file
25.1 --- a/sourcepawn/vm/jit/x86/ungen_opcodes.h Tue Nov 07 23:26:40 2006 +0000
25.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
25.3 @@ -1,294 +0,0 @@
25.4 -#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
25.5 -#define _INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
25.6 -
25.7 -inline void WriteOp_UMul(JitWriter *jit)
25.8 -{
25.9 - //mov ecx, edx
25.10 - //mul edx
25.11 - //mov edx, ecx
25.12 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
25.13 - IA32_Mul_Rm(jit, AMX_REG_ALT, MOD_REG);
25.14 - IA32_Mov_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_TMP, MOD_REG);
25.15 -}
25.16 -
25.17 -inline void WriteOp_Less(JitWriter *jit)
25.18 -{
25.19 - //cmp eax, edx ; PRI < ALT ? (unsigned)
25.20 - //mov eax, 0
25.21 - //setb al
25.22 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.23 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
25.24 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_B);
25.25 -}
25.26 -
25.27 -inline void WriteOp_Leq(JitWriter *jit)
25.28 -{
25.29 - //cmp eax, edx ; PRI <= ALT ? (unsigned)
25.30 - //mov eax, 0
25.31 - //setbe al
25.32 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.33 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
25.34 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_BE);
25.35 -}
25.36 -
25.37 -inline void WriteOp_Grtr(JitWriter *jit)
25.38 -{
25.39 - //cmp eax, edx ; PRI > ALT ? (unsigned)
25.40 - //mov eax, 0
25.41 - //seta al
25.42 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.43 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
25.44 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_A);
25.45 -}
25.46 -
25.47 -inline void WriteOp_Geq(JitWriter *jit)
25.48 -{
25.49 - //cmp eax, edx ; PRI >= ALT ? (unsigned)
25.50 - //mov eax, 0
25.51 - //setae al
25.52 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.53 - IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
25.54 - IA32_SetCC_Rm8(jit, AMX_REG_PRI, CC_AE);
25.55 -}
25.56 -
25.57 -inline void WriteOp_Align_Pri(JitWriter *jit)
25.58 -{
25.59 - //xor eax, <cellsize - val>
25.60 - cell_t val = sizeof(cell_t) - jit->read_cell();
25.61 - if (val < SCHAR_MAX && val > SCHAR_MIN)
25.62 - {
25.63 - IA32_Xor_Rm_Imm8(jit, AMX_REG_PRI, MOD_REG, (jit_int8_t)val);
25.64 - } else {
25.65 - IA32_Xor_Eax_Imm32(jit, val);
25.66 - }
25.67 -}
25.68 -
25.69 -inline void WriteOp_Align_Alt(JitWriter *jit)
25.70 -{
25.71 - //xor edx, <cellsize - val>
25.72 - cell_t val = sizeof(cell_t) - jit->read_cell();
25.73 - if (val < SCHAR_MAX && val > SCHAR_MIN)
25.74 - {
25.75 - IA32_Xor_Rm_Imm8(jit, AMX_REG_ALT, MOD_REG, (jit_int8_t)val);
25.76 - } else {
25.77 - IA32_Xor_Rm_Imm32(jit, AMX_REG_ALT, MOD_REG, val);
25.78 - }
25.79 -}
25.80 -
25.81 -inline void WriteOp_Cmps(JitWriter *jit)
25.82 -{
25.83 - //push edi
25.84 - //push esi
25.85 - //lea esi, [ebp+edx]
25.86 - //lea edi, [ebp+eax]
25.87 - //mov ecx, <val>
25.88 - unsigned int val = jit->read_cell();
25.89 -
25.90 - IA32_Push_Reg(jit, REG_EDI);
25.91 - IA32_Push_Reg(jit, REG_ESI);
25.92 - IA32_Lea_Reg_DispEBPRegMult(jit, REG_ESI, AMX_REG_DAT, AMX_REG_ALT, NOSCALE);
25.93 - IA32_Lea_Reg_DispEBPRegMult(jit, REG_EDI, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
25.94 - IA32_Mov_Reg_Imm32(jit, REG_ECX, val);
25.95 -
25.96 - //xor eax, eax
25.97 - //repe cmpsb
25.98 - //je :cmps1
25.99 - IA32_Xor_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
25.100 - IA32_Rep(jit);
25.101 - IA32_Cmpsb(jit);
25.102 - jitoffs_t jmp = IA32_Jump_Cond_Imm8(jit, CC_E, 0);
25.103 -
25.104 - //sbb eax, eax
25.105 - //sbb eax, -1
25.106 - IA32_Sbb_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_PRI, MOD_REG);
25.107 - IA32_Sbb_Rm_Imm8(jit, AMX_REG_PRI, -1, MOD_REG);
25.108 -
25.109 - //:cmps1
25.110 - //pop esi
25.111 - //pop edi
25.112 - IA32_Send_Jump8_Here(jit, jmp);
25.113 - IA32_Pop_Reg(jit, REG_ESI);
25.114 - IA32_Pop_Reg(jit, REG_EDI);
25.115 -}
25.116 -
25.117 -inline void WriteOp_Lctrl(JitWriter *jit)
25.118 -{
25.119 - cell_t val = jit->read_cell();
25.120 - switch (val)
25.121 - {
25.122 - case 0:
25.123 - {
25.124 - //mov ecx, [esi+ctx]
25.125 - //mov eax, [ecx+ctx.codebase]
25.126 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
25.127 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, codebase));
25.128 - break;
25.129 - }
25.130 - case 1:
25.131 - {
25.132 - //mov eax, ebp
25.133 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
25.134 - break;
25.135 - }
25.136 - case 2:
25.137 - {
25.138 - //mov eax, [esi+hea]
25.139 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_INFO, AMX_INFO_HEAP);
25.140 - break;
25.141 - }
25.142 - case 3:
25.143 - {
25.144 - //mov ecx, [esi+ctx]
25.145 - //mov eax, [ecx+ctx.memory]
25.146 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_TMP, AMX_REG_INFO, AMX_INFO_CONTEXT);
25.147 - IA32_Mov_Reg_Rm_Disp8(jit, AMX_REG_PRI, AMX_REG_TMP, offsetof(sp_context_t, memory));
25.148 - break;
25.149 - }
25.150 - case 4:
25.151 - {
25.152 - //mov eax, edi
25.153 - //sub eax, ebp - unrelocate
25.154 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_STK, MOD_REG);
25.155 - IA32_Sub_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_DAT, MOD_REG);
25.156 - break;
25.157 - }
25.158 - case 5:
25.159 - {
25.160 - //mov eax, [esi+frm]
25.161 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_INFO, MOD_MEM_REG);
25.162 - break;
25.163 - }
25.164 - case 6:
25.165 - {
25.166 - //mov eax, [cip]
25.167 - jitoffs_t imm32 = IA32_Mov_Reg_Imm32(jit, AMX_REG_PRI, 0);
25.168 - jitoffs_t save = jit->get_outputpos();
25.169 - jit->set_outputpos(imm32);
25.170 - jit->write_int32((uint32_t)(jit->outbase + save));
25.171 - jit->set_outputpos(save);
25.172 - break;
25.173 - }
25.174 - }
25.175 -}
25.176 -
25.177 -inline void WriteOp_Sctrl(JitWriter *jit)
25.178 -{
25.179 - cell_t val = jit->read_cell();
25.180 - switch (val)
25.181 - {
25.182 - case 2:
25.183 - {
25.184 - //mov [esi+hea], eax
25.185 - IA32_Mov_Rm_Reg_Disp8(jit, AMX_REG_INFO, AMX_REG_PRI, AMX_INFO_HEAP);
25.186 - break;
25.187 - }
25.188 - case 4:
25.189 - {
25.190 - //lea edi, [ebp+eax]
25.191 - IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_STK, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
25.192 - break;
25.193 - }
25.194 - case 5:
25.195 - {
25.196 - //lea ebx, [ebp+eax] - overwrite frm
25.197 - //mov [esi+frm], eax - overwrite stacked frame
25.198 - IA32_Lea_Reg_DispEBPRegMult(jit, AMX_REG_FRM, AMX_REG_DAT, AMX_REG_PRI, NOSCALE);
25.199 - IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_PRI, MOD_MEM_REG);
25.200 - break;
25.201 - }
25.202 - case 6:
25.203 - {
25.204 - IA32_Jump_Reg(jit, AMX_REG_PRI);
25.205 - break;
25.206 - }
25.207 - }
25.208 -}
25.209 -
25.210 -inline void WriteOp_UDiv(JitWriter *jit)
25.211 -{
25.212 - //mov ecx, edx
25.213 - //xor edx, edx
25.214 - //div ecx
25.215 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_ALT, MOD_REG);
25.216 - IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
25.217 - Write_Check_DivZero(jit, AMX_REG_TMP);
25.218 - IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
25.219 -}
25.220 -
25.221 -inline void WriteOp_UDiv_Alt(JitWriter *jit)
25.222 -{
25.223 - //mov ecx, eax
25.224 - //mov eax, edx
25.225 - //xor edx, edx
25.226 - //div ecx
25.227 - IA32_Mov_Reg_Rm(jit, AMX_REG_TMP, AMX_REG_PRI, MOD_REG);
25.228 - IA32_Mov_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.229 - IA32_Xor_Reg_Rm(jit, AMX_REG_ALT, AMX_REG_ALT, MOD_REG);
25.230 - Write_Check_DivZero(jit, AMX_REG_TMP);
25.231 - IA32_Div_Rm(jit, AMX_REG_TMP, MOD_REG);
25.232 -}
25.233 -
25.234 -inline void WriteOp_Ret(JitWriter *jit)
25.235 -{
25.236 - //mov ebx, [edi] - get old FRM
25.237 - //add edi, 4 - pop stack
25.238 - //mov [esi+frm], ebx - restore
25.239 - //add ebx, ebp - relocate
25.240 - //ret
25.241 - IA32_Mov_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_STK, MOD_MEM_REG);
25.242 - IA32_Add_Rm_Imm8(jit, AMX_REG_STK, 4, MOD_REG);
25.243 - IA32_Mov_Rm_Reg(jit, AMX_REG_INFO, AMX_REG_FRM, MOD_MEM_REG);
25.244 - IA32_Add_Reg_Rm(jit, AMX_REG_FRM, AMX_REG_DAT, MOD_REG);
25.245 - IA32_Return(jit);
25.246 -}
25.247 -
25.248 -inline void WriteOp_JRel(JitWriter *jit)
25.249 -{
25.250 - //jmp <offs> ;relative jump
25.251 - cell_t cip_offs = jit->read_cell();
25.252 -
25.253 - /* Note that since code size calculation has to be done in the same
25.254 - * phase as building relocation information, we cannot know the jump size
25.255 - * beforehand. Thus, we always write full 32bit jumps for safety.
25.256 - */
25.257 - jitoffs_t jmp = IA32_Jump_Imm32(jit, 0);
25.258 - IA32_Write_Jump32(jit, jmp, RelocLookup(jit, cip_offs));
25.259 -}
25.260 -
25.261 -inline void WriteOp_Jless(JitWriter *jit)
25.262 -{
25.263 - //cmp eax, edx
25.264 - //jb <target>
25.265 - cell_t target = jit->read_cell();
25.266 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.267 - IA32_Jump_Cond_Imm32(jit, CC_B, RelocLookup(jit, target, false));
25.268 -}
25.269 -
25.270 -inline void WriteOp_Jleq(JitWriter *jit)
25.271 -{
25.272 - //cmp eax, edx
25.273 - //jbe <target>
25.274 - cell_t target = jit->read_cell();
25.275 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.276 - IA32_Jump_Cond_Imm32(jit, CC_BE, RelocLookup(jit, target, false));
25.277 -}
25.278 -
25.279 -inline void WriteOp_Jgrtr(JitWriter *jit)
25.280 -{
25.281 - //cmp eax, edx
25.282 - //ja <target>
25.283 - cell_t target = jit->read_cell();
25.284 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.285 - IA32_Jump_Cond_Imm32(jit, CC_A, RelocLookup(jit, target, false));
25.286 -}
25.287 -
25.288 -inline void WriteOp_Jgeq(JitWriter *jit)
25.289 -{
25.290 - //cmp eax, edx
25.291 - //jae <target>
25.292 - cell_t target = jit->read_cell();
25.293 - IA32_Cmp_Reg_Rm(jit, AMX_REG_PRI, AMX_REG_ALT, MOD_REG);
25.294 - IA32_Jump_Cond_Imm32(jit, CC_AE, RelocLookup(jit, target, false));
25.295 -}
25.296 -
25.297 -#endif //_INCLUDE_SOURCEPAWN_JIT_X86_UNGEN_OPCODES_H_
26.1 --- a/sourcepawn/vm/jit/x86/x86_macros.h Tue Nov 07 23:26:40 2006 +0000
26.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
26.3 @@ -1,1135 +0,0 @@
26.4 -#ifndef _INCLUDE_JIT_X86_MACROS_H
26.5 -#define _INCLUDE_JIT_X86_MACROS_H
26.6 -
26.7 -#include <limits.h>
26.8 -
26.9 -//MOD R/M
26.10 -#define MOD_MEM_REG 0
26.11 -#define MOD_DISP8 1
26.12 -#define MOD_DISP32 2
26.13 -#define MOD_REG 3
26.14 -
26.15 -//SIB
26.16 -#define NOSCALE 0
26.17 -#define SCALE2 1
26.18 -#define SCALE4 2
26.19 -#define SCALE8 3
26.20 -
26.21 -//Register codes
26.22 -#define REG_EAX 0
26.23 -#define REG_ECX 1
26.24 -#define REG_EDX 2
26.25 -#define REG_EBX 3
26.26 -#define REG_ESP 4
26.27 -#define REG_SIB 4
26.28 -#define REG_NOIDX 4
26.29 -#define REG_IMM_BASE 5
26.30 -#define REG_EBP 5
26.31 -#define REG_ESI 6
26.32 -#define REG_EDI 7
26.33 -
26.34 -#define IA32_16BIT_PREFIX 0x66
26.35 -
26.36 -//condition codes (for example, Jcc opcodes)
26.37 -#define CC_B 0x2
26.38 -#define CC_NAE CC_B
26.39 -#define CC_NB 0x3
26.40 -#define CC_AE CC_NB
26.41 -#define CC_E 0x4
26.42 -#define CC_Z CC_E
26.43 -#define CC_NE 0x5
26.44 -#define CC_NZ CC_NE
26.45 -#define CC_NA 0x6
26.46 -#define CC_BE CC_NA
26.47 -#define CC_A 0x7
26.48 -#define CC_NBE CC_A
26.49 -#define CC_L 0xC
26.50 -#define CC_NGE CC_L
26.51 -#define CC_NL 0xD
26.52 -#define CC_GE CC_NL
26.53 -#define CC_NG 0xE
26.54 -#define CC_LE CC_NG
26.55 -#define CC_G 0xF
26.56 -#define CC_NLE CC_G
26.57 -
26.58 -//Opcodes with encoding information
26.59 -#define IA32_XOR_RM_REG 0x31 // encoding is /r
26.60 -#define IA32_XOR_REG_RM 0x33 // encoding is /r
26.61 -#define IA32_XOR_EAX_IMM32 0x35 // encoding is /r
26.62 -#define IA32_XOR_RM_IMM32 0x81 // encoding is /6
26.63 -#define IA32_XOR_RM_IMM8 0x83 // encoding is /6
26.64 -#define IA32_ADD_RM_REG 0x01 // encoding is /r
26.65 -#define IA32_ADD_REG_RM 0x03 // encoding is /r
26.66 -#define IA32_ADD_RM_IMM32 0x81 // encoding is /0
26.67 -#define IA32_ADD_RM_IMM8 0x83 // encoding is /0
26.68 -#define IA32_ADD_EAX_IMM32 0x05 // no extra encoding
26.69 -#define IA32_SUB_RM_REG 0x29 // encoding is /r
26.70 -#define IA32_SUB_REG_RM 0x2B // encoding is /r
26.71 -#define IA32_SUB_RM_IMM8 0x83 // encoding is /5 <imm8>
26.72 -#define IA32_SUB_RM_IMM32 0x81 // encoding is /5 <imm32>
26.73 -#define IA32_SBB_REG_RM 0x1B // encoding is /r
26.74 -#define IA32_SBB_RM_IMM8 0x83 // encoding is <imm32>
26.75 -#define IA32_JMP_IMM32 0xE9 // encoding is imm32
26.76 -#define IA32_JMP_IMM8 0xEB // encoding is imm8
26.77 -#define IA32_JMP_RM 0xFF // encoding is /4
26.78 -#define IA32_CALL_IMM32 0xE8 // relative call, <imm32>
26.79 -#define IA32_CALL_RM 0xFF // encoding is /2
26.80 -#define IA32_MOV_REG_IMM 0xB8 // encoding is +r <imm32>
26.81 -#define IA32_MOV_RM8_REG 0x88 // encoding is /r
26.82 -#define IA32_MOV_RM_REG 0x89 // encoding is /r
26.83 -#define IA32_MOV_REG_MEM 0x8B // encoding is /r
26.84 -#define IA32_MOV_RM_IMM32 0xC7 // encoding is /0
26.85 -#define IA32_CMP_RM_IMM32 0x81 // encoding is /7 <imm32>
26.86 -#define IA32_CMP_RM_IMM8 0x83 // encoding is /7 <imm8>
26.87 -#define IA32_CMP_AL_IMM32 0x3C // no extra encoding
26.88 -#define IA32_CMP_EAX_IMM32 0x3D // no extra encoding
26.89 -#define IA32_CMP_RM_REG 0x39 // encoding is /r
26.90 -#define IA32_CMP_REG_RM 0x3B // encoding is /r
26.91 -#define IA32_CMPSB 0xA6 // no extra encoding
26.92 -#define IA32_TEST_RM_REG 0x85 // encoding is /r
26.93 -#define IA32_JCC_IMM 0x70 // encoding is +cc <imm8>
26.94 -#define IA32_JCC_IMM32_1 0x0F // opcode part 1
26.95 -#define IA32_JCC_IMM32_2 0x80 // encoding is +cc <imm32>
26.96 -#define IA32_RET 0xC3 // no extra encoding
26.97 -#define IA32_NEG_RM 0xF7 // encoding is /3
26.98 -#define IA32_INC_REG 0x40 // encoding is +r
26.99 -#define IA32_INC_RM 0xFF // encoding is /0
26.100 -#define IA32_DEC_REG 0x48 // encoding is +r
26.101 -#define IA32_DEC_RM 0xFF // encoding is /1
26.102 -#define IA32_OR_REG_RM 0x0B // encoding is /r
26.103 -#define IA32_AND_REG_RM 0x23 // encoding is /r
26.104 -#define IA32_AND_EAX_IMM32 0x25 // encoding is <imm32>
26.105 -#define IA32_AND_RM_IMM32 0x81 // encoding is /4
26.106 -#define IA32_NOT_RM 0xF7 // encoding is /2
26.107 -#define IA32_DIV_RM 0xF7 // encoding is /6
26.108 -#define IA32_MUL_RM 0xF7 // encoding is /4
26.109 -#define IA32_IDIV_RM 0xF7 // encoding is /7
26.110 -#define IA32_IMUL_RM 0xF7 // encoding is /5
26.111 -#define IA32_IMUL_REG_IMM32 0x69 // encoding is /r
26.112 -#define IA32_IMUL_REG_IMM8 0x6B // encoding is /r
26.113 -#define IA32_IMUL_REG_RM_1 0x0F // encoding is _2
26.114 -#define IA32_IMUL_REG_RM_2 0xAF // encoding is /r
26.115 -#define IA32_SHR_RM_IMM8 0xC1 // encoding is /5 <ib>
26.116 -#define IA32_SHR_RM_1 0xD1 // encoding is /5
26.117 -#define IA32_SHL_RM_IMM8 0xC1 // encoding is /4 <ib>
26.118 -#define IA32_SHL_RM_1 0xD1 // encoding is /4
26.119 -#define IA32_SAR_RM_CL 0xD3 // encoding is /7
26.120 -#define IA32_SHR_RM_CL 0xD3 // encoding is /5
26.121 -#define IA32_SHL_RM_CL 0xD3 // encoding is /4
26.122 -#define IA32_SAR_RM_IMM8 0xC1 // encoding is /7 <ib>
26.123 -#define IA32_SETCC_RM8_1 0x0F // opcode part 1
26.124 -#define IA32_SETCC_RM8_2 0x90 // encoding is +cc /0 (8bits)
26.125 -#define IA32_XCHG_EAX_REG 0x90 // encoding is +r
26.126 -#define IA32_LEA_REG_MEM 0x8D // encoding is /r
26.127 -#define IA32_POP_REG 0x58 // encoding is +r
26.128 -#define IA32_PUSH_REG 0x50 // encoding is +r
26.129 -#define IA32_PUSH_RM 0xFF // encoding is /6
26.130 -#define IA32_PUSH_IMM32 0x68 // encoding is <imm32>
26.131 -#define IA32_PUSH_IMM8 0x6A // encoding is <imm8>
26.132 -#define IA32_REP 0xF3 // no extra encoding
26.133 -#define IA32_MOVSD 0xA5 // no extra encoding
26.134 -#define IA32_MOVSB 0xA4 // no extra encoding
26.135 -#define IA32_STOSD 0xAB // no extra encoding
26.136 -#define IA32_CLD 0xFC // no extra encoding
26.137 -#define IA32_PUSHAD 0x60 // no extra encoding
26.138 -#define IA32_POPAD 0x61 // no extra encoding
26.139 -#define IA32_NOP 0x90 // no extra encoding
26.140 -#define IA32_INT3 0xCC // no extra encoding
26.141 -
26.142 -inline jit_uint8_t ia32_modrm(jit_uint8_t mode, jit_uint8_t reg, jit_uint8_t rm)
26.143 -{
26.144 - jit_uint8_t modrm = (mode << 6);
26.145 -
26.146 - modrm |= (reg << 3);
26.147 - modrm |= (rm);
26.148 -
26.149 - return modrm;
26.150 -}
26.151 -
26.152 -//mode is the scaling method - NOSCALE ... SCALE8
26.153 -//index is the register that is scaled
26.154 -//base is the base register
26.155 -inline jit_uint8_t ia32_sib(jit_uint8_t mode, jit_uint8_t index, jit_uint8_t base)
26.156 -{
26.157 - jit_uint8_t sib = (mode << 6);
26.158 -
26.159 - sib |= (index << 3);
26.160 - sib |= (base);
26.161 -
26.162 - return sib;
26.163 -}
26.164 -
26.165 -/***********************
26.166 - * INCREMENT/DECREMENT *
26.167 - ***********************/
26.168 -
26.169 -inline void IA32_Inc_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
26.170 -{
26.171 - jit->write_ubyte(IA32_INC_RM);
26.172 - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, reg));
26.173 - jit->write_int32(disp);
26.174 -}
26.175 -
26.176 -inline void IA32_Inc_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
26.177 -{
26.178 - jit->write_ubyte(IA32_INC_RM);
26.179 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, reg));
26.180 - jit->write_byte(disp);
26.181 -}
26.182 -
26.183 -inline void IA32_Inc_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
26.184 -{
26.185 - jit->write_ubyte(IA32_INC_RM);
26.186 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 0, REG_SIB));
26.187 - jit->write_ubyte(ia32_sib(scale, reg, base));
26.188 -}
26.189 -
26.190 -inline void IA32_Inc_Reg(JitWriter *jit, jit_uint8_t reg)
26.191 -{
26.192 - jit->write_ubyte(IA32_INC_REG+reg);
26.193 -}
26.194 -
26.195 -inline void IA32_Dec_Rm_Disp32(JitWriter *jit, jit_uint8_t reg, jit_int32_t disp)
26.196 -{
26.197 - jit->write_ubyte(IA32_DEC_RM);
26.198 - jit->write_ubyte(ia32_modrm(MOD_DISP32, 1, reg));
26.199 - jit->write_int32(disp);
26.200 -}
26.201 -
26.202 -inline void IA32_Dec_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp)
26.203 -{
26.204 - jit->write_ubyte(IA32_DEC_RM);
26.205 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 1, reg));
26.206 - jit->write_byte(disp);
26.207 -}
26.208 -
26.209 -inline void IA32_Dec_Rm_Disp_Reg(JitWriter *jit, jit_uint8_t base, jit_uint8_t reg, jit_uint8_t scale)
26.210 -{
26.211 - jit->write_ubyte(IA32_DEC_RM);
26.212 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, 1, REG_SIB));
26.213 - jit->write_ubyte(ia32_sib(scale, reg, base));
26.214 -}
26.215 -
26.216 -inline void IA32_Dec_Reg(JitWriter *jit, jit_uint8_t reg)
26.217 -{
26.218 - jit->write_ubyte(IA32_DEC_REG+reg);
26.219 -}
26.220 -
26.221 -/****************
26.222 - * BINARY LOGIC *
26.223 - ****************/
26.224 -
26.225 -inline void IA32_Xor_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
26.226 -{
26.227 - jit->write_ubyte(IA32_XOR_RM_REG);
26.228 - jit->write_ubyte(ia32_modrm(dest_mode, src, dest));
26.229 -}
26.230 -
26.231 -inline void IA32_Xor_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t dest_mode)
26.232 -{
26.233 - jit->write_ubyte(IA32_XOR_REG_RM);
26.234 - jit->write_ubyte(ia32_modrm(dest_mode, dest, src));
26.235 -}
26.236 -
26.237 -inline void IA32_Xor_Eax_Imm32(JitWriter *jit, jit_int32_t value)
26.238 -{
26.239 - jit->write_ubyte(IA32_XOR_EAX_IMM32);
26.240 - jit->write_int32(value);
26.241 -}
26.242 -
26.243 -inline void IA32_Xor_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
26.244 -{
26.245 - jit->write_ubyte(IA32_XOR_RM_IMM32);
26.246 - jit->write_ubyte(ia32_modrm(mode, 6, reg));
26.247 - jit->write_int32(value);
26.248 -}
26.249 -
26.250 -inline void IA32_Xor_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
26.251 -{
26.252 - jit->write_ubyte(IA32_XOR_RM_IMM8);
26.253 - jit->write_ubyte(ia32_modrm(mode, 6, reg));
26.254 - jit->write_byte(value);
26.255 -}
26.256 -
26.257 -inline void IA32_Neg_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.258 -{
26.259 - jit->write_ubyte(IA32_NEG_RM);
26.260 - jit->write_ubyte(ia32_modrm(mode, 3, reg));
26.261 -}
26.262 -
26.263 -inline void IA32_Or_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.264 -{
26.265 - jit->write_ubyte(IA32_OR_REG_RM);
26.266 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.267 -}
26.268 -
26.269 -inline void IA32_And_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.270 -{
26.271 - jit->write_ubyte(IA32_AND_REG_RM);
26.272 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.273 -}
26.274 -
26.275 -inline void IA32_And_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t c)
26.276 -{
26.277 - if (reg == REG_EAX)
26.278 - {
26.279 - jit->write_ubyte(IA32_AND_EAX_IMM32);
26.280 - } else {
26.281 - jit->write_ubyte(IA32_AND_RM_IMM32);
26.282 - jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg));
26.283 - }
26.284 - jit->write_int32(c);
26.285 -}
26.286 -
26.287 -inline void IA32_Not_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.288 -{
26.289 - jit->write_ubyte(IA32_NOT_RM);
26.290 - jit->write_ubyte(ia32_modrm(mode, 2, reg));
26.291 -}
26.292 -
26.293 -inline void IA32_Shr_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
26.294 -{
26.295 - jit->write_ubyte(IA32_SHR_RM_IMM8);
26.296 - jit->write_ubyte(ia32_modrm(mode, 5, dest));
26.297 - jit->write_ubyte(value);
26.298 -}
26.299 -
26.300 -inline void IA32_Shr_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
26.301 -{
26.302 - jit->write_ubyte(IA32_SHR_RM_1);
26.303 - jit->write_ubyte(ia32_modrm(mode, 5, dest));
26.304 -}
26.305 -
26.306 -inline void IA32_Shl_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
26.307 -{
26.308 - jit->write_ubyte(IA32_SHL_RM_IMM8);
26.309 - jit->write_ubyte(ia32_modrm(mode, 4, dest));
26.310 - jit->write_ubyte(value);
26.311 -}
26.312 -
26.313 -inline void IA32_Shl_Rm_1(JitWriter *jit, jit_uint8_t dest, jit_uint8_t mode)
26.314 -{
26.315 - jit->write_ubyte(IA32_SHL_RM_1);
26.316 - jit->write_ubyte(ia32_modrm(mode, 4, dest));
26.317 -}
26.318 -
26.319 -inline void IA32_Sar_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t value, jit_uint8_t mode)
26.320 -{
26.321 - jit->write_ubyte(IA32_SAR_RM_IMM8);
26.322 - jit->write_ubyte(ia32_modrm(mode, 7, dest));
26.323 - jit->write_ubyte(value);
26.324 -}
26.325 -
26.326 -inline void IA32_Sar_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.327 -{
26.328 - jit->write_ubyte(IA32_SAR_RM_CL);
26.329 - jit->write_ubyte(ia32_modrm(mode, 7, reg));
26.330 -}
26.331 -
26.332 -inline void IA32_Shr_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.333 -{
26.334 - jit->write_ubyte(IA32_SHR_RM_CL);
26.335 - jit->write_ubyte(ia32_modrm(mode, 5, reg));
26.336 -}
26.337 -
26.338 -inline void IA32_Shl_Rm_CL(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.339 -{
26.340 - jit->write_ubyte(IA32_SHL_RM_CL);
26.341 - jit->write_ubyte(ia32_modrm(mode, 4, reg));
26.342 -}
26.343 -
26.344 -inline void IA32_Xchg_Eax_Reg(JitWriter *jit, jit_uint8_t reg)
26.345 -{
26.346 - jit->write_ubyte(IA32_XCHG_EAX_REG+reg);
26.347 -}
26.348 -
26.349 -/**********************
26.350 - * ARITHMETIC (BASIC) *
26.351 - **********************/
26.352 -
26.353 -inline void IA32_Add_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.354 -{
26.355 - jit->write_ubyte(IA32_ADD_RM_REG);
26.356 - jit->write_ubyte(ia32_modrm(mode, src, dest));
26.357 -}
26.358 -
26.359 -inline void IA32_Add_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.360 -{
26.361 - jit->write_ubyte(IA32_ADD_REG_RM);
26.362 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.363 -}
26.364 -
26.365 -inline void IA32_Add_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t value, jit_uint8_t mode)
26.366 -{
26.367 - jit->write_ubyte(IA32_ADD_RM_IMM8);
26.368 - jit->write_ubyte(ia32_modrm(mode, 0, reg));
26.369 - jit->write_byte(value);
26.370 -}
26.371 -
26.372 -inline void IA32_Add_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t value, jit_uint8_t mode)
26.373 -{
26.374 - jit->write_ubyte(IA32_ADD_RM_IMM32);
26.375 - jit->write_ubyte(ia32_modrm(mode, 0, reg));
26.376 - jit->write_int32(value);
26.377 -}
26.378 -
26.379 -inline void IA32_Add_Eax_Imm32(JitWriter *jit, jit_int32_t value)
26.380 -{
26.381 - jit->write_ubyte(IA32_ADD_EAX_IMM32);
26.382 - jit->write_int32(value);
26.383 -}
26.384 -
26.385 -inline void IA32_Sub_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.386 -{
26.387 - jit->write_ubyte(IA32_SUB_RM_REG);
26.388 - jit->write_ubyte(ia32_modrm(mode, src, dest));
26.389 -}
26.390 -
26.391 -inline void IA32_Sub_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.392 -{
26.393 - jit->write_ubyte(IA32_SUB_REG_RM);
26.394 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.395 -}
26.396 -
26.397 -inline void IA32_Sub_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
26.398 -{
26.399 - jit->write_ubyte(IA32_SUB_REG_RM);
26.400 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
26.401 - jit->write_byte(disp8);
26.402 -}
26.403 -
26.404 -inline void IA32_Sub_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp8)
26.405 -{
26.406 - jit->write_ubyte(IA32_SUB_RM_REG);
26.407 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
26.408 - jit->write_byte(disp8);
26.409 -}
26.410 -
26.411 -inline void IA32_Sub_Rm_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t val, jit_uint8_t mode)
26.412 -{
26.413 - jit->write_ubyte(IA32_SUB_RM_IMM8);
26.414 - jit->write_ubyte(ia32_modrm(mode, 5, reg));
26.415 - jit->write_byte(val);
26.416 -}
26.417 -
26.418 -inline void IA32_Sub_Rm_Imm32(JitWriter *jit, jit_uint8_t reg, jit_int32_t val, jit_uint8_t mode)
26.419 -{
26.420 - jit->write_ubyte(IA32_SUB_RM_IMM32);
26.421 - jit->write_ubyte(ia32_modrm(mode, 5, reg));
26.422 - jit->write_int32(val);
26.423 -}
26.424 -
26.425 -inline void IA32_Sbb_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.426 -{
26.427 - jit->write_ubyte(IA32_SBB_REG_RM);
26.428 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.429 -}
26.430 -
26.431 -inline void IA32_Sbb_Rm_Imm8(JitWriter *jit, jit_uint8_t dest, jit_int8_t value, jit_uint8_t mode)
26.432 -{
26.433 - jit->write_ubyte(IA32_SBB_RM_IMM8);
26.434 - jit->write_ubyte(ia32_modrm(mode, 3, dest));
26.435 - jit->write_byte(value);
26.436 -}
26.437 -
26.438 -inline void IA32_Div_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.439 -{
26.440 - jit->write_ubyte(IA32_DIV_RM);
26.441 - jit->write_ubyte(ia32_modrm(mode, 6, reg));
26.442 -}
26.443 -
26.444 -inline void IA32_IDiv_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.445 -{
26.446 - jit->write_ubyte(IA32_IDIV_RM);
26.447 - jit->write_ubyte(ia32_modrm(mode, 7, reg));
26.448 -}
26.449 -
26.450 -inline void IA32_Mul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.451 -{
26.452 - jit->write_ubyte(IA32_MUL_RM);
26.453 - jit->write_ubyte(ia32_modrm(mode, 4, reg));
26.454 -}
26.455 -
26.456 -inline void IA32_IMul_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.457 -{
26.458 - jit->write_ubyte(IA32_IMUL_RM);
26.459 - jit->write_ubyte(ia32_modrm(mode, 5, reg));
26.460 -}
26.461 -
26.462 -inline void IA32_IMul_Reg_Imm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int8_t value)
26.463 -{
26.464 - jit->write_ubyte(IA32_IMUL_REG_IMM8);
26.465 - jit->write_ubyte(ia32_modrm(mode, 0, reg));
26.466 - jit->write_byte(value);
26.467 -}
26.468 -
26.469 -inline void IA32_IMul_Reg_Imm32(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode, jit_int32_t value)
26.470 -{
26.471 - jit->write_ubyte(IA32_IMUL_REG_IMM32);
26.472 - jit->write_ubyte(ia32_modrm(mode, 0, reg));
26.473 - jit->write_int32(value);
26.474 -}
26.475 -
26.476 -inline void IA32_IMul_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.477 -{
26.478 - jit->write_ubyte(IA32_IMUL_REG_RM_1);
26.479 - jit->write_ubyte(IA32_IMUL_REG_RM_2);
26.480 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.481 -}
26.482 -
26.483 -inline void IA32_Add_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
26.484 -{
26.485 - jit->write_ubyte(IA32_ADD_RM_REG);
26.486 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
26.487 - jit->write_byte(disp);
26.488 -}
26.489 -
26.490 -inline void IA32_Add_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
26.491 -{
26.492 - jit->write_ubyte(IA32_ADD_REG_RM);
26.493 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
26.494 - jit->write_byte(disp);
26.495 -}
26.496 -
26.497 -inline void IA32_Add_Rm_Imm8_Disp8(JitWriter *jit,
26.498 - jit_uint8_t dest,
26.499 - jit_int8_t val,
26.500 - jit_int8_t disp8)
26.501 -{
26.502 - jit->write_ubyte(IA32_ADD_RM_IMM8);
26.503 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
26.504 - jit->write_byte(disp8);
26.505 - jit->write_byte(val);
26.506 -}
26.507 -
26.508 -inline void IA32_Add_Rm_Imm32_Disp8(JitWriter *jit,
26.509 - jit_uint8_t dest,
26.510 - jit_int32_t val,
26.511 - jit_int8_t disp8)
26.512 -{
26.513 - jit->write_ubyte(IA32_ADD_RM_IMM32);
26.514 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
26.515 - jit->write_byte(disp8);
26.516 - jit->write_int32(val);
26.517 -}
26.518 -
26.519 -inline jitoffs_t IA32_Add_Rm_Imm32_Later(JitWriter *jit,
26.520 - jit_uint8_t dest,
26.521 - jit_uint8_t mode)
26.522 -{
26.523 - jit->write_ubyte(IA32_ADD_RM_IMM32);
26.524 - jit->write_ubyte(ia32_modrm(mode, 0, dest));
26.525 - jitoffs_t ptr = jit->get_outputpos();
26.526 - jit->write_int32(0);
26.527 - return ptr;
26.528 -}
26.529 -
26.530 -inline void IA32_Add_Rm_Imm8_Disp32(JitWriter *jit,
26.531 - jit_uint8_t dest,
26.532 - jit_int8_t val,
26.533 - jit_int32_t disp32)
26.534 -{
26.535 - jit->write_ubyte(IA32_ADD_RM_IMM8);
26.536 - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
26.537 - jit->write_int32(disp32);
26.538 - jit->write_byte(val);
26.539 -}
26.540 -
26.541 -inline void IA32_Add_RmEBP_Imm8_Disp_Reg(JitWriter *jit,
26.542 - jit_uint8_t dest_base,
26.543 - jit_uint8_t dest_index,
26.544 - jit_uint8_t dest_scale,
26.545 - jit_int8_t val)
26.546 -{
26.547 - jit->write_ubyte(IA32_ADD_RM_IMM8);
26.548 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
26.549 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.550 - jit->write_byte(0);
26.551 - jit->write_byte(val);
26.552 -}
26.553 -
26.554 -inline void IA32_Sub_Rm_Imm8_Disp8(JitWriter *jit,
26.555 - jit_uint8_t dest,
26.556 - jit_int8_t val,
26.557 - jit_int8_t disp8)
26.558 -{
26.559 - jit->write_ubyte(IA32_SUB_RM_IMM8);
26.560 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, dest));
26.561 - jit->write_byte(disp8);
26.562 - jit->write_byte(val);
26.563 -}
26.564 -
26.565 -inline void IA32_Sub_Rm_Imm8_Disp32(JitWriter *jit,
26.566 - jit_uint8_t dest,
26.567 - jit_int8_t val,
26.568 - jit_int32_t disp32)
26.569 -{
26.570 - jit->write_ubyte(IA32_SUB_RM_IMM8);
26.571 - jit->write_ubyte(ia32_modrm(MOD_DISP32, 5, dest));
26.572 - jit->write_int32(disp32);
26.573 - jit->write_byte(val);
26.574 -}
26.575 -
26.576 -inline void IA32_Sub_RmEBP_Imm8_Disp_Reg(JitWriter *jit,
26.577 - jit_uint8_t dest_base,
26.578 - jit_uint8_t dest_index,
26.579 - jit_uint8_t dest_scale,
26.580 - jit_int8_t val)
26.581 -{
26.582 - jit->write_ubyte(IA32_SUB_RM_IMM8);
26.583 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 5, REG_SIB));
26.584 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.585 - jit->write_byte(0);
26.586 - jit->write_byte(val);
26.587 -}
26.588 -
26.589 -/**
26.590 -* Memory Instructions
26.591 -*/
26.592 -
26.593 -inline void IA32_Lea_Reg_DispRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
26.594 -{
26.595 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.596 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
26.597 - jit->write_ubyte(ia32_sib(scale, src_index, src_base));
26.598 -}
26.599 -
26.600 -inline void IA32_Lea_Reg_DispEBPRegMult(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_uint8_t src_index, jit_uint8_t scale)
26.601 -{
26.602 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.603 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
26.604 - jit->write_ubyte(ia32_sib(scale, src_index, src_base));
26.605 - jit->write_byte(0);
26.606 -}
26.607 -
26.608 -inline void IA32_Lea_Reg_DispRegMultImm8(JitWriter *jit,
26.609 - jit_uint8_t dest,
26.610 - jit_uint8_t src_base,
26.611 - jit_uint8_t src_index,
26.612 - jit_uint8_t scale,
26.613 - jit_int8_t val)
26.614 -{
26.615 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.616 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
26.617 - jit->write_ubyte(ia32_sib(scale, src_index, src_base));
26.618 - jit->write_byte(val);
26.619 -}
26.620 -
26.621 -inline void IA32_Lea_Reg_RegMultImm32(JitWriter *jit,
26.622 - jit_uint8_t dest,
26.623 - jit_uint8_t src_index,
26.624 - jit_uint8_t scale,
26.625 - jit_int32_t val)
26.626 -{
26.627 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.628 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
26.629 - jit->write_ubyte(ia32_sib(scale, src_index, REG_IMM_BASE));
26.630 - jit->write_int32(val);
26.631 -}
26.632 -
26.633 -inline void IA32_Lea_DispRegImm8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int8_t val)
26.634 -{
26.635 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.636 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src_base));
26.637 - jit->write_byte(val);
26.638 -}
26.639 -
26.640 -inline void IA32_Lea_DispRegImm32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src_base, jit_int32_t val)
26.641 -{
26.642 - jit->write_ubyte(IA32_LEA_REG_MEM);
26.643 - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src_base));
26.644 - jit->write_int32(val);
26.645 -}
26.646 -
26.647 -/**
26.648 -* Stack Instructions
26.649 -*/
26.650 -
26.651 -inline void IA32_Pop_Reg(JitWriter *jit, jit_uint8_t reg)
26.652 -{
26.653 - jit->write_ubyte(IA32_POP_REG+reg);
26.654 -}
26.655 -
26.656 -inline void IA32_Push_Reg(JitWriter *jit, jit_uint8_t reg)
26.657 -{
26.658 - jit->write_ubyte(IA32_PUSH_REG+reg);
26.659 -}
26.660 -
26.661 -inline void IA32_Push_Imm8(JitWriter *jit, jit_int8_t val)
26.662 -{
26.663 - jit->write_ubyte(IA32_PUSH_IMM8);
26.664 - jit->write_byte(val);
26.665 -}
26.666 -
26.667 -inline void IA32_Push_Imm32(JitWriter *jit, jit_int32_t val)
26.668 -{
26.669 - jit->write_ubyte(IA32_PUSH_IMM32);
26.670 - jit->write_int32(val);
26.671 -}
26.672 -
26.673 -inline void IA32_Pushad(JitWriter *jit)
26.674 -{
26.675 - jit->write_ubyte(IA32_PUSHAD);
26.676 -}
26.677 -
26.678 -inline void IA32_Popad(JitWriter *jit)
26.679 -{
26.680 - jit->write_ubyte(IA32_POPAD);
26.681 -}
26.682 -
26.683 -inline void IA32_Push_Rm_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8)
26.684 -{
26.685 - jit->write_ubyte(IA32_PUSH_RM);
26.686 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, reg));
26.687 - jit->write_byte(disp8);
26.688 -}
26.689 -
26.690 -inline void IA32_Push_Rm_Disp8_ESP(JitWriter *jit, jit_int8_t disp8)
26.691 -{
26.692 - jit->write_ubyte(IA32_PUSH_RM);
26.693 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 6, REG_SIB));
26.694 - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
26.695 - jit->write_byte(disp8);
26.696 -}
26.697 -
26.698 -/**
26.699 - * Moving from REGISTER/MEMORY to REGISTER
26.700 - */
26.701 -
26.702 -inline void IA32_Mov_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.703 -{
26.704 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.705 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.706 -}
26.707 -
26.708 -inline void IA32_Mov_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
26.709 -{
26.710 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.711 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, src));
26.712 - jit->write_byte(disp);
26.713 -}
26.714 -
26.715 -inline void IA32_Mov_Reg_Esp_Disp8(JitWriter *jit, jit_uint8_t dest, jit_int8_t disp)
26.716 -{
26.717 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.718 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
26.719 - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
26.720 - jit->write_byte(disp);
26.721 -}
26.722 -
26.723 -inline void IA32_Mov_Reg_Rm_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
26.724 -{
26.725 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.726 - jit->write_ubyte(ia32_modrm(MOD_DISP32, dest, src));
26.727 - jit->write_int32(disp);
26.728 -}
26.729 -
26.730 -inline void IA32_Mov_Reg_Rm_Disp_Reg(JitWriter *jit,
26.731 - jit_uint8_t dest,
26.732 - jit_uint8_t src_base,
26.733 - jit_uint8_t src_index,
26.734 - jit_uint8_t src_scale)
26.735 -{
26.736 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.737 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, dest, REG_SIB));
26.738 - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
26.739 -}
26.740 -
26.741 -inline void IA32_Mov_Reg_Rm_Disp_Reg_Disp8(JitWriter *jit,
26.742 - jit_uint8_t dest,
26.743 - jit_uint8_t src_base,
26.744 - jit_uint8_t src_index,
26.745 - jit_uint8_t src_scale,
26.746 - jit_int8_t disp8)
26.747 -{
26.748 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.749 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
26.750 - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
26.751 - jit->write_byte(disp8);
26.752 -}
26.753 -
26.754 -inline void IA32_Mov_Reg_RmEBP_Disp_Reg(JitWriter *jit,
26.755 - jit_uint8_t dest,
26.756 - jit_uint8_t src_base,
26.757 - jit_uint8_t src_index,
26.758 - jit_uint8_t src_scale)
26.759 -{
26.760 - jit->write_ubyte(IA32_MOV_REG_MEM);
26.761 - jit->write_ubyte(ia32_modrm(MOD_DISP8, dest, REG_SIB));
26.762 - jit->write_ubyte(ia32_sib(src_scale, src_index, src_base));
26.763 - jit->write_byte(0);
26.764 -}
26.765 -
26.766 -/**
26.767 - * Moving from REGISTER to REGISTER/MEMORY
26.768 - */
26.769 -
26.770 -inline void IA32_Mov_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.771 -{
26.772 - jit->write_ubyte(IA32_MOV_RM_REG);
26.773 - jit->write_ubyte(ia32_modrm(mode, src, dest));
26.774 -}
26.775 -
26.776 -inline void IA32_Mov_Rm_Reg_Disp8(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int8_t disp)
26.777 -{
26.778 - jit->write_ubyte(IA32_MOV_RM_REG);
26.779 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, dest));
26.780 - jit->write_byte(disp);
26.781 -}
26.782 -
26.783 -inline void IA32_Mov_Rm_Reg_Disp32(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_int32_t disp)
26.784 -{
26.785 - jit->write_ubyte(IA32_MOV_RM_REG);
26.786 - jit->write_ubyte(ia32_modrm(MOD_DISP32, src, dest));
26.787 - jit->write_int32(disp);
26.788 -}
26.789 -
26.790 -inline void IA32_Mov_RmEBP_Reg_Disp_Reg(JitWriter *jit,
26.791 - jit_uint8_t dest_base,
26.792 - jit_uint8_t dest_index,
26.793 - jit_uint8_t dest_scale,
26.794 - jit_uint8_t src)
26.795 -{
26.796 - jit->write_ubyte(IA32_MOV_RM_REG);
26.797 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
26.798 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.799 - jit->write_byte(0);
26.800 -}
26.801 -
26.802 -inline void IA32_Mov_Rm8EBP_Reg_Disp_Reg(JitWriter *jit,
26.803 - jit_uint8_t dest_base,
26.804 - jit_uint8_t dest_index,
26.805 - jit_uint8_t dest_scale,
26.806 - jit_uint8_t src)
26.807 -{
26.808 - jit->write_ubyte(IA32_MOV_RM8_REG);
26.809 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
26.810 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.811 - jit->write_byte(0);
26.812 -}
26.813 -
26.814 -inline void IA32_Mov_Rm16EBP_Reg_Disp_Reg(JitWriter *jit,
26.815 - jit_uint8_t dest_base,
26.816 - jit_uint8_t dest_index,
26.817 - jit_uint8_t dest_scale,
26.818 - jit_uint8_t src)
26.819 -{
26.820 - jit->write_ubyte(IA32_16BIT_PREFIX);
26.821 - jit->write_ubyte(IA32_MOV_RM_REG);
26.822 - jit->write_ubyte(ia32_modrm(MOD_DISP8, src, REG_SIB));
26.823 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.824 - jit->write_byte(0);
26.825 -}
26.826 -
26.827 -/**
26.828 - * Moving from IMMEDIATE to REGISTER
26.829 - */
26.830 -
26.831 -inline jitoffs_t IA32_Mov_Reg_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t num)
26.832 -{
26.833 - jitoffs_t offs;
26.834 - jit->write_ubyte(IA32_MOV_REG_IMM+dest);
26.835 - offs = jit->get_outputpos();
26.836 - jit->write_int32(num);
26.837 - return offs;
26.838 -}
26.839 -
26.840 -inline void IA32_Mov_Rm_Imm32_Disp8(JitWriter *jit,
26.841 - jit_uint8_t dest,
26.842 - jit_int32_t val,
26.843 - jit_int8_t disp8)
26.844 -{
26.845 - jit->write_ubyte(IA32_MOV_RM_IMM32);
26.846 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, dest));
26.847 - jit->write_byte(disp8);
26.848 - jit->write_int32(val);
26.849 -}
26.850 -
26.851 -inline void IA32_Mov_Rm_Imm32(JitWriter *jit, jit_uint8_t dest, jit_int32_t val, jit_uint8_t mode)
26.852 -{
26.853 - jit->write_ubyte(IA32_MOV_RM_IMM32);
26.854 - jit->write_ubyte(ia32_modrm(mode, 0, dest));
26.855 - jit->write_int32(val);
26.856 -}
26.857 -
26.858 -inline void IA32_Mov_Rm_Imm32_Disp32(JitWriter *jit,
26.859 - jit_uint8_t dest,
26.860 - jit_int32_t val,
26.861 - jit_int32_t disp32)
26.862 -{
26.863 - jit->write_ubyte(IA32_MOV_RM_IMM32);
26.864 - jit->write_ubyte(ia32_modrm(MOD_DISP32, 0, dest));
26.865 - jit->write_int32(disp32);
26.866 - jit->write_int32(val);
26.867 -}
26.868 -
26.869 -inline void IA32_Mov_RmEBP_Imm32_Disp_Reg(JitWriter *jit,
26.870 - jit_uint8_t dest_base,
26.871 - jit_uint8_t dest_index,
26.872 - jit_uint8_t dest_scale,
26.873 - jit_int32_t val)
26.874 -{
26.875 - jit->write_ubyte(IA32_MOV_RM_IMM32);
26.876 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 0, REG_SIB));
26.877 - jit->write_ubyte(ia32_sib(dest_scale, dest_index, dest_base));
26.878 - jit->write_byte(0);
26.879 - jit->write_int32(val);
26.880 -}
26.881 -
26.882 -/**
26.883 - * Branching/Jumping
26.884 - */
26.885 -
26.886 -inline jitoffs_t IA32_Jump_Cond_Imm8(JitWriter *jit, jit_uint8_t cond, jit_int8_t disp)
26.887 -{
26.888 - jitoffs_t ptr;
26.889 - jit->write_ubyte(IA32_JCC_IMM+cond);
26.890 - ptr = jit->get_outputpos();
26.891 - jit->write_byte(disp);
26.892 - return ptr;
26.893 -}
26.894 -
26.895 -inline jitoffs_t IA32_Jump_Imm32(JitWriter *jit, jit_int32_t disp)
26.896 -{
26.897 - jitoffs_t ptr;
26.898 - jit->write_ubyte(IA32_JMP_IMM32);
26.899 - ptr = jit->get_outputpos();
26.900 - jit->write_int32(disp);
26.901 - return ptr;
26.902 -}
26.903 -
26.904 -inline jitoffs_t IA32_Jump_Imm8(JitWriter *jit, jit_int8_t disp)
26.905 -{
26.906 - jitoffs_t ptr;
26.907 - jit->write_ubyte(IA32_JMP_IMM8);
26.908 - ptr = jit->get_outputpos();
26.909 - jit->write_byte(disp);
26.910 - return ptr;
26.911 -}
26.912 -
26.913 -inline jitoffs_t IA32_Jump_Cond_Imm32(JitWriter *jit, jit_uint8_t cond, jit_int32_t disp)
26.914 -{
26.915 - jitoffs_t ptr;
26.916 - jit->write_ubyte(IA32_JCC_IMM32_1);
26.917 - jit->write_ubyte(IA32_JCC_IMM32_2+cond);
26.918 - ptr = jit->get_outputpos();
26.919 - jit->write_int32(disp);
26.920 - return ptr;
26.921 -}
26.922 -
26.923 -inline void IA32_Jump_Reg(JitWriter *jit, jit_uint8_t reg)
26.924 -{
26.925 - jit->write_ubyte(IA32_JMP_RM);
26.926 - jit->write_ubyte(ia32_modrm(MOD_REG, 4, reg));
26.927 -}
26.928 -
26.929 -inline void IA32_Jump_Rm(JitWriter *jit, jit_uint8_t reg, jit_uint8_t mode)
26.930 -{
26.931 - jit->write_ubyte(IA32_JMP_RM);
26.932 - jit->write_ubyte(ia32_modrm(mode, 4, reg));
26.933 -}
26.934 -
26.935 -inline jitoffs_t IA32_Call_Imm32(JitWriter *jit, jit_int32_t disp)
26.936 -{
26.937 - jitoffs_t ptr;
26.938 - jit->write_ubyte(IA32_CALL_IMM32);
26.939 - ptr = jit->get_outputpos();
26.940 - jit->write_int32(disp);
26.941 - return ptr;
26.942 -}
26.943 -
26.944 -inline void IA32_Call_Reg(JitWriter *jit, jit_uint8_t reg)
26.945 -{
26.946 - jit->write_ubyte(IA32_CALL_RM);
26.947 - jit->write_ubyte(ia32_modrm(MOD_REG, 2, reg));
26.948 -}
26.949 -
26.950 -inline void IA32_Write_Jump8(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
26.951 -{
26.952 - //save old ptr
26.953 - jitcode_t oldptr = jit->outptr;
26.954 - //get relative difference
26.955 - jit_int8_t diff = (target - (jmp + 1));
26.956 - //overwrite old value
26.957 - jit->outptr = jit->outbase + jmp;
26.958 - jit->write_byte(diff);
26.959 - //restore old ptr
26.960 - jit->outptr = oldptr;
26.961 -}
26.962 -
26.963 -inline void IA32_Write_Jump32(JitWriter *jit, jitoffs_t jmp, jitoffs_t target)
26.964 -{
26.965 - //save old ptr
26.966 - jitcode_t oldptr = jit->outptr;
26.967 - //get relative difference
26.968 - jit_int32_t diff = (target - (jmp + 4));
26.969 - //overwrite old value
26.970 - jit->outptr = jit->outbase + jmp;
26.971 - jit->write_int32(diff);
26.972 - //restore old ptr
26.973 - jit->outptr = oldptr;
26.974 -}
26.975 -
26.976 -/**
26.977 - * Corrects a jump using an absolute offset, not a relative one.
26.978 - */
26.979 -inline void IA32_Write_Jump32_Abs(JitWriter *jit, jitoffs_t jmp, void *target)
26.980 -{
26.981 - //save old ptr
26.982 - jitcode_t oldptr = jit->outptr;
26.983 - //get relative difference
26.984 - long diff = ((long)target - ((long)jit->outbase + jmp + 4));
26.985 - //overwrite old value
26.986 - jit->outptr = jit->outbase + jmp;
26.987 - jit->write_int32(diff);
26.988 - //restore old ptr
26.989 - jit->outptr = oldptr;
26.990 -}
26.991 -
26.992 -/* For writing and auto-calculating an absolute target */
26.993 -inline void IA32_Jump_Imm32_Abs(JitWriter *jit, jitoffs_t target)
26.994 -{
26.995 - /* :TODO: this should work, but does it? */
26.996 - jit->write_ubyte(IA32_JMP_IMM32);
26.997 - IA32_Write_Jump32(jit, jit->get_outputpos(), target);
26.998 - jit->outptr += 4;
26.999 -}
26.1000 -
26.1001 -inline void IA32_Jump_Cond_Imm32_Abs(JitWriter *jit, jit_uint8_t cond, jitoffs_t target)
26.1002 -{
26.1003 - /* :TODO: this should work, but does it? */
26.1004 - jit->write_ubyte(IA32_JCC_IMM32_1);
26.1005 - jit->write_ubyte(IA32_JCC_IMM32_2+cond);
26.1006 - IA32_Write_Jump32(jit, jit->get_outputpos(), target);
26.1007 - jit->outptr += 4;
26.1008 -}
26.1009 -
26.1010 -inline void IA32_Send_Jump8_Here(JitWriter *jit, jitoffs_t jmp)
26.1011 -{
26.1012 - jitoffs_t curptr = jit->get_outputpos();
26.1013 - IA32_Write_Jump8(jit, jmp, curptr);
26.1014 -}
26.1015 -
26.1016 -inline void IA32_Send_Jump32_Here(JitWriter *jit, jitoffs_t jmp)
26.1017 -{
26.1018 - jitoffs_t curptr = jit->get_outputpos();
26.1019 - IA32_Write_Jump32(jit, jmp, curptr);
26.1020 -}
26.1021 -
26.1022 -inline void IA32_Return(JitWriter *jit)
26.1023 -{
26.1024 - jit->write_ubyte(IA32_RET);
26.1025 -}
26.1026 -
26.1027 -inline void IA32_Test_Rm_Reg(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_uint8_t mode)
26.1028 -{
26.1029 - jit->write_ubyte(IA32_TEST_RM_REG);
26.1030 - jit->write_ubyte(ia32_modrm(mode, reg2, reg1));
26.1031 -}
26.1032 -
26.1033 -inline void IA32_Cmp_Rm_Reg(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.1034 -{
26.1035 - jit->write_ubyte(IA32_CMP_RM_REG);
26.1036 - jit->write_ubyte(ia32_modrm(mode, src, dest));
26.1037 -}
26.1038 -
26.1039 -inline void IA32_Cmp_Reg_Rm(JitWriter *jit, jit_uint8_t dest, jit_uint8_t src, jit_uint8_t mode)
26.1040 -{
26.1041 - jit->write_ubyte(IA32_CMP_REG_RM);
26.1042 - jit->write_ubyte(ia32_modrm(mode, dest, src));
26.1043 -}
26.1044 -
26.1045 -inline void IA32_Cmp_Reg_Rm_ESP(JitWriter *jit, jit_uint8_t cmpreg)
26.1046 -{
26.1047 - jit->write_ubyte(IA32_CMP_REG_RM);
26.1048 - jit->write_ubyte(ia32_modrm(MOD_MEM_REG, cmpreg, REG_SIB));
26.1049 - jit->write_ubyte(ia32_sib(NOSCALE, REG_NOIDX, REG_ESP));
26.1050 -}
26.1051 -
26.1052 -inline void IA32_Cmp_Reg_Rm_Disp8(JitWriter *jit, jit_uint8_t reg1, jit_uint8_t reg2, jit_int8_t disp8)
26.1053 -{
26.1054 - jit->write_ubyte(IA32_CMP_REG_RM);
26.1055 - jit->write_ubyte(ia32_modrm(MOD_DISP8, reg1, reg2));
26.1056 - jit->write_byte(disp8);
26.1057 -}
26.1058 -
26.1059 -inline void IA32_Cmp_Rm_Imm8(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int8_t imm8)
26.1060 -{
26.1061 - jit->write_ubyte(IA32_CMP_RM_IMM8);
26.1062 - jit->write_ubyte(ia32_modrm(mode, 7, rm));
26.1063 - jit->write_byte(imm8);
26.1064 -}
26.1065 -
26.1066 -inline void IA32_Cmp_Rm_Imm32(JitWriter *jit, jit_uint8_t mode, jit_uint8_t rm, jit_int32_t imm32)
26.1067 -{
26.1068 - jit->write_ubyte(IA32_CMP_RM_IMM32);
26.1069 - jit->write_ubyte(ia32_modrm(mode, 7, rm));
26.1070 - jit->write_int32(imm32);
26.1071 -}
26.1072 -
26.1073 -inline void IA32_Cmp_Rm_Imm32_Disp8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp8, jit_int32_t imm32)
26.1074 -{
26.1075 - jit->write_ubyte(IA32_CMP_RM_IMM32);
26.1076 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
26.1077 - jit->write_byte(disp8);
26.1078 - jit->write_int32(imm32);
26.1079 -}
26.1080 -
26.1081 -inline void IA32_Cmp_Rm_Disp8_Imm8(JitWriter *jit, jit_uint8_t reg, jit_int8_t disp, jit_int8_t imm8)
26.1082 -{
26.1083 - jit->write_ubyte(IA32_CMP_RM_IMM8);
26.1084 - jit->write_ubyte(ia32_modrm(MOD_DISP8, 7, reg));
26.1085 - jit->write_byte(disp);
26.1086 - jit->write_byte(imm8);
26.1087 -}
26.1088 -
26.1089 -inline void IA32_Cmp_Al_Imm8(JitWriter *jit, jit_int8_t value)
26.1090 -{
26.1091 - jit->write_ubyte(IA32_CMP_AL_IMM32);
26.1092 - jit->write_byte(value);
26.1093 -}
26.1094 -
26.1095 -inline void IA32_Cmp_Eax_Imm32(JitWriter *jit, jit_int32_t value)
26.1096 -{
26.1097 - jit->write_ubyte(IA32_CMP_EAX_IMM32);
26.1098 - jit->write_int32(value);
26.1099 -}
26.1100 -
26.1101 -inline void IA32_SetCC_Rm8(JitWriter *jit, jit_uint8_t reg, jit_uint8_t cond)
26.1102 -{
26.1103 - jit->write_ubyte(IA32_SETCC_RM8_1);
26.1104 - jit->write_ubyte(IA32_SETCC_RM8_2+cond);
26.1105 - jit->write_ubyte(ia32_modrm(MOD_REG, 0, reg));
26.1106 -}
26.1107 -
26.1108 -inline void IA32_Cmpsb(JitWriter *jit)
26.1109 -{
26.1110 - jit->write_ubyte(IA32_CMPSB);
26.1111 -}
26.1112 -
26.1113 -inline void IA32_Rep(JitWriter *jit)
26.1114 -{
26.1115 - jit->write_ubyte(IA32_REP);
26.1116 -}
26.1117 -
26.1118 -inline void IA32_Movsd(JitWriter *jit)
26.1119 -{
26.1120 - jit->write_ubyte(IA32_MOVSD);
26.1121 -}
26.1122 -
26.1123 -inline void IA32_Movsb(JitWriter *jit)
26.1124 -{
26.1125 - jit->write_ubyte(IA32_MOVSB);
26.1126 -}
26.1127 -
26.1128 -inline void IA32_Stosd(JitWriter *jit)
26.1129 -{
26.1130 - jit->write_ubyte(IA32_STOSD);
26.1131 -}
26.1132 -
26.1133 -inline void IA32_Cld(JitWriter *jit)
26.1134 -{
26.1135 - jit->write_ubyte(IA32_CLD);
26.1136 -}
26.1137 -
26.1138 -#endif //_INCLUDE_JIT_X86_MACROS_H
27.1 --- a/sourcepawn/vm/msvc8/vm.sln Tue Nov 07 23:26:40 2006 +0000
27.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
27.3 @@ -1,20 +0,0 @@
27.4 -
27.5 -Microsoft Visual Studio Solution File, Format Version 9.00
27.6 -# Visual Studio 2005
27.7 -Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vm", "vm.vcproj", "{1B84D3AE-5938-401E-AD85-84D22A823BDA}"
27.8 -EndProject
27.9 -Global
27.10 - GlobalSection(SolutionConfigurationPlatforms) = preSolution
27.11 - Debug|Win32 = Debug|Win32
27.12 - Release|Win32 = Release|Win32
27.13 - EndGlobalSection
27.14 - GlobalSection(ProjectConfigurationPlatforms) = postSolution
27.15 - {1B84D3AE-5938-401E-AD85-84D22A823BDA}.Debug|Win32.ActiveCfg = Debug|Win32
27.16 - {1B84D3AE-5938-401E-AD85-84D22A823BDA}.Debug|Win32.Build.0 = Debug|Win32
27.17 - {1B84D3AE-5938-401E-AD85-84D22A823BDA}.Release|Win32.ActiveCfg = Release|Win32
27.18 - {1B84D3AE-5938-401E-AD85-84D22A823BDA}.Release|Win32.Build.0 = Release|Win32
27.19 - EndGlobalSection
27.20 - GlobalSection(SolutionProperties) = preSolution
27.21 - HideSolutionNode = FALSE
27.22 - EndGlobalSection
27.23 -EndGlobal
28.1 --- a/sourcepawn/vm/msvc8/vm.vcproj Tue Nov 07 23:26:40 2006 +0000
28.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
28.3 @@ -1,338 +0,0 @@
28.4 -<?xml version="1.0" encoding="Windows-1252"?>
28.5 -<VisualStudioProject
28.6 - ProjectType="Visual C++"
28.7 - Version="8.00"
28.8 - Name="vm"
28.9 - ProjectGUID="{1B84D3AE-5938-401E-AD85-84D22A823BDA}"
28.10 - RootNamespace="vm"
28.11 - Keyword="Win32Proj"
28.12 - >
28.13 - <Platforms>
28.14 - <Platform
28.15 - Name="Win32"
28.16 - />
28.17 - </Platforms>
28.18 - <ToolFiles>
28.19 - </ToolFiles>
28.20 - <Configurations>
28.21 - <Configuration
28.22 - Name="Debug|Win32"
28.23 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
28.24 - IntermediateDirectory="$(ConfigurationName)"
28.25 - ConfigurationType="1"
28.26 - CharacterSet="2"
28.27 - >
28.28 - <Tool
28.29 - Name="VCPreBuildEventTool"
28.30 - />
28.31 - <Tool
28.32 - Name="VCCustomBuildTool"
28.33 - />
28.34 - <Tool
28.35 - Name="VCXMLDataGeneratorTool"
28.36 - />
28.37 - <Tool
28.38 - Name="VCWebServiceProxyGeneratorTool"
28.39 - />
28.40 - <Tool
28.41 - Name="VCMIDLTool"
28.42 - />
28.43 - <Tool
28.44 - Name="VCCLCompilerTool"
28.45 - Optimization="0"
28.46 - AdditionalIncludeDirectories="..\..\include"
28.47 - PreprocessorDefinitions="WIN32;_DEBUG;_CONSOLE;_CRT_SECURE_NO_DEPRECATE"
28.48 - MinimalRebuild="true"
28.49 - BasicRuntimeChecks="3"
28.50 - RuntimeLibrary="1"
28.51 - UsePrecompiledHeader="0"
28.52 - WarningLevel="3"
28.53 - Detect64BitPortabilityProblems="false"
28.54 - DebugInformationFormat="4"
28.55 - />
28.56 - <Tool
28.57 - Name="VCManagedResourceCompilerTool"
28.58 - />
28.59 - <Tool
28.60 - Name="VCResourceCompilerTool"
28.61 - />
28.62 - <Tool
28.63 - Name="VCPreLinkEventTool"
28.64 - />
28.65 - <Tool
28.66 - Name="VCLinkerTool"
28.67 - LinkIncremental="2"
28.68 - GenerateDebugInformation="true"
28.69 - SubSystem="1"
28.70 - TargetMachine="1"
28.71 - />
28.72 - <Tool
28.73 - Name="VCALinkTool"
28.74 - />
28.75 - <Tool
28.76 - Name="VCManifestTool"
28.77 - />
28.78 - <Tool
28.79 - Name="VCXDCMakeTool"
28.80 - />
28.81 - <Tool
28.82 - Name="VCBscMakeTool"
28.83 - />
28.84 - <Tool
28.85 - Name="VCFxCopTool"
28.86 - />
28.87 - <Tool
28.88 - Name="VCAppVerifierTool"
28.89 - />
28.90 - <Tool
28.91 - Name="VCWebDeploymentTool"
28.92 - />
28.93 - <Tool
28.94 - Name="VCPostBuildEventTool"
28.95 - />
28.96 - </Configuration>
28.97 - <Configuration
28.98 - Name="Release|Win32"
28.99 - OutputDirectory="$(SolutionDir)$(ConfigurationName)"
28.100 - IntermediateDirectory="$(ConfigurationName)"
28.101 - ConfigurationType="1"
28.102 - CharacterSet="1"
28.103 - WholeProgramOptimization="1"
28.104 - >
28.105 - <Tool
28.106 - Name="VCPreBuildEventTool"
28.107 - />
28.108 - <Tool
28.109 - Name="VCCustomBuildTool"
28.110 - />
28.111 - <Tool
28.112 - Name="VCXMLDataGeneratorTool"
28.113 - />
28.114 - <Tool
28.115 - Name="VCWebServiceProxyGeneratorTool"
28.116 - />
28.117 - <Tool
28.118 - Name="VCMIDLTool"
28.119 - />
28.120 - <Tool
28.121 - Name="VCCLCompilerTool"
28.122 - PreprocessorDefinitions="WIN32;NDEBUG;_CONSOLE"
28.123 - RuntimeLibrary="2"
28.124 - UsePrecompiledHeader="0"
28.125 - WarningLevel="3"
28.126 - Detect64BitPortabilityProblems="true"
28.127 - DebugInformationFormat="3"
28.128 - />
28.129 - <Tool
28.130 - Name="VCManagedResourceCompilerTool"
28.131 - />
28.132 - <Tool
28.133 - Name="VCResourceCompilerTool"
28.134 - />
28.135 - <Tool
28.136 - Name="VCPreLinkEventTool"
28.137 - />
28.138 - <Tool
28.139 - Name="VCLinkerTool"
28.140 - LinkIncremental="1"
28.141 - GenerateDebugInformation="true"
28.142 - SubSystem="1"
28.143 - OptimizeReferences="2"
28.144 - EnableCOMDATFolding="2"
28.145 - TargetMachine="1"
28.146 - />
28.147 - <Tool
28.148 - Name="VCALinkTool"
28.149 - />
28.150 - <Tool
28.151 - Name="VCManifestTool"
28.152 - />
28.153 - <Tool
28.154 - Name="VCXDCMakeTool"
28.155 - />
28.156 - <Tool
28.157 - Name="VCBscMakeTool"
28.158 - />
28.159 - <Tool
28.160 - Name="VCFxCopTool"
28.161 - />
28.162 - <Tool
28.163 - Name="VCAppVerifierTool"
28.164 - />
28.165 - <Tool
28.166 - Name="VCWebDeploymentTool"
28.167 - />
28.168 - <Tool
28.169 - Name="VCPostBuildEventTool"
28.170 - />
28.171 - </Configuration>
28.172 - </Configurations>
28.173 - <References>
28.174 - </References>
28.175 - <Files>
28.176 - <Filter
28.177 - Name="Source Files"
28.178 - Filter="cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx"
28.179 - UniqueIdentifier="{4FC737F1-C7A5-4376-A066-2A32D752A2FF}"
28.180 - >
28.181 - <File
28.182 - RelativePath="..\sp_vm_basecontext.cpp"
28.183 - >
28.184 - </File>
28.185 - <File
28.186 - RelativePath="..\sp_vm_engine.cpp"
28.187 - >
28.188 - </File>
28.189 - <File
28.190 - RelativePath="..\test_main.cpp"
28.191 - >
28.192 - </File>
28.193 - </Filter>
28.194 - <Filter
28.195 - Name="Header Files"
28.196 - Filter="h;hpp;hxx;hm;inl;inc;xsd"
28.197 - UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}"
28.198 - >
28.199 - <File
28.200 - RelativePath="..\sp_vm_basecontext.h"
28.201 - >
28.202 - </File>
28.203 - <File
28.204 - RelativePath="..\sp_vm_engine.h"
28.205 - >
28.206 - </File>
28.207 - </Filter>
28.208 - <Filter
28.209 - Name="Resource Files"
28.210 - Filter="rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav"
28.211 - UniqueIdentifier="{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}"
28.212 - >
28.213 - </Filter>
28.214 - <Filter
28.215 - Name="zlib"
28.216 - >
28.217 - <Filter
28.218 - Name="Header Files"
28.219 - >
28.220 - <File
28.221 - RelativePath="..\..\compiler\zlib\crc32.h"
28.222 - >
28.223 - </File>
28.224 - <File
28.225 - RelativePath="..\..\compiler\zlib\deflate.h"
28.226 - >
28.227 - </File>
28.228 - <File
28.229 - RelativePath="..\..\compiler\zlib\inffast.h"
28.230 - >
28.231 - </File>
28.232 - <File
28.233 - RelativePath="..\..\compiler\zlib\inffixed.h"
28.234 - >
28.235 - </File>
28.236 - <File
28.237 - RelativePath="..\..\compiler\zlib\inflate.h"
28.238 - >
28.239 - </File>
28.240 - <File
28.241 - RelativePath="..\..\compiler\zlib\inftrees.h"
28.242 - >
28.243 - </File>
28.244 - <File
28.245 - RelativePath="..\..\compiler\zlib\trees.h"
28.246 - >
28.247 - </File>
28.248 - <File
28.249 - RelativePath="..\..\compiler\zlib\zconf.h"
28.250 - >
28.251 - </File>
28.252 - <File
28.253 - RelativePath="..\..\compiler\zlib\zlib.h"
28.254 - >
28.255 - </File>
28.256 - <File
28.257 - RelativePath="..\..\compiler\zlib\zutil.h"
28.258 - >
28.259 - </File>
28.260 - </Filter>
28.261 - <Filter
28.262 - Name="Source Files"
28.263 - >
28.264 - <File
28.265 - RelativePath="..\..\compiler\zlib\adler32.c"
28.266 - >
28.267 - </File>
28.268 - <File
28.269 - RelativePath="..\..\compiler\zlib\compress.c"
28.270 - >
28.271 - </File>
28.272 - <File
28.273 - RelativePath="..\..\compiler\zlib\crc32.c"
28.274 - >
28.275 - </File>
28.276 - <File
28.277 - RelativePath="..\..\compiler\zlib\deflate.c"
28.278 - >
28.279 - </File>
28.280 - <File
28.281 - RelativePath="..\..\compiler\zlib\gzio.c"
28.282 - >
28.283 - </File>
28.284 - <File
28.285 - RelativePath="..\..\compiler\zlib\infback.c"
28.286 - >
28.287 - </File>
28.288 - <File
28.289 - RelativePath="..\..\compiler\zlib\inffast.c"
28.290 - >
28.291 - </File>
28.292 - <File
28.293 - RelativePath="..\..\compiler\zlib\inflate.c"
28.294 - >
28.295 - </File>
28.296 - <File
28.297 - RelativePath="..\..\compiler\zlib\inftrees.c"
28.298 - >
28.299 - </File>
28.300 - <File
28.301 - RelativePath="..\..\compiler\zlib\trees.c"
28.302 - >
28.303 - </File>
28.304 - <File
28.305 - RelativePath="..\..\compiler\zlib\uncompr.c"
28.306 - >
28.307 - </File>
28.308 - <File
28.309 - RelativePath="..\..\compiler\zlib\zutil.c"
28.310 - >
28.311 - </File>
28.312 - </Filter>
28.313 - </Filter>
28.314 - <Filter
28.315 - Name="SDK"
28.316 - >
28.317 - <File
28.318 - RelativePath="..\..\include\sp_file_headers.h"
28.319 - >
28.320 - </File>
28.321 - <File
28.322 - RelativePath="..\..\include\sp_vm_api.h"
28.323 - >
28.324 - </File>
28.325 - <File
28.326 - RelativePath="..\..\include\sp_vm_base.h"
28.327 - >
28.328 - </File>
28.329 - <File
28.330 - RelativePath="..\..\include\sp_vm_context.h"
28.331 - >
28.332 - </File>
28.333 - <File
28.334 - RelativePath="..\..\include\sp_vm_types.h"
28.335 - >
28.336 - </File>
28.337 - </Filter>
28.338 - </Files>
28.339 - <Globals>
28.340 - </Globals>
28.341 -</VisualStudioProject>
29.1 --- a/sourcepawn/vm/sp_vm_basecontext.cpp Tue Nov 07 23:26:40 2006 +0000
29.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
29.3 @@ -1,620 +0,0 @@
29.4 -#include <string.h>
29.5 -#include <assert.h>
29.6 -#include <limits.h>
29.7 -#include "sp_vm_api.h"
29.8 -#include "sp_vm_basecontext.h"
29.9 -
29.10 -using namespace SourcePawn;
29.11 -
29.12 -#define CELLBOUNDMAX (INT_MAX/sizeof(cell_t))
29.13 -#define STACKMARGIN ((cell_t)(16*sizeof(cell_t)))
29.14 -
29.15 -BaseContext::BaseContext(sp_context_t *_ctx)
29.16 -{
29.17 - ctx = _ctx;
29.18 - ctx->context = this;
29.19 -}
29.20 -
29.21 -IVirtualMachine *BaseContext::GetVirtualMachine()
29.22 -{
29.23 - return (IVirtualMachine *)ctx->vmbase;
29.24 -}
29.25 -
29.26 -sp_context_t *BaseContext::GetContext()
29.27 -{
29.28 - return ctx;
29.29 -}
29.30 -
29.31 -bool BaseContext::IsDebugging()
29.32 -{
29.33 - return (ctx->flags & SPFLAG_PLUGIN_DEBUG);
29.34 -}
29.35 -
29.36 -int BaseContext::SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn)
29.37 -{
29.38 - if (!IsDebugging())
29.39 - {
29.40 - return SP_ERROR_NOTDEBUGGING;
29.41 - }
29.42 -
29.43 - *oldpfn = ctx->dbreak;
29.44 - ctx->dbreak = newpfn;
29.45 -
29.46 - return SP_ERROR_NONE;
29.47 -}
29.48 -
29.49 -IPluginDebugInfo *BaseContext::GetDebugInfo()
29.50 -{
29.51 - return this;
29.52 -}
29.53 -
29.54 -int BaseContext::Execute(uint32_t public_func, cell_t *result)
29.55 -{
29.56 - IVirtualMachine *vm = (IVirtualMachine *)ctx->vmbase;
29.57 -
29.58 - uint32_t pushcount = ctx->pushcount;
29.59 -
29.60 - int err;
29.61 - sp_public_t *pubfunc;
29.62 - if ((err=GetPublicByIndex(public_func, &pubfunc)) != SP_ERROR_NONE)
29.63 - {
29.64 - return err;
29.65 - }
29.66 -
29.67 - PushCell(pushcount++);
29.68 - ctx->pushcount = 0;
29.69 -
29.70 - cell_t save_sp = ctx->sp;
29.71 - cell_t save_hp = ctx->hp;
29.72 -
29.73 - err = vm->ContextExecute(ctx, pubfunc->offs, result);
29.74 -
29.75 - /**
29.76 - * :TODO: turn this into an error check
29.77 - */
29.78 -
29.79 -#if defined _DEBUG
29.80 - if (err == SP_ERROR_NONE)
29.81 - {
29.82 - assert(ctx->sp - pushcount * sizeof(cell_t) == save_sp);
29.83 - assert(ctx->hp == save_hp);
29.84 - }
29.85 -#endif
29.86 - if (err != SP_ERROR_NONE)
29.87 - {
29.88 - ctx->sp = save_sp;
29.89 - ctx->hp = save_hp;
29.90 - }
29.91 -
29.92 - return err;
29.93 -}
29.94 -
29.95 -int BaseContext::HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys_addr)
29.96 -{
29.97 - cell_t *addr;
29.98 - ucell_t realmem;
29.99 -
29.100 -#if 0
29.101 - if (cells > CELLBOUNDMAX)
29.102 - {
29.103 - return SP_ERROR_ARAM;
29.104 - }
29.105 -#else
29.106 - assert(cells < CELLBOUNDMAX);
29.107 -#endif
29.108 -
29.109 - realmem = cells * sizeof(cell_t);
29.110 -
29.111 - /**
29.112 - * Check if the space between the heap and stack is sufficient.
29.113 - */
29.114 - if ((cell_t)(ctx->sp - ctx->hp - realmem) < STACKMARGIN)
29.115 - {
29.116 - return SP_ERROR_HEAPLOW;
29.117 - }
29.118 -
29.119 - addr = (cell_t *)(ctx->memory + ctx->hp);
29.120 - /* store size of allocation in cells */
29.121 - *addr = (cell_t)cells;
29.122 - addr++;
29.123 - ctx->hp += sizeof(cell_t);
29.124 -
29.125 - *local_addr = ctx->hp;
29.126 -
29.127 - if (phys_addr)
29.128 - {
29.129 - *phys_addr = addr;
29.130 - }
29.131 -
29.132 - ctx->hp += realmem;
29.133 -
29.134 - return SP_ERROR_NONE;
29.135 -}
29.136 -
29.137 -int BaseContext::HeapPop(cell_t local_addr)
29.138 -{
29.139 - cell_t cellcount;
29.140 - cell_t *addr;
29.141 -
29.142 - /* check the bounds of this address */
29.143 - local_addr -= sizeof(cell_t);
29.144 - if (local_addr < ctx->heap_base || local_addr >= ctx->sp)
29.145 - {
29.146 - return SP_ERROR_INVALID_ADDRESS;
29.147 - }
29.148 -
29.149 - addr = (cell_t *)(ctx->memory + local_addr);
29.150 - cellcount = (*addr) * sizeof(cell_t);
29.151 - /* check if this memory count looks valid */
29.152 - if (ctx->hp - cellcount - sizeof(cell_t) != local_addr)
29.153 - {
29.154 - return SP_ERROR_INVALID_ADDRESS;
29.155 - }
29.156 -
29.157 - ctx->hp = local_addr;
29.158 -
29.159 - return SP_ERROR_NONE;
29.160 -}
29.161 -
29.162 -
29.163 -int BaseContext::HeapRelease(cell_t local_addr)
29.164 -{
29.165 - if (local_addr < ctx->heap_base)
29.166 - {
29.167 - return SP_ERROR_INVALID_ADDRESS;
29.168 - }
29.169 -
29.170 - ctx->hp = local_addr - sizeof(cell_t);
29.171 -
29.172 - return SP_ERROR_NONE;
29.173 -}
29.174 -
29.175 -int BaseContext::FindNativeByName(const char *name, uint32_t *index)
29.176 -{
29.177 - int diff, high, low;
29.178 - uint32_t mid;
29.179 -
29.180 - high = ctx->plugin->info.natives_num - 1;
29.181 - low = 0;
29.182 -
29.183 - while (low <= high)
29.184 - {
29.185 - mid = (low + high) / 2;
29.186 - diff = strcmp(ctx->natives[mid].name, name);
29.187 - if (diff == 0)
29.188 - {
29.189 - if (index)
29.190 - {
29.191 - *index = mid;
29.192 - }
29.193 - return SP_ERROR_NONE;
29.194 - } else if (diff < 0) {
29.195 - low = mid + 1;
29.196 - } else {
29.197 - high = mid - 1;
29.198 - }
29.199 - }
29.200 -
29.201 - return SP_ERROR_NOT_FOUND;
29.202 -}
29.203 -
29.204 -int BaseContext::GetNativeByIndex(uint32_t index, sp_native_t **native)
29.205 -{
29.206 - if (index >= ctx->plugin->info.natives_num)
29.207 - {
29.208 - return SP_ERROR_INDEX;
29.209 - }
29.210 -
29.211 - if (native)
29.212 - {
29.213 - *native = &(ctx->natives[index]);
29.214 - }
29.215 -
29.216 - return SP_ERROR_NONE;
29.217 -}
29.218 -
29.219 -
29.220 -uint32_t BaseContext::GetNativesNum()
29.221 -{
29.222 - return ctx->plugin->info.natives_num;
29.223 -}
29.224 -
29.225 -int BaseContext::FindPublicByName(const char *name, uint32_t *index)
29.226 -{
29.227 - int diff, high, low;
29.228 - uint32_t mid;
29.229 -
29.230 - high = ctx->plugin->info.publics_num - 1;
29.231 - low = 0;
29.232 -
29.233 - while (low <= high)
29.234 - {
29.235 - mid = (low + high) / 2;
29.236 - diff = strcmp(ctx->publics[mid].name, name);
29.237 - if (diff == 0)
29.238 - {
29.239 - if (index)
29.240 - {
29.241 - *index = mid;
29.242 - }
29.243 - return SP_ERROR_NONE;
29.244 - } else if (diff < 0) {
29.245 - low = mid + 1;
29.246 - } else {
29.247 - high = mid - 1;
29.248 - }
29.249 - }
29.250 -
29.251 - return SP_ERROR_NOT_FOUND;
29.252 -}
29.253 -
29.254 -int BaseContext::GetPublicByIndex(uint32_t index, sp_public_t **pblic)
29.255 -{
29.256 - if (index >= ctx->plugin->info.publics_num)
29.257 - {
29.258 - return SP_ERROR_INDEX;
29.259 - }
29.260 -
29.261 - if (pblic)
29.262 - {
29.263 - *pblic = &(ctx->publics[index]);
29.264 - }
29.265 -
29.266 - return SP_ERROR_NONE;
29.267 -}
29.268 -
29.269 -uint32_t BaseContext::GetPublicsNum()
29.270 -{
29.271 - return ctx->plugin->info.publics_num;
29.272 -}
29.273 -
29.274 -int BaseContext::GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar)
29.275 -{
29.276 - if (index >= ctx->plugin->info.pubvars_num)
29.277 - {
29.278 - return SP_ERROR_INDEX;
29.279 - }
29.280 -
29.281 - if (pubvar)
29.282 - {
29.283 - *pubvar = &(ctx->pubvars[index]);
29.284 - }
29.285 -
29.286 - return SP_ERROR_NONE;
29.287 -}
29.288 -
29.289 -int BaseContext::FindPubvarByName(const char *name, uint32_t *index)
29.290 -{
29.291 - int diff, high, low;
29.292 - uint32_t mid;
29.293 -
29.294 - high = ctx->plugin->info.pubvars_num - 1;
29.295 - low = 0;
29.296 -
29.297 - while (low <= high)
29.298 - {
29.299 - mid = (low + high) / 2;
29.300 - diff = strcmp(ctx->pubvars[mid].name, name);
29.301 - if (diff == 0)
29.302 - {
29.303 - if (index)
29.304 - {
29.305 - *index = mid;
29.306 - }
29.307 - return SP_ERROR_NONE;
29.308 - } else if (diff < 0) {
29.309 - low = mid + 1;
29.310 - } else {
29.311 - high = mid - 1;
29.312 - }
29.313 - }
29.314 -
29.315 - return SP_ERROR_NOT_FOUND;
29.316 -}
29.317 -
29.318 -int BaseContext::GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr)
29.319 -{
29.320 - if (index >= ctx->plugin->info.pubvars_num)
29.321 - {
29.322 - return SP_ERROR_INDEX;
29.323 - }
29.324 -
29.325 - *local_addr = ctx->plugin->info.pubvars[index].address;
29.326 - *phys_addr = ctx->pubvars[index].offs;
29.327 -
29.328 - return SP_ERROR_NONE;
29.329 -}
29.330 -
29.331 -uint32_t BaseContext::GetPubVarsNum()
29.332 -{
29.333 - return ctx->plugin->info.pubvars_num;
29.334 -}
29.335 -
29.336 -int BaseContext::BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite)
29.337 -{
29.338 - uint32_t i, j, max;
29.339 -
29.340 - max = ctx->plugin->info.natives_num;
29.341 -
29.342 - for (i=0; i<max; i++)
29.343 - {
29.344 - if ((ctx->natives[i].status == SP_NATIVE_OKAY) && !overwrite)
29.345 - {
29.346 - continue;
29.347 - }
29.348 -
29.349 - for (j=0; (natives[j].name) && (!num || j<num); j++)
29.350 - {
29.351 - if (!strcmp(ctx->natives[i].name, natives[j].name))
29.352 - {
29.353 - ctx->natives[i].pfn = natives[j].func;
29.354 - ctx->natives[i].status = SP_NATIVE_OKAY;
29.355 - }
29.356 - }
29.357 - }
29.358 -
29.359 - return SP_ERROR_NONE;
29.360 -}
29.361 -
29.362 -
29.363 -
29.364 -int BaseContext::BindNative(sp_nativeinfo_t *native, uint32_t status)
29.365 -{
29.366 - uint32_t index;
29.367 - int err;
29.368 -
29.369 - if ((err = FindNativeByName(native->name, &index)) != SP_ERROR_NONE)
29.370 - {
29.371 - return err;
29.372 - }
29.373 -
29.374 - ctx->natives[index].pfn = native->func;
29.375 - ctx->natives[index].status = status;
29.376 -
29.377 - return SP_ERROR_NONE;
29.378 -}
29.379 -
29.380 -int BaseContext::BindNativeToAny(SPVM_NATIVE_FUNC native)
29.381 -{
29.382 - uint32_t nativesnum, i;
29.383 -
29.384 - nativesnum = ctx->plugin->info.natives_num;
29.385 -
29.386 - for (i=0; i<nativesnum; i++)
29.387 - {
29.388 - if (ctx->natives[i].status != SP_NATIVE_OKAY)
29.389 - {
29.390 - ctx->natives[i].pfn = native;
29.391 - ctx->natives[i].status = SP_NATIVE_PENDING;
29.392 - }
29.393 - }
29.394 -
29.395 - return SP_ERROR_NONE;
29.396 -}
29.397 -
29.398 -int BaseContext::LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr)
29.399 -{
29.400 - if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->mem_size))
29.401 - {
29.402 - return SP_ERROR_INVALID_ADDRESS;
29.403 - }
29.404 -
29.405 - if (phys_addr)
29.406 - {
29.407 - *phys_addr = (cell_t *)(ctx->memory + local_addr);
29.408 - }
29.409 -
29.410 - return SP_ERROR_NONE;
29.411 -}
29.412 -
29.413 -int BaseContext::PushCell(cell_t value)
29.414 -{
29.415 - if ((ctx->hp + STACKMARGIN) > (cell_t)(ctx->sp - sizeof(cell_t)))
29.416 - {
29.417 - return SP_ERROR_STACKLOW;
29.418 - }
29.419 -
29.420 - ctx->sp -= sizeof(cell_t);
29.421 - *(cell_t *)(ctx->memory + ctx->sp) = value;
29.422 - ctx->pushcount++;
29.423 -
29.424 - return SP_ERROR_NONE;
29.425 -}
29.426 -
29.427 -int BaseContext::PushCellsFromArray(cell_t array[], unsigned int numcells)
29.428 -{
29.429 - unsigned int i;
29.430 - int err;
29.431 -
29.432 - for (i=0; i<numcells; i++)
29.433 - {
29.434 - if ((err = PushCell(array[i])) != SP_ERROR_NONE)
29.435 - {
29.436 - ctx->sp += (cell_t)(i * sizeof(cell_t));
29.437 - ctx->pushcount -= i;
29.438 - return err;
29.439 - }
29.440 - }
29.441 -
29.442 - return SP_ERROR_NONE;
29.443 -}
29.444 -
29.445 -int BaseContext::PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells)
29.446 -{
29.447 - cell_t *ph_addr;
29.448 - int err;
29.449 -
29.450 - if ((err = HeapAlloc(numcells, local_addr, &ph_addr)) != SP_ERROR_NONE)
29.451 - {
29.452 - return err;
29.453 - }
29.454 -
29.455 - memcpy(ph_addr, array, numcells * sizeof(cell_t));
29.456 -
29.457 - if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
29.458 - {
29.459 - HeapRelease(*local_addr);
29.460 - return err;
29.461 - }
29.462 -
29.463 - if (phys_addr)
29.464 - {
29.465 - *phys_addr = ph_addr;
29.466 - }
29.467 -
29.468 - return SP_ERROR_NONE;
29.469 -}
29.470 -
29.471 -int BaseContext::LocalToString(cell_t local_addr, char **addr)
29.472 -{
29.473 - int len = 0;
29.474 - cell_t *src;
29.475 -
29.476 - if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->mem_size))
29.477 - {
29.478 - return SP_ERROR_INVALID_ADDRESS;
29.479 - }
29.480 - *addr = (char *)(ctx->memory + local_addr);
29.481 -
29.482 - return SP_ERROR_NONE;
29.483 -}
29.484 -
29.485 -int BaseContext::PushString(cell_t *local_addr, cell_t **phys_addr, const char *string)
29.486 -{
29.487 - cell_t *ph_addr;
29.488 - int err;
29.489 - unsigned int i, numcells = strlen(string);
29.490 -
29.491 - if ((err = HeapAlloc(numcells+1, local_addr, &ph_addr)) != SP_ERROR_NONE)
29.492 - {
29.493 - return err;
29.494 - }
29.495 -
29.496 - for (i=0; i<numcells; i++)
29.497 - {
29.498 - ph_addr[i] = (cell_t)string[i];
29.499 - }
29.500 - ph_addr[numcells] = '\0';
29.501 -
29.502 - if ((err = PushCell(*local_addr)) != SP_ERROR_NONE)
29.503 - {
29.504 - HeapRelease(*local_addr);
29.505 - return err;
29.506 - }
29.507 -
29.508 - if (phys_addr)
29.509 - {
29.510 - *phys_addr = ph_addr;
29.511 - }
29.512 -
29.513 - return SP_ERROR_NONE;
29.514 -}
29.515 -
29.516 -int BaseContext::StringToLocal(cell_t local_addr, size_t chars, const char *source)
29.517 -{
29.518 - cell_t *dest;
29.519 - int i, len;
29.520 -
29.521 - if (((local_addr >= ctx->hp) && (local_addr < ctx->sp)) || (local_addr < 0) || ((ucell_t)local_addr >= ctx->mem_size))
29.522 - {
29.523 - return SP_ERROR_INVALID_ADDRESS;
29.524 - }
29.525 -
29.526 - len = strlen(source);
29.527 - dest = (cell_t *)(ctx->memory + local_addr);
29.528 -
29.529 - if ((size_t)len >= chars)
29.530 - {
29.531 - len = chars - 1;
29.532 - }
29.533 -
29.534 - for (i=0; i<len; i++)
29.535 - {
29.536 - dest[i] = (cell_t)source[i];
29.537 - }
29.538 - dest[len] = '\0';
29.539 -
29.540 - return SP_ERROR_NONE;
29.541 -}
29.542 -
29.543 -#define USHR(x) ((unsigned int)(x)>>1)
29.544 -
29.545 -int BaseContext::LookupFile(ucell_t addr, const char **filename)
29.546 -{
29.547 - int high, low, mid;
29.548 -
29.549 - high = ctx->plugin->debug.files_num;
29.550 - low = -1;
29.551 -
29.552 - while (high - low > 1)
29.553 - {
29.554 - mid = USHR(low + high);
29.555 - if (ctx->files[mid].addr <= addr)
29.556 - {
29.557 - low = mid;
29.558 - } else {
29.559 - high = mid;
29.560 - }
29.561 - }
29.562 -
29.563 - if (low == -1)
29.564 - {
29.565 - return SP_ERROR_NOT_FOUND;
29.566 - }
29.567 -
29.568 - *filename = ctx->files[low].name;
29.569 -
29.570 - return SP_ERROR_NONE;
29.571 -}
29.572 -
29.573 -int BaseContext::LookupFunction(ucell_t addr, const char **name)
29.574 -{
29.575 - uint32_t iter, max = ctx->plugin->debug.syms_num;
29.576 -
29.577 - for (iter=0; iter<max; iter++)
29.578 - {
29.579 - if ((ctx->symbols[iter].sym->ident == SP_SYM_FUNCTION)
29.580 - && (ctx->symbols[iter].codestart <= addr)
29.581 - && (ctx->symbols[iter].codeend > addr))
29.582 - {
29.583 - break;
29.584 - }
29.585 - }
29.586 -
29.587 - if (iter >= max)
29.588 - {
29.589 - return SP_ERROR_NOT_FOUND;
29.590 - }
29.591 -
29.592 - *name = ctx->symbols[iter].name;
29.593 -
29.594 - return SP_ERROR_NONE;
29.595 -}
29.596 -
29.597 -int BaseContext::LookupLine(ucell_t addr, uint32_t *line)
29.598 -{
29.599 - int high, low, mid;
29.600 -
29.601 - high = ctx->plugin->debug.lines_num;
29.602 - low = -1;
29.603 -
29.604 - while (high - low > 1)
29.605 - {
29.606 - mid = USHR(low + high);
29.607 - if (ctx->lines[mid].addr <= addr)
29.608 - {
29.609 - low = mid;
29.610 - } else {
29.611 - high = mid;
29.612 - }
29.613 - }
29.614 -
29.615 - if (low == -1)
29.616 - {
29.617 - return SP_ERROR_NOT_FOUND;
29.618 - }
29.619 -
29.620 - *line = ctx->lines[low].line;
29.621 -
29.622 - return SP_ERROR_NONE;
29.623 -}
30.1 --- a/sourcepawn/vm/sp_vm_basecontext.h Tue Nov 07 23:26:40 2006 +0000
30.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
30.3 @@ -1,53 +0,0 @@
30.4 -#ifndef _INCLUDE_SOURCEPAWN_BASECONTEXT_H_
30.5 -#define _INCLUDE_SOURCEPAWN_BASECONTEXT_H_
30.6 -
30.7 -#include "sp_vm_context.h"
30.8 -
30.9 -namespace SourcePawn
30.10 -{
30.11 - class BaseContext :
30.12 - public IPluginContext,
30.13 - public IPluginDebugInfo
30.14 - {
30.15 - public:
30.16 - BaseContext(sp_context_t *ctx);
30.17 - public: //IPluginContext
30.18 - IVirtualMachine *GetVirtualMachine();
30.19 - sp_context_t *GetContext();
30.20 - bool IsDebugging();
30.21 - int SetDebugBreak(SPVM_DEBUGBREAK newpfn, SPVM_DEBUGBREAK *oldpfn);
30.22 - IPluginDebugInfo *GetDebugInfo();
30.23 - virtual int HeapAlloc(unsigned int cells, cell_t *local_addr, cell_t **phys_addr);
30.24 - virtual int HeapPop(cell_t local_addr);
30.25 - virtual int HeapRelease(cell_t local_addr);
30.26 - virtual int FindNativeByName(const char *name, uint32_t *index);
30.27 - virtual int GetNativeByIndex(uint32_t index, sp_native_t **native);
30.28 - virtual uint32_t GetNativesNum();
30.29 - virtual int FindPublicByName(const char *name, uint32_t *index);
30.30 - virtual int GetPublicByIndex(uint32_t index, sp_public_t **publicptr);
30.31 - virtual uint32_t GetPublicsNum();
30.32 - virtual int GetPubvarByIndex(uint32_t index, sp_pubvar_t **pubvar);
30.33 - virtual int FindPubvarByName(const char *name, uint32_t *index);
30.34 - virtual int GetPubvarAddrs(uint32_t index, cell_t *local_addr, cell_t **phys_addr);
30.35 - virtual uint32_t GetPubVarsNum();
30.36 - virtual int LocalToPhysAddr(cell_t local_addr, cell_t **phys_addr);
30.37 - virtual int LocalToString(cell_t local_addr, char **addr);
30.38 - virtual int StringToLocal(cell_t local_addr, size_t chars, const char *source);
30.39 - virtual int PushCell(cell_t value);
30.40 - virtual int PushCellArray(cell_t *local_addr, cell_t **phys_addr, cell_t array[], unsigned int numcells);
30.41 - virtual int PushString(cell_t *local_addr, cell_t **phys_addr, const char *string);
30.42 - virtual int PushCellsFromArray(cell_t array[], unsigned int numcells);
30.43 - virtual int BindNatives(sp_nativeinfo_t *natives, unsigned int num, int overwrite);
30.44 - virtual int BindNative(sp_nativeinfo_t *native, uint32_t status);
30.45 - virtual int BindNativeToAny(SPVM_NATIVE_FUNC native);
30.46 - virtual int Execute(uint32_t public_func, cell_t *result);
30.47 - public: //IPluginDebugInfo
30.48 - virtual int LookupFile(ucell_t addr, const char **filename);
30.49 - virtual int LookupFunction(ucell_t addr, const char **name);
30.50 - virtual int LookupLine(ucell_t addr, uint32_t *line);
30.51 - private:
30.52 - sp_context_t *ctx;
30.53 - };
30.54 -};
30.55 -
30.56 -#endif //_INCLUDE_SOURCEPAWN_BASECONTEXT_H_
31.1 --- a/sourcepawn/vm/sp_vm_engine.cpp Tue Nov 07 23:26:40 2006 +0000
31.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
31.3 @@ -1,309 +0,0 @@
31.4 -#include <malloc.h>
31.5 -#include <string.h>
31.6 -#include "sp_file_headers.h"
31.7 -#include "sp_vm_types.h"
31.8 -#include "sp_vm_engine.h"
31.9 -#include "zlib/zlib.h"
31.10 -#include "sp_vm_basecontext.h"
31.11 -
31.12 -#if defined WIN32
31.13 - #define WIN32_LEAN_AND_MEAN
31.14 - #include <windows.h>
31.15 -#else if defined __GNUC__
31.16 - #include <sys/mman.h>
31.17 -#endif
31.18 -
31.19 -using namespace SourcePawn;
31.20 -
31.21 -void *SourcePawnEngine::ExecAlloc(size_t size)
31.22 -{
31.23 -#if defined WIN32
31.24 - return VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
31.25 -#else if defined __GNUC__
31.26 - void *base = memalign(sysconf(_SC_PAGESIZE), size);
31.27 - if (mprotect(base, size, PROT_READ|PROT_WRITE|PROT_EXEC) != 0)
31.28 - {
31.29 - free(base);
31.30 - return NULL;
31.31 - }
31.32 - return base;
31.33 -#endif
31.34 -}
31.35 -
31.36 -void SourcePawnEngine::ExecFree(void *address)
31.37 -{
31.38 -#if defined WIN32
31.39 - VirtualFree(address, 0, MEM_RELEASE);
31.40 -#else if defined __GNUC__
31.41 - free(address);
31.42 -#endif
31.43 -}
31.44 -
31.45 -void *SourcePawnEngine::BaseAlloc(size_t size)
31.46 -{
31.47 - return malloc(size);
31.48 -}
31.49 -
31.50 -void SourcePawnEngine::BaseFree(void *memory)
31.51 -{
31.52 - free(memory);
31.53 -}
31.54 -
31.55 -IPluginContext *SourcePawnEngine::CreateBaseContext(sp_context_t *ctx)
31.56 -{
31.57 - return new BaseContext(ctx);
31.58 -}
31.59 -
31.60 -void SourcePawnEngine::FreeBaseContext(IPluginContext *ctx)
31.61 -{
31.62 - sp_context_t *_ctx = ctx->GetContext();
31.63 - IVirtualMachine *vm = ctx->GetVirtualMachine();
31.64 -
31.65 - vm->FreeContext(_ctx);
31.66 -
31.67 - delete ctx;
31.68 -}
31.69 -
31.70 -sp_plugin_t *_ReadPlugin(sp_file_hdr_t *hdr, uint8_t *base, sp_plugin_t *plugin, int *err)
31.71 -{
31.72 - char *nameptr;
31.73 - uint8_t sectnum = 0;
31.74 - sp_file_section_t *secptr = (sp_file_section_t *)(base + sizeof(sp_file_hdr_t));
31.75 -
31.76 - memset(plugin, 0, sizeof(sp_plugin_t));
31.77 -
31.78 - plugin->base = base;
31.79 -
31.80 - while (sectnum < hdr->sections)
31.81 - {
31.82 - nameptr = (char *)(base + hdr->stringtab + secptr->nameoffs);
31.83 -
31.84 - if (!(plugin->pcode) && !strcmp(nameptr, ".code"))
31.85 - {
31.86 - sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
31.87 - plugin->pcode = base + secptr->dataoffs + cod->code;
31.88 - plugin->pcode_size = cod->codesize;
31.89 - plugin->flags = cod->flags;
31.90 - }
31.91 - else if (!(plugin->data) && !strcmp(nameptr, ".data"))
31.92 - {
31.93 - sp_file_data_t *dat = (sp_file_data_t *)(base + secptr->dataoffs);
31.94 - plugin->data = base + secptr->dataoffs + dat->data;
31.95 - plugin->data_size = dat->datasize;
31.96 - plugin->memory = dat->memsize;
31.97 - }
31.98 - else if (!(plugin->info.publics) && !strcmp(nameptr, ".publics"))
31.99 - {
31.100 - plugin->info.publics_num = secptr->size / sizeof(sp_file_publics_t);
31.101 - plugin->info.publics = (sp_file_publics_t *)(base + secptr->dataoffs);
31.102 - }
31.103 - else if (!(plugin->info.pubvars) && !strcmp(nameptr, ".pubvars"))
31.104 - {
31.105 - plugin->info.pubvars_num = secptr->size / sizeof(sp_file_pubvars_t);
31.106 - plugin->info.pubvars = (sp_file_pubvars_t *)(base + secptr->dataoffs);
31.107 - }
31.108 - else if (!(plugin->info.natives) && !strcmp(nameptr, ".natives"))
31.109 - {
31.110 - plugin->info.natives_num = secptr->size / sizeof(sp_file_natives_t);
31.111 - plugin->info.natives = (sp_file_natives_t *)(base + secptr->dataoffs);
31.112 - }
31.113 - else if (!(plugin->info.lib) && !strcmp(nameptr, ".libraries"))
31.114 - {
31.115 - plugin->info.libraries_num = secptr->size / sizeof(sp_file_libraries_t);
31.116 - plugin->info.lib = (sp_file_libraries_t *)(base + secptr->dataoffs);
31.117 - }
31.118 - else if (!(plugin->info.stringbase) && !strcmp(nameptr, ".names"))
31.119 - {
31.120 - plugin->info.stringbase = (const char *)(base + secptr->dataoffs);
31.121 - }
31.122 - else if (!(plugin->debug.files) && !strcmp(nameptr, ".dbg.files"))
31.123 - {
31.124 - plugin->debug.files = (sp_fdbg_file_t *)(base + secptr->dataoffs);
31.125 - }
31.126 - else if (!(plugin->debug.lines) && !strcmp(nameptr, ".dbg.lines"))
31.127 - {
31.128 - plugin->debug.lines = (sp_fdbg_line_t *)(base + secptr->dataoffs);
31.129 - }
31.130 - else if (!(plugin->debug.symbols) && !strcmp(nameptr, ".dbg.symbols"))
31.131 - {
31.132 - plugin->debug.symbols = (sp_fdbg_symbol_t *)(base + secptr->dataoffs);
31.133 - }
31.134 - else if (!(plugin->debug.lines_num) && !strcmp(nameptr, ".dbg.info"))
31.135 - {
31.136 - sp_fdbg_info_t *inf = (sp_fdbg_info_t *)(base + secptr->dataoffs);
31.137 - plugin->debug.files_num = inf->num_files;
31.138 - plugin->debug.lines_num = inf->num_lines;
31.139 - plugin->debug.syms_num = inf->num_syms;
31.140 - }
31.141 - else if (!(plugin->debug.stringbase) && !strcmp(nameptr, ".dbg.strings"))
31.142 - {
31.143 - plugin->debug.stringbase = (const char *)(base + secptr->dataoffs);
31.144 - }
31.145 -
31.146 - secptr++;
31.147 - sectnum++;
31.148 - }
31.149 -
31.150 - if (!(plugin->pcode) || !(plugin->data) || !(plugin->info.stringbase))
31.151 - {
31.152 - goto return_error;
31.153 - }
31.154 -
31.155 - if ((plugin->flags & SP_FLAG_DEBUG) && (!(plugin->debug.files) || !(plugin->debug.lines) || !(plugin->debug.symbols)))
31.156 - {
31.157 - goto return_error;
31.158 - }
31.159 -
31.160 - if (err)
31.161 - {
31.162 - *err = SP_ERROR_NONE;
31.163 - }
31.164 -
31.165 - return plugin;
31.166 -
31.167 -return_error:
31.168 - if (err)
31.169 - {
31.170 - *err = SP_ERROR_FILE_FORMAT;
31.171 - }
31.172 -
31.173 - return NULL;
31.174 -}
31.175 -
31.176 -sp_plugin_t *SourcePawnEngine::LoadFromFilePointer(FILE *fp, int *err)
31.177 -{
31.178 - sp_file_hdr_t hdr;
31.179 - sp_plugin_t *plugin;
31.180 - uint8_t *base;
31.181 - int z_result;
31.182 - int error;
31.183 -
31.184 - if (!fp)
31.185 - {
31.186 - error = SP_ERROR_NOT_FOUND;
31.187 - goto return_error;
31.188 - }
31.189 -
31.190 - /* Rewind for safety */
31.191 - rewind(fp);
31.192 - fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
31.193 -
31.194 - if (hdr.magic != SPFILE_MAGIC)
31.195 - {
31.196 - error = SP_ERROR_FILE_FORMAT;
31.197 - goto return_error;
31.198 - }
31.199 -
31.200 - switch (hdr.compression)
31.201 - {
31.202 - case SPFILE_COMPRESSION_GZ:
31.203 - {
31.204 - uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
31.205 - uint32_t compsize = hdr.disksize - hdr.dataoffs;
31.206 - uint32_t sectsize = hdr.dataoffs - sizeof(sp_file_hdr_t);
31.207 - uLongf destlen = uncompsize;
31.208 -
31.209 - char *tempbuf = (char *)malloc(compsize);
31.210 - void *uncompdata = malloc(uncompsize);
31.211 - void *sectheader = malloc(sectsize);
31.212 -
31.213 - fread(sectheader, sectsize, 1, fp);
31.214 - fread(tempbuf, compsize, 1, fp);
31.215 -
31.216 - z_result = uncompress((Bytef *)uncompdata, &destlen, (Bytef *)tempbuf, compsize);
31.217 - free(tempbuf);
31.218 - if (z_result != Z_OK)
31.219 - {
31.220 - free(sectheader);
31.221 - free(uncompdata);
31.222 - error = SP_ERROR_DECOMPRESSOR;
31.223 - goto return_error;
31.224 - }
31.225 -
31.226 - base = (uint8_t *)malloc(hdr.imagesize);
31.227 - memcpy(base, &hdr, sizeof(sp_file_hdr_t));
31.228 - memcpy(base + sizeof(sp_file_hdr_t), sectheader, sectsize);
31.229 - free(sectheader);
31.230 - memcpy(base + hdr.dataoffs, uncompdata, uncompsize);
31.231 - free(uncompdata);
31.232 - break;
31.233 - }
31.234 - case SPFILE_COMPRESSION_NONE:
31.235 - {
31.236 - base = (uint8_t *)malloc(hdr.imagesize);
31.237 - rewind(fp);
31.238 - fread(base, hdr.imagesize, 1, fp);
31.239 - break;
31.240 - }
31.241 - default:
31.242 - {
31.243 - error = SP_ERROR_DECOMPRESSOR;
31.244 - goto return_error;
31.245 - }
31.246 - }
31.247 -
31.248 - plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
31.249 - if (!_ReadPlugin(&hdr, base, plugin, err))
31.250 - {
31.251 - free(plugin);
31.252 - free(base);
31.253 - return NULL;
31.254 - }
31.255 -
31.256 - plugin->allocflags = 0;
31.257 -
31.258 - return plugin;
31.259 -
31.260 -return_error:
31.261 - if (err)
31.262 - {
31.263 - *err = error;
31.264 - }
31.265 - return NULL;
31.266 -}
31.267 -
31.268 -sp_plugin_t *SourcePawnEngine::LoadFromMemory(void *base, sp_plugin_t *plugin, int *err)
31.269 -{
31.270 - sp_file_hdr_t hdr;
31.271 - uint8_t noptr = 0;
31.272 -
31.273 - memcpy(&hdr, base, sizeof(sp_file_hdr_t));
31.274 -
31.275 - if (!plugin)
31.276 - {
31.277 - plugin = (sp_plugin_t *)malloc(sizeof(sp_plugin_t));
31.278 - noptr = 1;
31.279 - }
31.280 -
31.281 - if (!_ReadPlugin(&hdr, (uint8_t *)base, plugin, err))
31.282 - {
31.283 - if (noptr)
31.284 - {
31.285 - free(plugin);
31.286 - }
31.287 - return NULL;
31.288 - }
31.289 -
31.290 - if (!noptr)
31.291 - {
31.292 - plugin->allocflags |= SP_FA_SELF_EXTERNAL;
31.293 - }
31.294 - plugin->allocflags |= SP_FA_BASE_EXTERNAL;
31.295 -
31.296 - return plugin;
31.297 -}
31.298 -
31.299 -int SourcePawnEngine::FreeFromMemory(sp_plugin_t *plugin)
31.300 -{
31.301 - if (!(plugin->allocflags & SP_FA_BASE_EXTERNAL))
31.302 - {
31.303 - free(plugin->base);
31.304 - plugin->base = NULL;
31.305 - }
31.306 - if (!(plugin->allocflags & SP_FA_SELF_EXTERNAL))
31.307 - {
31.308 - free(plugin);
31.309 - }
31.310 -
31.311 - return SP_ERROR_NONE;
31.312 -}
32.1 --- a/sourcepawn/vm/sp_vm_engine.h Tue Nov 07 23:26:40 2006 +0000
32.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
32.3 @@ -1,88 +0,0 @@
32.4 -#ifndef _INCLUDE_SOURCEPAWN_VM_ENGINE_H_
32.5 -#define _INCLUDE_SOURCEPAWN_VM_ENGINE_H_
32.6 -
32.7 -#include "sp_vm_api.h"
32.8 -
32.9 -namespace SourcePawn
32.10 -{
32.11 - class SourcePawnEngine : public ISourcePawnEngine
32.12 - {
32.13 - public:
32.14 - /**
32.15 - * Loads a named file from a file pointer.
32.16 - * Using this means base memory will be allocated by the VM.
32.17 - * Note: The file handle position may be undefined on entry, and is
32.18 - * always undefined on conclusion.
32.19 - *
32.20 - * @param fp File pointer. May be at any offset. Not closed on return.
32.21 - * @param err Optional error code pointer.
32.22 - * @return A new plugin structure.
32.23 - */
32.24 - sp_plugin_t *LoadFromFilePointer(FILE *fp, int *err);
32.25 -
32.26 - /**
32.27 - * Loads a file from a base memory address.
32.28 - *
32.29 - * @param base Base address of the plugin's memory region.
32.30 - * @param plugin If NULL, a new plugin pointer is returned.
32.31 - * Otherwise, the passed pointer is used.
32.32 - * @param err Optional error code pointer.
32.33 - * @return The resulting plugin pointer.
32.34 - */
32.35 - sp_plugin_t *LoadFromMemory(void *base, sp_plugin_t *plugin, int *err);
32.36 -
32.37 - /**
32.38 - * Frees all of the memory associated with a plugin file.
32.39 - * If allocated using SP_LoadFromMemory, the base and plugin pointer
32.40 - * itself are not freed (so this may end up doing nothing).
32.41 - */
32.42 - int FreeFromMemory(sp_plugin_t *plugin);
32.43 -
32.44 - /**
32.45 - * Creates a new IContext from a context handle.
32.46 - *
32.47 - * @param ctx Context to use as a basis for the IPluginContext.
32.48 - * @return New IPluginContext handle.
32.49 - */
32.50 - IPluginContext *CreateBaseContext(sp_context_t *ctx);
32.51 -
32.52 - /**
32.53 - * Frees a context.
32.54 - *
32.55 - * @param ctx Context pointer to free.
32.56 - */
32.57 - void FreeBaseContext(IPluginContext *ctx);
32.58 -
32.59 - /**
32.60 - * Allocates memory.
32.61 - *
32.62 - * @param size Size of memory to allocate.
32.63 - * @return Pointer to memory, NULL if allocation failed.
32.64 - */
32.65 - void *BaseAlloc(size_t size);
32.66 -
32.67 - /**
32.68 - * Frees memory allocated with BaseAlloc.
32.69 - *
32.70 - * @param memory Memory address to free.
32.71 - */
32.72 - void BaseFree(void *memory);
32.73 -
32.74 - /**
32.75 - * Allocates executable memory.
32.76 - *
32.77 - * @param size Size of memory to allocate.
32.78 - * @return Pointer to memory, NULL if allocation failed.
32.79 - */
32.80 - void *ExecAlloc(size_t size);
32.81 -
32.82 - /**
32.83 - * Frees executable memory.
32.84 - *
32.85 - * @param address Address to free.
32.86 - */
32.87 - void ExecFree(void *address);
32.88 - };
32.89 -};
32.90 -
32.91 -#endif //_INCLUDE_SOURCEPAWN_VM_ENGINE_H_
33.1 --- a/sourcepawn/vm/zlib/adler32.c Tue Nov 07 23:26:40 2006 +0000
33.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
33.3 @@ -1,149 +0,0 @@
33.4 -/* adler32.c -- compute the Adler-32 checksum of a data stream
33.5 - * Copyright (C) 1995-2004 Mark Adler
33.6 - * For conditions of distribution and use, see copyright notice in zlib.h
33.7 - */
33.8 -
33.9 -/* @(#) $Id$ */
33.10 -
33.11 -#define ZLIB_INTERNAL
33.12 -#include "zlib.h"
33.13 -
33.14 -#define BASE 65521UL /* largest prime smaller than 65536 */
33.15 -#define NMAX 5552
33.16 -/* NMAX is the largest n such that 255n(n+1)/2 + (n+1)(BASE-1) <= 2^32-1 */
33.17 -
33.18 -#define DO1(buf,i) {adler += (buf)[i]; sum2 += adler;}
33.19 -#define DO2(buf,i) DO1(buf,i); DO1(buf,i+1);
33.20 -#define DO4(buf,i) DO2(buf,i); DO2(buf,i+2);
33.21 -#define DO8(buf,i) DO4(buf,i); DO4(buf,i+4);
33.22 -#define DO16(buf) DO8(buf,0); DO8(buf,8);
33.23 -
33.24 -/* use NO_DIVIDE if your processor does not do division in hardware */
33.25 -#ifdef NO_DIVIDE
33.26 -# define MOD(a) \
33.27 - do { \
33.28 - if (a >= (BASE << 16)) a -= (BASE << 16); \
33.29 - if (a >= (BASE << 15)) a -= (BASE << 15); \
33.30 - if (a >= (BASE << 14)) a -= (BASE << 14); \
33.31 - if (a >= (BASE << 13)) a -= (BASE << 13); \
33.32 - if (a >= (BASE << 12)) a -= (BASE << 12); \
33.33 - if (a >= (BASE << 11)) a -= (BASE << 11); \
33.34 - if (a >= (BASE << 10)) a -= (BASE << 10); \
33.35 - if (a >= (BASE << 9)) a -= (BASE << 9); \
33.36 - if (a >= (BASE << 8)) a -= (BASE << 8); \
33.37 - if (a >= (BASE << 7)) a -= (BASE << 7); \
33.38 - if (a >= (BASE << 6)) a -= (BASE << 6); \
33.39 - if (a >= (BASE << 5)) a -= (BASE << 5); \
33.40 - if (a >= (BASE << 4)) a -= (BASE << 4); \
33.41 - if (a >= (BASE << 3)) a -= (BASE << 3); \
33.42 - if (a >= (BASE << 2)) a -= (BASE << 2); \
33.43 - if (a >= (BASE << 1)) a -= (BASE << 1); \
33.44 - if (a >= BASE) a -= BASE; \
33.45 - } while (0)
33.46 -# define MOD4(a) \
33.47 - do { \
33.48 - if (a >= (BASE << 4)) a -= (BASE << 4); \
33.49 - if (a >= (BASE << 3)) a -= (BASE << 3); \
33.50 - if (a >= (BASE << 2)) a -= (BASE << 2); \
33.51 - if (a >= (BASE << 1)) a -= (BASE << 1); \
33.52 - if (a >= BASE) a -= BASE; \
33.53 - } while (0)
33.54 -#else
33.55 -# define MOD(a) a %= BASE
33.56 -# define MOD4(a) a %= BASE
33.57 -#endif
33.58 -
33.59 -/* ========================================================================= */
33.60 -uLong ZEXPORT adler32(adler, buf, len)
33.61 - uLong adler;
33.62 - const Bytef *buf;
33.63 - uInt len;
33.64 -{
33.65 - unsigned long sum2;
33.66 - unsigned n;
33.67 -
33.68 - /* split Adler-32 into component sums */
33.69 - sum2 = (adler >> 16) & 0xffff;
33.70 - adler &= 0xffff;
33.71 -
33.72 - /* in case user likes doing a byte at a time, keep it fast */
33.73 - if (len == 1) {
33.74 - adler += buf[0];
33.75 - if (adler >= BASE)
33.76 - adler -= BASE;
33.77 - sum2 += adler;
33.78 - if (sum2 >= BASE)
33.79 - sum2 -= BASE;
33.80 - return adler | (sum2 << 16);
33.81 - }
33.82 -
33.83 - /* initial Adler-32 value (deferred check for len == 1 speed) */
33.84 - if (buf == Z_NULL)
33.85 - return 1L;
33.86 -
33.87 - /* in case short lengths are provided, keep it somewhat fast */
33.88 - if (len < 16) {
33.89 - while (len--) {
33.90 - adler += *buf++;
33.91 - sum2 += adler;
33.92 - }
33.93 - if (adler >= BASE)
33.94 - adler -= BASE;
33.95 - MOD4(sum2); /* only added so many BASE's */
33.96 - return adler | (sum2 << 16);
33.97 - }
33.98 -
33.99 - /* do length NMAX blocks -- requires just one modulo operation */
33.100 - while (len >= NMAX) {
33.101 - len -= NMAX;
33.102 - n = NMAX / 16; /* NMAX is divisible by 16 */
33.103 - do {
33.104 - DO16(buf); /* 16 sums unrolled */
33.105 - buf += 16;
33.106 - } while (--n);
33.107 - MOD(adler);
33.108 - MOD(sum2);
33.109 - }
33.110 -
33.111 - /* do remaining bytes (less than NMAX, still just one modulo) */
33.112 - if (len) { /* avoid modulos if none remaining */
33.113 - while (len >= 16) {
33.114 - len -= 16;
33.115 - DO16(buf);
33.116 - buf += 16;
33.117 - }
33.118 - while (len--) {
33.119 - adler += *buf++;
33.120 - sum2 += adler;
33.121 - }
33.122 - MOD(adler);
33.123 - MOD(sum2);
33.124 - }
33.125 -
33.126 - /* return recombined sums */
33.127 - return adler | (sum2 << 16);
33.128 -}
33.129 -
33.130 -/* ========================================================================= */
33.131 -uLong ZEXPORT adler32_combine(adler1, adler2, len2)
33.132 - uLong adler1;
33.133 - uLong adler2;
33.134 - z_off_t len2;
33.135 -{
33.136 - unsigned long sum1;
33.137 - unsigned long sum2;
33.138 - unsigned rem;
33.139 -
33.140 - /* the derivation of this formula is left as an exercise for the reader */
33.141 - rem = (unsigned)(len2 % BASE);
33.142 - sum1 = adler1 & 0xffff;
33.143 - sum2 = rem * sum1;
33.144 - MOD(sum2);
33.145 - sum1 += (adler2 & 0xffff) + BASE - 1;
33.146 - sum2 += ((adler1 >> 16) & 0xffff) + ((adler2 >> 16) & 0xffff) + BASE - rem;
33.147 - if (sum1 > BASE) sum1 -= BASE;
33.148 - if (sum1 > BASE) sum1 -= BASE;
33.149 - if (sum2 > (BASE << 1)) sum2 -= (BASE << 1);
33.150 - if (sum2 > BASE) sum2 -= BASE;
33.151 - return sum1 | (sum2 << 16);
33.152 -}
34.1 --- a/sourcepawn/vm/zlib/compress.c Tue Nov 07 23:26:40 2006 +0000
34.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
34.3 @@ -1,79 +0,0 @@
34.4 -/* compress.c -- compress a memory buffer
34.5 - * Copyright (C) 1995-2003 Jean-loup Gailly.
34.6 - * For conditions of distribution and use, see copyright notice in zlib.h
34.7 - */
34.8 -
34.9 -/* @(#) $Id$ */
34.10 -
34.11 -#define ZLIB_INTERNAL
34.12 -#include "zlib.h"
34.13 -
34.14 -/* ===========================================================================
34.15 - Compresses the source buffer into the destination buffer. The level
34.16 - parameter has the same meaning as in deflateInit. sourceLen is the byte
34.17 - length of the source buffer. Upon entry, destLen is the total size of the
34.18 - destination buffer, which must be at least 0.1% larger than sourceLen plus
34.19 - 12 bytes. Upon exit, destLen is the actual size of the compressed buffer.
34.20 -
34.21 - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
34.22 - memory, Z_BUF_ERROR if there was not enough room in the output buffer,
34.23 - Z_STREAM_ERROR if the level parameter is invalid.
34.24 -*/
34.25 -int ZEXPORT compress2 (dest, destLen, source, sourceLen, level)
34.26 - Bytef *dest;
34.27 - uLongf *destLen;
34.28 - const Bytef *source;
34.29 - uLong sourceLen;
34.30 - int level;
34.31 -{
34.32 - z_stream stream;
34.33 - int err;
34.34 -
34.35 - stream.next_in = (Bytef*)source;
34.36 - stream.avail_in = (uInt)sourceLen;
34.37 -#ifdef MAXSEG_64K
34.38 - /* Check for source > 64K on 16-bit machine: */
34.39 - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
34.40 -#endif
34.41 - stream.next_out = dest;
34.42 - stream.avail_out = (uInt)*destLen;
34.43 - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
34.44 -
34.45 - stream.zalloc = (alloc_func)0;
34.46 - stream.zfree = (free_func)0;
34.47 - stream.opaque = (voidpf)0;
34.48 -
34.49 - err = deflateInit(&stream, level);
34.50 - if (err != Z_OK) return err;
34.51 -
34.52 - err = deflate(&stream, Z_FINISH);
34.53 - if (err != Z_STREAM_END) {
34.54 - deflateEnd(&stream);
34.55 - return err == Z_OK ? Z_BUF_ERROR : err;
34.56 - }
34.57 - *destLen = stream.total_out;
34.58 -
34.59 - err = deflateEnd(&stream);
34.60 - return err;
34.61 -}
34.62 -
34.63 -/* ===========================================================================
34.64 - */
34.65 -int ZEXPORT compress (dest, destLen, source, sourceLen)
34.66 - Bytef *dest;
34.67 - uLongf *destLen;
34.68 - const Bytef *source;
34.69 - uLong sourceLen;
34.70 -{
34.71 - return compress2(dest, destLen, source, sourceLen, Z_DEFAULT_COMPRESSION);
34.72 -}
34.73 -
34.74 -/* ===========================================================================
34.75 - If the default memLevel or windowBits for deflateInit() is changed, then
34.76 - this function needs to be updated.
34.77 - */
34.78 -uLong ZEXPORT compressBound (sourceLen)
34.79 - uLong sourceLen;
34.80 -{
34.81 - return sourceLen + (sourceLen >> 12) + (sourceLen >> 14) + 11;
34.82 -}
35.1 --- a/sourcepawn/vm/zlib/crc32.c Tue Nov 07 23:26:40 2006 +0000
35.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
35.3 @@ -1,423 +0,0 @@
35.4 -/* crc32.c -- compute the CRC-32 of a data stream
35.5 - * Copyright (C) 1995-2005 Mark Adler
35.6 - * For conditions of distribution and use, see copyright notice in zlib.h
35.7 - *
35.8 - * Thanks to Rodney Brown <[email protected]> for his contribution of faster
35.9 - * CRC methods: exclusive-oring 32 bits of data at a time, and pre-computing
35.10 - * tables for updating the shift register in one step with three exclusive-ors
35.11 - * instead of four steps with four exclusive-ors. This results in about a
35.12 - * factor of two increase in speed on a Power PC G4 (PPC7455) using gcc -O3.
35.13 - */
35.14 -
35.15 -/* @(#) $Id$ */
35.16 -
35.17 -/*
35.18 - Note on the use of DYNAMIC_CRC_TABLE: there is no mutex or semaphore
35.19 - protection on the static variables used to control the first-use generation
35.20 - of the crc tables. Therefore, if you #define DYNAMIC_CRC_TABLE, you should
35.21 - first call get_crc_table() to initialize the tables before allowing more than
35.22 - one thread to use crc32().
35.23 - */
35.24 -
35.25 -#ifdef MAKECRCH
35.26 -# include <stdio.h>
35.27 -# ifndef DYNAMIC_CRC_TABLE
35.28 -# define DYNAMIC_CRC_TABLE
35.29 -# endif /* !DYNAMIC_CRC_TABLE */
35.30 -#endif /* MAKECRCH */
35.31 -
35.32 -#include "zutil.h" /* for STDC and FAR definitions */
35.33 -
35.34 -#define local static
35.35 -
35.36 -/* Find a four-byte integer type for crc32_little() and crc32_big(). */
35.37 -#ifndef NOBYFOUR
35.38 -# ifdef STDC /* need ANSI C limits.h to determine sizes */
35.39 -# include <limits.h>
35.40 -# define BYFOUR
35.41 -# if (UINT_MAX == 0xffffffffUL)
35.42 - typedef unsigned int u4;
35.43 -# else
35.44 -# if (ULONG_MAX == 0xffffffffUL)
35.45 - typedef unsigned long u4;
35.46 -# else
35.47 -# if (USHRT_MAX == 0xffffffffUL)
35.48 - typedef unsigned short u4;
35.49 -# else
35.50 -# undef BYFOUR /* can't find a four-byte integer type! */
35.51 -# endif
35.52 -# endif
35.53 -# endif
35.54 -# endif /* STDC */
35.55 -#endif /* !NOBYFOUR */
35.56 -
35.57 -/* Definitions for doing the crc four data bytes at a time. */
35.58 -#ifdef BYFOUR
35.59 -# define REV(w) (((w)>>24)+(((w)>>8)&0xff00)+ \
35.60 - (((w)&0xff00)<<8)+(((w)&0xff)<<24))
35.61 - local unsigned long crc32_little OF((unsigned long,
35.62 - const unsigned char FAR *, unsigned));
35.63 - local unsigned long crc32_big OF((unsigned long,
35.64 - const unsigned char FAR *, unsigned));
35.65 -# define TBLS 8
35.66 -#else
35.67 -# define TBLS 1
35.68 -#endif /* BYFOUR */
35.69 -
35.70 -/* Local functions for crc concatenation */
35.71 -local unsigned long gf2_matrix_times OF((unsigned long *mat,
35.72 - unsigned long vec));
35.73 -local void gf2_matrix_square OF((unsigned long *square, unsigned long *mat));
35.74 -
35.75 -#ifdef DYNAMIC_CRC_TABLE
35.76 -
35.77 -local volatile int crc_table_empty = 1;
35.78 -local unsigned long FAR crc_table[TBLS][256];
35.79 -local void make_crc_table OF((void));
35.80 -#ifdef MAKECRCH
35.81 - local void write_table OF((FILE *, const unsigned long FAR *));
35.82 -#endif /* MAKECRCH */
35.83 -/*
35.84 - Generate tables for a byte-wise 32-bit CRC calculation on the polynomial:
35.85 - x^32+x^26+x^23+x^22+x^16+x^12+x^11+x^10+x^8+x^7+x^5+x^4+x^2+x+1.
35.86 -
35.87 - Polynomials over GF(2) are represented in binary, one bit per coefficient,
35.88 - with the lowest powers in the most significant bit. Then adding polynomials
35.89 - is just exclusive-or, and multiplying a polynomial by x is a right shift by
35.90 - one. If we call the above polynomial p, and represent a byte as the
35.91 - polynomial q, also with the lowest power in the most significant bit (so the
35.92 - byte 0xb1 is the polynomial x^7+x^3+x+1), then the CRC is (q*x^32) mod p,
35.93 - where a mod b means the remainder after dividing a by b.
35.94 -
35.95 - This calculation is done using the shift-register method of multiplying and
35.96 - taking the remainder. The register is initialized to zero, and for each
35.97 - incoming bit, x^32 is added mod p to the register if the bit is a one (where
35.98 - x^32 mod p is p+x^32 = x^26+...+1), and the register is multiplied mod p by
35.99 - x (which is shifting right by one and adding x^32 mod p if the bit shifted
35.100 - out is a one). We start with the highest power (least significant bit) of
35.101 - q and repeat for all eight bits of q.
35.102 -
35.103 - The first table is simply the CRC of all possible eight bit values. This is
35.104 - all the information needed to generate CRCs on data a byte at a time for all
35.105 - combinations of CRC register values and incoming bytes. The remaining tables
35.106 - allow for word-at-a-time CRC calculation for both big-endian and little-
35.107 - endian machines, where a word is four bytes.
35.108 -*/
35.109 -local void make_crc_table()
35.110 -{
35.111 - unsigned long c;
35.112 - int n, k;
35.113 - unsigned long poly; /* polynomial exclusive-or pattern */
35.114 - /* terms of polynomial defining this crc (except x^32): */
35.115 - static volatile int first = 1; /* flag to limit concurrent making */
35.116 - static const unsigned char p[] = {0,1,2,4,5,7,8,10,11,12,16,22,23,26};
35.117 -
35.118 - /* See if another task is already doing this (not thread-safe, but better
35.119 - than nothing -- significantly reduces duration of vulnerability in
35.120 - case the advice about DYNAMIC_CRC_TABLE is ignored) */
35.121 - if (first) {
35.122 - first = 0;
35.123 -
35.124 - /* make exclusive-or pattern from polynomial (0xedb88320UL) */
35.125 - poly = 0UL;
35.126 - for (n = 0; n < sizeof(p)/sizeof(unsigned char); n++)
35.127 - poly |= 1UL << (31 - p[n]);
35.128 -
35.129 - /* generate a crc for every 8-bit value */
35.130 - for (n = 0; n < 256; n++) {
35.131 - c = (unsigned long)n;
35.132 - for (k = 0; k < 8; k++)
35.133 - c = c & 1 ? poly ^ (c >> 1) : c >> 1;
35.134 - crc_table[0][n] = c;
35.135 - }
35.136 -
35.137 -#ifdef BYFOUR
35.138 - /* generate crc for each value followed by one, two, and three zeros,
35.139 - and then the byte reversal of those as well as the first table */
35.140 - for (n = 0; n < 256; n++) {
35.141 - c = crc_table[0][n];
35.142 - crc_table[4][n] = REV(c);
35.143 - for (k = 1; k < 4; k++) {
35.144 - c = crc_table[0][c & 0xff] ^ (c >> 8);
35.145 - crc_table[k][n] = c;
35.146 - crc_table[k + 4][n] = REV(c);
35.147 - }
35.148 - }
35.149 -#endif /* BYFOUR */
35.150 -
35.151 - crc_table_empty = 0;
35.152 - }
35.153 - else { /* not first */
35.154 - /* wait for the other guy to finish (not efficient, but rare) */
35.155 - while (crc_table_empty)
35.156 - ;
35.157 - }
35.158 -
35.159 -#ifdef MAKECRCH
35.160 - /* write out CRC tables to crc32.h */
35.161 - {
35.162 - FILE *out;
35.163 -
35.164 - out = fopen("crc32.h", "w");
35.165 - if (out == NULL) return;
35.166 - fprintf(out, "/* crc32.h -- tables for rapid CRC calculation\n");
35.167 - fprintf(out, " * Generated automatically by crc32.c\n */\n\n");
35.168 - fprintf(out, "local const unsigned long FAR ");
35.169 - fprintf(out, "crc_table[TBLS][256] =\n{\n {\n");
35.170 - write_table(out, crc_table[0]);
35.171 -# ifdef BYFOUR
35.172 - fprintf(out, "#ifdef BYFOUR\n");
35.173 - for (k = 1; k < 8; k++) {
35.174 - fprintf(out, " },\n {\n");
35.175 - write_table(out, crc_table[k]);
35.176 - }
35.177 - fprintf(out, "#endif\n");
35.178 -# endif /* BYFOUR */
35.179 - fprintf(out, " }\n};\n");
35.180 - fclose(out);
35.181 - }
35.182 -#endif /* MAKECRCH */
35.183 -}
35.184 -
35.185 -#ifdef MAKECRCH
35.186 -local void write_table(out, table)
35.187 - FILE *out;
35.188 - const unsigned long FAR *table;
35.189 -{
35.190 - int n;
35.191 -
35.192 - for (n = 0; n < 256; n++)
35.193 - fprintf(out, "%s0x%08lxUL%s", n % 5 ? "" : " ", table[n],
35.194 - n == 255 ? "\n" : (n % 5 == 4 ? ",\n" : ", "));
35.195 -}
35.196 -#endif /* MAKECRCH */
35.197 -
35.198 -#else /* !DYNAMIC_CRC_TABLE */
35.199 -/* ========================================================================
35.200 - * Tables of CRC-32s of all single-byte values, made by make_crc_table().
35.201 - */
35.202 -#include "crc32.h"
35.203 -#endif /* DYNAMIC_CRC_TABLE */
35.204 -
35.205 -/* =========================================================================
35.206 - * This function can be used by asm versions of crc32()
35.207 - */
35.208 -const unsigned long FAR * ZEXPORT get_crc_table()
35.209 -{
35.210 -#ifdef DYNAMIC_CRC_TABLE
35.211 - if (crc_table_empty)
35.212 - make_crc_table();
35.213 -#endif /* DYNAMIC_CRC_TABLE */
35.214 - return (const unsigned long FAR *)crc_table;
35.215 -}
35.216 -
35.217 -/* ========================================================================= */
35.218 -#define DO1 crc = crc_table[0][((int)crc ^ (*buf++)) & 0xff] ^ (crc >> 8)
35.219 -#define DO8 DO1; DO1; DO1; DO1; DO1; DO1; DO1; DO1
35.220 -
35.221 -/* ========================================================================= */
35.222 -unsigned long ZEXPORT crc32(crc, buf, len)
35.223 - unsigned long crc;
35.224 - const unsigned char FAR *buf;
35.225 - unsigned len;
35.226 -{
35.227 - if (buf == Z_NULL) return 0UL;
35.228 -
35.229 -#ifdef DYNAMIC_CRC_TABLE
35.230 - if (crc_table_empty)
35.231 - make_crc_table();
35.232 -#endif /* DYNAMIC_CRC_TABLE */
35.233 -
35.234 -#ifdef BYFOUR
35.235 - if (sizeof(void *) == sizeof(ptrdiff_t)) {
35.236 - u4 endian;
35.237 -
35.238 - endian = 1;
35.239 - if (*((unsigned char *)(&endian)))
35.240 - return crc32_little(crc, buf, len);
35.241 - else
35.242 - return crc32_big(crc, buf, len);
35.243 - }
35.244 -#endif /* BYFOUR */
35.245 - crc = crc ^ 0xffffffffUL;
35.246 - while (len >= 8) {
35.247 - DO8;
35.248 - len -= 8;
35.249 - }
35.250 - if (len) do {
35.251 - DO1;
35.252 - } while (--len);
35.253 - return crc ^ 0xffffffffUL;
35.254 -}
35.255 -
35.256 -#ifdef BYFOUR
35.257 -
35.258 -/* ========================================================================= */
35.259 -#define DOLIT4 c ^= *buf4++; \
35.260 - c = crc_table[3][c & 0xff] ^ crc_table[2][(c >> 8) & 0xff] ^ \
35.261 - crc_table[1][(c >> 16) & 0xff] ^ crc_table[0][c >> 24]
35.262 -#define DOLIT32 DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4; DOLIT4
35.263 -
35.264 -/* ========================================================================= */
35.265 -local unsigned long crc32_little(crc, buf, len)
35.266 - unsigned long crc;
35.267 - const unsigned char FAR *buf;
35.268 - unsigned len;
35.269 -{
35.270 - register u4 c;
35.271 - register const u4 FAR *buf4;
35.272 -
35.273 - c = (u4)crc;
35.274 - c = ~c;
35.275 - while (len && ((ptrdiff_t)buf & 3)) {
35.276 - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
35.277 - len--;
35.278 - }
35.279 -
35.280 - buf4 = (const u4 FAR *)(const void FAR *)buf;
35.281 - while (len >= 32) {
35.282 - DOLIT32;
35.283 - len -= 32;
35.284 - }
35.285 - while (len >= 4) {
35.286 - DOLIT4;
35.287 - len -= 4;
35.288 - }
35.289 - buf = (const unsigned char FAR *)buf4;
35.290 -
35.291 - if (len) do {
35.292 - c = crc_table[0][(c ^ *buf++) & 0xff] ^ (c >> 8);
35.293 - } while (--len);
35.294 - c = ~c;
35.295 - return (unsigned long)c;
35.296 -}
35.297 -
35.298 -/* ========================================================================= */
35.299 -#define DOBIG4 c ^= *++buf4; \
35.300 - c = crc_table[4][c & 0xff] ^ crc_table[5][(c >> 8) & 0xff] ^ \
35.301 - crc_table[6][(c >> 16) & 0xff] ^ crc_table[7][c >> 24]
35.302 -#define DOBIG32 DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4; DOBIG4
35.303 -
35.304 -/* ========================================================================= */
35.305 -local unsigned long crc32_big(crc, buf, len)
35.306 - unsigned long crc;
35.307 - const unsigned char FAR *buf;
35.308 - unsigned len;
35.309 -{
35.310 - register u4 c;
35.311 - register const u4 FAR *buf4;
35.312 -
35.313 - c = REV((u4)crc);
35.314 - c = ~c;
35.315 - while (len && ((ptrdiff_t)buf & 3)) {
35.316 - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
35.317 - len--;
35.318 - }
35.319 -
35.320 - buf4 = (const u4 FAR *)(const void FAR *)buf;
35.321 - buf4--;
35.322 - while (len >= 32) {
35.323 - DOBIG32;
35.324 - len -= 32;
35.325 - }
35.326 - while (len >= 4) {
35.327 - DOBIG4;
35.328 - len -= 4;
35.329 - }
35.330 - buf4++;
35.331 - buf = (const unsigned char FAR *)buf4;
35.332 -
35.333 - if (len) do {
35.334 - c = crc_table[4][(c >> 24) ^ *buf++] ^ (c << 8);
35.335 - } while (--len);
35.336 - c = ~c;
35.337 - return (unsigned long)(REV(c));
35.338 -}
35.339 -
35.340 -#endif /* BYFOUR */
35.341 -
35.342 -#define GF2_DIM 32 /* dimension of GF(2) vectors (length of CRC) */
35.343 -
35.344 -/* ========================================================================= */
35.345 -local unsigned long gf2_matrix_times(mat, vec)
35.346 - unsigned long *mat;
35.347 - unsigned long vec;
35.348 -{
35.349 - unsigned long sum;
35.350 -
35.351 - sum = 0;
35.352 - while (vec) {
35.353 - if (vec & 1)
35.354 - sum ^= *mat;
35.355 - vec >>= 1;
35.356 - mat++;
35.357 - }
35.358 - return sum;
35.359 -}
35.360 -
35.361 -/* ========================================================================= */
35.362 -local void gf2_matrix_square(square, mat)
35.363 - unsigned long *square;
35.364 - unsigned long *mat;
35.365 -{
35.366 - int n;
35.367 -
35.368 - for (n = 0; n < GF2_DIM; n++)
35.369 - square[n] = gf2_matrix_times(mat, mat[n]);
35.370 -}
35.371 -
35.372 -/* ========================================================================= */
35.373 -uLong ZEXPORT crc32_combine(crc1, crc2, len2)
35.374 - uLong crc1;
35.375 - uLong crc2;
35.376 - z_off_t len2;
35.377 -{
35.378 - int n;
35.379 - unsigned long row;
35.380 - unsigned long even[GF2_DIM]; /* even-power-of-two zeros operator */
35.381 - unsigned long odd[GF2_DIM]; /* odd-power-of-two zeros operator */
35.382 -
35.383 - /* degenerate case */
35.384 - if (len2 == 0)
35.385 - return crc1;
35.386 -
35.387 - /* put operator for one zero bit in odd */
35.388 - odd[0] = 0xedb88320L; /* CRC-32 polynomial */
35.389 - row = 1;
35.390 - for (n = 1; n < GF2_DIM; n++) {
35.391 - odd[n] = row;
35.392 - row <<= 1;
35.393 - }
35.394 -
35.395 - /* put operator for two zero bits in even */
35.396 - gf2_matrix_square(even, odd);
35.397 -
35.398 - /* put operator for four zero bits in odd */
35.399 - gf2_matrix_square(odd, even);
35.400 -
35.401 - /* apply len2 zeros to crc1 (first square will put the operator for one
35.402 - zero byte, eight zero bits, in even) */
35.403 - do {
35.404 - /* apply zeros operator for this bit of len2 */
35.405 - gf2_matrix_square(even, odd);
35.406 - if (len2 & 1)
35.407 - crc1 = gf2_matrix_times(even, crc1);
35.408 - len2 >>= 1;
35.409 -
35.410 - /* if no more bits set, then done */
35.411 - if (len2 == 0)
35.412 - break;
35.413 -
35.414 - /* another iteration of the loop with odd and even swapped */
35.415 - gf2_matrix_square(odd, even);
35.416 - if (len2 & 1)
35.417 - crc1 = gf2_matrix_times(odd, crc1);
35.418 - len2 >>= 1;
35.419 -
35.420 - /* if no more bits set, then done */
35.421 - } while (len2 != 0);
35.422 -
35.423 - /* return combined crc */
35.424 - crc1 ^= crc2;
35.425 - return crc1;
35.426 -}
36.1 --- a/sourcepawn/vm/zlib/crc32.h Tue Nov 07 23:26:40 2006 +0000
36.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
36.3 @@ -1,441 +0,0 @@
36.4 -/* crc32.h -- tables for rapid CRC calculation
36.5 - * Generated automatically by crc32.c
36.6 - */
36.7 -
36.8 -local const unsigned long FAR crc_table[TBLS][256] =
36.9 -{
36.10 - {
36.11 - 0x00000000UL, 0x77073096UL, 0xee0e612cUL, 0x990951baUL, 0x076dc419UL,
36.12 - 0x706af48fUL, 0xe963a535UL, 0x9e6495a3UL, 0x0edb8832UL, 0x79dcb8a4UL,
36.13 - 0xe0d5e91eUL, 0x97d2d988UL, 0x09b64c2bUL, 0x7eb17cbdUL, 0xe7b82d07UL,
36.14 - 0x90bf1d91UL, 0x1db71064UL, 0x6ab020f2UL, 0xf3b97148UL, 0x84be41deUL,
36.15 - 0x1adad47dUL, 0x6ddde4ebUL, 0xf4d4b551UL, 0x83d385c7UL, 0x136c9856UL,
36.16 - 0x646ba8c0UL, 0xfd62f97aUL, 0x8a65c9ecUL, 0x14015c4fUL, 0x63066cd9UL,
36.17 - 0xfa0f3d63UL, 0x8d080df5UL, 0x3b6e20c8UL, 0x4c69105eUL, 0xd56041e4UL,
36.18 - 0xa2677172UL, 0x3c03e4d1UL, 0x4b04d447UL, 0xd20d85fdUL, 0xa50ab56bUL,
36.19 - 0x35b5a8faUL, 0x42b2986cUL, 0xdbbbc9d6UL, 0xacbcf940UL, 0x32d86ce3UL,
36.20 - 0x45df5c75UL, 0xdcd60dcfUL, 0xabd13d59UL, 0x26d930acUL, 0x51de003aUL,
36.21 - 0xc8d75180UL, 0xbfd06116UL, 0x21b4f4b5UL, 0x56b3c423UL, 0xcfba9599UL,
36.22 - 0xb8bda50fUL, 0x2802b89eUL, 0x5f058808UL, 0xc60cd9b2UL, 0xb10be924UL,
36.23 - 0x2f6f7c87UL, 0x58684c11UL, 0xc1611dabUL, 0xb6662d3dUL, 0x76dc4190UL,
36.24 - 0x01db7106UL, 0x98d220bcUL, 0xefd5102aUL, 0x71b18589UL, 0x06b6b51fUL,
36.25 - 0x9fbfe4a5UL, 0xe8b8d433UL, 0x7807c9a2UL, 0x0f00f934UL, 0x9609a88eUL,
36.26 - 0xe10e9818UL, 0x7f6a0dbbUL, 0x086d3d2dUL, 0x91646c97UL, 0xe6635c01UL,
36.27 - 0x6b6b51f4UL, 0x1c6c6162UL, 0x856530d8UL, 0xf262004eUL, 0x6c0695edUL,
36.28 - 0x1b01a57bUL, 0x8208f4c1UL, 0xf50fc457UL, 0x65b0d9c6UL, 0x12b7e950UL,
36.29 - 0x8bbeb8eaUL, 0xfcb9887cUL, 0x62dd1ddfUL, 0x15da2d49UL, 0x8cd37cf3UL,
36.30 - 0xfbd44c65UL, 0x4db26158UL, 0x3ab551ceUL, 0xa3bc0074UL, 0xd4bb30e2UL,
36.31 - 0x4adfa541UL, 0x3dd895d7UL, 0xa4d1c46dUL, 0xd3d6f4fbUL, 0x4369e96aUL,
36.32 - 0x346ed9fcUL, 0xad678846UL, 0xda60b8d0UL, 0x44042d73UL, 0x33031de5UL,
36.33 - 0xaa0a4c5fUL, 0xdd0d7cc9UL, 0x5005713cUL, 0x270241aaUL, 0xbe0b1010UL,
36.34 - 0xc90c2086UL, 0x5768b525UL, 0x206f85b3UL, 0xb966d409UL, 0xce61e49fUL,
36.35 - 0x5edef90eUL, 0x29d9c998UL, 0xb0d09822UL, 0xc7d7a8b4UL, 0x59b33d17UL,
36.36 - 0x2eb40d81UL, 0xb7bd5c3bUL, 0xc0ba6cadUL, 0xedb88320UL, 0x9abfb3b6UL,
36.37 - 0x03b6e20cUL, 0x74b1d29aUL, 0xead54739UL, 0x9dd277afUL, 0x04db2615UL,
36.38 - 0x73dc1683UL, 0xe3630b12UL, 0x94643b84UL, 0x0d6d6a3eUL, 0x7a6a5aa8UL,
36.39 - 0xe40ecf0bUL, 0x9309ff9dUL, 0x0a00ae27UL, 0x7d079eb1UL, 0xf00f9344UL,
36.40 - 0x8708a3d2UL, 0x1e01f268UL, 0x6906c2feUL, 0xf762575dUL, 0x806567cbUL,
36.41 - 0x196c3671UL, 0x6e6b06e7UL, 0xfed41b76UL, 0x89d32be0UL, 0x10da7a5aUL,
36.42 - 0x67dd4accUL, 0xf9b9df6fUL, 0x8ebeeff9UL, 0x17b7be43UL, 0x60b08ed5UL,
36.43 - 0xd6d6a3e8UL, 0xa1d1937eUL, 0x38d8c2c4UL, 0x4fdff252UL, 0xd1bb67f1UL,
36.44 - 0xa6bc5767UL, 0x3fb506ddUL, 0x48b2364bUL, 0xd80d2bdaUL, 0xaf0a1b4cUL,
36.45 - 0x36034af6UL, 0x41047a60UL, 0xdf60efc3UL, 0xa867df55UL, 0x316e8eefUL,
36.46 - 0x4669be79UL, 0xcb61b38cUL, 0xbc66831aUL, 0x256fd2a0UL, 0x5268e236UL,
36.47 - 0xcc0c7795UL, 0xbb0b4703UL, 0x220216b9UL, 0x5505262fUL, 0xc5ba3bbeUL,
36.48 - 0xb2bd0b28UL, 0x2bb45a92UL, 0x5cb36a04UL, 0xc2d7ffa7UL, 0xb5d0cf31UL,
36.49 - 0x2cd99e8bUL, 0x5bdeae1dUL, 0x9b64c2b0UL, 0xec63f226UL, 0x756aa39cUL,
36.50 - 0x026d930aUL, 0x9c0906a9UL, 0xeb0e363fUL, 0x72076785UL, 0x05005713UL,
36.51 - 0x95bf4a82UL, 0xe2b87a14UL, 0x7bb12baeUL, 0x0cb61b38UL, 0x92d28e9bUL,
36.52 - 0xe5d5be0dUL, 0x7cdcefb7UL, 0x0bdbdf21UL, 0x86d3d2d4UL, 0xf1d4e242UL,
36.53 - 0x68ddb3f8UL, 0x1fda836eUL, 0x81be16cdUL, 0xf6b9265bUL, 0x6fb077e1UL,
36.54 - 0x18b74777UL, 0x88085ae6UL, 0xff0f6a70UL, 0x66063bcaUL, 0x11010b5cUL,
36.55 - 0x8f659effUL, 0xf862ae69UL, 0x616bffd3UL, 0x166ccf45UL, 0xa00ae278UL,
36.56 - 0xd70dd2eeUL, 0x4e048354UL, 0x3903b3c2UL, 0xa7672661UL, 0xd06016f7UL,
36.57 - 0x4969474dUL, 0x3e6e77dbUL, 0xaed16a4aUL, 0xd9d65adcUL, 0x40df0b66UL,
36.58 - 0x37d83bf0UL, 0xa9bcae53UL, 0xdebb9ec5UL, 0x47b2cf7fUL, 0x30b5ffe9UL,
36.59 - 0xbdbdf21cUL, 0xcabac28aUL, 0x53b39330UL, 0x24b4a3a6UL, 0xbad03605UL,
36.60 - 0xcdd70693UL, 0x54de5729UL, 0x23d967bfUL, 0xb3667a2eUL, 0xc4614ab8UL,
36.61 - 0x5d681b02UL, 0x2a6f2b94UL, 0xb40bbe37UL, 0xc30c8ea1UL, 0x5a05df1bUL,
36.62 - 0x2d02ef8dUL
36.63 -#ifdef BYFOUR
36.64 - },
36.65 - {
36.66 - 0x00000000UL, 0x191b3141UL, 0x32366282UL, 0x2b2d53c3UL, 0x646cc504UL,
36.67 - 0x7d77f445UL, 0x565aa786UL, 0x4f4196c7UL, 0xc8d98a08UL, 0xd1c2bb49UL,
36.68 - 0xfaefe88aUL, 0xe3f4d9cbUL, 0xacb54f0cUL, 0xb5ae7e4dUL, 0x9e832d8eUL,
36.69 - 0x87981ccfUL, 0x4ac21251UL, 0x53d92310UL, 0x78f470d3UL, 0x61ef4192UL,
36.70 - 0x2eaed755UL, 0x37b5e614UL, 0x1c98b5d7UL, 0x05838496UL, 0x821b9859UL,
36.71 - 0x9b00a918UL, 0xb02dfadbUL, 0xa936cb9aUL, 0xe6775d5dUL, 0xff6c6c1cUL,
36.72 - 0xd4413fdfUL, 0xcd5a0e9eUL, 0x958424a2UL, 0x8c9f15e3UL, 0xa7b24620UL,
36.73 - 0xbea97761UL, 0xf1e8e1a6UL, 0xe8f3d0e7UL, 0xc3de8324UL, 0xdac5b265UL,
36.74 - 0x5d5daeaaUL, 0x44469febUL, 0x6f6bcc28UL, 0x7670fd69UL, 0x39316baeUL,
36.75 - 0x202a5aefUL, 0x0b07092cUL, 0x121c386dUL, 0xdf4636f3UL, 0xc65d07b2UL,
36.76 - 0xed705471UL, 0xf46b6530UL, 0xbb2af3f7UL, 0xa231c2b6UL, 0x891c9175UL,
36.77 - 0x9007a034UL, 0x179fbcfbUL, 0x0e848dbaUL, 0x25a9de79UL, 0x3cb2ef38UL,
36.78 - 0x73f379ffUL, 0x6ae848beUL, 0x41c51b7dUL, 0x58de2a3cUL, 0xf0794f05UL,
36.79 - 0xe9627e44UL, 0xc24f2d87UL, 0xdb541cc6UL, 0x94158a01UL, 0x8d0ebb40UL,
36.80 - 0xa623e883UL, 0xbf38d9c2UL, 0x38a0c50dUL, 0x21bbf44cUL, 0x0a96a78fUL,
36.81 - 0x138d96ceUL, 0x5ccc0009UL, 0x45d73148UL, 0x6efa628bUL, 0x77e153caUL,
36.82 - 0xbabb5d54UL, 0xa3a06c15UL, 0x888d3fd6UL, 0x91960e97UL, 0xded79850UL,
36.83 - 0xc7cca911UL, 0xece1fad2UL, 0xf5facb93UL, 0x7262d75cUL, 0x6b79e61dUL,
36.84 - 0x4054b5deUL, 0x594f849fUL, 0x160e1258UL, 0x0f152319UL, 0x243870daUL,
36.85 - 0x3d23419bUL, 0x65fd6ba7UL, 0x7ce65ae6UL, 0x57cb0925UL, 0x4ed03864UL,
36.86 - 0x0191aea3UL, 0x188a9fe2UL, 0x33a7cc21UL, 0x2abcfd60UL, 0xad24e1afUL,
36.87 - 0xb43fd0eeUL, 0x9f12832dUL, 0x8609b26cUL, 0xc94824abUL, 0xd05315eaUL,
36.88 - 0xfb7e4629UL, 0xe2657768UL, 0x2f3f79f6UL, 0x362448b7UL, 0x1d091b74UL,
36.89 - 0x04122a35UL, 0x4b53bcf2UL, 0x52488db3UL, 0x7965de70UL, 0x607eef31UL,
36.90 - 0xe7e6f3feUL, 0xfefdc2bfUL, 0xd5d0917cUL, 0xcccba03dUL, 0x838a36faUL,
36.91 - 0x9a9107bbUL, 0xb1bc5478UL, 0xa8a76539UL, 0x3b83984bUL, 0x2298a90aUL,
36.92 - 0x09b5fac9UL, 0x10aecb88UL, 0x5fef5d4fUL, 0x46f46c0eUL, 0x6dd93fcdUL,
36.93 - 0x74c20e8cUL, 0xf35a1243UL, 0xea412302UL, 0xc16c70c1UL, 0xd8774180UL,
36.94 - 0x9736d747UL, 0x8e2de606UL, 0xa500b5c5UL, 0xbc1b8484UL, 0x71418a1aUL,
36.95 - 0x685abb5bUL, 0x4377e898UL, 0x5a6cd9d9UL, 0x152d4f1eUL, 0x0c367e5fUL,
36.96 - 0x271b2d9cUL, 0x3e001cddUL, 0xb9980012UL, 0xa0833153UL, 0x8bae6290UL,
36.97 - 0x92b553d1UL, 0xddf4c516UL, 0xc4eff457UL, 0xefc2a794UL, 0xf6d996d5UL,
36.98 - 0xae07bce9UL, 0xb71c8da8UL, 0x9c31de6bUL, 0x852aef2aUL, 0xca6b79edUL,
36.99 - 0xd37048acUL, 0xf85d1b6fUL, 0xe1462a2eUL, 0x66de36e1UL, 0x7fc507a0UL,
36.100 - 0x54e85463UL, 0x4df36522UL, 0x02b2f3e5UL, 0x1ba9c2a4UL, 0x30849167UL,
36.101 - 0x299fa026UL, 0xe4c5aeb8UL, 0xfdde9ff9UL, 0xd6f3cc3aUL, 0xcfe8fd7bUL,
36.102 - 0x80a96bbcUL, 0x99b25afdUL, 0xb29f093eUL, 0xab84387fUL, 0x2c1c24b0UL,
36.103 - 0x350715f1UL, 0x1e2a4632UL, 0x07317773UL, 0x4870e1b4UL, 0x516bd0f5UL,
36.104 - 0x7a468336UL, 0x635db277UL, 0xcbfad74eUL, 0xd2e1e60fUL, 0xf9ccb5ccUL,
36.105 - 0xe0d7848dUL, 0xaf96124aUL, 0xb68d230bUL, 0x9da070c8UL, 0x84bb4189UL,
36.106 - 0x03235d46UL, 0x1a386c07UL, 0x31153fc4UL, 0x280e0e85UL, 0x674f9842UL,
36.107 - 0x7e54a903UL, 0x5579fac0UL, 0x4c62cb81UL, 0x8138c51fUL, 0x9823f45eUL,
36.108 - 0xb30ea79dUL, 0xaa1596dcUL, 0xe554001bUL, 0xfc4f315aUL, 0xd7626299UL,
36.109 - 0xce7953d8UL, 0x49e14f17UL, 0x50fa7e56UL, 0x7bd72d95UL, 0x62cc1cd4UL,
36.110 - 0x2d8d8a13UL, 0x3496bb52UL, 0x1fbbe891UL, 0x06a0d9d0UL, 0x5e7ef3ecUL,
36.111 - 0x4765c2adUL, 0x6c48916eUL, 0x7553a02fUL, 0x3a1236e8UL, 0x230907a9UL,
36.112 - 0x0824546aUL, 0x113f652bUL, 0x96a779e4UL, 0x8fbc48a5UL, 0xa4911b66UL,
36.113 - 0xbd8a2a27UL, 0xf2cbbce0UL, 0xebd08da1UL, 0xc0fdde62UL, 0xd9e6ef23UL,
36.114 - 0x14bce1bdUL, 0x0da7d0fcUL, 0x268a833fUL, 0x3f91b27eUL, 0x70d024b9UL,
36.115 - 0x69cb15f8UL, 0x42e6463bUL, 0x5bfd777aUL, 0xdc656bb5UL, 0xc57e5af4UL,
36.116 - 0xee530937UL, 0xf7483876UL, 0xb809aeb1UL, 0xa1129ff0UL, 0x8a3fcc33UL,
36.117 - 0x9324fd72UL
36.118 - },
36.119 - {
36.120 - 0x00000000UL, 0x01c26a37UL, 0x0384d46eUL, 0x0246be59UL, 0x0709a8dcUL,
36.121 - 0x06cbc2ebUL, 0x048d7cb2UL, 0x054f1685UL, 0x0e1351b8UL, 0x0fd13b8fUL,
36.122 - 0x0d9785d6UL, 0x0c55efe1UL, 0x091af964UL, 0x08d89353UL, 0x0a9e2d0aUL,
36.123 - 0x0b5c473dUL, 0x1c26a370UL, 0x1de4c947UL, 0x1fa2771eUL, 0x1e601d29UL,
36.124 - 0x1b2f0bacUL, 0x1aed619bUL, 0x18abdfc2UL, 0x1969b5f5UL, 0x1235f2c8UL,
36.125 - 0x13f798ffUL, 0x11b126a6UL, 0x10734c91UL, 0x153c5a14UL, 0x14fe3023UL,
36.126 - 0x16b88e7aUL, 0x177ae44dUL, 0x384d46e0UL, 0x398f2cd7UL, 0x3bc9928eUL,
36.127 - 0x3a0bf8b9UL, 0x3f44ee3cUL, 0x3e86840bUL, 0x3cc03a52UL, 0x3d025065UL,
36.128 - 0x365e1758UL, 0x379c7d6fUL, 0x35dac336UL, 0x3418a901UL, 0x3157bf84UL,
36.129 - 0x3095d5b3UL, 0x32d36beaUL, 0x331101ddUL, 0x246be590UL, 0x25a98fa7UL,
36.130 - 0x27ef31feUL, 0x262d5bc9UL, 0x23624d4cUL, 0x22a0277bUL, 0x20e69922UL,
36.131 - 0x2124f315UL, 0x2a78b428UL, 0x2bbade1fUL, 0x29fc6046UL, 0x283e0a71UL,
36.132 - 0x2d711cf4UL, 0x2cb376c3UL, 0x2ef5c89aUL, 0x2f37a2adUL, 0x709a8dc0UL,
36.133 - 0x7158e7f7UL, 0x731e59aeUL, 0x72dc3399UL, 0x7793251cUL, 0x76514f2bUL,
36.134 - 0x7417f172UL, 0x75d59b45UL, 0x7e89dc78UL, 0x7f4bb64fUL, 0x7d0d0816UL,
36.135 - 0x7ccf6221UL, 0x798074a4UL, 0x78421e93UL, 0x7a04a0caUL, 0x7bc6cafdUL,
36.136 - 0x6cbc2eb0UL, 0x6d7e4487UL, 0x6f38fadeUL, 0x6efa90e9UL, 0x6bb5866cUL,
36.137 - 0x6a77ec5bUL, 0x68315202UL, 0x69f33835UL, 0x62af7f08UL, 0x636d153fUL,
36.138 - 0x612bab66UL, 0x60e9c151UL, 0x65a6d7d4UL, 0x6464bde3UL, 0x662203baUL,
36.139 - 0x67e0698dUL, 0x48d7cb20UL, 0x4915a117UL, 0x4b531f4eUL, 0x4a917579UL,
36.140 - 0x4fde63fcUL, 0x4e1c09cbUL, 0x4c5ab792UL, 0x4d98dda5UL, 0x46c49a98UL,
36.141 - 0x4706f0afUL, 0x45404ef6UL, 0x448224c1UL, 0x41cd3244UL, 0x400f5873UL,
36.142 - 0x4249e62aUL, 0x438b8c1dUL, 0x54f16850UL, 0x55330267UL, 0x5775bc3eUL,
36.143 - 0x56b7d609UL, 0x53f8c08cUL, 0x523aaabbUL, 0x507c14e2UL, 0x51be7ed5UL,
36.144 - 0x5ae239e8UL, 0x5b2053dfUL, 0x5966ed86UL, 0x58a487b1UL, 0x5deb9134UL,
36.145 - 0x5c29fb03UL, 0x5e6f455aUL, 0x5fad2f6dUL, 0xe1351b80UL, 0xe0f771b7UL,
36.146 - 0xe2b1cfeeUL, 0xe373a5d9UL, 0xe63cb35cUL, 0xe7fed96bUL, 0xe5b86732UL,
36.147 - 0xe47a0d05UL, 0xef264a38UL, 0xeee4200fUL, 0xeca29e56UL, 0xed60f461UL,
36.148 - 0xe82fe2e4UL, 0xe9ed88d3UL, 0xebab368aUL, 0xea695cbdUL, 0xfd13b8f0UL,
36.149 - 0xfcd1d2c7UL, 0xfe976c9eUL, 0xff5506a9UL, 0xfa1a102cUL, 0xfbd87a1bUL,
36.150 - 0xf99ec442UL, 0xf85cae75UL, 0xf300e948UL, 0xf2c2837fUL, 0xf0843d26UL,
36.151 - 0xf1465711UL, 0xf4094194UL, 0xf5cb2ba3UL, 0xf78d95faUL, 0xf64fffcdUL,
36.152 - 0xd9785d60UL, 0xd8ba3757UL, 0xdafc890eUL, 0xdb3ee339UL, 0xde71f5bcUL,
36.153 - 0xdfb39f8bUL, 0xddf521d2UL, 0xdc374be5UL, 0xd76b0cd8UL, 0xd6a966efUL,
36.154 - 0xd4efd8b6UL, 0xd52db281UL, 0xd062a404UL, 0xd1a0ce33UL, 0xd3e6706aUL,
36.155 - 0xd2241a5dUL, 0xc55efe10UL, 0xc49c9427UL, 0xc6da2a7eUL, 0xc7184049UL,
36.156 - 0xc25756ccUL, 0xc3953cfbUL, 0xc1d382a2UL, 0xc011e895UL, 0xcb4dafa8UL,
36.157 - 0xca8fc59fUL, 0xc8c97bc6UL, 0xc90b11f1UL, 0xcc440774UL, 0xcd866d43UL,
36.158 - 0xcfc0d31aUL, 0xce02b92dUL, 0x91af9640UL, 0x906dfc77UL, 0x922b422eUL,
36.159 - 0x93e92819UL, 0x96a63e9cUL, 0x976454abUL, 0x9522eaf2UL, 0x94e080c5UL,
36.160 - 0x9fbcc7f8UL, 0x9e7eadcfUL, 0x9c381396UL, 0x9dfa79a1UL, 0x98b56f24UL,
36.161 - 0x99770513UL, 0x9b31bb4aUL, 0x9af3d17dUL, 0x8d893530UL, 0x8c4b5f07UL,
36.162 - 0x8e0de15eUL, 0x8fcf8b69UL, 0x8a809decUL, 0x8b42f7dbUL, 0x89044982UL,
36.163 - 0x88c623b5UL, 0x839a6488UL, 0x82580ebfUL, 0x801eb0e6UL, 0x81dcdad1UL,
36.164 - 0x8493cc54UL, 0x8551a663UL, 0x8717183aUL, 0x86d5720dUL, 0xa9e2d0a0UL,
36.165 - 0xa820ba97UL, 0xaa6604ceUL, 0xaba46ef9UL, 0xaeeb787cUL, 0xaf29124bUL,
36.166 - 0xad6fac12UL, 0xacadc625UL, 0xa7f18118UL, 0xa633eb2fUL, 0xa4755576UL,
36.167 - 0xa5b73f41UL, 0xa0f829c4UL, 0xa13a43f3UL, 0xa37cfdaaUL, 0xa2be979dUL,
36.168 - 0xb5c473d0UL, 0xb40619e7UL, 0xb640a7beUL, 0xb782cd89UL, 0xb2cddb0cUL,
36.169 - 0xb30fb13bUL, 0xb1490f62UL, 0xb08b6555UL, 0xbbd72268UL, 0xba15485fUL,
36.170 - 0xb853f606UL, 0xb9919c31UL, 0xbcde8ab4UL, 0xbd1ce083UL, 0xbf5a5edaUL,
36.171 - 0xbe9834edUL
36.172 - },
36.173 - {
36.174 - 0x00000000UL, 0xb8bc6765UL, 0xaa09c88bUL, 0x12b5afeeUL, 0x8f629757UL,
36.175 - 0x37def032UL, 0x256b5fdcUL, 0x9dd738b9UL, 0xc5b428efUL, 0x7d084f8aUL,
36.176 - 0x6fbde064UL, 0xd7018701UL, 0x4ad6bfb8UL, 0xf26ad8ddUL, 0xe0df7733UL,
36.177 - 0x58631056UL, 0x5019579fUL, 0xe8a530faUL, 0xfa109f14UL, 0x42acf871UL,
36.178 - 0xdf7bc0c8UL, 0x67c7a7adUL, 0x75720843UL, 0xcdce6f26UL, 0x95ad7f70UL,
36.179 - 0x2d111815UL, 0x3fa4b7fbUL, 0x8718d09eUL, 0x1acfe827UL, 0xa2738f42UL,
36.180 - 0xb0c620acUL, 0x087a47c9UL, 0xa032af3eUL, 0x188ec85bUL, 0x0a3b67b5UL,
36.181 - 0xb28700d0UL, 0x2f503869UL, 0x97ec5f0cUL, 0x8559f0e2UL, 0x3de59787UL,
36.182 - 0x658687d1UL, 0xdd3ae0b4UL, 0xcf8f4f5aUL, 0x7733283fUL, 0xeae41086UL,
36.183 - 0x525877e3UL, 0x40edd80dUL, 0xf851bf68UL, 0xf02bf8a1UL, 0x48979fc4UL,
36.184 - 0x5a22302aUL, 0xe29e574fUL, 0x7f496ff6UL, 0xc7f50893UL, 0xd540a77dUL,
36.185 - 0x6dfcc018UL, 0x359fd04eUL, 0x8d23b72bUL, 0x9f9618c5UL, 0x272a7fa0UL,
36.186 - 0xbafd4719UL, 0x0241207cUL, 0x10f48f92UL, 0xa848e8f7UL, 0x9b14583dUL,
36.187 - 0x23a83f58UL, 0x311d90b6UL, 0x89a1f7d3UL, 0x1476cf6aUL, 0xaccaa80fUL,
36.188 - 0xbe7f07e1UL, 0x06c36084UL, 0x5ea070d2UL, 0xe61c17b7UL, 0xf4a9b859UL,
36.189 - 0x4c15df3cUL, 0xd1c2e785UL, 0x697e80e0UL, 0x7bcb2f0eUL, 0xc377486bUL,
36.190 - 0xcb0d0fa2UL, 0x73b168c7UL, 0x6104c729UL, 0xd9b8a04cUL, 0x446f98f5UL,
36.191 - 0xfcd3ff90UL, 0xee66507eUL, 0x56da371bUL, 0x0eb9274dUL, 0xb6054028UL,
36.192 - 0xa4b0efc6UL, 0x1c0c88a3UL, 0x81dbb01aUL, 0x3967d77fUL, 0x2bd27891UL,
36.193 - 0x936e1ff4UL, 0x3b26f703UL, 0x839a9066UL, 0x912f3f88UL, 0x299358edUL,
36.194 - 0xb4446054UL, 0x0cf80731UL, 0x1e4da8dfUL, 0xa6f1cfbaUL, 0xfe92dfecUL,
36.195 - 0x462eb889UL, 0x549b1767UL, 0xec277002UL, 0x71f048bbUL, 0xc94c2fdeUL,
36.196 - 0xdbf98030UL, 0x6345e755UL, 0x6b3fa09cUL, 0xd383c7f9UL, 0xc1366817UL,
36.197 - 0x798a0f72UL, 0xe45d37cbUL, 0x5ce150aeUL, 0x4e54ff40UL, 0xf6e89825UL,
36.198 - 0xae8b8873UL, 0x1637ef16UL, 0x048240f8UL, 0xbc3e279dUL, 0x21e91f24UL,
36.199 - 0x99557841UL, 0x8be0d7afUL, 0x335cb0caUL, 0xed59b63bUL, 0x55e5d15eUL,
36.200 - 0x47507eb0UL, 0xffec19d5UL, 0x623b216cUL, 0xda874609UL, 0xc832e9e7UL,
36.201 - 0x708e8e82UL, 0x28ed9ed4UL, 0x9051f9b1UL, 0x82e4565fUL, 0x3a58313aUL,
36.202 - 0xa78f0983UL, 0x1f336ee6UL, 0x0d86c108UL, 0xb53aa66dUL, 0xbd40e1a4UL,
36.203 - 0x05fc86c1UL, 0x1749292fUL, 0xaff54e4aUL, 0x322276f3UL, 0x8a9e1196UL,
36.204 - 0x982bbe78UL, 0x2097d91dUL, 0x78f4c94bUL, 0xc048ae2eUL, 0xd2fd01c0UL,
36.205 - 0x6a4166a5UL, 0xf7965e1cUL, 0x4f2a3979UL, 0x5d9f9697UL, 0xe523f1f2UL,
36.206 - 0x4d6b1905UL, 0xf5d77e60UL, 0xe762d18eUL, 0x5fdeb6ebUL, 0xc2098e52UL,
36.207 - 0x7ab5e937UL, 0x680046d9UL, 0xd0bc21bcUL, 0x88df31eaUL, 0x3063568fUL,
36.208 - 0x22d6f961UL, 0x9a6a9e04UL, 0x07bda6bdUL, 0xbf01c1d8UL, 0xadb46e36UL,
36.209 - 0x15080953UL, 0x1d724e9aUL, 0xa5ce29ffUL, 0xb77b8611UL, 0x0fc7e174UL,
36.210 - 0x9210d9cdUL, 0x2aacbea8UL, 0x38191146UL, 0x80a57623UL, 0xd8c66675UL,
36.211 - 0x607a0110UL, 0x72cfaefeUL, 0xca73c99bUL, 0x57a4f122UL, 0xef189647UL,
36.212 - 0xfdad39a9UL, 0x45115eccUL, 0x764dee06UL, 0xcef18963UL, 0xdc44268dUL,
36.213 - 0x64f841e8UL, 0xf92f7951UL, 0x41931e34UL, 0x5326b1daUL, 0xeb9ad6bfUL,
36.214 - 0xb3f9c6e9UL, 0x0b45a18cUL, 0x19f00e62UL, 0xa14c6907UL, 0x3c9b51beUL,
36.215 - 0x842736dbUL, 0x96929935UL, 0x2e2efe50UL, 0x2654b999UL, 0x9ee8defcUL,
36.216 - 0x8c5d7112UL, 0x34e11677UL, 0xa9362eceUL, 0x118a49abUL, 0x033fe645UL,
36.217 - 0xbb838120UL, 0xe3e09176UL, 0x5b5cf613UL, 0x49e959fdUL, 0xf1553e98UL,
36.218 - 0x6c820621UL, 0xd43e6144UL, 0xc68bceaaUL, 0x7e37a9cfUL, 0xd67f4138UL,
36.219 - 0x6ec3265dUL, 0x7c7689b3UL, 0xc4caeed6UL, 0x591dd66fUL, 0xe1a1b10aUL,
36.220 - 0xf3141ee4UL, 0x4ba87981UL, 0x13cb69d7UL, 0xab770eb2UL, 0xb9c2a15cUL,
36.221 - 0x017ec639UL, 0x9ca9fe80UL, 0x241599e5UL, 0x36a0360bUL, 0x8e1c516eUL,
36.222 - 0x866616a7UL, 0x3eda71c2UL, 0x2c6fde2cUL, 0x94d3b949UL, 0x090481f0UL,
36.223 - 0xb1b8e695UL, 0xa30d497bUL, 0x1bb12e1eUL, 0x43d23e48UL, 0xfb6e592dUL,
36.224 - 0xe9dbf6c3UL, 0x516791a6UL, 0xccb0a91fUL, 0x740cce7aUL, 0x66b96194UL,
36.225 - 0xde0506f1UL
36.226 - },
36.227 - {
36.228 - 0x00000000UL, 0x96300777UL, 0x2c610eeeUL, 0xba510999UL, 0x19c46d07UL,
36.229 - 0x8ff46a70UL, 0x35a563e9UL, 0xa395649eUL, 0x3288db0eUL, 0xa4b8dc79UL,
36.230 - 0x1ee9d5e0UL, 0x88d9d297UL, 0x2b4cb609UL, 0xbd7cb17eUL, 0x072db8e7UL,
36.231 - 0x911dbf90UL, 0x6410b71dUL, 0xf220b06aUL, 0x4871b9f3UL, 0xde41be84UL,
36.232 - 0x7dd4da1aUL, 0xebe4dd6dUL, 0x51b5d4f4UL, 0xc785d383UL, 0x56986c13UL,
36.233 - 0xc0a86b64UL, 0x7af962fdUL, 0xecc9658aUL, 0x4f5c0114UL, 0xd96c0663UL,
36.234 - 0x633d0ffaUL, 0xf50d088dUL, 0xc8206e3bUL, 0x5e10694cUL, 0xe44160d5UL,
36.235 - 0x727167a2UL, 0xd1e4033cUL, 0x47d4044bUL, 0xfd850dd2UL, 0x6bb50aa5UL,
36.236 - 0xfaa8b535UL, 0x6c98b242UL, 0xd6c9bbdbUL, 0x40f9bcacUL, 0xe36cd832UL,
36.237 - 0x755cdf45UL, 0xcf0dd6dcUL, 0x593dd1abUL, 0xac30d926UL, 0x3a00de51UL,
36.238 - 0x8051d7c8UL, 0x1661d0bfUL, 0xb5f4b421UL, 0x23c4b356UL, 0x9995bacfUL,
36.239 - 0x0fa5bdb8UL, 0x9eb80228UL, 0x0888055fUL, 0xb2d90cc6UL, 0x24e90bb1UL,
36.240 - 0x877c6f2fUL, 0x114c6858UL, 0xab1d61c1UL, 0x3d2d66b6UL, 0x9041dc76UL,
36.241 - 0x0671db01UL, 0xbc20d298UL, 0x2a10d5efUL, 0x8985b171UL, 0x1fb5b606UL,
36.242 - 0xa5e4bf9fUL, 0x33d4b8e8UL, 0xa2c90778UL, 0x34f9000fUL, 0x8ea80996UL,
36.243 - 0x18980ee1UL, 0xbb0d6a7fUL, 0x2d3d6d08UL, 0x976c6491UL, 0x015c63e6UL,
36.244 - 0xf4516b6bUL, 0x62616c1cUL, 0xd8306585UL, 0x4e0062f2UL, 0xed95066cUL,
36.245 - 0x7ba5011bUL, 0xc1f40882UL, 0x57c40ff5UL, 0xc6d9b065UL, 0x50e9b712UL,
36.246 - 0xeab8be8bUL, 0x7c88b9fcUL, 0xdf1ddd62UL, 0x492dda15UL, 0xf37cd38cUL,
36.247 - 0x654cd4fbUL, 0x5861b24dUL, 0xce51b53aUL, 0x7400bca3UL, 0xe230bbd4UL,
36.248 - 0x41a5df4aUL, 0xd795d83dUL, 0x6dc4d1a4UL, 0xfbf4d6d3UL, 0x6ae96943UL,
36.249 - 0xfcd96e34UL, 0x468867adUL, 0xd0b860daUL, 0x732d0444UL, 0xe51d0333UL,
36.250 - 0x5f4c0aaaUL, 0xc97c0dddUL, 0x3c710550UL, 0xaa410227UL, 0x10100bbeUL,
36.251 - 0x86200cc9UL, 0x25b56857UL, 0xb3856f20UL, 0x09d466b9UL, 0x9fe461ceUL,
36.252 - 0x0ef9de5eUL, 0x98c9d929UL, 0x2298d0b0UL, 0xb4a8d7c7UL, 0x173db359UL,
36.253 - 0x810db42eUL, 0x3b5cbdb7UL, 0xad6cbac0UL, 0x2083b8edUL, 0xb6b3bf9aUL,
36.254 - 0x0ce2b603UL, 0x9ad2b174UL, 0x3947d5eaUL, 0xaf77d29dUL, 0x1526db04UL,
36.255 - 0x8316dc73UL, 0x120b63e3UL, 0x843b6494UL, 0x3e6a6d0dUL, 0xa85a6a7aUL,
36.256 - 0x0bcf0ee4UL, 0x9dff0993UL, 0x27ae000aUL, 0xb19e077dUL, 0x44930ff0UL,
36.257 - 0xd2a30887UL, 0x68f2011eUL, 0xfec20669UL, 0x5d5762f7UL, 0xcb676580UL,
36.258 - 0x71366c19UL, 0xe7066b6eUL, 0x761bd4feUL, 0xe02bd389UL, 0x5a7ada10UL,
36.259 - 0xcc4add67UL, 0x6fdfb9f9UL, 0xf9efbe8eUL, 0x43beb717UL, 0xd58eb060UL,
36.260 - 0xe8a3d6d6UL, 0x7e93d1a1UL, 0xc4c2d838UL, 0x52f2df4fUL, 0xf167bbd1UL,
36.261 - 0x6757bca6UL, 0xdd06b53fUL, 0x4b36b248UL, 0xda2b0dd8UL, 0x4c1b0aafUL,
36.262 - 0xf64a0336UL, 0x607a0441UL, 0xc3ef60dfUL, 0x55df67a8UL, 0xef8e6e31UL,
36.263 - 0x79be6946UL, 0x8cb361cbUL, 0x1a8366bcUL, 0xa0d26f25UL, 0x36e26852UL,
36.264 - 0x95770cccUL, 0x03470bbbUL, 0xb9160222UL, 0x2f260555UL, 0xbe3bbac5UL,
36.265 - 0x280bbdb2UL, 0x925ab42bUL, 0x046ab35cUL, 0xa7ffd7c2UL, 0x31cfd0b5UL,
36.266 - 0x8b9ed92cUL, 0x1daede5bUL, 0xb0c2649bUL, 0x26f263ecUL, 0x9ca36a75UL,
36.267 - 0x0a936d02UL, 0xa906099cUL, 0x3f360eebUL, 0x85670772UL, 0x13570005UL,
36.268 - 0x824abf95UL, 0x147ab8e2UL, 0xae2bb17bUL, 0x381bb60cUL, 0x9b8ed292UL,
36.269 - 0x0dbed5e5UL, 0xb7efdc7cUL, 0x21dfdb0bUL, 0xd4d2d386UL, 0x42e2d4f1UL,
36.270 - 0xf8b3dd68UL, 0x6e83da1fUL, 0xcd16be81UL, 0x5b26b9f6UL, 0xe177b06fUL,
36.271 - 0x7747b718UL, 0xe65a0888UL, 0x706a0fffUL, 0xca3b0666UL, 0x5c0b0111UL,
36.272 - 0xff9e658fUL, 0x69ae62f8UL, 0xd3ff6b61UL, 0x45cf6c16UL, 0x78e20aa0UL,
36.273 - 0xeed20dd7UL, 0x5483044eUL, 0xc2b30339UL, 0x612667a7UL, 0xf71660d0UL,
36.274 - 0x4d476949UL, 0xdb776e3eUL, 0x4a6ad1aeUL, 0xdc5ad6d9UL, 0x660bdf40UL,
36.275 - 0xf03bd837UL, 0x53aebca9UL, 0xc59ebbdeUL, 0x7fcfb247UL, 0xe9ffb530UL,
36.276 - 0x1cf2bdbdUL, 0x8ac2bacaUL, 0x3093b353UL, 0xa6a3b424UL, 0x0536d0baUL,
36.277 - 0x9306d7cdUL, 0x2957de54UL, 0xbf67d923UL, 0x2e7a66b3UL, 0xb84a61c4UL,
36.278 - 0x021b685dUL, 0x942b6f2aUL, 0x37be0bb4UL, 0xa18e0cc3UL, 0x1bdf055aUL,
36.279 - 0x8def022dUL
36.280 - },
36.281 - {
36.282 - 0x00000000UL, 0x41311b19UL, 0x82623632UL, 0xc3532d2bUL, 0x04c56c64UL,
36.283 - 0x45f4777dUL, 0x86a75a56UL, 0xc796414fUL, 0x088ad9c8UL, 0x49bbc2d1UL,
36.284 - 0x8ae8effaUL, 0xcbd9f4e3UL, 0x0c4fb5acUL, 0x4d7eaeb5UL, 0x8e2d839eUL,
36.285 - 0xcf1c9887UL, 0x5112c24aUL, 0x1023d953UL, 0xd370f478UL, 0x9241ef61UL,
36.286 - 0x55d7ae2eUL, 0x14e6b537UL, 0xd7b5981cUL, 0x96848305UL, 0x59981b82UL,
36.287 - 0x18a9009bUL, 0xdbfa2db0UL, 0x9acb36a9UL, 0x5d5d77e6UL, 0x1c6c6cffUL,
36.288 - 0xdf3f41d4UL, 0x9e0e5acdUL, 0xa2248495UL, 0xe3159f8cUL, 0x2046b2a7UL,
36.289 - 0x6177a9beUL, 0xa6e1e8f1UL, 0xe7d0f3e8UL, 0x2483dec3UL, 0x65b2c5daUL,
36.290 - 0xaaae5d5dUL, 0xeb9f4644UL, 0x28cc6b6fUL, 0x69fd7076UL, 0xae6b3139UL,
36.291 - 0xef5a2a20UL, 0x2c09070bUL, 0x6d381c12UL, 0xf33646dfUL, 0xb2075dc6UL,
36.292 - 0x715470edUL, 0x30656bf4UL, 0xf7f32abbUL, 0xb6c231a2UL, 0x75911c89UL,
36.293 - 0x34a00790UL, 0xfbbc9f17UL, 0xba8d840eUL, 0x79dea925UL, 0x38efb23cUL,
36.294 - 0xff79f373UL, 0xbe48e86aUL, 0x7d1bc541UL, 0x3c2ade58UL, 0x054f79f0UL,
36.295 - 0x447e62e9UL, 0x872d4fc2UL, 0xc61c54dbUL, 0x018a1594UL, 0x40bb0e8dUL,
36.296 - 0x83e823a6UL, 0xc2d938bfUL, 0x0dc5a038UL, 0x4cf4bb21UL, 0x8fa7960aUL,
36.297 - 0xce968d13UL, 0x0900cc5cUL, 0x4831d745UL, 0x8b62fa6eUL, 0xca53e177UL,
36.298 - 0x545dbbbaUL, 0x156ca0a3UL, 0xd63f8d88UL, 0x970e9691UL, 0x5098d7deUL,
36.299 - 0x11a9ccc7UL, 0xd2fae1ecUL, 0x93cbfaf5UL, 0x5cd76272UL, 0x1de6796bUL,
36.300 - 0xdeb55440UL, 0x9f844f59UL, 0x58120e16UL, 0x1923150fUL, 0xda703824UL,
36.301 - 0x9b41233dUL, 0xa76bfd65UL, 0xe65ae67cUL, 0x2509cb57UL, 0x6438d04eUL,
36.302 - 0xa3ae9101UL, 0xe29f8a18UL, 0x21cca733UL, 0x60fdbc2aUL, 0xafe124adUL,
36.303 - 0xeed03fb4UL, 0x2d83129fUL, 0x6cb20986UL, 0xab2448c9UL, 0xea1553d0UL,
36.304 - 0x29467efbUL, 0x687765e2UL, 0xf6793f2fUL, 0xb7482436UL, 0x741b091dUL,
36.305 - 0x352a1204UL, 0xf2bc534bUL, 0xb38d4852UL, 0x70de6579UL, 0x31ef7e60UL,
36.306 - 0xfef3e6e7UL, 0xbfc2fdfeUL, 0x7c91d0d5UL, 0x3da0cbccUL, 0xfa368a83UL,
36.307 - 0xbb07919aUL, 0x7854bcb1UL, 0x3965a7a8UL, 0x4b98833bUL, 0x0aa99822UL,
36.308 - 0xc9fab509UL, 0x88cbae10UL, 0x4f5def5fUL, 0x0e6cf446UL, 0xcd3fd96dUL,
36.309 - 0x8c0ec274UL, 0x43125af3UL, 0x022341eaUL, 0xc1706cc1UL, 0x804177d8UL,
36.310 - 0x47d73697UL, 0x06e62d8eUL, 0xc5b500a5UL, 0x84841bbcUL, 0x1a8a4171UL,
36.311 - 0x5bbb5a68UL, 0x98e87743UL, 0xd9d96c5aUL, 0x1e4f2d15UL, 0x5f7e360cUL,
36.312 - 0x9c2d1b27UL, 0xdd1c003eUL, 0x120098b9UL, 0x533183a0UL, 0x9062ae8bUL,
36.313 - 0xd153b592UL, 0x16c5f4ddUL, 0x57f4efc4UL, 0x94a7c2efUL, 0xd596d9f6UL,
36.314 - 0xe9bc07aeUL, 0xa88d1cb7UL, 0x6bde319cUL, 0x2aef2a85UL, 0xed796bcaUL,
36.315 - 0xac4870d3UL, 0x6f1b5df8UL, 0x2e2a46e1UL, 0xe136de66UL, 0xa007c57fUL,
36.316 - 0x6354e854UL, 0x2265f34dUL, 0xe5f3b202UL, 0xa4c2a91bUL, 0x67918430UL,
36.317 - 0x26a09f29UL, 0xb8aec5e4UL, 0xf99fdefdUL, 0x3accf3d6UL, 0x7bfde8cfUL,
36.318 - 0xbc6ba980UL, 0xfd5ab299UL, 0x3e099fb2UL, 0x7f3884abUL, 0xb0241c2cUL,
36.319 - 0xf1150735UL, 0x32462a1eUL, 0x73773107UL, 0xb4e17048UL, 0xf5d06b51UL,
36.320 - 0x3683467aUL, 0x77b25d63UL, 0x4ed7facbUL, 0x0fe6e1d2UL, 0xccb5ccf9UL,
36.321 - 0x8d84d7e0UL, 0x4a1296afUL, 0x0b238db6UL, 0xc870a09dUL, 0x8941bb84UL,
36.322 - 0x465d2303UL, 0x076c381aUL, 0xc43f1531UL, 0x850e0e28UL, 0x42984f67UL,
36.323 - 0x03a9547eUL, 0xc0fa7955UL, 0x81cb624cUL, 0x1fc53881UL, 0x5ef42398UL,
36.324 - 0x9da70eb3UL, 0xdc9615aaUL, 0x1b0054e5UL, 0x5a314ffcUL, 0x996262d7UL,
36.325 - 0xd85379ceUL, 0x174fe149UL, 0x567efa50UL, 0x952dd77bUL, 0xd41ccc62UL,
36.326 - 0x138a8d2dUL, 0x52bb9634UL, 0x91e8bb1fUL, 0xd0d9a006UL, 0xecf37e5eUL,
36.327 - 0xadc26547UL, 0x6e91486cUL, 0x2fa05375UL, 0xe836123aUL, 0xa9070923UL,
36.328 - 0x6a542408UL, 0x2b653f11UL, 0xe479a796UL, 0xa548bc8fUL, 0x661b91a4UL,
36.329 - 0x272a8abdUL, 0xe0bccbf2UL, 0xa18dd0ebUL, 0x62defdc0UL, 0x23efe6d9UL,
36.330 - 0xbde1bc14UL, 0xfcd0a70dUL, 0x3f838a26UL, 0x7eb2913fUL, 0xb924d070UL,
36.331 - 0xf815cb69UL, 0x3b46e642UL, 0x7a77fd5bUL, 0xb56b65dcUL, 0xf45a7ec5UL,
36.332 - 0x370953eeUL, 0x763848f7UL, 0xb1ae09b8UL, 0xf09f12a1UL, 0x33cc3f8aUL,
36.333 - 0x72fd2493UL
36.334 - },
36.335 - {
36.336 - 0x00000000UL, 0x376ac201UL, 0x6ed48403UL, 0x59be4602UL, 0xdca80907UL,
36.337 - 0xebc2cb06UL, 0xb27c8d04UL, 0x85164f05UL, 0xb851130eUL, 0x8f3bd10fUL,
36.338 - 0xd685970dUL, 0xe1ef550cUL, 0x64f91a09UL, 0x5393d808UL, 0x0a2d9e0aUL,
36.339 - 0x3d475c0bUL, 0x70a3261cUL, 0x47c9e41dUL, 0x1e77a21fUL, 0x291d601eUL,
36.340 - 0xac0b2f1bUL, 0x9b61ed1aUL, 0xc2dfab18UL, 0xf5b56919UL, 0xc8f23512UL,
36.341 - 0xff98f713UL, 0xa626b111UL, 0x914c7310UL, 0x145a3c15UL, 0x2330fe14UL,
36.342 - 0x7a8eb816UL, 0x4de47a17UL, 0xe0464d38UL, 0xd72c8f39UL, 0x8e92c93bUL,
36.343 - 0xb9f80b3aUL, 0x3cee443fUL, 0x0b84863eUL, 0x523ac03cUL, 0x6550023dUL,
36.344 - 0x58175e36UL, 0x6f7d9c37UL, 0x36c3da35UL, 0x01a91834UL, 0x84bf5731UL,
36.345 - 0xb3d59530UL, 0xea6bd332UL, 0xdd011133UL, 0x90e56b24UL, 0xa78fa925UL,
36.346 - 0xfe31ef27UL, 0xc95b2d26UL, 0x4c4d6223UL, 0x7b27a022UL, 0x2299e620UL,
36.347 - 0x15f32421UL, 0x28b4782aUL, 0x1fdeba2bUL, 0x4660fc29UL, 0x710a3e28UL,
36.348 - 0xf41c712dUL, 0xc376b32cUL, 0x9ac8f52eUL, 0xada2372fUL, 0xc08d9a70UL,
36.349 - 0xf7e75871UL, 0xae591e73UL, 0x9933dc72UL, 0x1c259377UL, 0x2b4f5176UL,
36.350 - 0x72f11774UL, 0x459bd575UL, 0x78dc897eUL, 0x4fb64b7fUL, 0x16080d7dUL,
36.351 - 0x2162cf7cUL, 0xa4748079UL, 0x931e4278UL, 0xcaa0047aUL, 0xfdcac67bUL,
36.352 - 0xb02ebc6cUL, 0x87447e6dUL, 0xdefa386fUL, 0xe990fa6eUL, 0x6c86b56bUL,
36.353 - 0x5bec776aUL, 0x02523168UL, 0x3538f369UL, 0x087faf62UL, 0x3f156d63UL,
36.354 - 0x66ab2b61UL, 0x51c1e960UL, 0xd4d7a665UL, 0xe3bd6464UL, 0xba032266UL,
36.355 - 0x8d69e067UL, 0x20cbd748UL, 0x17a11549UL, 0x4e1f534bUL, 0x7975914aUL,
36.356 - 0xfc63de4fUL, 0xcb091c4eUL, 0x92b75a4cUL, 0xa5dd984dUL, 0x989ac446UL,
36.357 - 0xaff00647UL, 0xf64e4045UL, 0xc1248244UL, 0x4432cd41UL, 0x73580f40UL,
36.358 - 0x2ae64942UL, 0x1d8c8b43UL, 0x5068f154UL, 0x67023355UL, 0x3ebc7557UL,
36.359 - 0x09d6b756UL, 0x8cc0f853UL, 0xbbaa3a52UL, 0xe2147c50UL, 0xd57ebe51UL,
36.360 - 0xe839e25aUL, 0xdf53205bUL, 0x86ed6659UL, 0xb187a458UL, 0x3491eb5dUL,
36.361 - 0x03fb295cUL, 0x5a456f5eUL, 0x6d2fad5fUL, 0x801b35e1UL, 0xb771f7e0UL,
36.362 - 0xeecfb1e2UL, 0xd9a573e3UL, 0x5cb33ce6UL, 0x6bd9fee7UL, 0x3267b8e5UL,
36.363 - 0x050d7ae4UL, 0x384a26efUL, 0x0f20e4eeUL, 0x569ea2ecUL, 0x61f460edUL,
36.364 - 0xe4e22fe8UL, 0xd388ede9UL, 0x8a36abebUL, 0xbd5c69eaUL, 0xf0b813fdUL,
36.365 - 0xc7d2d1fcUL, 0x9e6c97feUL, 0xa90655ffUL, 0x2c101afaUL, 0x1b7ad8fbUL,
36.366 - 0x42c49ef9UL, 0x75ae5cf8UL, 0x48e900f3UL, 0x7f83c2f2UL, 0x263d84f0UL,
36.367 - 0x115746f1UL, 0x944109f4UL, 0xa32bcbf5UL, 0xfa958df7UL, 0xcdff4ff6UL,
36.368 - 0x605d78d9UL, 0x5737bad8UL, 0x0e89fcdaUL, 0x39e33edbUL, 0xbcf571deUL,
36.369 - 0x8b9fb3dfUL, 0xd221f5ddUL, 0xe54b37dcUL, 0xd80c6bd7UL, 0xef66a9d6UL,
36.370 - 0xb6d8efd4UL, 0x81b22dd5UL, 0x04a462d0UL, 0x33cea0d1UL, 0x6a70e6d3UL,
36.371 - 0x5d1a24d2UL, 0x10fe5ec5UL, 0x27949cc4UL, 0x7e2adac6UL, 0x494018c7UL,
36.372 - 0xcc5657c2UL, 0xfb3c95c3UL, 0xa282d3c1UL, 0x95e811c0UL, 0xa8af4dcbUL,
36.373 - 0x9fc58fcaUL, 0xc67bc9c8UL, 0xf1110bc9UL, 0x740744ccUL, 0x436d86cdUL,
36.374 - 0x1ad3c0cfUL, 0x2db902ceUL, 0x4096af91UL, 0x77fc6d90UL, 0x2e422b92UL,
36.375 - 0x1928e993UL, 0x9c3ea696UL, 0xab546497UL, 0xf2ea2295UL, 0xc580e094UL,
36.376 - 0xf8c7bc9fUL, 0xcfad7e9eUL, 0x9613389cUL, 0xa179fa9dUL, 0x246fb598UL,
36.377 - 0x13057799UL, 0x4abb319bUL, 0x7dd1f39aUL, 0x3035898dUL, 0x075f4b8cUL,
36.378 - 0x5ee10d8eUL, 0x698bcf8fUL, 0xec9d808aUL, 0xdbf7428bUL, 0x82490489UL,
36.379 - 0xb523c688UL, 0x88649a83UL, 0xbf0e5882UL, 0xe6b01e80UL, 0xd1dadc81UL,
36.380 - 0x54cc9384UL, 0x63a65185UL, 0x3a181787UL, 0x0d72d586UL, 0xa0d0e2a9UL,
36.381 - 0x97ba20a8UL, 0xce0466aaUL, 0xf96ea4abUL, 0x7c78ebaeUL, 0x4b1229afUL,
36.382 - 0x12ac6fadUL, 0x25c6adacUL, 0x1881f1a7UL, 0x2feb33a6UL, 0x765575a4UL,
36.383 - 0x413fb7a5UL, 0xc429f8a0UL, 0xf3433aa1UL, 0xaafd7ca3UL, 0x9d97bea2UL,
36.384 - 0xd073c4b5UL, 0xe71906b4UL, 0xbea740b6UL, 0x89cd82b7UL, 0x0cdbcdb2UL,
36.385 - 0x3bb10fb3UL, 0x620f49b1UL, 0x55658bb0UL, 0x6822d7bbUL, 0x5f4815baUL,
36.386 - 0x06f653b8UL, 0x319c91b9UL, 0xb48adebcUL, 0x83e01cbdUL, 0xda5e5abfUL,
36.387 - 0xed3498beUL
36.388 - },
36.389 - {
36.390 - 0x00000000UL, 0x6567bcb8UL, 0x8bc809aaUL, 0xeeafb512UL, 0x5797628fUL,
36.391 - 0x32f0de37UL, 0xdc5f6b25UL, 0xb938d79dUL, 0xef28b4c5UL, 0x8a4f087dUL,
36.392 - 0x64e0bd6fUL, 0x018701d7UL, 0xb8bfd64aUL, 0xddd86af2UL, 0x3377dfe0UL,
36.393 - 0x56106358UL, 0x9f571950UL, 0xfa30a5e8UL, 0x149f10faUL, 0x71f8ac42UL,
36.394 - 0xc8c07bdfUL, 0xada7c767UL, 0x43087275UL, 0x266fcecdUL, 0x707fad95UL,
36.395 - 0x1518112dUL, 0xfbb7a43fUL, 0x9ed01887UL, 0x27e8cf1aUL, 0x428f73a2UL,
36.396 - 0xac20c6b0UL, 0xc9477a08UL, 0x3eaf32a0UL, 0x5bc88e18UL, 0xb5673b0aUL,
36.397 - 0xd00087b2UL, 0x6938502fUL, 0x0c5fec97UL, 0xe2f05985UL, 0x8797e53dUL,
36.398 - 0xd1878665UL, 0xb4e03addUL, 0x5a4f8fcfUL, 0x3f283377UL, 0x8610e4eaUL,
36.399 - 0xe3775852UL, 0x0dd8ed40UL, 0x68bf51f8UL, 0xa1f82bf0UL, 0xc49f9748UL,
36.400 - 0x2a30225aUL, 0x4f579ee2UL, 0xf66f497fUL, 0x9308f5c7UL, 0x7da740d5UL,
36.401 - 0x18c0fc6dUL, 0x4ed09f35UL, 0x2bb7238dUL, 0xc518969fUL, 0xa07f2a27UL,
36.402 - 0x1947fdbaUL, 0x7c204102UL, 0x928ff410UL, 0xf7e848a8UL, 0x3d58149bUL,
36.403 - 0x583fa823UL, 0xb6901d31UL, 0xd3f7a189UL, 0x6acf7614UL, 0x0fa8caacUL,
36.404 - 0xe1077fbeUL, 0x8460c306UL, 0xd270a05eUL, 0xb7171ce6UL, 0x59b8a9f4UL,
36.405 - 0x3cdf154cUL, 0x85e7c2d1UL, 0xe0807e69UL, 0x0e2fcb7bUL, 0x6b4877c3UL,
36.406 - 0xa20f0dcbUL, 0xc768b173UL, 0x29c70461UL, 0x4ca0b8d9UL, 0xf5986f44UL,
36.407 - 0x90ffd3fcUL, 0x7e5066eeUL, 0x1b37da56UL, 0x4d27b90eUL, 0x284005b6UL,
36.408 - 0xc6efb0a4UL, 0xa3880c1cUL, 0x1ab0db81UL, 0x7fd76739UL, 0x9178d22bUL,
36.409 - 0xf41f6e93UL, 0x03f7263bUL, 0x66909a83UL, 0x883f2f91UL, 0xed589329UL,
36.410 - 0x546044b4UL, 0x3107f80cUL, 0xdfa84d1eUL, 0xbacff1a6UL, 0xecdf92feUL,
36.411 - 0x89b82e46UL, 0x67179b54UL, 0x027027ecUL, 0xbb48f071UL, 0xde2f4cc9UL,
36.412 - 0x3080f9dbUL, 0x55e74563UL, 0x9ca03f6bUL, 0xf9c783d3UL, 0x176836c1UL,
36.413 - 0x720f8a79UL, 0xcb375de4UL, 0xae50e15cUL, 0x40ff544eUL, 0x2598e8f6UL,
36.414 - 0x73888baeUL, 0x16ef3716UL, 0xf8408204UL, 0x9d273ebcUL, 0x241fe921UL,
36.415 - 0x41785599UL, 0xafd7e08bUL, 0xcab05c33UL, 0x3bb659edUL, 0x5ed1e555UL,
36.416 - 0xb07e5047UL, 0xd519ecffUL, 0x6c213b62UL, 0x094687daUL, 0xe7e932c8UL,
36.417 - 0x828e8e70UL, 0xd49eed28UL, 0xb1f95190UL, 0x5f56e482UL, 0x3a31583aUL,
36.418 - 0x83098fa7UL, 0xe66e331fUL, 0x08c1860dUL, 0x6da63ab5UL, 0xa4e140bdUL,
36.419 - 0xc186fc05UL, 0x2f294917UL, 0x4a4ef5afUL, 0xf3762232UL, 0x96119e8aUL,
36.420 - 0x78be2b98UL, 0x1dd99720UL, 0x4bc9f478UL, 0x2eae48c0UL, 0xc001fdd2UL,
36.421 - 0xa566416aUL, 0x1c5e96f7UL, 0x79392a4fUL, 0x97969f5dUL, 0xf2f123e5UL,
36.422 - 0x05196b4dUL, 0x607ed7f5UL, 0x8ed162e7UL, 0xebb6de5fUL, 0x528e09c2UL,
36.423 - 0x37e9b57aUL, 0xd9460068UL, 0xbc21bcd0UL, 0xea31df88UL, 0x8f566330UL,
36.424 - 0x61f9d622UL, 0x049e6a9aUL, 0xbda6bd07UL, 0xd8c101bfUL, 0x366eb4adUL,
36.425 - 0x53090815UL, 0x9a4e721dUL, 0xff29cea5UL, 0x11867bb7UL, 0x74e1c70fUL,
36.426 - 0xcdd91092UL, 0xa8beac2aUL, 0x46111938UL, 0x2376a580UL, 0x7566c6d8UL,
36.427 - 0x10017a60UL, 0xfeaecf72UL, 0x9bc973caUL, 0x22f1a457UL, 0x479618efUL,
36.428 - 0xa939adfdUL, 0xcc5e1145UL, 0x06ee4d76UL, 0x6389f1ceUL, 0x8d2644dcUL,
36.429 - 0xe841f864UL, 0x51792ff9UL, 0x341e9341UL, 0xdab12653UL, 0xbfd69aebUL,
36.430 - 0xe9c6f9b3UL, 0x8ca1450bUL, 0x620ef019UL, 0x07694ca1UL, 0xbe519b3cUL,
36.431 - 0xdb362784UL, 0x35999296UL, 0x50fe2e2eUL, 0x99b95426UL, 0xfcdee89eUL,
36.432 - 0x12715d8cUL, 0x7716e134UL, 0xce2e36a9UL, 0xab498a11UL, 0x45e63f03UL,
36.433 - 0x208183bbUL, 0x7691e0e3UL, 0x13f65c5bUL, 0xfd59e949UL, 0x983e55f1UL,
36.434 - 0x2106826cUL, 0x44613ed4UL, 0xaace8bc6UL, 0xcfa9377eUL, 0x38417fd6UL,
36.435 - 0x5d26c36eUL, 0xb389767cUL, 0xd6eecac4UL, 0x6fd61d59UL, 0x0ab1a1e1UL,
36.436 - 0xe41e14f3UL, 0x8179a84bUL, 0xd769cb13UL, 0xb20e77abUL, 0x5ca1c2b9UL,
36.437 - 0x39c67e01UL, 0x80fea99cUL, 0xe5991524UL, 0x0b36a036UL, 0x6e511c8eUL,
36.438 - 0xa7166686UL, 0xc271da3eUL, 0x2cde6f2cUL, 0x49b9d394UL, 0xf0810409UL,
36.439 - 0x95e6b8b1UL, 0x7b490da3UL, 0x1e2eb11bUL, 0x483ed243UL, 0x2d596efbUL,
36.440 - 0xc3f6dbe9UL, 0xa6916751UL, 0x1fa9b0ccUL, 0x7ace0c74UL, 0x9461b966UL,
36.441 - 0xf10605deUL
36.442 -#endif
36.443 - }
36.444 -};
37.1 --- a/sourcepawn/vm/zlib/deflate.c Tue Nov 07 23:26:40 2006 +0000
37.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
37.3 @@ -1,1736 +0,0 @@
37.4 -/* deflate.c -- compress data using the deflation algorithm
37.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
37.6 - * For conditions of distribution and use, see copyright notice in zlib.h
37.7 - */
37.8 -
37.9 -/*
37.10 - * ALGORITHM
37.11 - *
37.12 - * The "deflation" process depends on being able to identify portions
37.13 - * of the input text which are identical to earlier input (within a
37.14 - * sliding window trailing behind the input currently being processed).
37.15 - *
37.16 - * The most straightforward technique turns out to be the fastest for
37.17 - * most input files: try all possible matches and select the longest.
37.18 - * The key feature of this algorithm is that insertions into the string
37.19 - * dictionary are very simple and thus fast, and deletions are avoided
37.20 - * completely. Insertions are performed at each input character, whereas
37.21 - * string matches are performed only when the previous match ends. So it
37.22 - * is preferable to spend more time in matches to allow very fast string
37.23 - * insertions and avoid deletions. The matching algorithm for small
37.24 - * strings is inspired from that of Rabin & Karp. A brute force approach
37.25 - * is used to find longer strings when a small match has been found.
37.26 - * A similar algorithm is used in comic (by Jan-Mark Wams) and freeze
37.27 - * (by Leonid Broukhis).
37.28 - * A previous version of this file used a more sophisticated algorithm
37.29 - * (by Fiala and Greene) which is guaranteed to run in linear amortized
37.30 - * time, but has a larger average cost, uses more memory and is patented.
37.31 - * However the F&G algorithm may be faster for some highly redundant
37.32 - * files if the parameter max_chain_length (described below) is too large.
37.33 - *
37.34 - * ACKNOWLEDGEMENTS
37.35 - *
37.36 - * The idea of lazy evaluation of matches is due to Jan-Mark Wams, and
37.37 - * I found it in 'freeze' written by Leonid Broukhis.
37.38 - * Thanks to many people for bug reports and testing.
37.39 - *
37.40 - * REFERENCES
37.41 - *
37.42 - * Deutsch, L.P.,"DEFLATE Compressed Data Format Specification".
37.43 - * Available in http://www.ietf.org/rfc/rfc1951.txt
37.44 - *
37.45 - * A description of the Rabin and Karp algorithm is given in the book
37.46 - * "Algorithms" by R. Sedgewick, Addison-Wesley, p252.
37.47 - *
37.48 - * Fiala,E.R., and Greene,D.H.
37.49 - * Data Compression with Finite Windows, Comm.ACM, 32,4 (1989) 490-595
37.50 - *
37.51 - */
37.52 -
37.53 -/* @(#) $Id$ */
37.54 -
37.55 -#include "deflate.h"
37.56 -
37.57 -const char deflate_copyright[] =
37.58 - " deflate 1.2.3 Copyright 1995-2005 Jean-loup Gailly ";
37.59 -/*
37.60 - If you use the zlib library in a product, an acknowledgment is welcome
37.61 - in the documentation of your product. If for some reason you cannot
37.62 - include such an acknowledgment, I would appreciate that you keep this
37.63 - copyright string in the executable of your product.
37.64 - */
37.65 -
37.66 -/* ===========================================================================
37.67 - * Function prototypes.
37.68 - */
37.69 -typedef enum {
37.70 - need_more, /* block not completed, need more input or more output */
37.71 - block_done, /* block flush performed */
37.72 - finish_started, /* finish started, need only more output at next deflate */
37.73 - finish_done /* finish done, accept no more input or output */
37.74 -} block_state;
37.75 -
37.76 -typedef block_state (*compress_func) OF((deflate_state *s, int flush));
37.77 -/* Compression function. Returns the block state after the call. */
37.78 -
37.79 -local void fill_window OF((deflate_state *s));
37.80 -local block_state deflate_stored OF((deflate_state *s, int flush));
37.81 -local block_state deflate_fast OF((deflate_state *s, int flush));
37.82 -#ifndef FASTEST
37.83 -local block_state deflate_slow OF((deflate_state *s, int flush));
37.84 -#endif
37.85 -local void lm_init OF((deflate_state *s));
37.86 -local void putShortMSB OF((deflate_state *s, uInt b));
37.87 -local void flush_pending OF((z_streamp strm));
37.88 -local int read_buf OF((z_streamp strm, Bytef *buf, unsigned size));
37.89 -#ifndef FASTEST
37.90 -#ifdef ASMV
37.91 - void match_init OF((void)); /* asm code initialization */
37.92 - uInt longest_match OF((deflate_state *s, IPos cur_match));
37.93 -#else
37.94 -local uInt longest_match OF((deflate_state *s, IPos cur_match));
37.95 -#endif
37.96 -#endif
37.97 -local uInt longest_match_fast OF((deflate_state *s, IPos cur_match));
37.98 -
37.99 -#ifdef DEBUG
37.100 -local void check_match OF((deflate_state *s, IPos start, IPos match,
37.101 - int length));
37.102 -#endif
37.103 -
37.104 -/* ===========================================================================
37.105 - * Local data
37.106 - */
37.107 -
37.108 -#define NIL 0
37.109 -/* Tail of hash chains */
37.110 -
37.111 -#ifndef TOO_FAR
37.112 -# define TOO_FAR 4096
37.113 -#endif
37.114 -/* Matches of length 3 are discarded if their distance exceeds TOO_FAR */
37.115 -
37.116 -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
37.117 -/* Minimum amount of lookahead, except at the end of the input file.
37.118 - * See deflate.c for comments about the MIN_MATCH+1.
37.119 - */
37.120 -
37.121 -/* Values for max_lazy_match, good_match and max_chain_length, depending on
37.122 - * the desired pack level (0..9). The values given below have been tuned to
37.123 - * exclude worst case performance for pathological files. Better values may be
37.124 - * found for specific files.
37.125 - */
37.126 -typedef struct config_s {
37.127 - ush good_length; /* reduce lazy search above this match length */
37.128 - ush max_lazy; /* do not perform lazy search above this match length */
37.129 - ush nice_length; /* quit search above this match length */
37.130 - ush max_chain;
37.131 - compress_func func;
37.132 -} config;
37.133 -
37.134 -#ifdef FASTEST
37.135 -local const config configuration_table[2] = {
37.136 -/* good lazy nice chain */
37.137 -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
37.138 -/* 1 */ {4, 4, 8, 4, deflate_fast}}; /* max speed, no lazy matches */
37.139 -#else
37.140 -local const config configuration_table[10] = {
37.141 -/* good lazy nice chain */
37.142 -/* 0 */ {0, 0, 0, 0, deflate_stored}, /* store only */
37.143 -/* 1 */ {4, 4, 8, 4, deflate_fast}, /* max speed, no lazy matches */
37.144 -/* 2 */ {4, 5, 16, 8, deflate_fast},
37.145 -/* 3 */ {4, 6, 32, 32, deflate_fast},
37.146 -
37.147 -/* 4 */ {4, 4, 16, 16, deflate_slow}, /* lazy matches */
37.148 -/* 5 */ {8, 16, 32, 32, deflate_slow},
37.149 -/* 6 */ {8, 16, 128, 128, deflate_slow},
37.150 -/* 7 */ {8, 32, 128, 256, deflate_slow},
37.151 -/* 8 */ {32, 128, 258, 1024, deflate_slow},
37.152 -/* 9 */ {32, 258, 258, 4096, deflate_slow}}; /* max compression */
37.153 -#endif
37.154 -
37.155 -/* Note: the deflate() code requires max_lazy >= MIN_MATCH and max_chain >= 4
37.156 - * For deflate_fast() (levels <= 3) good is ignored and lazy has a different
37.157 - * meaning.
37.158 - */
37.159 -
37.160 -#define EQUAL 0
37.161 -/* result of memcmp for equal strings */
37.162 -
37.163 -#ifndef NO_DUMMY_DECL
37.164 -struct static_tree_desc_s {int dummy;}; /* for buggy compilers */
37.165 -#endif
37.166 -
37.167 -/* ===========================================================================
37.168 - * Update a hash value with the given input byte
37.169 - * IN assertion: all calls to to UPDATE_HASH are made with consecutive
37.170 - * input characters, so that a running hash key can be computed from the
37.171 - * previous key instead of complete recalculation each time.
37.172 - */
37.173 -#define UPDATE_HASH(s,h,c) (h = (((h)<<s->hash_shift) ^ (c)) & s->hash_mask)
37.174 -
37.175 -
37.176 -/* ===========================================================================
37.177 - * Insert string str in the dictionary and set match_head to the previous head
37.178 - * of the hash chain (the most recent string with same hash key). Return
37.179 - * the previous length of the hash chain.
37.180 - * If this file is compiled with -DFASTEST, the compression level is forced
37.181 - * to 1, and no hash chains are maintained.
37.182 - * IN assertion: all calls to to INSERT_STRING are made with consecutive
37.183 - * input characters and the first MIN_MATCH bytes of str are valid
37.184 - * (except for the last MIN_MATCH-1 bytes of the input file).
37.185 - */
37.186 -#ifdef FASTEST
37.187 -#define INSERT_STRING(s, str, match_head) \
37.188 - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
37.189 - match_head = s->head[s->ins_h], \
37.190 - s->head[s->ins_h] = (Pos)(str))
37.191 -#else
37.192 -#define INSERT_STRING(s, str, match_head) \
37.193 - (UPDATE_HASH(s, s->ins_h, s->window[(str) + (MIN_MATCH-1)]), \
37.194 - match_head = s->prev[(str) & s->w_mask] = s->head[s->ins_h], \
37.195 - s->head[s->ins_h] = (Pos)(str))
37.196 -#endif
37.197 -
37.198 -/* ===========================================================================
37.199 - * Initialize the hash table (avoiding 64K overflow for 16 bit systems).
37.200 - * prev[] will be initialized on the fly.
37.201 - */
37.202 -#define CLEAR_HASH(s) \
37.203 - s->head[s->hash_size-1] = NIL; \
37.204 - zmemzero((Bytef *)s->head, (unsigned)(s->hash_size-1)*sizeof(*s->head));
37.205 -
37.206 -/* ========================================================================= */
37.207 -int ZEXPORT deflateInit_(strm, level, version, stream_size)
37.208 - z_streamp strm;
37.209 - int level;
37.210 - const char *version;
37.211 - int stream_size;
37.212 -{
37.213 - return deflateInit2_(strm, level, Z_DEFLATED, MAX_WBITS, DEF_MEM_LEVEL,
37.214 - Z_DEFAULT_STRATEGY, version, stream_size);
37.215 - /* To do: ignore strm->next_in if we use it as window */
37.216 -}
37.217 -
37.218 -/* ========================================================================= */
37.219 -int ZEXPORT deflateInit2_(strm, level, method, windowBits, memLevel, strategy,
37.220 - version, stream_size)
37.221 - z_streamp strm;
37.222 - int level;
37.223 - int method;
37.224 - int windowBits;
37.225 - int memLevel;
37.226 - int strategy;
37.227 - const char *version;
37.228 - int stream_size;
37.229 -{
37.230 - deflate_state *s;
37.231 - int wrap = 1;
37.232 - static const char my_version[] = ZLIB_VERSION;
37.233 -
37.234 - ushf *overlay;
37.235 - /* We overlay pending_buf and d_buf+l_buf. This works since the average
37.236 - * output size for (length,distance) codes is <= 24 bits.
37.237 - */
37.238 -
37.239 - if (version == Z_NULL || version[0] != my_version[0] ||
37.240 - stream_size != sizeof(z_stream)) {
37.241 - return Z_VERSION_ERROR;
37.242 - }
37.243 - if (strm == Z_NULL) return Z_STREAM_ERROR;
37.244 -
37.245 - strm->msg = Z_NULL;
37.246 - if (strm->zalloc == (alloc_func)0) {
37.247 - strm->zalloc = zcalloc;
37.248 - strm->opaque = (voidpf)0;
37.249 - }
37.250 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
37.251 -
37.252 -#ifdef FASTEST
37.253 - if (level != 0) level = 1;
37.254 -#else
37.255 - if (level == Z_DEFAULT_COMPRESSION) level = 6;
37.256 -#endif
37.257 -
37.258 - if (windowBits < 0) { /* suppress zlib wrapper */
37.259 - wrap = 0;
37.260 - windowBits = -windowBits;
37.261 - }
37.262 -#ifdef GZIP
37.263 - else if (windowBits > 15) {
37.264 - wrap = 2; /* write gzip wrapper instead */
37.265 - windowBits -= 16;
37.266 - }
37.267 -#endif
37.268 - if (memLevel < 1 || memLevel > MAX_MEM_LEVEL || method != Z_DEFLATED ||
37.269 - windowBits < 8 || windowBits > 15 || level < 0 || level > 9 ||
37.270 - strategy < 0 || strategy > Z_FIXED) {
37.271 - return Z_STREAM_ERROR;
37.272 - }
37.273 - if (windowBits == 8) windowBits = 9; /* until 256-byte window bug fixed */
37.274 - s = (deflate_state *) ZALLOC(strm, 1, sizeof(deflate_state));
37.275 - if (s == Z_NULL) return Z_MEM_ERROR;
37.276 - strm->state = (struct internal_state FAR *)s;
37.277 - s->strm = strm;
37.278 -
37.279 - s->wrap = wrap;
37.280 - s->gzhead = Z_NULL;
37.281 - s->w_bits = windowBits;
37.282 - s->w_size = 1 << s->w_bits;
37.283 - s->w_mask = s->w_size - 1;
37.284 -
37.285 - s->hash_bits = memLevel + 7;
37.286 - s->hash_size = 1 << s->hash_bits;
37.287 - s->hash_mask = s->hash_size - 1;
37.288 - s->hash_shift = ((s->hash_bits+MIN_MATCH-1)/MIN_MATCH);
37.289 -
37.290 - s->window = (Bytef *) ZALLOC(strm, s->w_size, 2*sizeof(Byte));
37.291 - s->prev = (Posf *) ZALLOC(strm, s->w_size, sizeof(Pos));
37.292 - s->head = (Posf *) ZALLOC(strm, s->hash_size, sizeof(Pos));
37.293 -
37.294 - s->lit_bufsize = 1 << (memLevel + 6); /* 16K elements by default */
37.295 -
37.296 - overlay = (ushf *) ZALLOC(strm, s->lit_bufsize, sizeof(ush)+2);
37.297 - s->pending_buf = (uchf *) overlay;
37.298 - s->pending_buf_size = (ulg)s->lit_bufsize * (sizeof(ush)+2L);
37.299 -
37.300 - if (s->window == Z_NULL || s->prev == Z_NULL || s->head == Z_NULL ||
37.301 - s->pending_buf == Z_NULL) {
37.302 - s->status = FINISH_STATE;
37.303 - strm->msg = (char*)ERR_MSG(Z_MEM_ERROR);
37.304 - deflateEnd (strm);
37.305 - return Z_MEM_ERROR;
37.306 - }
37.307 - s->d_buf = overlay + s->lit_bufsize/sizeof(ush);
37.308 - s->l_buf = s->pending_buf + (1+sizeof(ush))*s->lit_bufsize;
37.309 -
37.310 - s->level = level;
37.311 - s->strategy = strategy;
37.312 - s->method = (Byte)method;
37.313 -
37.314 - return deflateReset(strm);
37.315 -}
37.316 -
37.317 -/* ========================================================================= */
37.318 -int ZEXPORT deflateSetDictionary (strm, dictionary, dictLength)
37.319 - z_streamp strm;
37.320 - const Bytef *dictionary;
37.321 - uInt dictLength;
37.322 -{
37.323 - deflate_state *s;
37.324 - uInt length = dictLength;
37.325 - uInt n;
37.326 - IPos hash_head = 0;
37.327 -
37.328 - if (strm == Z_NULL || strm->state == Z_NULL || dictionary == Z_NULL ||
37.329 - strm->state->wrap == 2 ||
37.330 - (strm->state->wrap == 1 && strm->state->status != INIT_STATE))
37.331 - return Z_STREAM_ERROR;
37.332 -
37.333 - s = strm->state;
37.334 - if (s->wrap)
37.335 - strm->adler = adler32(strm->adler, dictionary, dictLength);
37.336 -
37.337 - if (length < MIN_MATCH) return Z_OK;
37.338 - if (length > MAX_DIST(s)) {
37.339 - length = MAX_DIST(s);
37.340 - dictionary += dictLength - length; /* use the tail of the dictionary */
37.341 - }
37.342 - zmemcpy(s->window, dictionary, length);
37.343 - s->strstart = length;
37.344 - s->block_start = (long)length;
37.345 -
37.346 - /* Insert all strings in the hash table (except for the last two bytes).
37.347 - * s->lookahead stays null, so s->ins_h will be recomputed at the next
37.348 - * call of fill_window.
37.349 - */
37.350 - s->ins_h = s->window[0];
37.351 - UPDATE_HASH(s, s->ins_h, s->window[1]);
37.352 - for (n = 0; n <= length - MIN_MATCH; n++) {
37.353 - INSERT_STRING(s, n, hash_head);
37.354 - }
37.355 - if (hash_head) hash_head = 0; /* to make compiler happy */
37.356 - return Z_OK;
37.357 -}
37.358 -
37.359 -/* ========================================================================= */
37.360 -int ZEXPORT deflateReset (strm)
37.361 - z_streamp strm;
37.362 -{
37.363 - deflate_state *s;
37.364 -
37.365 - if (strm == Z_NULL || strm->state == Z_NULL ||
37.366 - strm->zalloc == (alloc_func)0 || strm->zfree == (free_func)0) {
37.367 - return Z_STREAM_ERROR;
37.368 - }
37.369 -
37.370 - strm->total_in = strm->total_out = 0;
37.371 - strm->msg = Z_NULL; /* use zfree if we ever allocate msg dynamically */
37.372 - strm->data_type = Z_UNKNOWN;
37.373 -
37.374 - s = (deflate_state *)strm->state;
37.375 - s->pending = 0;
37.376 - s->pending_out = s->pending_buf;
37.377 -
37.378 - if (s->wrap < 0) {
37.379 - s->wrap = -s->wrap; /* was made negative by deflate(..., Z_FINISH); */
37.380 - }
37.381 - s->status = s->wrap ? INIT_STATE : BUSY_STATE;
37.382 - strm->adler =
37.383 -#ifdef GZIP
37.384 - s->wrap == 2 ? crc32(0L, Z_NULL, 0) :
37.385 -#endif
37.386 - adler32(0L, Z_NULL, 0);
37.387 - s->last_flush = Z_NO_FLUSH;
37.388 -
37.389 - _tr_init(s);
37.390 - lm_init(s);
37.391 -
37.392 - return Z_OK;
37.393 -}
37.394 -
37.395 -/* ========================================================================= */
37.396 -int ZEXPORT deflateSetHeader (strm, head)
37.397 - z_streamp strm;
37.398 - gz_headerp head;
37.399 -{
37.400 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37.401 - if (strm->state->wrap != 2) return Z_STREAM_ERROR;
37.402 - strm->state->gzhead = head;
37.403 - return Z_OK;
37.404 -}
37.405 -
37.406 -/* ========================================================================= */
37.407 -int ZEXPORT deflatePrime (strm, bits, value)
37.408 - z_streamp strm;
37.409 - int bits;
37.410 - int value;
37.411 -{
37.412 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37.413 - strm->state->bi_valid = bits;
37.414 - strm->state->bi_buf = (ush)(value & ((1 << bits) - 1));
37.415 - return Z_OK;
37.416 -}
37.417 -
37.418 -/* ========================================================================= */
37.419 -int ZEXPORT deflateParams(strm, level, strategy)
37.420 - z_streamp strm;
37.421 - int level;
37.422 - int strategy;
37.423 -{
37.424 - deflate_state *s;
37.425 - compress_func func;
37.426 - int err = Z_OK;
37.427 -
37.428 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37.429 - s = strm->state;
37.430 -
37.431 -#ifdef FASTEST
37.432 - if (level != 0) level = 1;
37.433 -#else
37.434 - if (level == Z_DEFAULT_COMPRESSION) level = 6;
37.435 -#endif
37.436 - if (level < 0 || level > 9 || strategy < 0 || strategy > Z_FIXED) {
37.437 - return Z_STREAM_ERROR;
37.438 - }
37.439 - func = configuration_table[s->level].func;
37.440 -
37.441 - if (func != configuration_table[level].func && strm->total_in != 0) {
37.442 - /* Flush the last buffer: */
37.443 - err = deflate(strm, Z_PARTIAL_FLUSH);
37.444 - }
37.445 - if (s->level != level) {
37.446 - s->level = level;
37.447 - s->max_lazy_match = configuration_table[level].max_lazy;
37.448 - s->good_match = configuration_table[level].good_length;
37.449 - s->nice_match = configuration_table[level].nice_length;
37.450 - s->max_chain_length = configuration_table[level].max_chain;
37.451 - }
37.452 - s->strategy = strategy;
37.453 - return err;
37.454 -}
37.455 -
37.456 -/* ========================================================================= */
37.457 -int ZEXPORT deflateTune(strm, good_length, max_lazy, nice_length, max_chain)
37.458 - z_streamp strm;
37.459 - int good_length;
37.460 - int max_lazy;
37.461 - int nice_length;
37.462 - int max_chain;
37.463 -{
37.464 - deflate_state *s;
37.465 -
37.466 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37.467 - s = strm->state;
37.468 - s->good_match = good_length;
37.469 - s->max_lazy_match = max_lazy;
37.470 - s->nice_match = nice_length;
37.471 - s->max_chain_length = max_chain;
37.472 - return Z_OK;
37.473 -}
37.474 -
37.475 -/* =========================================================================
37.476 - * For the default windowBits of 15 and memLevel of 8, this function returns
37.477 - * a close to exact, as well as small, upper bound on the compressed size.
37.478 - * They are coded as constants here for a reason--if the #define's are
37.479 - * changed, then this function needs to be changed as well. The return
37.480 - * value for 15 and 8 only works for those exact settings.
37.481 - *
37.482 - * For any setting other than those defaults for windowBits and memLevel,
37.483 - * the value returned is a conservative worst case for the maximum expansion
37.484 - * resulting from using fixed blocks instead of stored blocks, which deflate
37.485 - * can emit on compressed data for some combinations of the parameters.
37.486 - *
37.487 - * This function could be more sophisticated to provide closer upper bounds
37.488 - * for every combination of windowBits and memLevel, as well as wrap.
37.489 - * But even the conservative upper bound of about 14% expansion does not
37.490 - * seem onerous for output buffer allocation.
37.491 - */
37.492 -uLong ZEXPORT deflateBound(strm, sourceLen)
37.493 - z_streamp strm;
37.494 - uLong sourceLen;
37.495 -{
37.496 - deflate_state *s;
37.497 - uLong destLen;
37.498 -
37.499 - /* conservative upper bound */
37.500 - destLen = sourceLen +
37.501 - ((sourceLen + 7) >> 3) + ((sourceLen + 63) >> 6) + 11;
37.502 -
37.503 - /* if can't get parameters, return conservative bound */
37.504 - if (strm == Z_NULL || strm->state == Z_NULL)
37.505 - return destLen;
37.506 -
37.507 - /* if not default parameters, return conservative bound */
37.508 - s = strm->state;
37.509 - if (s->w_bits != 15 || s->hash_bits != 8 + 7)
37.510 - return destLen;
37.511 -
37.512 - /* default settings: return tight bound for that case */
37.513 - return compressBound(sourceLen);
37.514 -}
37.515 -
37.516 -/* =========================================================================
37.517 - * Put a short in the pending buffer. The 16-bit value is put in MSB order.
37.518 - * IN assertion: the stream state is correct and there is enough room in
37.519 - * pending_buf.
37.520 - */
37.521 -local void putShortMSB (s, b)
37.522 - deflate_state *s;
37.523 - uInt b;
37.524 -{
37.525 - put_byte(s, (Byte)(b >> 8));
37.526 - put_byte(s, (Byte)(b & 0xff));
37.527 -}
37.528 -
37.529 -/* =========================================================================
37.530 - * Flush as much pending output as possible. All deflate() output goes
37.531 - * through this function so some applications may wish to modify it
37.532 - * to avoid allocating a large strm->next_out buffer and copying into it.
37.533 - * (See also read_buf()).
37.534 - */
37.535 -local void flush_pending(strm)
37.536 - z_streamp strm;
37.537 -{
37.538 - unsigned len = strm->state->pending;
37.539 -
37.540 - if (len > strm->avail_out) len = strm->avail_out;
37.541 - if (len == 0) return;
37.542 -
37.543 - zmemcpy(strm->next_out, strm->state->pending_out, len);
37.544 - strm->next_out += len;
37.545 - strm->state->pending_out += len;
37.546 - strm->total_out += len;
37.547 - strm->avail_out -= len;
37.548 - strm->state->pending -= len;
37.549 - if (strm->state->pending == 0) {
37.550 - strm->state->pending_out = strm->state->pending_buf;
37.551 - }
37.552 -}
37.553 -
37.554 -/* ========================================================================= */
37.555 -int ZEXPORT deflate (strm, flush)
37.556 - z_streamp strm;
37.557 - int flush;
37.558 -{
37.559 - int old_flush; /* value of flush param for previous deflate call */
37.560 - deflate_state *s;
37.561 -
37.562 - if (strm == Z_NULL || strm->state == Z_NULL ||
37.563 - flush > Z_FINISH || flush < 0) {
37.564 - return Z_STREAM_ERROR;
37.565 - }
37.566 - s = strm->state;
37.567 -
37.568 - if (strm->next_out == Z_NULL ||
37.569 - (strm->next_in == Z_NULL && strm->avail_in != 0) ||
37.570 - (s->status == FINISH_STATE && flush != Z_FINISH)) {
37.571 - ERR_RETURN(strm, Z_STREAM_ERROR);
37.572 - }
37.573 - if (strm->avail_out == 0) ERR_RETURN(strm, Z_BUF_ERROR);
37.574 -
37.575 - s->strm = strm; /* just in case */
37.576 - old_flush = s->last_flush;
37.577 - s->last_flush = flush;
37.578 -
37.579 - /* Write the header */
37.580 - if (s->status == INIT_STATE) {
37.581 -#ifdef GZIP
37.582 - if (s->wrap == 2) {
37.583 - strm->adler = crc32(0L, Z_NULL, 0);
37.584 - put_byte(s, 31);
37.585 - put_byte(s, 139);
37.586 - put_byte(s, 8);
37.587 - if (s->gzhead == NULL) {
37.588 - put_byte(s, 0);
37.589 - put_byte(s, 0);
37.590 - put_byte(s, 0);
37.591 - put_byte(s, 0);
37.592 - put_byte(s, 0);
37.593 - put_byte(s, s->level == 9 ? 2 :
37.594 - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
37.595 - 4 : 0));
37.596 - put_byte(s, OS_CODE);
37.597 - s->status = BUSY_STATE;
37.598 - }
37.599 - else {
37.600 - put_byte(s, (s->gzhead->text ? 1 : 0) +
37.601 - (s->gzhead->hcrc ? 2 : 0) +
37.602 - (s->gzhead->extra == Z_NULL ? 0 : 4) +
37.603 - (s->gzhead->name == Z_NULL ? 0 : 8) +
37.604 - (s->gzhead->comment == Z_NULL ? 0 : 16)
37.605 - );
37.606 - put_byte(s, (Byte)(s->gzhead->time & 0xff));
37.607 - put_byte(s, (Byte)((s->gzhead->time >> 8) & 0xff));
37.608 - put_byte(s, (Byte)((s->gzhead->time >> 16) & 0xff));
37.609 - put_byte(s, (Byte)((s->gzhead->time >> 24) & 0xff));
37.610 - put_byte(s, s->level == 9 ? 2 :
37.611 - (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2 ?
37.612 - 4 : 0));
37.613 - put_byte(s, s->gzhead->os & 0xff);
37.614 - if (s->gzhead->extra != NULL) {
37.615 - put_byte(s, s->gzhead->extra_len & 0xff);
37.616 - put_byte(s, (s->gzhead->extra_len >> 8) & 0xff);
37.617 - }
37.618 - if (s->gzhead->hcrc)
37.619 - strm->adler = crc32(strm->adler, s->pending_buf,
37.620 - s->pending);
37.621 - s->gzindex = 0;
37.622 - s->status = EXTRA_STATE;
37.623 - }
37.624 - }
37.625 - else
37.626 -#endif
37.627 - {
37.628 - uInt header = (Z_DEFLATED + ((s->w_bits-8)<<4)) << 8;
37.629 - uInt level_flags;
37.630 -
37.631 - if (s->strategy >= Z_HUFFMAN_ONLY || s->level < 2)
37.632 - level_flags = 0;
37.633 - else if (s->level < 6)
37.634 - level_flags = 1;
37.635 - else if (s->level == 6)
37.636 - level_flags = 2;
37.637 - else
37.638 - level_flags = 3;
37.639 - header |= (level_flags << 6);
37.640 - if (s->strstart != 0) header |= PRESET_DICT;
37.641 - header += 31 - (header % 31);
37.642 -
37.643 - s->status = BUSY_STATE;
37.644 - putShortMSB(s, header);
37.645 -
37.646 - /* Save the adler32 of the preset dictionary: */
37.647 - if (s->strstart != 0) {
37.648 - putShortMSB(s, (uInt)(strm->adler >> 16));
37.649 - putShortMSB(s, (uInt)(strm->adler & 0xffff));
37.650 - }
37.651 - strm->adler = adler32(0L, Z_NULL, 0);
37.652 - }
37.653 - }
37.654 -#ifdef GZIP
37.655 - if (s->status == EXTRA_STATE) {
37.656 - if (s->gzhead->extra != NULL) {
37.657 - uInt beg = s->pending; /* start of bytes to update crc */
37.658 -
37.659 - while (s->gzindex < (s->gzhead->extra_len & 0xffff)) {
37.660 - if (s->pending == s->pending_buf_size) {
37.661 - if (s->gzhead->hcrc && s->pending > beg)
37.662 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.663 - s->pending - beg);
37.664 - flush_pending(strm);
37.665 - beg = s->pending;
37.666 - if (s->pending == s->pending_buf_size)
37.667 - break;
37.668 - }
37.669 - put_byte(s, s->gzhead->extra[s->gzindex]);
37.670 - s->gzindex++;
37.671 - }
37.672 - if (s->gzhead->hcrc && s->pending > beg)
37.673 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.674 - s->pending - beg);
37.675 - if (s->gzindex == s->gzhead->extra_len) {
37.676 - s->gzindex = 0;
37.677 - s->status = NAME_STATE;
37.678 - }
37.679 - }
37.680 - else
37.681 - s->status = NAME_STATE;
37.682 - }
37.683 - if (s->status == NAME_STATE) {
37.684 - if (s->gzhead->name != NULL) {
37.685 - uInt beg = s->pending; /* start of bytes to update crc */
37.686 - int val;
37.687 -
37.688 - do {
37.689 - if (s->pending == s->pending_buf_size) {
37.690 - if (s->gzhead->hcrc && s->pending > beg)
37.691 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.692 - s->pending - beg);
37.693 - flush_pending(strm);
37.694 - beg = s->pending;
37.695 - if (s->pending == s->pending_buf_size) {
37.696 - val = 1;
37.697 - break;
37.698 - }
37.699 - }
37.700 - val = s->gzhead->name[s->gzindex++];
37.701 - put_byte(s, val);
37.702 - } while (val != 0);
37.703 - if (s->gzhead->hcrc && s->pending > beg)
37.704 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.705 - s->pending - beg);
37.706 - if (val == 0) {
37.707 - s->gzindex = 0;
37.708 - s->status = COMMENT_STATE;
37.709 - }
37.710 - }
37.711 - else
37.712 - s->status = COMMENT_STATE;
37.713 - }
37.714 - if (s->status == COMMENT_STATE) {
37.715 - if (s->gzhead->comment != NULL) {
37.716 - uInt beg = s->pending; /* start of bytes to update crc */
37.717 - int val;
37.718 -
37.719 - do {
37.720 - if (s->pending == s->pending_buf_size) {
37.721 - if (s->gzhead->hcrc && s->pending > beg)
37.722 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.723 - s->pending - beg);
37.724 - flush_pending(strm);
37.725 - beg = s->pending;
37.726 - if (s->pending == s->pending_buf_size) {
37.727 - val = 1;
37.728 - break;
37.729 - }
37.730 - }
37.731 - val = s->gzhead->comment[s->gzindex++];
37.732 - put_byte(s, val);
37.733 - } while (val != 0);
37.734 - if (s->gzhead->hcrc && s->pending > beg)
37.735 - strm->adler = crc32(strm->adler, s->pending_buf + beg,
37.736 - s->pending - beg);
37.737 - if (val == 0)
37.738 - s->status = HCRC_STATE;
37.739 - }
37.740 - else
37.741 - s->status = HCRC_STATE;
37.742 - }
37.743 - if (s->status == HCRC_STATE) {
37.744 - if (s->gzhead->hcrc) {
37.745 - if (s->pending + 2 > s->pending_buf_size)
37.746 - flush_pending(strm);
37.747 - if (s->pending + 2 <= s->pending_buf_size) {
37.748 - put_byte(s, (Byte)(strm->adler & 0xff));
37.749 - put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
37.750 - strm->adler = crc32(0L, Z_NULL, 0);
37.751 - s->status = BUSY_STATE;
37.752 - }
37.753 - }
37.754 - else
37.755 - s->status = BUSY_STATE;
37.756 - }
37.757 -#endif
37.758 -
37.759 - /* Flush as much pending output as possible */
37.760 - if (s->pending != 0) {
37.761 - flush_pending(strm);
37.762 - if (strm->avail_out == 0) {
37.763 - /* Since avail_out is 0, deflate will be called again with
37.764 - * more output space, but possibly with both pending and
37.765 - * avail_in equal to zero. There won't be anything to do,
37.766 - * but this is not an error situation so make sure we
37.767 - * return OK instead of BUF_ERROR at next call of deflate:
37.768 - */
37.769 - s->last_flush = -1;
37.770 - return Z_OK;
37.771 - }
37.772 -
37.773 - /* Make sure there is something to do and avoid duplicate consecutive
37.774 - * flushes. For repeated and useless calls with Z_FINISH, we keep
37.775 - * returning Z_STREAM_END instead of Z_BUF_ERROR.
37.776 - */
37.777 - } else if (strm->avail_in == 0 && flush <= old_flush &&
37.778 - flush != Z_FINISH) {
37.779 - ERR_RETURN(strm, Z_BUF_ERROR);
37.780 - }
37.781 -
37.782 - /* User must not provide more input after the first FINISH: */
37.783 - if (s->status == FINISH_STATE && strm->avail_in != 0) {
37.784 - ERR_RETURN(strm, Z_BUF_ERROR);
37.785 - }
37.786 -
37.787 - /* Start a new block or continue the current one.
37.788 - */
37.789 - if (strm->avail_in != 0 || s->lookahead != 0 ||
37.790 - (flush != Z_NO_FLUSH && s->status != FINISH_STATE)) {
37.791 - block_state bstate;
37.792 -
37.793 - bstate = (*(configuration_table[s->level].func))(s, flush);
37.794 -
37.795 - if (bstate == finish_started || bstate == finish_done) {
37.796 - s->status = FINISH_STATE;
37.797 - }
37.798 - if (bstate == need_more || bstate == finish_started) {
37.799 - if (strm->avail_out == 0) {
37.800 - s->last_flush = -1; /* avoid BUF_ERROR next call, see above */
37.801 - }
37.802 - return Z_OK;
37.803 - /* If flush != Z_NO_FLUSH && avail_out == 0, the next call
37.804 - * of deflate should use the same flush parameter to make sure
37.805 - * that the flush is complete. So we don't have to output an
37.806 - * empty block here, this will be done at next call. This also
37.807 - * ensures that for a very small output buffer, we emit at most
37.808 - * one empty block.
37.809 - */
37.810 - }
37.811 - if (bstate == block_done) {
37.812 - if (flush == Z_PARTIAL_FLUSH) {
37.813 - _tr_align(s);
37.814 - } else { /* FULL_FLUSH or SYNC_FLUSH */
37.815 - _tr_stored_block(s, (char*)0, 0L, 0);
37.816 - /* For a full flush, this empty block will be recognized
37.817 - * as a special marker by inflate_sync().
37.818 - */
37.819 - if (flush == Z_FULL_FLUSH) {
37.820 - CLEAR_HASH(s); /* forget history */
37.821 - }
37.822 - }
37.823 - flush_pending(strm);
37.824 - if (strm->avail_out == 0) {
37.825 - s->last_flush = -1; /* avoid BUF_ERROR at next call, see above */
37.826 - return Z_OK;
37.827 - }
37.828 - }
37.829 - }
37.830 - Assert(strm->avail_out > 0, "bug2");
37.831 -
37.832 - if (flush != Z_FINISH) return Z_OK;
37.833 - if (s->wrap <= 0) return Z_STREAM_END;
37.834 -
37.835 - /* Write the trailer */
37.836 -#ifdef GZIP
37.837 - if (s->wrap == 2) {
37.838 - put_byte(s, (Byte)(strm->adler & 0xff));
37.839 - put_byte(s, (Byte)((strm->adler >> 8) & 0xff));
37.840 - put_byte(s, (Byte)((strm->adler >> 16) & 0xff));
37.841 - put_byte(s, (Byte)((strm->adler >> 24) & 0xff));
37.842 - put_byte(s, (Byte)(strm->total_in & 0xff));
37.843 - put_byte(s, (Byte)((strm->total_in >> 8) & 0xff));
37.844 - put_byte(s, (Byte)((strm->total_in >> 16) & 0xff));
37.845 - put_byte(s, (Byte)((strm->total_in >> 24) & 0xff));
37.846 - }
37.847 - else
37.848 -#endif
37.849 - {
37.850 - putShortMSB(s, (uInt)(strm->adler >> 16));
37.851 - putShortMSB(s, (uInt)(strm->adler & 0xffff));
37.852 - }
37.853 - flush_pending(strm);
37.854 - /* If avail_out is zero, the application will call deflate again
37.855 - * to flush the rest.
37.856 - */
37.857 - if (s->wrap > 0) s->wrap = -s->wrap; /* write the trailer only once! */
37.858 - return s->pending != 0 ? Z_OK : Z_STREAM_END;
37.859 -}
37.860 -
37.861 -/* ========================================================================= */
37.862 -int ZEXPORT deflateEnd (strm)
37.863 - z_streamp strm;
37.864 -{
37.865 - int status;
37.866 -
37.867 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
37.868 -
37.869 - status = strm->state->status;
37.870 - if (status != INIT_STATE &&
37.871 - status != EXTRA_STATE &&
37.872 - status != NAME_STATE &&
37.873 - status != COMMENT_STATE &&
37.874 - status != HCRC_STATE &&
37.875 - status != BUSY_STATE &&
37.876 - status != FINISH_STATE) {
37.877 - return Z_STREAM_ERROR;
37.878 - }
37.879 -
37.880 - /* Deallocate in reverse order of allocations: */
37.881 - TRY_FREE(strm, strm->state->pending_buf);
37.882 - TRY_FREE(strm, strm->state->head);
37.883 - TRY_FREE(strm, strm->state->prev);
37.884 - TRY_FREE(strm, strm->state->window);
37.885 -
37.886 - ZFREE(strm, strm->state);
37.887 - strm->state = Z_NULL;
37.888 -
37.889 - return status == BUSY_STATE ? Z_DATA_ERROR : Z_OK;
37.890 -}
37.891 -
37.892 -/* =========================================================================
37.893 - * Copy the source state to the destination state.
37.894 - * To simplify the source, this is not supported for 16-bit MSDOS (which
37.895 - * doesn't have enough memory anyway to duplicate compression states).
37.896 - */
37.897 -int ZEXPORT deflateCopy (dest, source)
37.898 - z_streamp dest;
37.899 - z_streamp source;
37.900 -{
37.901 -#ifdef MAXSEG_64K
37.902 - return Z_STREAM_ERROR;
37.903 -#else
37.904 - deflate_state *ds;
37.905 - deflate_state *ss;
37.906 - ushf *overlay;
37.907 -
37.908 -
37.909 - if (source == Z_NULL || dest == Z_NULL || source->state == Z_NULL) {
37.910 - return Z_STREAM_ERROR;
37.911 - }
37.912 -
37.913 - ss = source->state;
37.914 -
37.915 - zmemcpy(dest, source, sizeof(z_stream));
37.916 -
37.917 - ds = (deflate_state *) ZALLOC(dest, 1, sizeof(deflate_state));
37.918 - if (ds == Z_NULL) return Z_MEM_ERROR;
37.919 - dest->state = (struct internal_state FAR *) ds;
37.920 - zmemcpy(ds, ss, sizeof(deflate_state));
37.921 - ds->strm = dest;
37.922 -
37.923 - ds->window = (Bytef *) ZALLOC(dest, ds->w_size, 2*sizeof(Byte));
37.924 - ds->prev = (Posf *) ZALLOC(dest, ds->w_size, sizeof(Pos));
37.925 - ds->head = (Posf *) ZALLOC(dest, ds->hash_size, sizeof(Pos));
37.926 - overlay = (ushf *) ZALLOC(dest, ds->lit_bufsize, sizeof(ush)+2);
37.927 - ds->pending_buf = (uchf *) overlay;
37.928 -
37.929 - if (ds->window == Z_NULL || ds->prev == Z_NULL || ds->head == Z_NULL ||
37.930 - ds->pending_buf == Z_NULL) {
37.931 - deflateEnd (dest);
37.932 - return Z_MEM_ERROR;
37.933 - }
37.934 - /* following zmemcpy do not work for 16-bit MSDOS */
37.935 - zmemcpy(ds->window, ss->window, ds->w_size * 2 * sizeof(Byte));
37.936 - zmemcpy(ds->prev, ss->prev, ds->w_size * sizeof(Pos));
37.937 - zmemcpy(ds->head, ss->head, ds->hash_size * sizeof(Pos));
37.938 - zmemcpy(ds->pending_buf, ss->pending_buf, (uInt)ds->pending_buf_size);
37.939 -
37.940 - ds->pending_out = ds->pending_buf + (ss->pending_out - ss->pending_buf);
37.941 - ds->d_buf = overlay + ds->lit_bufsize/sizeof(ush);
37.942 - ds->l_buf = ds->pending_buf + (1+sizeof(ush))*ds->lit_bufsize;
37.943 -
37.944 - ds->l_desc.dyn_tree = ds->dyn_ltree;
37.945 - ds->d_desc.dyn_tree = ds->dyn_dtree;
37.946 - ds->bl_desc.dyn_tree = ds->bl_tree;
37.947 -
37.948 - return Z_OK;
37.949 -#endif /* MAXSEG_64K */
37.950 -}
37.951 -
37.952 -/* ===========================================================================
37.953 - * Read a new buffer from the current input stream, update the adler32
37.954 - * and total number of bytes read. All deflate() input goes through
37.955 - * this function so some applications may wish to modify it to avoid
37.956 - * allocating a large strm->next_in buffer and copying from it.
37.957 - * (See also flush_pending()).
37.958 - */
37.959 -local int read_buf(strm, buf, size)
37.960 - z_streamp strm;
37.961 - Bytef *buf;
37.962 - unsigned size;
37.963 -{
37.964 - unsigned len = strm->avail_in;
37.965 -
37.966 - if (len > size) len = size;
37.967 - if (len == 0) return 0;
37.968 -
37.969 - strm->avail_in -= len;
37.970 -
37.971 - if (strm->state->wrap == 1) {
37.972 - strm->adler = adler32(strm->adler, strm->next_in, len);
37.973 - }
37.974 -#ifdef GZIP
37.975 - else if (strm->state->wrap == 2) {
37.976 - strm->adler = crc32(strm->adler, strm->next_in, len);
37.977 - }
37.978 -#endif
37.979 - zmemcpy(buf, strm->next_in, len);
37.980 - strm->next_in += len;
37.981 - strm->total_in += len;
37.982 -
37.983 - return (int)len;
37.984 -}
37.985 -
37.986 -/* ===========================================================================
37.987 - * Initialize the "longest match" routines for a new zlib stream
37.988 - */
37.989 -local void lm_init (s)
37.990 - deflate_state *s;
37.991 -{
37.992 - s->window_size = (ulg)2L*s->w_size;
37.993 -
37.994 - CLEAR_HASH(s);
37.995 -
37.996 - /* Set the default configuration parameters:
37.997 - */
37.998 - s->max_lazy_match = configuration_table[s->level].max_lazy;
37.999 - s->good_match = configuration_table[s->level].good_length;
37.1000 - s->nice_match = configuration_table[s->level].nice_length;
37.1001 - s->max_chain_length = configuration_table[s->level].max_chain;
37.1002 -
37.1003 - s->strstart = 0;
37.1004 - s->block_start = 0L;
37.1005 - s->lookahead = 0;
37.1006 - s->match_length = s->prev_length = MIN_MATCH-1;
37.1007 - s->match_available = 0;
37.1008 - s->ins_h = 0;
37.1009 -#ifndef FASTEST
37.1010 -#ifdef ASMV
37.1011 - match_init(); /* initialize the asm code */
37.1012 -#endif
37.1013 -#endif
37.1014 -}
37.1015 -
37.1016 -#ifndef FASTEST
37.1017 -/* ===========================================================================
37.1018 - * Set match_start to the longest match starting at the given string and
37.1019 - * return its length. Matches shorter or equal to prev_length are discarded,
37.1020 - * in which case the result is equal to prev_length and match_start is
37.1021 - * garbage.
37.1022 - * IN assertions: cur_match is the head of the hash chain for the current
37.1023 - * string (strstart) and its distance is <= MAX_DIST, and prev_length >= 1
37.1024 - * OUT assertion: the match length is not greater than s->lookahead.
37.1025 - */
37.1026 -#ifndef ASMV
37.1027 -/* For 80x86 and 680x0, an optimized version will be provided in match.asm or
37.1028 - * match.S. The code will be functionally equivalent.
37.1029 - */
37.1030 -local uInt longest_match(s, cur_match)
37.1031 - deflate_state *s;
37.1032 - IPos cur_match; /* current match */
37.1033 -{
37.1034 - unsigned chain_length = s->max_chain_length;/* max hash chain length */
37.1035 - register Bytef *scan = s->window + s->strstart; /* current string */
37.1036 - register Bytef *match; /* matched string */
37.1037 - register int len; /* length of current match */
37.1038 - int best_len = s->prev_length; /* best match length so far */
37.1039 - int nice_match = s->nice_match; /* stop if match long enough */
37.1040 - IPos limit = s->strstart > (IPos)MAX_DIST(s) ?
37.1041 - s->strstart - (IPos)MAX_DIST(s) : NIL;
37.1042 - /* Stop when cur_match becomes <= limit. To simplify the code,
37.1043 - * we prevent matches with the string of window index 0.
37.1044 - */
37.1045 - Posf *prev = s->prev;
37.1046 - uInt wmask = s->w_mask;
37.1047 -
37.1048 -#ifdef UNALIGNED_OK
37.1049 - /* Compare two bytes at a time. Note: this is not always beneficial.
37.1050 - * Try with and without -DUNALIGNED_OK to check.
37.1051 - */
37.1052 - register Bytef *strend = s->window + s->strstart + MAX_MATCH - 1;
37.1053 - register ush scan_start = *(ushf*)scan;
37.1054 - register ush scan_end = *(ushf*)(scan+best_len-1);
37.1055 -#else
37.1056 - register Bytef *strend = s->window + s->strstart + MAX_MATCH;
37.1057 - register Byte scan_end1 = scan[best_len-1];
37.1058 - register Byte scan_end = scan[best_len];
37.1059 -#endif
37.1060 -
37.1061 - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
37.1062 - * It is easy to get rid of this optimization if necessary.
37.1063 - */
37.1064 - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
37.1065 -
37.1066 - /* Do not waste too much time if we already have a good match: */
37.1067 - if (s->prev_length >= s->good_match) {
37.1068 - chain_length >>= 2;
37.1069 - }
37.1070 - /* Do not look for matches beyond the end of the input. This is necessary
37.1071 - * to make deflate deterministic.
37.1072 - */
37.1073 - if ((uInt)nice_match > s->lookahead) nice_match = s->lookahead;
37.1074 -
37.1075 - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
37.1076 -
37.1077 - do {
37.1078 - Assert(cur_match < s->strstart, "no future");
37.1079 - match = s->window + cur_match;
37.1080 -
37.1081 - /* Skip to next match if the match length cannot increase
37.1082 - * or if the match length is less than 2. Note that the checks below
37.1083 - * for insufficient lookahead only occur occasionally for performance
37.1084 - * reasons. Therefore uninitialized memory will be accessed, and
37.1085 - * conditional jumps will be made that depend on those values.
37.1086 - * However the length of the match is limited to the lookahead, so
37.1087 - * the output of deflate is not affected by the uninitialized values.
37.1088 - */
37.1089 -#if (defined(UNALIGNED_OK) && MAX_MATCH == 258)
37.1090 - /* This code assumes sizeof(unsigned short) == 2. Do not use
37.1091 - * UNALIGNED_OK if your compiler uses a different size.
37.1092 - */
37.1093 - if (*(ushf*)(match+best_len-1) != scan_end ||
37.1094 - *(ushf*)match != scan_start) continue;
37.1095 -
37.1096 - /* It is not necessary to compare scan[2] and match[2] since they are
37.1097 - * always equal when the other bytes match, given that the hash keys
37.1098 - * are equal and that HASH_BITS >= 8. Compare 2 bytes at a time at
37.1099 - * strstart+3, +5, ... up to strstart+257. We check for insufficient
37.1100 - * lookahead only every 4th comparison; the 128th check will be made
37.1101 - * at strstart+257. If MAX_MATCH-2 is not a multiple of 8, it is
37.1102 - * necessary to put more guard bytes at the end of the window, or
37.1103 - * to check more often for insufficient lookahead.
37.1104 - */
37.1105 - Assert(scan[2] == match[2], "scan[2]?");
37.1106 - scan++, match++;
37.1107 - do {
37.1108 - } while (*(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37.1109 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37.1110 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37.1111 - *(ushf*)(scan+=2) == *(ushf*)(match+=2) &&
37.1112 - scan < strend);
37.1113 - /* The funny "do {}" generates better code on most compilers */
37.1114 -
37.1115 - /* Here, scan <= window+strstart+257 */
37.1116 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37.1117 - if (*scan == *match) scan++;
37.1118 -
37.1119 - len = (MAX_MATCH - 1) - (int)(strend-scan);
37.1120 - scan = strend - (MAX_MATCH-1);
37.1121 -
37.1122 -#else /* UNALIGNED_OK */
37.1123 -
37.1124 - if (match[best_len] != scan_end ||
37.1125 - match[best_len-1] != scan_end1 ||
37.1126 - *match != *scan ||
37.1127 - *++match != scan[1]) continue;
37.1128 -
37.1129 - /* The check at best_len-1 can be removed because it will be made
37.1130 - * again later. (This heuristic is not always a win.)
37.1131 - * It is not necessary to compare scan[2] and match[2] since they
37.1132 - * are always equal when the other bytes match, given that
37.1133 - * the hash keys are equal and that HASH_BITS >= 8.
37.1134 - */
37.1135 - scan += 2, match++;
37.1136 - Assert(*scan == *match, "match[2]?");
37.1137 -
37.1138 - /* We check for insufficient lookahead only every 8th comparison;
37.1139 - * the 256th check will be made at strstart+258.
37.1140 - */
37.1141 - do {
37.1142 - } while (*++scan == *++match && *++scan == *++match &&
37.1143 - *++scan == *++match && *++scan == *++match &&
37.1144 - *++scan == *++match && *++scan == *++match &&
37.1145 - *++scan == *++match && *++scan == *++match &&
37.1146 - scan < strend);
37.1147 -
37.1148 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37.1149 -
37.1150 - len = MAX_MATCH - (int)(strend - scan);
37.1151 - scan = strend - MAX_MATCH;
37.1152 -
37.1153 -#endif /* UNALIGNED_OK */
37.1154 -
37.1155 - if (len > best_len) {
37.1156 - s->match_start = cur_match;
37.1157 - best_len = len;
37.1158 - if (len >= nice_match) break;
37.1159 -#ifdef UNALIGNED_OK
37.1160 - scan_end = *(ushf*)(scan+best_len-1);
37.1161 -#else
37.1162 - scan_end1 = scan[best_len-1];
37.1163 - scan_end = scan[best_len];
37.1164 -#endif
37.1165 - }
37.1166 - } while ((cur_match = prev[cur_match & wmask]) > limit
37.1167 - && --chain_length != 0);
37.1168 -
37.1169 - if ((uInt)best_len <= s->lookahead) return (uInt)best_len;
37.1170 - return s->lookahead;
37.1171 -}
37.1172 -#endif /* ASMV */
37.1173 -#endif /* FASTEST */
37.1174 -
37.1175 -/* ---------------------------------------------------------------------------
37.1176 - * Optimized version for level == 1 or strategy == Z_RLE only
37.1177 - */
37.1178 -local uInt longest_match_fast(s, cur_match)
37.1179 - deflate_state *s;
37.1180 - IPos cur_match; /* current match */
37.1181 -{
37.1182 - register Bytef *scan = s->window + s->strstart; /* current string */
37.1183 - register Bytef *match; /* matched string */
37.1184 - register int len; /* length of current match */
37.1185 - register Bytef *strend = s->window + s->strstart + MAX_MATCH;
37.1186 -
37.1187 - /* The code is optimized for HASH_BITS >= 8 and MAX_MATCH-2 multiple of 16.
37.1188 - * It is easy to get rid of this optimization if necessary.
37.1189 - */
37.1190 - Assert(s->hash_bits >= 8 && MAX_MATCH == 258, "Code too clever");
37.1191 -
37.1192 - Assert((ulg)s->strstart <= s->window_size-MIN_LOOKAHEAD, "need lookahead");
37.1193 -
37.1194 - Assert(cur_match < s->strstart, "no future");
37.1195 -
37.1196 - match = s->window + cur_match;
37.1197 -
37.1198 - /* Return failure if the match length is less than 2:
37.1199 - */
37.1200 - if (match[0] != scan[0] || match[1] != scan[1]) return MIN_MATCH-1;
37.1201 -
37.1202 - /* The check at best_len-1 can be removed because it will be made
37.1203 - * again later. (This heuristic is not always a win.)
37.1204 - * It is not necessary to compare scan[2] and match[2] since they
37.1205 - * are always equal when the other bytes match, given that
37.1206 - * the hash keys are equal and that HASH_BITS >= 8.
37.1207 - */
37.1208 - scan += 2, match += 2;
37.1209 - Assert(*scan == *match, "match[2]?");
37.1210 -
37.1211 - /* We check for insufficient lookahead only every 8th comparison;
37.1212 - * the 256th check will be made at strstart+258.
37.1213 - */
37.1214 - do {
37.1215 - } while (*++scan == *++match && *++scan == *++match &&
37.1216 - *++scan == *++match && *++scan == *++match &&
37.1217 - *++scan == *++match && *++scan == *++match &&
37.1218 - *++scan == *++match && *++scan == *++match &&
37.1219 - scan < strend);
37.1220 -
37.1221 - Assert(scan <= s->window+(unsigned)(s->window_size-1), "wild scan");
37.1222 -
37.1223 - len = MAX_MATCH - (int)(strend - scan);
37.1224 -
37.1225 - if (len < MIN_MATCH) return MIN_MATCH - 1;
37.1226 -
37.1227 - s->match_start = cur_match;
37.1228 - return (uInt)len <= s->lookahead ? (uInt)len : s->lookahead;
37.1229 -}
37.1230 -
37.1231 -#ifdef DEBUG
37.1232 -/* ===========================================================================
37.1233 - * Check that the match at match_start is indeed a match.
37.1234 - */
37.1235 -local void check_match(s, start, match, length)
37.1236 - deflate_state *s;
37.1237 - IPos start, match;
37.1238 - int length;
37.1239 -{
37.1240 - /* check that the match is indeed a match */
37.1241 - if (zmemcmp(s->window + match,
37.1242 - s->window + start, length) != EQUAL) {
37.1243 - fprintf(stderr, " start %u, match %u, length %d\n",
37.1244 - start, match, length);
37.1245 - do {
37.1246 - fprintf(stderr, "%c%c", s->window[match++], s->window[start++]);
37.1247 - } while (--length != 0);
37.1248 - z_error("invalid match");
37.1249 - }
37.1250 - if (z_verbose > 1) {
37.1251 - fprintf(stderr,"\\[%d,%d]", start-match, length);
37.1252 - do { putc(s->window[start++], stderr); } while (--length != 0);
37.1253 - }
37.1254 -}
37.1255 -#else
37.1256 -# define check_match(s, start, match, length)
37.1257 -#endif /* DEBUG */
37.1258 -
37.1259 -/* ===========================================================================
37.1260 - * Fill the window when the lookahead becomes insufficient.
37.1261 - * Updates strstart and lookahead.
37.1262 - *
37.1263 - * IN assertion: lookahead < MIN_LOOKAHEAD
37.1264 - * OUT assertions: strstart <= window_size-MIN_LOOKAHEAD
37.1265 - * At least one byte has been read, or avail_in == 0; reads are
37.1266 - * performed for at least two bytes (required for the zip translate_eol
37.1267 - * option -- not supported here).
37.1268 - */
37.1269 -local void fill_window(s)
37.1270 - deflate_state *s;
37.1271 -{
37.1272 - register unsigned n, m;
37.1273 - register Posf *p;
37.1274 - unsigned more; /* Amount of free space at the end of the window. */
37.1275 - uInt wsize = s->w_size;
37.1276 -
37.1277 - do {
37.1278 - more = (unsigned)(s->window_size -(ulg)s->lookahead -(ulg)s->strstart);
37.1279 -
37.1280 - /* Deal with !@#$% 64K limit: */
37.1281 - if (sizeof(int) <= 2) {
37.1282 - if (more == 0 && s->strstart == 0 && s->lookahead == 0) {
37.1283 - more = wsize;
37.1284 -
37.1285 - } else if (more == (unsigned)(-1)) {
37.1286 - /* Very unlikely, but possible on 16 bit machine if
37.1287 - * strstart == 0 && lookahead == 1 (input done a byte at time)
37.1288 - */
37.1289 - more--;
37.1290 - }
37.1291 - }
37.1292 -
37.1293 - /* If the window is almost full and there is insufficient lookahead,
37.1294 - * move the upper half to the lower one to make room in the upper half.
37.1295 - */
37.1296 - if (s->strstart >= wsize+MAX_DIST(s)) {
37.1297 -
37.1298 - zmemcpy(s->window, s->window+wsize, (unsigned)wsize);
37.1299 - s->match_start -= wsize;
37.1300 - s->strstart -= wsize; /* we now have strstart >= MAX_DIST */
37.1301 - s->block_start -= (long) wsize;
37.1302 -
37.1303 - /* Slide the hash table (could be avoided with 32 bit values
37.1304 - at the expense of memory usage). We slide even when level == 0
37.1305 - to keep the hash table consistent if we switch back to level > 0
37.1306 - later. (Using level 0 permanently is not an optimal usage of
37.1307 - zlib, so we don't care about this pathological case.)
37.1308 - */
37.1309 - /* %%% avoid this when Z_RLE */
37.1310 - n = s->hash_size;
37.1311 - p = &s->head[n];
37.1312 - do {
37.1313 - m = *--p;
37.1314 - *p = (Pos)(m >= wsize ? m-wsize : NIL);
37.1315 - } while (--n);
37.1316 -
37.1317 - n = wsize;
37.1318 -#ifndef FASTEST
37.1319 - p = &s->prev[n];
37.1320 - do {
37.1321 - m = *--p;
37.1322 - *p = (Pos)(m >= wsize ? m-wsize : NIL);
37.1323 - /* If n is not on any hash chain, prev[n] is garbage but
37.1324 - * its value will never be used.
37.1325 - */
37.1326 - } while (--n);
37.1327 -#endif
37.1328 - more += wsize;
37.1329 - }
37.1330 - if (s->strm->avail_in == 0) return;
37.1331 -
37.1332 - /* If there was no sliding:
37.1333 - * strstart <= WSIZE+MAX_DIST-1 && lookahead <= MIN_LOOKAHEAD - 1 &&
37.1334 - * more == window_size - lookahead - strstart
37.1335 - * => more >= window_size - (MIN_LOOKAHEAD-1 + WSIZE + MAX_DIST-1)
37.1336 - * => more >= window_size - 2*WSIZE + 2
37.1337 - * In the BIG_MEM or MMAP case (not yet supported),
37.1338 - * window_size == input_size + MIN_LOOKAHEAD &&
37.1339 - * strstart + s->lookahead <= input_size => more >= MIN_LOOKAHEAD.
37.1340 - * Otherwise, window_size == 2*WSIZE so more >= 2.
37.1341 - * If there was sliding, more >= WSIZE. So in all cases, more >= 2.
37.1342 - */
37.1343 - Assert(more >= 2, "more < 2");
37.1344 -
37.1345 - n = read_buf(s->strm, s->window + s->strstart + s->lookahead, more);
37.1346 - s->lookahead += n;
37.1347 -
37.1348 - /* Initialize the hash value now that we have some input: */
37.1349 - if (s->lookahead >= MIN_MATCH) {
37.1350 - s->ins_h = s->window[s->strstart];
37.1351 - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
37.1352 -#if MIN_MATCH != 3
37.1353 - Call UPDATE_HASH() MIN_MATCH-3 more times
37.1354 -#endif
37.1355 - }
37.1356 - /* If the whole input has less than MIN_MATCH bytes, ins_h is garbage,
37.1357 - * but this is not important since only literal bytes will be emitted.
37.1358 - */
37.1359 -
37.1360 - } while (s->lookahead < MIN_LOOKAHEAD && s->strm->avail_in != 0);
37.1361 -}
37.1362 -
37.1363 -/* ===========================================================================
37.1364 - * Flush the current block, with given end-of-file flag.
37.1365 - * IN assertion: strstart is set to the end of the current match.
37.1366 - */
37.1367 -#define FLUSH_BLOCK_ONLY(s, eof) { \
37.1368 - _tr_flush_block(s, (s->block_start >= 0L ? \
37.1369 - (charf *)&s->window[(unsigned)s->block_start] : \
37.1370 - (charf *)Z_NULL), \
37.1371 - (ulg)((long)s->strstart - s->block_start), \
37.1372 - (eof)); \
37.1373 - s->block_start = s->strstart; \
37.1374 - flush_pending(s->strm); \
37.1375 - Tracev((stderr,"[FLUSH]")); \
37.1376 -}
37.1377 -
37.1378 -/* Same but force premature exit if necessary. */
37.1379 -#define FLUSH_BLOCK(s, eof) { \
37.1380 - FLUSH_BLOCK_ONLY(s, eof); \
37.1381 - if (s->strm->avail_out == 0) return (eof) ? finish_started : need_more; \
37.1382 -}
37.1383 -
37.1384 -/* ===========================================================================
37.1385 - * Copy without compression as much as possible from the input stream, return
37.1386 - * the current block state.
37.1387 - * This function does not insert new strings in the dictionary since
37.1388 - * uncompressible data is probably not useful. This function is used
37.1389 - * only for the level=0 compression option.
37.1390 - * NOTE: this function should be optimized to avoid extra copying from
37.1391 - * window to pending_buf.
37.1392 - */
37.1393 -local block_state deflate_stored(s, flush)
37.1394 - deflate_state *s;
37.1395 - int flush;
37.1396 -{
37.1397 - /* Stored blocks are limited to 0xffff bytes, pending_buf is limited
37.1398 - * to pending_buf_size, and each stored block has a 5 byte header:
37.1399 - */
37.1400 - ulg max_block_size = 0xffff;
37.1401 - ulg max_start;
37.1402 -
37.1403 - if (max_block_size > s->pending_buf_size - 5) {
37.1404 - max_block_size = s->pending_buf_size - 5;
37.1405 - }
37.1406 -
37.1407 - /* Copy as much as possible from input to output: */
37.1408 - for (;;) {
37.1409 - /* Fill the window as much as possible: */
37.1410 - if (s->lookahead <= 1) {
37.1411 -
37.1412 - Assert(s->strstart < s->w_size+MAX_DIST(s) ||
37.1413 - s->block_start >= (long)s->w_size, "slide too late");
37.1414 -
37.1415 - fill_window(s);
37.1416 - if (s->lookahead == 0 && flush == Z_NO_FLUSH) return need_more;
37.1417 -
37.1418 - if (s->lookahead == 0) break; /* flush the current block */
37.1419 - }
37.1420 - Assert(s->block_start >= 0L, "block gone");
37.1421 -
37.1422 - s->strstart += s->lookahead;
37.1423 - s->lookahead = 0;
37.1424 -
37.1425 - /* Emit a stored block if pending_buf will be full: */
37.1426 - max_start = s->block_start + max_block_size;
37.1427 - if (s->strstart == 0 || (ulg)s->strstart >= max_start) {
37.1428 - /* strstart == 0 is possible when wraparound on 16-bit machine */
37.1429 - s->lookahead = (uInt)(s->strstart - max_start);
37.1430 - s->strstart = (uInt)max_start;
37.1431 - FLUSH_BLOCK(s, 0);
37.1432 - }
37.1433 - /* Flush if we may have to slide, otherwise block_start may become
37.1434 - * negative and the data will be gone:
37.1435 - */
37.1436 - if (s->strstart - (uInt)s->block_start >= MAX_DIST(s)) {
37.1437 - FLUSH_BLOCK(s, 0);
37.1438 - }
37.1439 - }
37.1440 - FLUSH_BLOCK(s, flush == Z_FINISH);
37.1441 - return flush == Z_FINISH ? finish_done : block_done;
37.1442 -}
37.1443 -
37.1444 -/* ===========================================================================
37.1445 - * Compress as much as possible from the input stream, return the current
37.1446 - * block state.
37.1447 - * This function does not perform lazy evaluation of matches and inserts
37.1448 - * new strings in the dictionary only for unmatched strings or for short
37.1449 - * matches. It is used only for the fast compression options.
37.1450 - */
37.1451 -local block_state deflate_fast(s, flush)
37.1452 - deflate_state *s;
37.1453 - int flush;
37.1454 -{
37.1455 - IPos hash_head = NIL; /* head of the hash chain */
37.1456 - int bflush; /* set if current block must be flushed */
37.1457 -
37.1458 - for (;;) {
37.1459 - /* Make sure that we always have enough lookahead, except
37.1460 - * at the end of the input file. We need MAX_MATCH bytes
37.1461 - * for the next match, plus MIN_MATCH bytes to insert the
37.1462 - * string following the next match.
37.1463 - */
37.1464 - if (s->lookahead < MIN_LOOKAHEAD) {
37.1465 - fill_window(s);
37.1466 - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
37.1467 - return need_more;
37.1468 - }
37.1469 - if (s->lookahead == 0) break; /* flush the current block */
37.1470 - }
37.1471 -
37.1472 - /* Insert the string window[strstart .. strstart+2] in the
37.1473 - * dictionary, and set hash_head to the head of the hash chain:
37.1474 - */
37.1475 - if (s->lookahead >= MIN_MATCH) {
37.1476 - INSERT_STRING(s, s->strstart, hash_head);
37.1477 - }
37.1478 -
37.1479 - /* Find the longest match, discarding those <= prev_length.
37.1480 - * At this point we have always match_length < MIN_MATCH
37.1481 - */
37.1482 - if (hash_head != NIL && s->strstart - hash_head <= MAX_DIST(s)) {
37.1483 - /* To simplify the code, we prevent matches with the string
37.1484 - * of window index 0 (in particular we have to avoid a match
37.1485 - * of the string with itself at the start of the input file).
37.1486 - */
37.1487 -#ifdef FASTEST
37.1488 - if ((s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) ||
37.1489 - (s->strategy == Z_RLE && s->strstart - hash_head == 1)) {
37.1490 - s->match_length = longest_match_fast (s, hash_head);
37.1491 - }
37.1492 -#else
37.1493 - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
37.1494 - s->match_length = longest_match (s, hash_head);
37.1495 - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
37.1496 - s->match_length = longest_match_fast (s, hash_head);
37.1497 - }
37.1498 -#endif
37.1499 - /* longest_match() or longest_match_fast() sets match_start */
37.1500 - }
37.1501 - if (s->match_length >= MIN_MATCH) {
37.1502 - check_match(s, s->strstart, s->match_start, s->match_length);
37.1503 -
37.1504 - _tr_tally_dist(s, s->strstart - s->match_start,
37.1505 - s->match_length - MIN_MATCH, bflush);
37.1506 -
37.1507 - s->lookahead -= s->match_length;
37.1508 -
37.1509 - /* Insert new strings in the hash table only if the match length
37.1510 - * is not too large. This saves time but degrades compression.
37.1511 - */
37.1512 -#ifndef FASTEST
37.1513 - if (s->match_length <= s->max_insert_length &&
37.1514 - s->lookahead >= MIN_MATCH) {
37.1515 - s->match_length--; /* string at strstart already in table */
37.1516 - do {
37.1517 - s->strstart++;
37.1518 - INSERT_STRING(s, s->strstart, hash_head);
37.1519 - /* strstart never exceeds WSIZE-MAX_MATCH, so there are
37.1520 - * always MIN_MATCH bytes ahead.
37.1521 - */
37.1522 - } while (--s->match_length != 0);
37.1523 - s->strstart++;
37.1524 - } else
37.1525 -#endif
37.1526 - {
37.1527 - s->strstart += s->match_length;
37.1528 - s->match_length = 0;
37.1529 - s->ins_h = s->window[s->strstart];
37.1530 - UPDATE_HASH(s, s->ins_h, s->window[s->strstart+1]);
37.1531 -#if MIN_MATCH != 3
37.1532 - Call UPDATE_HASH() MIN_MATCH-3 more times
37.1533 -#endif
37.1534 - /* If lookahead < MIN_MATCH, ins_h is garbage, but it does not
37.1535 - * matter since it will be recomputed at next deflate call.
37.1536 - */
37.1537 - }
37.1538 - } else {
37.1539 - /* No match, output a literal byte */
37.1540 - Tracevv((stderr,"%c", s->window[s->strstart]));
37.1541 - _tr_tally_lit (s, s->window[s->strstart], bflush);
37.1542 - s->lookahead--;
37.1543 - s->strstart++;
37.1544 - }
37.1545 - if (bflush) FLUSH_BLOCK(s, 0);
37.1546 - }
37.1547 - FLUSH_BLOCK(s, flush == Z_FINISH);
37.1548 - return flush == Z_FINISH ? finish_done : block_done;
37.1549 -}
37.1550 -
37.1551 -#ifndef FASTEST
37.1552 -/* ===========================================================================
37.1553 - * Same as above, but achieves better compression. We use a lazy
37.1554 - * evaluation for matches: a match is finally adopted only if there is
37.1555 - * no better match at the next window position.
37.1556 - */
37.1557 -local block_state deflate_slow(s, flush)
37.1558 - deflate_state *s;
37.1559 - int flush;
37.1560 -{
37.1561 - IPos hash_head = NIL; /* head of hash chain */
37.1562 - int bflush; /* set if current block must be flushed */
37.1563 -
37.1564 - /* Process the input block. */
37.1565 - for (;;) {
37.1566 - /* Make sure that we always have enough lookahead, except
37.1567 - * at the end of the input file. We need MAX_MATCH bytes
37.1568 - * for the next match, plus MIN_MATCH bytes to insert the
37.1569 - * string following the next match.
37.1570 - */
37.1571 - if (s->lookahead < MIN_LOOKAHEAD) {
37.1572 - fill_window(s);
37.1573 - if (s->lookahead < MIN_LOOKAHEAD && flush == Z_NO_FLUSH) {
37.1574 - return need_more;
37.1575 - }
37.1576 - if (s->lookahead == 0) break; /* flush the current block */
37.1577 - }
37.1578 -
37.1579 - /* Insert the string window[strstart .. strstart+2] in the
37.1580 - * dictionary, and set hash_head to the head of the hash chain:
37.1581 - */
37.1582 - if (s->lookahead >= MIN_MATCH) {
37.1583 - INSERT_STRING(s, s->strstart, hash_head);
37.1584 - }
37.1585 -
37.1586 - /* Find the longest match, discarding those <= prev_length.
37.1587 - */
37.1588 - s->prev_length = s->match_length, s->prev_match = s->match_start;
37.1589 - s->match_length = MIN_MATCH-1;
37.1590 -
37.1591 - if (hash_head != NIL && s->prev_length < s->max_lazy_match &&
37.1592 - s->strstart - hash_head <= MAX_DIST(s)) {
37.1593 - /* To simplify the code, we prevent matches with the string
37.1594 - * of window index 0 (in particular we have to avoid a match
37.1595 - * of the string with itself at the start of the input file).
37.1596 - */
37.1597 - if (s->strategy != Z_HUFFMAN_ONLY && s->strategy != Z_RLE) {
37.1598 - s->match_length = longest_match (s, hash_head);
37.1599 - } else if (s->strategy == Z_RLE && s->strstart - hash_head == 1) {
37.1600 - s->match_length = longest_match_fast (s, hash_head);
37.1601 - }
37.1602 - /* longest_match() or longest_match_fast() sets match_start */
37.1603 -
37.1604 - if (s->match_length <= 5 && (s->strategy == Z_FILTERED
37.1605 -#if TOO_FAR <= 32767
37.1606 - || (s->match_length == MIN_MATCH &&
37.1607 - s->strstart - s->match_start > TOO_FAR)
37.1608 -#endif
37.1609 - )) {
37.1610 -
37.1611 - /* If prev_match is also MIN_MATCH, match_start is garbage
37.1612 - * but we will ignore the current match anyway.
37.1613 - */
37.1614 - s->match_length = MIN_MATCH-1;
37.1615 - }
37.1616 - }
37.1617 - /* If there was a match at the previous step and the current
37.1618 - * match is not better, output the previous match:
37.1619 - */
37.1620 - if (s->prev_length >= MIN_MATCH && s->match_length <= s->prev_length) {
37.1621 - uInt max_insert = s->strstart + s->lookahead - MIN_MATCH;
37.1622 - /* Do not insert strings in hash table beyond this. */
37.1623 -
37.1624 - check_match(s, s->strstart-1, s->prev_match, s->prev_length);
37.1625 -
37.1626 - _tr_tally_dist(s, s->strstart -1 - s->prev_match,
37.1627 - s->prev_length - MIN_MATCH, bflush);
37.1628 -
37.1629 - /* Insert in hash table all strings up to the end of the match.
37.1630 - * strstart-1 and strstart are already inserted. If there is not
37.1631 - * enough lookahead, the last two strings are not inserted in
37.1632 - * the hash table.
37.1633 - */
37.1634 - s->lookahead -= s->prev_length-1;
37.1635 - s->prev_length -= 2;
37.1636 - do {
37.1637 - if (++s->strstart <= max_insert) {
37.1638 - INSERT_STRING(s, s->strstart, hash_head);
37.1639 - }
37.1640 - } while (--s->prev_length != 0);
37.1641 - s->match_available = 0;
37.1642 - s->match_length = MIN_MATCH-1;
37.1643 - s->strstart++;
37.1644 -
37.1645 - if (bflush) FLUSH_BLOCK(s, 0);
37.1646 -
37.1647 - } else if (s->match_available) {
37.1648 - /* If there was no match at the previous position, output a
37.1649 - * single literal. If there was a match but the current match
37.1650 - * is longer, truncate the previous match to a single literal.
37.1651 - */
37.1652 - Tracevv((stderr,"%c", s->window[s->strstart-1]));
37.1653 - _tr_tally_lit(s, s->window[s->strstart-1], bflush);
37.1654 - if (bflush) {
37.1655 - FLUSH_BLOCK_ONLY(s, 0);
37.1656 - }
37.1657 - s->strstart++;
37.1658 - s->lookahead--;
37.1659 - if (s->strm->avail_out == 0) return need_more;
37.1660 - } else {
37.1661 - /* There is no previous match to compare with, wait for
37.1662 - * the next step to decide.
37.1663 - */
37.1664 - s->match_available = 1;
37.1665 - s->strstart++;
37.1666 - s->lookahead--;
37.1667 - }
37.1668 - }
37.1669 - Assert (flush != Z_NO_FLUSH, "no flush?");
37.1670 - if (s->match_available) {
37.1671 - Tracevv((stderr,"%c", s->window[s->strstart-1]));
37.1672 - _tr_tally_lit(s, s->window[s->strstart-1], bflush);
37.1673 - s->match_available = 0;
37.1674 - }
37.1675 - FLUSH_BLOCK(s, flush == Z_FINISH);
37.1676 - return flush == Z_FINISH ? finish_done : block_done;
37.1677 -}
37.1678 -#endif /* FASTEST */
37.1679 -
37.1680 -#if 0
37.1681 -/* ===========================================================================
37.1682 - * For Z_RLE, simply look for runs of bytes, generate matches only of distance
37.1683 - * one. Do not maintain a hash table. (It will be regenerated if this run of
37.1684 - * deflate switches away from Z_RLE.)
37.1685 - */
37.1686 -local block_state deflate_rle(s, flush)
37.1687 - deflate_state *s;
37.1688 - int flush;
37.1689 -{
37.1690 - int bflush; /* set if current block must be flushed */
37.1691 - uInt run; /* length of run */
37.1692 - uInt max; /* maximum length of run */
37.1693 - uInt prev; /* byte at distance one to match */
37.1694 - Bytef *scan; /* scan for end of run */
37.1695 -
37.1696 - for (;;) {
37.1697 - /* Make sure that we always have enough lookahead, except
37.1698 - * at the end of the input file. We need MAX_MATCH bytes
37.1699 - * for the longest encodable run.
37.1700 - */
37.1701 - if (s->lookahead < MAX_MATCH) {
37.1702 - fill_window(s);
37.1703 - if (s->lookahead < MAX_MATCH && flush == Z_NO_FLUSH) {
37.1704 - return need_more;
37.1705 - }
37.1706 - if (s->lookahead == 0) break; /* flush the current block */
37.1707 - }
37.1708 -
37.1709 - /* See how many times the previous byte repeats */
37.1710 - run = 0;
37.1711 - if (s->strstart > 0) { /* if there is a previous byte, that is */
37.1712 - max = s->lookahead < MAX_MATCH ? s->lookahead : MAX_MATCH;
37.1713 - scan = s->window + s->strstart - 1;
37.1714 - prev = *scan++;
37.1715 - do {
37.1716 - if (*scan++ != prev)
37.1717 - break;
37.1718 - } while (++run < max);
37.1719 - }
37.1720 -
37.1721 - /* Emit match if have run of MIN_MATCH or longer, else emit literal */
37.1722 - if (run >= MIN_MATCH) {
37.1723 - check_match(s, s->strstart, s->strstart - 1, run);
37.1724 - _tr_tally_dist(s, 1, run - MIN_MATCH, bflush);
37.1725 - s->lookahead -= run;
37.1726 - s->strstart += run;
37.1727 - } else {
37.1728 - /* No match, output a literal byte */
37.1729 - Tracevv((stderr,"%c", s->window[s->strstart]));
37.1730 - _tr_tally_lit (s, s->window[s->strstart], bflush);
37.1731 - s->lookahead--;
37.1732 - s->strstart++;
37.1733 - }
37.1734 - if (bflush) FLUSH_BLOCK(s, 0);
37.1735 - }
37.1736 - FLUSH_BLOCK(s, flush == Z_FINISH);
37.1737 - return flush == Z_FINISH ? finish_done : block_done;
37.1738 -}
37.1739 -#endif
38.1 --- a/sourcepawn/vm/zlib/deflate.h Tue Nov 07 23:26:40 2006 +0000
38.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
38.3 @@ -1,331 +0,0 @@
38.4 -/* deflate.h -- internal compression state
38.5 - * Copyright (C) 1995-2004 Jean-loup Gailly
38.6 - * For conditions of distribution and use, see copyright notice in zlib.h
38.7 - */
38.8 -
38.9 -/* WARNING: this file should *not* be used by applications. It is
38.10 - part of the implementation of the compression library and is
38.11 - subject to change. Applications should only use zlib.h.
38.12 - */
38.13 -
38.14 -/* @(#) $Id$ */
38.15 -
38.16 -#ifndef DEFLATE_H
38.17 -#define DEFLATE_H
38.18 -
38.19 -#include "zutil.h"
38.20 -
38.21 -/* define NO_GZIP when compiling if you want to disable gzip header and
38.22 - trailer creation by deflate(). NO_GZIP would be used to avoid linking in
38.23 - the crc code when it is not needed. For shared libraries, gzip encoding
38.24 - should be left enabled. */
38.25 -#ifndef NO_GZIP
38.26 -# define GZIP
38.27 -#endif
38.28 -
38.29 -/* ===========================================================================
38.30 - * Internal compression state.
38.31 - */
38.32 -
38.33 -#define LENGTH_CODES 29
38.34 -/* number of length codes, not counting the special END_BLOCK code */
38.35 -
38.36 -#define LITERALS 256
38.37 -/* number of literal bytes 0..255 */
38.38 -
38.39 -#define L_CODES (LITERALS+1+LENGTH_CODES)
38.40 -/* number of Literal or Length codes, including the END_BLOCK code */
38.41 -
38.42 -#define D_CODES 30
38.43 -/* number of distance codes */
38.44 -
38.45 -#define BL_CODES 19
38.46 -/* number of codes used to transfer the bit lengths */
38.47 -
38.48 -#define HEAP_SIZE (2*L_CODES+1)
38.49 -/* maximum heap size */
38.50 -
38.51 -#define MAX_BITS 15
38.52 -/* All codes must not exceed MAX_BITS bits */
38.53 -
38.54 -#define INIT_STATE 42
38.55 -#define EXTRA_STATE 69
38.56 -#define NAME_STATE 73
38.57 -#define COMMENT_STATE 91
38.58 -#define HCRC_STATE 103
38.59 -#define BUSY_STATE 113
38.60 -#define FINISH_STATE 666
38.61 -/* Stream status */
38.62 -
38.63 -
38.64 -/* Data structure describing a single value and its code string. */
38.65 -typedef struct ct_data_s {
38.66 - union {
38.67 - ush freq; /* frequency count */
38.68 - ush code; /* bit string */
38.69 - } fc;
38.70 - union {
38.71 - ush dad; /* father node in Huffman tree */
38.72 - ush len; /* length of bit string */
38.73 - } dl;
38.74 -} FAR ct_data;
38.75 -
38.76 -#define Freq fc.freq
38.77 -#define Code fc.code
38.78 -#define Dad dl.dad
38.79 -#define Len dl.len
38.80 -
38.81 -typedef struct static_tree_desc_s static_tree_desc;
38.82 -
38.83 -typedef struct tree_desc_s {
38.84 - ct_data *dyn_tree; /* the dynamic tree */
38.85 - int max_code; /* largest code with non zero frequency */
38.86 - static_tree_desc *stat_desc; /* the corresponding static tree */
38.87 -} FAR tree_desc;
38.88 -
38.89 -typedef ush Pos;
38.90 -typedef Pos FAR Posf;
38.91 -typedef unsigned IPos;
38.92 -
38.93 -/* A Pos is an index in the character window. We use short instead of int to
38.94 - * save space in the various tables. IPos is used only for parameter passing.
38.95 - */
38.96 -
38.97 -typedef struct internal_state {
38.98 - z_streamp strm; /* pointer back to this zlib stream */
38.99 - int status; /* as the name implies */
38.100 - Bytef *pending_buf; /* output still pending */
38.101 - ulg pending_buf_size; /* size of pending_buf */
38.102 - Bytef *pending_out; /* next pending byte to output to the stream */
38.103 - uInt pending; /* nb of bytes in the pending buffer */
38.104 - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
38.105 - gz_headerp gzhead; /* gzip header information to write */
38.106 - uInt gzindex; /* where in extra, name, or comment */
38.107 - Byte method; /* STORED (for zip only) or DEFLATED */
38.108 - int last_flush; /* value of flush param for previous deflate call */
38.109 -
38.110 - /* used by deflate.c: */
38.111 -
38.112 - uInt w_size; /* LZ77 window size (32K by default) */
38.113 - uInt w_bits; /* log2(w_size) (8..16) */
38.114 - uInt w_mask; /* w_size - 1 */
38.115 -
38.116 - Bytef *window;
38.117 - /* Sliding window. Input bytes are read into the second half of the window,
38.118 - * and move to the first half later to keep a dictionary of at least wSize
38.119 - * bytes. With this organization, matches are limited to a distance of
38.120 - * wSize-MAX_MATCH bytes, but this ensures that IO is always
38.121 - * performed with a length multiple of the block size. Also, it limits
38.122 - * the window size to 64K, which is quite useful on MSDOS.
38.123 - * To do: use the user input buffer as sliding window.
38.124 - */
38.125 -
38.126 - ulg window_size;
38.127 - /* Actual size of window: 2*wSize, except when the user input buffer
38.128 - * is directly used as sliding window.
38.129 - */
38.130 -
38.131 - Posf *prev;
38.132 - /* Link to older string with same hash index. To limit the size of this
38.133 - * array to 64K, this link is maintained only for the last 32K strings.
38.134 - * An index in this array is thus a window index modulo 32K.
38.135 - */
38.136 -
38.137 - Posf *head; /* Heads of the hash chains or NIL. */
38.138 -
38.139 - uInt ins_h; /* hash index of string to be inserted */
38.140 - uInt hash_size; /* number of elements in hash table */
38.141 - uInt hash_bits; /* log2(hash_size) */
38.142 - uInt hash_mask; /* hash_size-1 */
38.143 -
38.144 - uInt hash_shift;
38.145 - /* Number of bits by which ins_h must be shifted at each input
38.146 - * step. It must be such that after MIN_MATCH steps, the oldest
38.147 - * byte no longer takes part in the hash key, that is:
38.148 - * hash_shift * MIN_MATCH >= hash_bits
38.149 - */
38.150 -
38.151 - long block_start;
38.152 - /* Window position at the beginning of the current output block. Gets
38.153 - * negative when the window is moved backwards.
38.154 - */
38.155 -
38.156 - uInt match_length; /* length of best match */
38.157 - IPos prev_match; /* previous match */
38.158 - int match_available; /* set if previous match exists */
38.159 - uInt strstart; /* start of string to insert */
38.160 - uInt match_start; /* start of matching string */
38.161 - uInt lookahead; /* number of valid bytes ahead in window */
38.162 -
38.163 - uInt prev_length;
38.164 - /* Length of the best match at previous step. Matches not greater than this
38.165 - * are discarded. This is used in the lazy match evaluation.
38.166 - */
38.167 -
38.168 - uInt max_chain_length;
38.169 - /* To speed up deflation, hash chains are never searched beyond this
38.170 - * length. A higher limit improves compression ratio but degrades the
38.171 - * speed.
38.172 - */
38.173 -
38.174 - uInt max_lazy_match;
38.175 - /* Attempt to find a better match only when the current match is strictly
38.176 - * smaller than this value. This mechanism is used only for compression
38.177 - * levels >= 4.
38.178 - */
38.179 -# define max_insert_length max_lazy_match
38.180 - /* Insert new strings in the hash table only if the match length is not
38.181 - * greater than this length. This saves time but degrades compression.
38.182 - * max_insert_length is used only for compression levels <= 3.
38.183 - */
38.184 -
38.185 - int level; /* compression level (1..9) */
38.186 - int strategy; /* favor or force Huffman coding*/
38.187 -
38.188 - uInt good_match;
38.189 - /* Use a faster search when the previous match is longer than this */
38.190 -
38.191 - int nice_match; /* Stop searching when current match exceeds this */
38.192 -
38.193 - /* used by trees.c: */
38.194 - /* Didn't use ct_data typedef below to supress compiler warning */
38.195 - struct ct_data_s dyn_ltree[HEAP_SIZE]; /* literal and length tree */
38.196 - struct ct_data_s dyn_dtree[2*D_CODES+1]; /* distance tree */
38.197 - struct ct_data_s bl_tree[2*BL_CODES+1]; /* Huffman tree for bit lengths */
38.198 -
38.199 - struct tree_desc_s l_desc; /* desc. for literal tree */
38.200 - struct tree_desc_s d_desc; /* desc. for distance tree */
38.201 - struct tree_desc_s bl_desc; /* desc. for bit length tree */
38.202 -
38.203 - ush bl_count[MAX_BITS+1];
38.204 - /* number of codes at each bit length for an optimal tree */
38.205 -
38.206 - int heap[2*L_CODES+1]; /* heap used to build the Huffman trees */
38.207 - int heap_len; /* number of elements in the heap */
38.208 - int heap_max; /* element of largest frequency */
38.209 - /* The sons of heap[n] are heap[2*n] and heap[2*n+1]. heap[0] is not used.
38.210 - * The same heap array is used to build all trees.
38.211 - */
38.212 -
38.213 - uch depth[2*L_CODES+1];
38.214 - /* Depth of each subtree used as tie breaker for trees of equal frequency
38.215 - */
38.216 -
38.217 - uchf *l_buf; /* buffer for literals or lengths */
38.218 -
38.219 - uInt lit_bufsize;
38.220 - /* Size of match buffer for literals/lengths. There are 4 reasons for
38.221 - * limiting lit_bufsize to 64K:
38.222 - * - frequencies can be kept in 16 bit counters
38.223 - * - if compression is not successful for the first block, all input
38.224 - * data is still in the window so we can still emit a stored block even
38.225 - * when input comes from standard input. (This can also be done for
38.226 - * all blocks if lit_bufsize is not greater than 32K.)
38.227 - * - if compression is not successful for a file smaller than 64K, we can
38.228 - * even emit a stored file instead of a stored block (saving 5 bytes).
38.229 - * This is applicable only for zip (not gzip or zlib).
38.230 - * - creating new Huffman trees less frequently may not provide fast
38.231 - * adaptation to changes in the input data statistics. (Take for
38.232 - * example a binary file with poorly compressible code followed by
38.233 - * a highly compressible string table.) Smaller buffer sizes give
38.234 - * fast adaptation but have of course the overhead of transmitting
38.235 - * trees more frequently.
38.236 - * - I can't count above 4
38.237 - */
38.238 -
38.239 - uInt last_lit; /* running index in l_buf */
38.240 -
38.241 - ushf *d_buf;
38.242 - /* Buffer for distances. To simplify the code, d_buf and l_buf have
38.243 - * the same number of elements. To use different lengths, an extra flag
38.244 - * array would be necessary.
38.245 - */
38.246 -
38.247 - ulg opt_len; /* bit length of current block with optimal trees */
38.248 - ulg static_len; /* bit length of current block with static trees */
38.249 - uInt matches; /* number of string matches in current block */
38.250 - int last_eob_len; /* bit length of EOB code for last block */
38.251 -
38.252 -#ifdef DEBUG
38.253 - ulg compressed_len; /* total bit length of compressed file mod 2^32 */
38.254 - ulg bits_sent; /* bit length of compressed data sent mod 2^32 */
38.255 -#endif
38.256 -
38.257 - ush bi_buf;
38.258 - /* Output buffer. bits are inserted starting at the bottom (least
38.259 - * significant bits).
38.260 - */
38.261 - int bi_valid;
38.262 - /* Number of valid bits in bi_buf. All bits above the last valid bit
38.263 - * are always zero.
38.264 - */
38.265 -
38.266 -} FAR deflate_state;
38.267 -
38.268 -/* Output a byte on the stream.
38.269 - * IN assertion: there is enough room in pending_buf.
38.270 - */
38.271 -#define put_byte(s, c) {s->pending_buf[s->pending++] = (c);}
38.272 -
38.273 -
38.274 -#define MIN_LOOKAHEAD (MAX_MATCH+MIN_MATCH+1)
38.275 -/* Minimum amount of lookahead, except at the end of the input file.
38.276 - * See deflate.c for comments about the MIN_MATCH+1.
38.277 - */
38.278 -
38.279 -#define MAX_DIST(s) ((s)->w_size-MIN_LOOKAHEAD)
38.280 -/* In order to simplify the code, particularly on 16 bit machines, match
38.281 - * distances are limited to MAX_DIST instead of WSIZE.
38.282 - */
38.283 -
38.284 - /* in trees.c */
38.285 -void _tr_init OF((deflate_state *s));
38.286 -int _tr_tally OF((deflate_state *s, unsigned dist, unsigned lc));
38.287 -void _tr_flush_block OF((deflate_state *s, charf *buf, ulg stored_len,
38.288 - int eof));
38.289 -void _tr_align OF((deflate_state *s));
38.290 -void _tr_stored_block OF((deflate_state *s, charf *buf, ulg stored_len,
38.291 - int eof));
38.292 -
38.293 -#define d_code(dist) \
38.294 - ((dist) < 256 ? _dist_code[dist] : _dist_code[256+((dist)>>7)])
38.295 -/* Mapping from a distance to a distance code. dist is the distance - 1 and
38.296 - * must not have side effects. _dist_code[256] and _dist_code[257] are never
38.297 - * used.
38.298 - */
38.299 -
38.300 -#ifndef DEBUG
38.301 -/* Inline versions of _tr_tally for speed: */
38.302 -
38.303 -#if defined(GEN_TREES_H) || !defined(STDC)
38.304 - extern uch _length_code[];
38.305 - extern uch _dist_code[];
38.306 -#else
38.307 - extern const uch _length_code[];
38.308 - extern const uch _dist_code[];
38.309 -#endif
38.310 -
38.311 -# define _tr_tally_lit(s, c, flush) \
38.312 - { uch cc = (c); \
38.313 - s->d_buf[s->last_lit] = 0; \
38.314 - s->l_buf[s->last_lit++] = cc; \
38.315 - s->dyn_ltree[cc].Freq++; \
38.316 - flush = (s->last_lit == s->lit_bufsize-1); \
38.317 - }
38.318 -# define _tr_tally_dist(s, distance, length, flush) \
38.319 - { uch len = (length); \
38.320 - ush dist = (distance); \
38.321 - s->d_buf[s->last_lit] = dist; \
38.322 - s->l_buf[s->last_lit++] = len; \
38.323 - dist--; \
38.324 - s->dyn_ltree[_length_code[len]+LITERALS+1].Freq++; \
38.325 - s->dyn_dtree[d_code(dist)].Freq++; \
38.326 - flush = (s->last_lit == s->lit_bufsize-1); \
38.327 - }
38.328 -#else
38.329 -# define _tr_tally_lit(s, c, flush) flush = _tr_tally(s, 0, c)
38.330 -# define _tr_tally_dist(s, distance, length, flush) \
38.331 - flush = _tr_tally(s, distance, length)
38.332 -#endif
38.333 -
38.334 -#endif /* DEFLATE_H */
39.1 --- a/sourcepawn/vm/zlib/gzio.c Tue Nov 07 23:26:40 2006 +0000
39.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
39.3 @@ -1,1026 +0,0 @@
39.4 -/* gzio.c -- IO on .gz files
39.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
39.6 - * For conditions of distribution and use, see copyright notice in zlib.h
39.7 - *
39.8 - * Compile this file with -DNO_GZCOMPRESS to avoid the compression code.
39.9 - */
39.10 -
39.11 -/* @(#) $Id$ */
39.12 -
39.13 -#include <stdio.h>
39.14 -
39.15 -#include "zutil.h"
39.16 -
39.17 -#ifdef NO_DEFLATE /* for compatibility with old definition */
39.18 -# define NO_GZCOMPRESS
39.19 -#endif
39.20 -
39.21 -#ifndef NO_DUMMY_DECL
39.22 -struct internal_state {int dummy;}; /* for buggy compilers */
39.23 -#endif
39.24 -
39.25 -#ifndef Z_BUFSIZE
39.26 -# ifdef MAXSEG_64K
39.27 -# define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
39.28 -# else
39.29 -# define Z_BUFSIZE 16384
39.30 -# endif
39.31 -#endif
39.32 -#ifndef Z_PRINTF_BUFSIZE
39.33 -# define Z_PRINTF_BUFSIZE 4096
39.34 -#endif
39.35 -
39.36 -#ifdef __MVS__
39.37 -# pragma map (fdopen , "\174\174FDOPEN")
39.38 - FILE *fdopen(int, const char *);
39.39 -#endif
39.40 -
39.41 -#ifndef STDC
39.42 -extern voidp malloc OF((uInt size));
39.43 -extern void free OF((voidpf ptr));
39.44 -#endif
39.45 -
39.46 -#define ALLOC(size) malloc(size)
39.47 -#define TRYFREE(p) {if (p) free(p);}
39.48 -
39.49 -static int const gz_magic[2] = {0x1f, 0x8b}; /* gzip magic header */
39.50 -
39.51 -/* gzip flag byte */
39.52 -#define ASCII_FLAG 0x01 /* bit 0 set: file probably ascii text */
39.53 -#define HEAD_CRC 0x02 /* bit 1 set: header CRC present */
39.54 -#define EXTRA_FIELD 0x04 /* bit 2 set: extra field present */
39.55 -#define ORIG_NAME 0x08 /* bit 3 set: original file name present */
39.56 -#define COMMENT 0x10 /* bit 4 set: file comment present */
39.57 -#define RESERVED 0xE0 /* bits 5..7: reserved */
39.58 -
39.59 -typedef struct gz_stream {
39.60 - z_stream stream;
39.61 - int z_err; /* error code for last stream operation */
39.62 - int z_eof; /* set if end of input file */
39.63 - FILE *file; /* .gz file */
39.64 - Byte *inbuf; /* input buffer */
39.65 - Byte *outbuf; /* output buffer */
39.66 - uLong crc; /* crc32 of uncompressed data */
39.67 - char *msg; /* error message */
39.68 - char *path; /* path name for debugging only */
39.69 - int transparent; /* 1 if input file is not a .gz file */
39.70 - char mode; /* 'w' or 'r' */
39.71 - z_off_t start; /* start of compressed data in file (header skipped) */
39.72 - z_off_t in; /* bytes into deflate or inflate */
39.73 - z_off_t out; /* bytes out of deflate or inflate */
39.74 - int back; /* one character push-back */
39.75 - int last; /* true if push-back is last character */
39.76 -} gz_stream;
39.77 -
39.78 -
39.79 -local gzFile gz_open OF((const char *path, const char *mode, int fd));
39.80 -local int do_flush OF((gzFile file, int flush));
39.81 -local int get_byte OF((gz_stream *s));
39.82 -local void check_header OF((gz_stream *s));
39.83 -local int destroy OF((gz_stream *s));
39.84 -local void putLong OF((FILE *file, uLong x));
39.85 -local uLong getLong OF((gz_stream *s));
39.86 -
39.87 -/* ===========================================================================
39.88 - Opens a gzip (.gz) file for reading or writing. The mode parameter
39.89 - is as in fopen ("rb" or "wb"). The file is given either by file descriptor
39.90 - or path name (if fd == -1).
39.91 - gz_open returns NULL if the file could not be opened or if there was
39.92 - insufficient memory to allocate the (de)compression state; errno
39.93 - can be checked to distinguish the two cases (if errno is zero, the
39.94 - zlib error is Z_MEM_ERROR).
39.95 -*/
39.96 -local gzFile gz_open (path, mode, fd)
39.97 - const char *path;
39.98 - const char *mode;
39.99 - int fd;
39.100 -{
39.101 - int err;
39.102 - int level = Z_DEFAULT_COMPRESSION; /* compression level */
39.103 - int strategy = Z_DEFAULT_STRATEGY; /* compression strategy */
39.104 - char *p = (char*)mode;
39.105 - gz_stream *s;
39.106 - char fmode[80]; /* copy of mode, without the compression level */
39.107 - char *m = fmode;
39.108 -
39.109 - if (!path || !mode) return Z_NULL;
39.110 -
39.111 - s = (gz_stream *)ALLOC(sizeof(gz_stream));
39.112 - if (!s) return Z_NULL;
39.113 -
39.114 - s->stream.zalloc = (alloc_func)0;
39.115 - s->stream.zfree = (free_func)0;
39.116 - s->stream.opaque = (voidpf)0;
39.117 - s->stream.next_in = s->inbuf = Z_NULL;
39.118 - s->stream.next_out = s->outbuf = Z_NULL;
39.119 - s->stream.avail_in = s->stream.avail_out = 0;
39.120 - s->file = NULL;
39.121 - s->z_err = Z_OK;
39.122 - s->z_eof = 0;
39.123 - s->in = 0;
39.124 - s->out = 0;
39.125 - s->back = EOF;
39.126 - s->crc = crc32(0L, Z_NULL, 0);
39.127 - s->msg = NULL;
39.128 - s->transparent = 0;
39.129 -
39.130 - s->path = (char*)ALLOC(strlen(path)+1);
39.131 - if (s->path == NULL) {
39.132 - return destroy(s), (gzFile)Z_NULL;
39.133 - }
39.134 - strcpy(s->path, path); /* do this early for debugging */
39.135 -
39.136 - s->mode = '\0';
39.137 - do {
39.138 - if (*p == 'r') s->mode = 'r';
39.139 - if (*p == 'w' || *p == 'a') s->mode = 'w';
39.140 - if (*p >= '0' && *p <= '9') {
39.141 - level = *p - '0';
39.142 - } else if (*p == 'f') {
39.143 - strategy = Z_FILTERED;
39.144 - } else if (*p == 'h') {
39.145 - strategy = Z_HUFFMAN_ONLY;
39.146 - } else if (*p == 'R') {
39.147 - strategy = Z_RLE;
39.148 - } else {
39.149 - *m++ = *p; /* copy the mode */
39.150 - }
39.151 - } while (*p++ && m != fmode + sizeof(fmode));
39.152 - if (s->mode == '\0') return destroy(s), (gzFile)Z_NULL;
39.153 -
39.154 - if (s->mode == 'w') {
39.155 -#ifdef NO_GZCOMPRESS
39.156 - err = Z_STREAM_ERROR;
39.157 -#else
39.158 - err = deflateInit2(&(s->stream), level,
39.159 - Z_DEFLATED, -MAX_WBITS, DEF_MEM_LEVEL, strategy);
39.160 - /* windowBits is passed < 0 to suppress zlib header */
39.161 -
39.162 - s->stream.next_out = s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
39.163 -#endif
39.164 - if (err != Z_OK || s->outbuf == Z_NULL) {
39.165 - return destroy(s), (gzFile)Z_NULL;
39.166 - }
39.167 - } else {
39.168 - s->stream.next_in = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
39.169 -
39.170 - err = inflateInit2(&(s->stream), -MAX_WBITS);
39.171 - /* windowBits is passed < 0 to tell that there is no zlib header.
39.172 - * Note that in this case inflate *requires* an extra "dummy" byte
39.173 - * after the compressed stream in order to complete decompression and
39.174 - * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
39.175 - * present after the compressed stream.
39.176 - */
39.177 - if (err != Z_OK || s->inbuf == Z_NULL) {
39.178 - return destroy(s), (gzFile)Z_NULL;
39.179 - }
39.180 - }
39.181 - s->stream.avail_out = Z_BUFSIZE;
39.182 -
39.183 - errno = 0;
39.184 - s->file = fd < 0 ? F_OPEN(path, fmode) : (FILE*)fdopen(fd, fmode);
39.185 -
39.186 - if (s->file == NULL) {
39.187 - return destroy(s), (gzFile)Z_NULL;
39.188 - }
39.189 - if (s->mode == 'w') {
39.190 - /* Write a very simple .gz header:
39.191 - */
39.192 - fprintf(s->file, "%c%c%c%c%c%c%c%c%c%c", gz_magic[0], gz_magic[1],
39.193 - Z_DEFLATED, 0 /*flags*/, 0,0,0,0 /*time*/, 0 /*xflags*/, OS_CODE);
39.194 - s->start = 10L;
39.195 - /* We use 10L instead of ftell(s->file) to because ftell causes an
39.196 - * fflush on some systems. This version of the library doesn't use
39.197 - * start anyway in write mode, so this initialization is not
39.198 - * necessary.
39.199 - */
39.200 - } else {
39.201 - check_header(s); /* skip the .gz header */
39.202 - s->start = ftell(s->file) - s->stream.avail_in;
39.203 - }
39.204 -
39.205 - return (gzFile)s;
39.206 -}
39.207 -
39.208 -/* ===========================================================================
39.209 - Opens a gzip (.gz) file for reading or writing.
39.210 -*/
39.211 -gzFile ZEXPORT gzopen (path, mode)
39.212 - const char *path;
39.213 - const char *mode;
39.214 -{
39.215 - return gz_open (path, mode, -1);
39.216 -}
39.217 -
39.218 -/* ===========================================================================
39.219 - Associate a gzFile with the file descriptor fd. fd is not dup'ed here
39.220 - to mimic the behavio(u)r of fdopen.
39.221 -*/
39.222 -gzFile ZEXPORT gzdopen (fd, mode)
39.223 - int fd;
39.224 - const char *mode;
39.225 -{
39.226 - char name[46]; /* allow for up to 128-bit integers */
39.227 -
39.228 - if (fd < 0) return (gzFile)Z_NULL;
39.229 - sprintf(name, "<fd:%d>", fd); /* for debugging */
39.230 -
39.231 - return gz_open (name, mode, fd);
39.232 -}
39.233 -
39.234 -/* ===========================================================================
39.235 - * Update the compression level and strategy
39.236 - */
39.237 -int ZEXPORT gzsetparams (file, level, strategy)
39.238 - gzFile file;
39.239 - int level;
39.240 - int strategy;
39.241 -{
39.242 - gz_stream *s = (gz_stream*)file;
39.243 -
39.244 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
39.245 -
39.246 - /* Make room to allow flushing */
39.247 - if (s->stream.avail_out == 0) {
39.248 -
39.249 - s->stream.next_out = s->outbuf;
39.250 - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
39.251 - s->z_err = Z_ERRNO;
39.252 - }
39.253 - s->stream.avail_out = Z_BUFSIZE;
39.254 - }
39.255 -
39.256 - return deflateParams (&(s->stream), level, strategy);
39.257 -}
39.258 -
39.259 -/* ===========================================================================
39.260 - Read a byte from a gz_stream; update next_in and avail_in. Return EOF
39.261 - for end of file.
39.262 - IN assertion: the stream s has been sucessfully opened for reading.
39.263 -*/
39.264 -local int get_byte(s)
39.265 - gz_stream *s;
39.266 -{
39.267 - if (s->z_eof) return EOF;
39.268 - if (s->stream.avail_in == 0) {
39.269 - errno = 0;
39.270 - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
39.271 - if (s->stream.avail_in == 0) {
39.272 - s->z_eof = 1;
39.273 - if (ferror(s->file)) s->z_err = Z_ERRNO;
39.274 - return EOF;
39.275 - }
39.276 - s->stream.next_in = s->inbuf;
39.277 - }
39.278 - s->stream.avail_in--;
39.279 - return *(s->stream.next_in)++;
39.280 -}
39.281 -
39.282 -/* ===========================================================================
39.283 - Check the gzip header of a gz_stream opened for reading. Set the stream
39.284 - mode to transparent if the gzip magic header is not present; set s->err
39.285 - to Z_DATA_ERROR if the magic header is present but the rest of the header
39.286 - is incorrect.
39.287 - IN assertion: the stream s has already been created sucessfully;
39.288 - s->stream.avail_in is zero for the first time, but may be non-zero
39.289 - for concatenated .gz files.
39.290 -*/
39.291 -local void check_header(s)
39.292 - gz_stream *s;
39.293 -{
39.294 - int method; /* method byte */
39.295 - int flags; /* flags byte */
39.296 - uInt len;
39.297 - int c;
39.298 -
39.299 - /* Assure two bytes in the buffer so we can peek ahead -- handle case
39.300 - where first byte of header is at the end of the buffer after the last
39.301 - gzip segment */
39.302 - len = s->stream.avail_in;
39.303 - if (len < 2) {
39.304 - if (len) s->inbuf[0] = s->stream.next_in[0];
39.305 - errno = 0;
39.306 - len = (uInt)fread(s->inbuf + len, 1, Z_BUFSIZE >> len, s->file);
39.307 - if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
39.308 - s->stream.avail_in += len;
39.309 - s->stream.next_in = s->inbuf;
39.310 - if (s->stream.avail_in < 2) {
39.311 - s->transparent = s->stream.avail_in;
39.312 - return;
39.313 - }
39.314 - }
39.315 -
39.316 - /* Peek ahead to check the gzip magic header */
39.317 - if (s->stream.next_in[0] != gz_magic[0] ||
39.318 - s->stream.next_in[1] != gz_magic[1]) {
39.319 - s->transparent = 1;
39.320 - return;
39.321 - }
39.322 - s->stream.avail_in -= 2;
39.323 - s->stream.next_in += 2;
39.324 -
39.325 - /* Check the rest of the gzip header */
39.326 - method = get_byte(s);
39.327 - flags = get_byte(s);
39.328 - if (method != Z_DEFLATED || (flags & RESERVED) != 0) {
39.329 - s->z_err = Z_DATA_ERROR;
39.330 - return;
39.331 - }
39.332 -
39.333 - /* Discard time, xflags and OS code: */
39.334 - for (len = 0; len < 6; len++) (void)get_byte(s);
39.335 -
39.336 - if ((flags & EXTRA_FIELD) != 0) { /* skip the extra field */
39.337 - len = (uInt)get_byte(s);
39.338 - len += ((uInt)get_byte(s))<<8;
39.339 - /* len is garbage if EOF but the loop below will quit anyway */
39.340 - while (len-- != 0 && get_byte(s) != EOF) ;
39.341 - }
39.342 - if ((flags & ORIG_NAME) != 0) { /* skip the original file name */
39.343 - while ((c = get_byte(s)) != 0 && c != EOF) ;
39.344 - }
39.345 - if ((flags & COMMENT) != 0) { /* skip the .gz file comment */
39.346 - while ((c = get_byte(s)) != 0 && c != EOF) ;
39.347 - }
39.348 - if ((flags & HEAD_CRC) != 0) { /* skip the header crc */
39.349 - for (len = 0; len < 2; len++) (void)get_byte(s);
39.350 - }
39.351 - s->z_err = s->z_eof ? Z_DATA_ERROR : Z_OK;
39.352 -}
39.353 -
39.354 - /* ===========================================================================
39.355 - * Cleanup then free the given gz_stream. Return a zlib error code.
39.356 - Try freeing in the reverse order of allocations.
39.357 - */
39.358 -local int destroy (s)
39.359 - gz_stream *s;
39.360 -{
39.361 - int err = Z_OK;
39.362 -
39.363 - if (!s) return Z_STREAM_ERROR;
39.364 -
39.365 - TRYFREE(s->msg);
39.366 -
39.367 - if (s->stream.state != NULL) {
39.368 - if (s->mode == 'w') {
39.369 -#ifdef NO_GZCOMPRESS
39.370 - err = Z_STREAM_ERROR;
39.371 -#else
39.372 - err = deflateEnd(&(s->stream));
39.373 -#endif
39.374 - } else if (s->mode == 'r') {
39.375 - err = inflateEnd(&(s->stream));
39.376 - }
39.377 - }
39.378 - if (s->file != NULL && fclose(s->file)) {
39.379 -#ifdef ESPIPE
39.380 - if (errno != ESPIPE) /* fclose is broken for pipes in HP/UX */
39.381 -#endif
39.382 - err = Z_ERRNO;
39.383 - }
39.384 - if (s->z_err < 0) err = s->z_err;
39.385 -
39.386 - TRYFREE(s->inbuf);
39.387 - TRYFREE(s->outbuf);
39.388 - TRYFREE(s->path);
39.389 - TRYFREE(s);
39.390 - return err;
39.391 -}
39.392 -
39.393 -/* ===========================================================================
39.394 - Reads the given number of uncompressed bytes from the compressed file.
39.395 - gzread returns the number of bytes actually read (0 for end of file).
39.396 -*/
39.397 -int ZEXPORT gzread (file, buf, len)
39.398 - gzFile file;
39.399 - voidp buf;
39.400 - unsigned len;
39.401 -{
39.402 - gz_stream *s = (gz_stream*)file;
39.403 - Bytef *start = (Bytef*)buf; /* starting point for crc computation */
39.404 - Byte *next_out; /* == stream.next_out but not forced far (for MSDOS) */
39.405 -
39.406 - if (s == NULL || s->mode != 'r') return Z_STREAM_ERROR;
39.407 -
39.408 - if (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO) return -1;
39.409 - if (s->z_err == Z_STREAM_END) return 0; /* EOF */
39.410 -
39.411 - next_out = (Byte*)buf;
39.412 - s->stream.next_out = (Bytef*)buf;
39.413 - s->stream.avail_out = len;
39.414 -
39.415 - if (s->stream.avail_out && s->back != EOF) {
39.416 - *next_out++ = s->back;
39.417 - s->stream.next_out++;
39.418 - s->stream.avail_out--;
39.419 - s->back = EOF;
39.420 - s->out++;
39.421 - start++;
39.422 - if (s->last) {
39.423 - s->z_err = Z_STREAM_END;
39.424 - return 1;
39.425 - }
39.426 - }
39.427 -
39.428 - while (s->stream.avail_out != 0) {
39.429 -
39.430 - if (s->transparent) {
39.431 - /* Copy first the lookahead bytes: */
39.432 - uInt n = s->stream.avail_in;
39.433 - if (n > s->stream.avail_out) n = s->stream.avail_out;
39.434 - if (n > 0) {
39.435 - zmemcpy(s->stream.next_out, s->stream.next_in, n);
39.436 - next_out += n;
39.437 - s->stream.next_out = next_out;
39.438 - s->stream.next_in += n;
39.439 - s->stream.avail_out -= n;
39.440 - s->stream.avail_in -= n;
39.441 - }
39.442 - if (s->stream.avail_out > 0) {
39.443 - s->stream.avail_out -=
39.444 - (uInt)fread(next_out, 1, s->stream.avail_out, s->file);
39.445 - }
39.446 - len -= s->stream.avail_out;
39.447 - s->in += len;
39.448 - s->out += len;
39.449 - if (len == 0) s->z_eof = 1;
39.450 - return (int)len;
39.451 - }
39.452 - if (s->stream.avail_in == 0 && !s->z_eof) {
39.453 -
39.454 - errno = 0;
39.455 - s->stream.avail_in = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
39.456 - if (s->stream.avail_in == 0) {
39.457 - s->z_eof = 1;
39.458 - if (ferror(s->file)) {
39.459 - s->z_err = Z_ERRNO;
39.460 - break;
39.461 - }
39.462 - }
39.463 - s->stream.next_in = s->inbuf;
39.464 - }
39.465 - s->in += s->stream.avail_in;
39.466 - s->out += s->stream.avail_out;
39.467 - s->z_err = inflate(&(s->stream), Z_NO_FLUSH);
39.468 - s->in -= s->stream.avail_in;
39.469 - s->out -= s->stream.avail_out;
39.470 -
39.471 - if (s->z_err == Z_STREAM_END) {
39.472 - /* Check CRC and original size */
39.473 - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
39.474 - start = s->stream.next_out;
39.475 -
39.476 - if (getLong(s) != s->crc) {
39.477 - s->z_err = Z_DATA_ERROR;
39.478 - } else {
39.479 - (void)getLong(s);
39.480 - /* The uncompressed length returned by above getlong() may be
39.481 - * different from s->out in case of concatenated .gz files.
39.482 - * Check for such files:
39.483 - */
39.484 - check_header(s);
39.485 - if (s->z_err == Z_OK) {
39.486 - inflateReset(&(s->stream));
39.487 - s->crc = crc32(0L, Z_NULL, 0);
39.488 - }
39.489 - }
39.490 - }
39.491 - if (s->z_err != Z_OK || s->z_eof) break;
39.492 - }
39.493 - s->crc = crc32(s->crc, start, (uInt)(s->stream.next_out - start));
39.494 -
39.495 - if (len == s->stream.avail_out &&
39.496 - (s->z_err == Z_DATA_ERROR || s->z_err == Z_ERRNO))
39.497 - return -1;
39.498 - return (int)(len - s->stream.avail_out);
39.499 -}
39.500 -
39.501 -
39.502 -/* ===========================================================================
39.503 - Reads one byte from the compressed file. gzgetc returns this byte
39.504 - or -1 in case of end of file or error.
39.505 -*/
39.506 -int ZEXPORT gzgetc(file)
39.507 - gzFile file;
39.508 -{
39.509 - unsigned char c;
39.510 -
39.511 - return gzread(file, &c, 1) == 1 ? c : -1;
39.512 -}
39.513 -
39.514 -
39.515 -/* ===========================================================================
39.516 - Push one byte back onto the stream.
39.517 -*/
39.518 -int ZEXPORT gzungetc(c, file)
39.519 - int c;
39.520 - gzFile file;
39.521 -{
39.522 - gz_stream *s = (gz_stream*)file;
39.523 -
39.524 - if (s == NULL || s->mode != 'r' || c == EOF || s->back != EOF) return EOF;
39.525 - s->back = c;
39.526 - s->out--;
39.527 - s->last = (s->z_err == Z_STREAM_END);
39.528 - if (s->last) s->z_err = Z_OK;
39.529 - s->z_eof = 0;
39.530 - return c;
39.531 -}
39.532 -
39.533 -
39.534 -/* ===========================================================================
39.535 - Reads bytes from the compressed file until len-1 characters are
39.536 - read, or a newline character is read and transferred to buf, or an
39.537 - end-of-file condition is encountered. The string is then terminated
39.538 - with a null character.
39.539 - gzgets returns buf, or Z_NULL in case of error.
39.540 -
39.541 - The current implementation is not optimized at all.
39.542 -*/
39.543 -char * ZEXPORT gzgets(file, buf, len)
39.544 - gzFile file;
39.545 - char *buf;
39.546 - int len;
39.547 -{
39.548 - char *b = buf;
39.549 - if (buf == Z_NULL || len <= 0) return Z_NULL;
39.550 -
39.551 - while (--len > 0 && gzread(file, buf, 1) == 1 && *buf++ != '\n') ;
39.552 - *buf = '\0';
39.553 - return b == buf && len > 0 ? Z_NULL : b;
39.554 -}
39.555 -
39.556 -
39.557 -#ifndef NO_GZCOMPRESS
39.558 -/* ===========================================================================
39.559 - Writes the given number of uncompressed bytes into the compressed file.
39.560 - gzwrite returns the number of bytes actually written (0 in case of error).
39.561 -*/
39.562 -int ZEXPORT gzwrite (file, buf, len)
39.563 - gzFile file;
39.564 - voidpc buf;
39.565 - unsigned len;
39.566 -{
39.567 - gz_stream *s = (gz_stream*)file;
39.568 -
39.569 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
39.570 -
39.571 - s->stream.next_in = (Bytef*)buf;
39.572 - s->stream.avail_in = len;
39.573 -
39.574 - while (s->stream.avail_in != 0) {
39.575 -
39.576 - if (s->stream.avail_out == 0) {
39.577 -
39.578 - s->stream.next_out = s->outbuf;
39.579 - if (fwrite(s->outbuf, 1, Z_BUFSIZE, s->file) != Z_BUFSIZE) {
39.580 - s->z_err = Z_ERRNO;
39.581 - break;
39.582 - }
39.583 - s->stream.avail_out = Z_BUFSIZE;
39.584 - }
39.585 - s->in += s->stream.avail_in;
39.586 - s->out += s->stream.avail_out;
39.587 - s->z_err = deflate(&(s->stream), Z_NO_FLUSH);
39.588 - s->in -= s->stream.avail_in;
39.589 - s->out -= s->stream.avail_out;
39.590 - if (s->z_err != Z_OK) break;
39.591 - }
39.592 - s->crc = crc32(s->crc, (const Bytef *)buf, len);
39.593 -
39.594 - return (int)(len - s->stream.avail_in);
39.595 -}
39.596 -
39.597 -
39.598 -/* ===========================================================================
39.599 - Converts, formats, and writes the args to the compressed file under
39.600 - control of the format string, as in fprintf. gzprintf returns the number of
39.601 - uncompressed bytes actually written (0 in case of error).
39.602 -*/
39.603 -#ifdef STDC
39.604 -#include <stdarg.h>
39.605 -
39.606 -int ZEXPORTVA gzprintf (gzFile file, const char *format, /* args */ ...)
39.607 -{
39.608 - char buf[Z_PRINTF_BUFSIZE];
39.609 - va_list va;
39.610 - int len;
39.611 -
39.612 - buf[sizeof(buf) - 1] = 0;
39.613 - va_start(va, format);
39.614 -#ifdef NO_vsnprintf
39.615 -# ifdef HAS_vsprintf_void
39.616 - (void)vsprintf(buf, format, va);
39.617 - va_end(va);
39.618 - for (len = 0; len < sizeof(buf); len++)
39.619 - if (buf[len] == 0) break;
39.620 -# else
39.621 - len = vsprintf(buf, format, va);
39.622 - va_end(va);
39.623 -# endif
39.624 -#else
39.625 -# ifdef HAS_vsnprintf_void
39.626 - (void)vsnprintf(buf, sizeof(buf), format, va);
39.627 - va_end(va);
39.628 - len = strlen(buf);
39.629 -# else
39.630 - len = vsnprintf(buf, sizeof(buf), format, va);
39.631 - va_end(va);
39.632 -# endif
39.633 -#endif
39.634 - if (len <= 0 || len >= (int)sizeof(buf) || buf[sizeof(buf) - 1] != 0)
39.635 - return 0;
39.636 - return gzwrite(file, buf, (unsigned)len);
39.637 -}
39.638 -#else /* not ANSI C */
39.639 -
39.640 -int ZEXPORTVA gzprintf (file, format, a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
39.641 - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20)
39.642 - gzFile file;
39.643 - const char *format;
39.644 - int a1, a2, a3, a4, a5, a6, a7, a8, a9, a10,
39.645 - a11, a12, a13, a14, a15, a16, a17, a18, a19, a20;
39.646 -{
39.647 - char buf[Z_PRINTF_BUFSIZE];
39.648 - int len;
39.649 -
39.650 - buf[sizeof(buf) - 1] = 0;
39.651 -#ifdef NO_snprintf
39.652 -# ifdef HAS_sprintf_void
39.653 - sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
39.654 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
39.655 - for (len = 0; len < sizeof(buf); len++)
39.656 - if (buf[len] == 0) break;
39.657 -# else
39.658 - len = sprintf(buf, format, a1, a2, a3, a4, a5, a6, a7, a8,
39.659 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
39.660 -# endif
39.661 -#else
39.662 -# ifdef HAS_snprintf_void
39.663 - snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
39.664 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
39.665 - len = strlen(buf);
39.666 -# else
39.667 - len = snprintf(buf, sizeof(buf), format, a1, a2, a3, a4, a5, a6, a7, a8,
39.668 - a9, a10, a11, a12, a13, a14, a15, a16, a17, a18, a19, a20);
39.669 -# endif
39.670 -#endif
39.671 - if (len <= 0 || len >= sizeof(buf) || buf[sizeof(buf) - 1] != 0)
39.672 - return 0;
39.673 - return gzwrite(file, buf, len);
39.674 -}
39.675 -#endif
39.676 -
39.677 -/* ===========================================================================
39.678 - Writes c, converted to an unsigned char, into the compressed file.
39.679 - gzputc returns the value that was written, or -1 in case of error.
39.680 -*/
39.681 -int ZEXPORT gzputc(file, c)
39.682 - gzFile file;
39.683 - int c;
39.684 -{
39.685 - unsigned char cc = (unsigned char) c; /* required for big endian systems */
39.686 -
39.687 - return gzwrite(file, &cc, 1) == 1 ? (int)cc : -1;
39.688 -}
39.689 -
39.690 -
39.691 -/* ===========================================================================
39.692 - Writes the given null-terminated string to the compressed file, excluding
39.693 - the terminating null character.
39.694 - gzputs returns the number of characters written, or -1 in case of error.
39.695 -*/
39.696 -int ZEXPORT gzputs(file, s)
39.697 - gzFile file;
39.698 - const char *s;
39.699 -{
39.700 - return gzwrite(file, (char*)s, (unsigned)strlen(s));
39.701 -}
39.702 -
39.703 -
39.704 -/* ===========================================================================
39.705 - Flushes all pending output into the compressed file. The parameter
39.706 - flush is as in the deflate() function.
39.707 -*/
39.708 -local int do_flush (file, flush)
39.709 - gzFile file;
39.710 - int flush;
39.711 -{
39.712 - uInt len;
39.713 - int done = 0;
39.714 - gz_stream *s = (gz_stream*)file;
39.715 -
39.716 - if (s == NULL || s->mode != 'w') return Z_STREAM_ERROR;
39.717 -
39.718 - s->stream.avail_in = 0; /* should be zero already anyway */
39.719 -
39.720 - for (;;) {
39.721 - len = Z_BUFSIZE - s->stream.avail_out;
39.722 -
39.723 - if (len != 0) {
39.724 - if ((uInt)fwrite(s->outbuf, 1, len, s->file) != len) {
39.725 - s->z_err = Z_ERRNO;
39.726 - return Z_ERRNO;
39.727 - }
39.728 - s->stream.next_out = s->outbuf;
39.729 - s->stream.avail_out = Z_BUFSIZE;
39.730 - }
39.731 - if (done) break;
39.732 - s->out += s->stream.avail_out;
39.733 - s->z_err = deflate(&(s->stream), flush);
39.734 - s->out -= s->stream.avail_out;
39.735 -
39.736 - /* Ignore the second of two consecutive flushes: */
39.737 - if (len == 0 && s->z_err == Z_BUF_ERROR) s->z_err = Z_OK;
39.738 -
39.739 - /* deflate has finished flushing only when it hasn't used up
39.740 - * all the available space in the output buffer:
39.741 - */
39.742 - done = (s->stream.avail_out != 0 || s->z_err == Z_STREAM_END);
39.743 -
39.744 - if (s->z_err != Z_OK && s->z_err != Z_STREAM_END) break;
39.745 - }
39.746 - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
39.747 -}
39.748 -
39.749 -int ZEXPORT gzflush (file, flush)
39.750 - gzFile file;
39.751 - int flush;
39.752 -{
39.753 - gz_stream *s = (gz_stream*)file;
39.754 - int err = do_flush (file, flush);
39.755 -
39.756 - if (err) return err;
39.757 - fflush(s->file);
39.758 - return s->z_err == Z_STREAM_END ? Z_OK : s->z_err;
39.759 -}
39.760 -#endif /* NO_GZCOMPRESS */
39.761 -
39.762 -/* ===========================================================================
39.763 - Sets the starting position for the next gzread or gzwrite on the given
39.764 - compressed file. The offset represents a number of bytes in the
39.765 - gzseek returns the resulting offset location as measured in bytes from
39.766 - the beginning of the uncompressed stream, or -1 in case of error.
39.767 - SEEK_END is not implemented, returns error.
39.768 - In this version of the library, gzseek can be extremely slow.
39.769 -*/
39.770 -z_off_t ZEXPORT gzseek (file, offset, whence)
39.771 - gzFile file;
39.772 - z_off_t offset;
39.773 - int whence;
39.774 -{
39.775 - gz_stream *s = (gz_stream*)file;
39.776 -
39.777 - if (s == NULL || whence == SEEK_END ||
39.778 - s->z_err == Z_ERRNO || s->z_err == Z_DATA_ERROR) {
39.779 - return -1L;
39.780 - }
39.781 -
39.782 - if (s->mode == 'w') {
39.783 -#ifdef NO_GZCOMPRESS
39.784 - return -1L;
39.785 -#else
39.786 - if (whence == SEEK_SET) {
39.787 - offset -= s->in;
39.788 - }
39.789 - if (offset < 0) return -1L;
39.790 -
39.791 - /* At this point, offset is the number of zero bytes to write. */
39.792 - if (s->inbuf == Z_NULL) {
39.793 - s->inbuf = (Byte*)ALLOC(Z_BUFSIZE); /* for seeking */
39.794 - if (s->inbuf == Z_NULL) return -1L;
39.795 - zmemzero(s->inbuf, Z_BUFSIZE);
39.796 - }
39.797 - while (offset > 0) {
39.798 - uInt size = Z_BUFSIZE;
39.799 - if (offset < Z_BUFSIZE) size = (uInt)offset;
39.800 -
39.801 - size = gzwrite(file, s->inbuf, size);
39.802 - if (size == 0) return -1L;
39.803 -
39.804 - offset -= size;
39.805 - }
39.806 - return s->in;
39.807 -#endif
39.808 - }
39.809 - /* Rest of function is for reading only */
39.810 -
39.811 - /* compute absolute position */
39.812 - if (whence == SEEK_CUR) {
39.813 - offset += s->out;
39.814 - }
39.815 - if (offset < 0) return -1L;
39.816 -
39.817 - if (s->transparent) {
39.818 - /* map to fseek */
39.819 - s->back = EOF;
39.820 - s->stream.avail_in = 0;
39.821 - s->stream.next_in = s->inbuf;
39.822 - if (fseek(s->file, offset, SEEK_SET) < 0) return -1L;
39.823 -
39.824 - s->in = s->out = offset;
39.825 - return offset;
39.826 - }
39.827 -
39.828 - /* For a negative seek, rewind and use positive seek */
39.829 - if (offset >= s->out) {
39.830 - offset -= s->out;
39.831 - } else if (gzrewind(file) < 0) {
39.832 - return -1L;
39.833 - }
39.834 - /* offset is now the number of bytes to skip. */
39.835 -
39.836 - if (offset != 0 && s->outbuf == Z_NULL) {
39.837 - s->outbuf = (Byte*)ALLOC(Z_BUFSIZE);
39.838 - if (s->outbuf == Z_NULL) return -1L;
39.839 - }
39.840 - if (offset && s->back != EOF) {
39.841 - s->back = EOF;
39.842 - s->out++;
39.843 - offset--;
39.844 - if (s->last) s->z_err = Z_STREAM_END;
39.845 - }
39.846 - while (offset > 0) {
39.847 - int size = Z_BUFSIZE;
39.848 - if (offset < Z_BUFSIZE) size = (int)offset;
39.849 -
39.850 - size = gzread(file, s->outbuf, (uInt)size);
39.851 - if (size <= 0) return -1L;
39.852 - offset -= size;
39.853 - }
39.854 - return s->out;
39.855 -}
39.856 -
39.857 -/* ===========================================================================
39.858 - Rewinds input file.
39.859 -*/
39.860 -int ZEXPORT gzrewind (file)
39.861 - gzFile file;
39.862 -{
39.863 - gz_stream *s = (gz_stream*)file;
39.864 -
39.865 - if (s == NULL || s->mode != 'r') return -1;
39.866 -
39.867 - s->z_err = Z_OK;
39.868 - s->z_eof = 0;
39.869 - s->back = EOF;
39.870 - s->stream.avail_in = 0;
39.871 - s->stream.next_in = s->inbuf;
39.872 - s->crc = crc32(0L, Z_NULL, 0);
39.873 - if (!s->transparent) (void)inflateReset(&s->stream);
39.874 - s->in = 0;
39.875 - s->out = 0;
39.876 - return fseek(s->file, s->start, SEEK_SET);
39.877 -}
39.878 -
39.879 -/* ===========================================================================
39.880 - Returns the starting position for the next gzread or gzwrite on the
39.881 - given compressed file. This position represents a number of bytes in the
39.882 - uncompressed data stream.
39.883 -*/
39.884 -z_off_t ZEXPORT gztell (file)
39.885 - gzFile file;
39.886 -{
39.887 - return gzseek(file, 0L, SEEK_CUR);
39.888 -}
39.889 -
39.890 -/* ===========================================================================
39.891 - Returns 1 when EOF has previously been detected reading the given
39.892 - input stream, otherwise zero.
39.893 -*/
39.894 -int ZEXPORT gzeof (file)
39.895 - gzFile file;
39.896 -{
39.897 - gz_stream *s = (gz_stream*)file;
39.898 -
39.899 - /* With concatenated compressed files that can have embedded
39.900 - * crc trailers, z_eof is no longer the only/best indicator of EOF
39.901 - * on a gz_stream. Handle end-of-stream error explicitly here.
39.902 - */
39.903 - if (s == NULL || s->mode != 'r') return 0;
39.904 - if (s->z_eof) return 1;
39.905 - return s->z_err == Z_STREAM_END;
39.906 -}
39.907 -
39.908 -/* ===========================================================================
39.909 - Returns 1 if reading and doing so transparently, otherwise zero.
39.910 -*/
39.911 -int ZEXPORT gzdirect (file)
39.912 - gzFile file;
39.913 -{
39.914 - gz_stream *s = (gz_stream*)file;
39.915 -
39.916 - if (s == NULL || s->mode != 'r') return 0;
39.917 - return s->transparent;
39.918 -}
39.919 -
39.920 -/* ===========================================================================
39.921 - Outputs a long in LSB order to the given file
39.922 -*/
39.923 -local void putLong (file, x)
39.924 - FILE *file;
39.925 - uLong x;
39.926 -{
39.927 - int n;
39.928 - for (n = 0; n < 4; n++) {
39.929 - fputc((int)(x & 0xff), file);
39.930 - x >>= 8;
39.931 - }
39.932 -}
39.933 -
39.934 -/* ===========================================================================
39.935 - Reads a long in LSB order from the given gz_stream. Sets z_err in case
39.936 - of error.
39.937 -*/
39.938 -local uLong getLong (s)
39.939 - gz_stream *s;
39.940 -{
39.941 - uLong x = (uLong)get_byte(s);
39.942 - int c;
39.943 -
39.944 - x += ((uLong)get_byte(s))<<8;
39.945 - x += ((uLong)get_byte(s))<<16;
39.946 - c = get_byte(s);
39.947 - if (c == EOF) s->z_err = Z_DATA_ERROR;
39.948 - x += ((uLong)c)<<24;
39.949 - return x;
39.950 -}
39.951 -
39.952 -/* ===========================================================================
39.953 - Flushes all pending output if necessary, closes the compressed file
39.954 - and deallocates all the (de)compression state.
39.955 -*/
39.956 -int ZEXPORT gzclose (file)
39.957 - gzFile file;
39.958 -{
39.959 - gz_stream *s = (gz_stream*)file;
39.960 -
39.961 - if (s == NULL) return Z_STREAM_ERROR;
39.962 -
39.963 - if (s->mode == 'w') {
39.964 -#ifdef NO_GZCOMPRESS
39.965 - return Z_STREAM_ERROR;
39.966 -#else
39.967 - if (do_flush (file, Z_FINISH) != Z_OK)
39.968 - return destroy((gz_stream*)file);
39.969 -
39.970 - putLong (s->file, s->crc);
39.971 - putLong (s->file, (uLong)(s->in & 0xffffffff));
39.972 -#endif
39.973 - }
39.974 - return destroy((gz_stream*)file);
39.975 -}
39.976 -
39.977 -#ifdef STDC
39.978 -# define zstrerror(errnum) strerror(errnum)
39.979 -#else
39.980 -# define zstrerror(errnum) ""
39.981 -#endif
39.982 -
39.983 -/* ===========================================================================
39.984 - Returns the error message for the last error which occurred on the
39.985 - given compressed file. errnum is set to zlib error number. If an
39.986 - error occurred in the file system and not in the compression library,
39.987 - errnum is set to Z_ERRNO and the application may consult errno
39.988 - to get the exact error code.
39.989 -*/
39.990 -const char * ZEXPORT gzerror (file, errnum)
39.991 - gzFile file;
39.992 - int *errnum;
39.993 -{
39.994 - char *m;
39.995 - gz_stream *s = (gz_stream*)file;
39.996 -
39.997 - if (s == NULL) {
39.998 - *errnum = Z_STREAM_ERROR;
39.999 - return (const char*)ERR_MSG(Z_STREAM_ERROR);
39.1000 - }
39.1001 - *errnum = s->z_err;
39.1002 - if (*errnum == Z_OK) return (const char*)"";
39.1003 -
39.1004 - m = (char*)(*errnum == Z_ERRNO ? zstrerror(errno) : s->stream.msg);
39.1005 -
39.1006 - if (m == NULL || *m == '\0') m = (char*)ERR_MSG(s->z_err);
39.1007 -
39.1008 - TRYFREE(s->msg);
39.1009 - s->msg = (char*)ALLOC(strlen(s->path) + strlen(m) + 3);
39.1010 - if (s->msg == Z_NULL) return (const char*)ERR_MSG(Z_MEM_ERROR);
39.1011 - strcpy(s->msg, s->path);
39.1012 - strcat(s->msg, ": ");
39.1013 - strcat(s->msg, m);
39.1014 - return (const char*)s->msg;
39.1015 -}
39.1016 -
39.1017 -/* ===========================================================================
39.1018 - Clear the error and end-of-file flags, and do the same for the real file.
39.1019 -*/
39.1020 -void ZEXPORT gzclearerr (file)
39.1021 - gzFile file;
39.1022 -{
39.1023 - gz_stream *s = (gz_stream*)file;
39.1024 -
39.1025 - if (s == NULL) return;
39.1026 - if (s->z_err != Z_STREAM_END) s->z_err = Z_OK;
39.1027 - s->z_eof = 0;
39.1028 - clearerr(s->file);
39.1029 -}
40.1 --- a/sourcepawn/vm/zlib/infback.c Tue Nov 07 23:26:40 2006 +0000
40.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
40.3 @@ -1,623 +0,0 @@
40.4 -/* infback.c -- inflate using a call-back interface
40.5 - * Copyright (C) 1995-2005 Mark Adler
40.6 - * For conditions of distribution and use, see copyright notice in zlib.h
40.7 - */
40.8 -
40.9 -/*
40.10 - This code is largely copied from inflate.c. Normally either infback.o or
40.11 - inflate.o would be linked into an application--not both. The interface
40.12 - with inffast.c is retained so that optimized assembler-coded versions of
40.13 - inflate_fast() can be used with either inflate.c or infback.c.
40.14 - */
40.15 -
40.16 -#include "zutil.h"
40.17 -#include "inftrees.h"
40.18 -#include "inflate.h"
40.19 -#include "inffast.h"
40.20 -
40.21 -/* function prototypes */
40.22 -local void fixedtables OF((struct inflate_state FAR *state));
40.23 -
40.24 -/*
40.25 - strm provides memory allocation functions in zalloc and zfree, or
40.26 - Z_NULL to use the library memory allocation functions.
40.27 -
40.28 - windowBits is in the range 8..15, and window is a user-supplied
40.29 - window and output buffer that is 2**windowBits bytes.
40.30 - */
40.31 -int ZEXPORT inflateBackInit_(strm, windowBits, window, version, stream_size)
40.32 -z_streamp strm;
40.33 -int windowBits;
40.34 -unsigned char FAR *window;
40.35 -const char *version;
40.36 -int stream_size;
40.37 -{
40.38 - struct inflate_state FAR *state;
40.39 -
40.40 - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
40.41 - stream_size != (int)(sizeof(z_stream)))
40.42 - return Z_VERSION_ERROR;
40.43 - if (strm == Z_NULL || window == Z_NULL ||
40.44 - windowBits < 8 || windowBits > 15)
40.45 - return Z_STREAM_ERROR;
40.46 - strm->msg = Z_NULL; /* in case we return an error */
40.47 - if (strm->zalloc == (alloc_func)0) {
40.48 - strm->zalloc = zcalloc;
40.49 - strm->opaque = (voidpf)0;
40.50 - }
40.51 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
40.52 - state = (struct inflate_state FAR *)ZALLOC(strm, 1,
40.53 - sizeof(struct inflate_state));
40.54 - if (state == Z_NULL) return Z_MEM_ERROR;
40.55 - Tracev((stderr, "inflate: allocated\n"));
40.56 - strm->state = (struct internal_state FAR *)state;
40.57 - state->dmax = 32768U;
40.58 - state->wbits = windowBits;
40.59 - state->wsize = 1U << windowBits;
40.60 - state->window = window;
40.61 - state->write = 0;
40.62 - state->whave = 0;
40.63 - return Z_OK;
40.64 -}
40.65 -
40.66 -/*
40.67 - Return state with length and distance decoding tables and index sizes set to
40.68 - fixed code decoding. Normally this returns fixed tables from inffixed.h.
40.69 - If BUILDFIXED is defined, then instead this routine builds the tables the
40.70 - first time it's called, and returns those tables the first time and
40.71 - thereafter. This reduces the size of the code by about 2K bytes, in
40.72 - exchange for a little execution time. However, BUILDFIXED should not be
40.73 - used for threaded applications, since the rewriting of the tables and virgin
40.74 - may not be thread-safe.
40.75 - */
40.76 -local void fixedtables(state)
40.77 -struct inflate_state FAR *state;
40.78 -{
40.79 -#ifdef BUILDFIXED
40.80 - static int virgin = 1;
40.81 - static code *lenfix, *distfix;
40.82 - static code fixed[544];
40.83 -
40.84 - /* build fixed huffman tables if first call (may not be thread safe) */
40.85 - if (virgin) {
40.86 - unsigned sym, bits;
40.87 - static code *next;
40.88 -
40.89 - /* literal/length table */
40.90 - sym = 0;
40.91 - while (sym < 144) state->lens[sym++] = 8;
40.92 - while (sym < 256) state->lens[sym++] = 9;
40.93 - while (sym < 280) state->lens[sym++] = 7;
40.94 - while (sym < 288) state->lens[sym++] = 8;
40.95 - next = fixed;
40.96 - lenfix = next;
40.97 - bits = 9;
40.98 - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
40.99 -
40.100 - /* distance table */
40.101 - sym = 0;
40.102 - while (sym < 32) state->lens[sym++] = 5;
40.103 - distfix = next;
40.104 - bits = 5;
40.105 - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
40.106 -
40.107 - /* do this just once */
40.108 - virgin = 0;
40.109 - }
40.110 -#else /* !BUILDFIXED */
40.111 -# include "inffixed.h"
40.112 -#endif /* BUILDFIXED */
40.113 - state->lencode = lenfix;
40.114 - state->lenbits = 9;
40.115 - state->distcode = distfix;
40.116 - state->distbits = 5;
40.117 -}
40.118 -
40.119 -/* Macros for inflateBack(): */
40.120 -
40.121 -/* Load returned state from inflate_fast() */
40.122 -#define LOAD() \
40.123 - do { \
40.124 - put = strm->next_out; \
40.125 - left = strm->avail_out; \
40.126 - next = strm->next_in; \
40.127 - have = strm->avail_in; \
40.128 - hold = state->hold; \
40.129 - bits = state->bits; \
40.130 - } while (0)
40.131 -
40.132 -/* Set state from registers for inflate_fast() */
40.133 -#define RESTORE() \
40.134 - do { \
40.135 - strm->next_out = put; \
40.136 - strm->avail_out = left; \
40.137 - strm->next_in = next; \
40.138 - strm->avail_in = have; \
40.139 - state->hold = hold; \
40.140 - state->bits = bits; \
40.141 - } while (0)
40.142 -
40.143 -/* Clear the input bit accumulator */
40.144 -#define INITBITS() \
40.145 - do { \
40.146 - hold = 0; \
40.147 - bits = 0; \
40.148 - } while (0)
40.149 -
40.150 -/* Assure that some input is available. If input is requested, but denied,
40.151 - then return a Z_BUF_ERROR from inflateBack(). */
40.152 -#define PULL() \
40.153 - do { \
40.154 - if (have == 0) { \
40.155 - have = in(in_desc, &next); \
40.156 - if (have == 0) { \
40.157 - next = Z_NULL; \
40.158 - ret = Z_BUF_ERROR; \
40.159 - goto inf_leave; \
40.160 - } \
40.161 - } \
40.162 - } while (0)
40.163 -
40.164 -/* Get a byte of input into the bit accumulator, or return from inflateBack()
40.165 - with an error if there is no input available. */
40.166 -#define PULLBYTE() \
40.167 - do { \
40.168 - PULL(); \
40.169 - have--; \
40.170 - hold += (unsigned long)(*next++) << bits; \
40.171 - bits += 8; \
40.172 - } while (0)
40.173 -
40.174 -/* Assure that there are at least n bits in the bit accumulator. If there is
40.175 - not enough available input to do that, then return from inflateBack() with
40.176 - an error. */
40.177 -#define NEEDBITS(n) \
40.178 - do { \
40.179 - while (bits < (unsigned)(n)) \
40.180 - PULLBYTE(); \
40.181 - } while (0)
40.182 -
40.183 -/* Return the low n bits of the bit accumulator (n < 16) */
40.184 -#define BITS(n) \
40.185 - ((unsigned)hold & ((1U << (n)) - 1))
40.186 -
40.187 -/* Remove n bits from the bit accumulator */
40.188 -#define DROPBITS(n) \
40.189 - do { \
40.190 - hold >>= (n); \
40.191 - bits -= (unsigned)(n); \
40.192 - } while (0)
40.193 -
40.194 -/* Remove zero to seven bits as needed to go to a byte boundary */
40.195 -#define BYTEBITS() \
40.196 - do { \
40.197 - hold >>= bits & 7; \
40.198 - bits -= bits & 7; \
40.199 - } while (0)
40.200 -
40.201 -/* Assure that some output space is available, by writing out the window
40.202 - if it's full. If the write fails, return from inflateBack() with a
40.203 - Z_BUF_ERROR. */
40.204 -#define ROOM() \
40.205 - do { \
40.206 - if (left == 0) { \
40.207 - put = state->window; \
40.208 - left = state->wsize; \
40.209 - state->whave = left; \
40.210 - if (out(out_desc, put, left)) { \
40.211 - ret = Z_BUF_ERROR; \
40.212 - goto inf_leave; \
40.213 - } \
40.214 - } \
40.215 - } while (0)
40.216 -
40.217 -/*
40.218 - strm provides the memory allocation functions and window buffer on input,
40.219 - and provides information on the unused input on return. For Z_DATA_ERROR
40.220 - returns, strm will also provide an error message.
40.221 -
40.222 - in() and out() are the call-back input and output functions. When
40.223 - inflateBack() needs more input, it calls in(). When inflateBack() has
40.224 - filled the window with output, or when it completes with data in the
40.225 - window, it calls out() to write out the data. The application must not
40.226 - change the provided input until in() is called again or inflateBack()
40.227 - returns. The application must not change the window/output buffer until
40.228 - inflateBack() returns.
40.229 -
40.230 - in() and out() are called with a descriptor parameter provided in the
40.231 - inflateBack() call. This parameter can be a structure that provides the
40.232 - information required to do the read or write, as well as accumulated
40.233 - information on the input and output such as totals and check values.
40.234 -
40.235 - in() should return zero on failure. out() should return non-zero on
40.236 - failure. If either in() or out() fails, than inflateBack() returns a
40.237 - Z_BUF_ERROR. strm->next_in can be checked for Z_NULL to see whether it
40.238 - was in() or out() that caused in the error. Otherwise, inflateBack()
40.239 - returns Z_STREAM_END on success, Z_DATA_ERROR for an deflate format
40.240 - error, or Z_MEM_ERROR if it could not allocate memory for the state.
40.241 - inflateBack() can also return Z_STREAM_ERROR if the input parameters
40.242 - are not correct, i.e. strm is Z_NULL or the state was not initialized.
40.243 - */
40.244 -int ZEXPORT inflateBack(strm, in, in_desc, out, out_desc)
40.245 -z_streamp strm;
40.246 -in_func in;
40.247 -void FAR *in_desc;
40.248 -out_func out;
40.249 -void FAR *out_desc;
40.250 -{
40.251 - struct inflate_state FAR *state;
40.252 - unsigned char FAR *next; /* next input */
40.253 - unsigned char FAR *put; /* next output */
40.254 - unsigned have, left; /* available input and output */
40.255 - unsigned long hold; /* bit buffer */
40.256 - unsigned bits; /* bits in bit buffer */
40.257 - unsigned copy; /* number of stored or match bytes to copy */
40.258 - unsigned char FAR *from; /* where to copy match bytes from */
40.259 - code this; /* current decoding table entry */
40.260 - code last; /* parent table entry */
40.261 - unsigned len; /* length to copy for repeats, bits to drop */
40.262 - int ret; /* return code */
40.263 - static const unsigned short order[19] = /* permutation of code lengths */
40.264 - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
40.265 -
40.266 - /* Check that the strm exists and that the state was initialized */
40.267 - if (strm == Z_NULL || strm->state == Z_NULL)
40.268 - return Z_STREAM_ERROR;
40.269 - state = (struct inflate_state FAR *)strm->state;
40.270 -
40.271 - /* Reset the state */
40.272 - strm->msg = Z_NULL;
40.273 - state->mode = TYPE;
40.274 - state->last = 0;
40.275 - state->whave = 0;
40.276 - next = strm->next_in;
40.277 - have = next != Z_NULL ? strm->avail_in : 0;
40.278 - hold = 0;
40.279 - bits = 0;
40.280 - put = state->window;
40.281 - left = state->wsize;
40.282 -
40.283 - /* Inflate until end of block marked as last */
40.284 - for (;;)
40.285 - switch (state->mode) {
40.286 - case TYPE:
40.287 - /* determine and dispatch block type */
40.288 - if (state->last) {
40.289 - BYTEBITS();
40.290 - state->mode = DONE;
40.291 - break;
40.292 - }
40.293 - NEEDBITS(3);
40.294 - state->last = BITS(1);
40.295 - DROPBITS(1);
40.296 - switch (BITS(2)) {
40.297 - case 0: /* stored block */
40.298 - Tracev((stderr, "inflate: stored block%s\n",
40.299 - state->last ? " (last)" : ""));
40.300 - state->mode = STORED;
40.301 - break;
40.302 - case 1: /* fixed block */
40.303 - fixedtables(state);
40.304 - Tracev((stderr, "inflate: fixed codes block%s\n",
40.305 - state->last ? " (last)" : ""));
40.306 - state->mode = LEN; /* decode codes */
40.307 - break;
40.308 - case 2: /* dynamic block */
40.309 - Tracev((stderr, "inflate: dynamic codes block%s\n",
40.310 - state->last ? " (last)" : ""));
40.311 - state->mode = TABLE;
40.312 - break;
40.313 - case 3:
40.314 - strm->msg = (char *)"invalid block type";
40.315 - state->mode = BAD;
40.316 - }
40.317 - DROPBITS(2);
40.318 - break;
40.319 -
40.320 - case STORED:
40.321 - /* get and verify stored block length */
40.322 - BYTEBITS(); /* go to byte boundary */
40.323 - NEEDBITS(32);
40.324 - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
40.325 - strm->msg = (char *)"invalid stored block lengths";
40.326 - state->mode = BAD;
40.327 - break;
40.328 - }
40.329 - state->length = (unsigned)hold & 0xffff;
40.330 - Tracev((stderr, "inflate: stored length %u\n",
40.331 - state->length));
40.332 - INITBITS();
40.333 -
40.334 - /* copy stored block from input to output */
40.335 - while (state->length != 0) {
40.336 - copy = state->length;
40.337 - PULL();
40.338 - ROOM();
40.339 - if (copy > have) copy = have;
40.340 - if (copy > left) copy = left;
40.341 - zmemcpy(put, next, copy);
40.342 - have -= copy;
40.343 - next += copy;
40.344 - left -= copy;
40.345 - put += copy;
40.346 - state->length -= copy;
40.347 - }
40.348 - Tracev((stderr, "inflate: stored end\n"));
40.349 - state->mode = TYPE;
40.350 - break;
40.351 -
40.352 - case TABLE:
40.353 - /* get dynamic table entries descriptor */
40.354 - NEEDBITS(14);
40.355 - state->nlen = BITS(5) + 257;
40.356 - DROPBITS(5);
40.357 - state->ndist = BITS(5) + 1;
40.358 - DROPBITS(5);
40.359 - state->ncode = BITS(4) + 4;
40.360 - DROPBITS(4);
40.361 -#ifndef PKZIP_BUG_WORKAROUND
40.362 - if (state->nlen > 286 || state->ndist > 30) {
40.363 - strm->msg = (char *)"too many length or distance symbols";
40.364 - state->mode = BAD;
40.365 - break;
40.366 - }
40.367 -#endif
40.368 - Tracev((stderr, "inflate: table sizes ok\n"));
40.369 -
40.370 - /* get code length code lengths (not a typo) */
40.371 - state->have = 0;
40.372 - while (state->have < state->ncode) {
40.373 - NEEDBITS(3);
40.374 - state->lens[order[state->have++]] = (unsigned short)BITS(3);
40.375 - DROPBITS(3);
40.376 - }
40.377 - while (state->have < 19)
40.378 - state->lens[order[state->have++]] = 0;
40.379 - state->next = state->codes;
40.380 - state->lencode = (code const FAR *)(state->next);
40.381 - state->lenbits = 7;
40.382 - ret = inflate_table(CODES, state->lens, 19, &(state->next),
40.383 - &(state->lenbits), state->work);
40.384 - if (ret) {
40.385 - strm->msg = (char *)"invalid code lengths set";
40.386 - state->mode = BAD;
40.387 - break;
40.388 - }
40.389 - Tracev((stderr, "inflate: code lengths ok\n"));
40.390 -
40.391 - /* get length and distance code code lengths */
40.392 - state->have = 0;
40.393 - while (state->have < state->nlen + state->ndist) {
40.394 - for (;;) {
40.395 - this = state->lencode[BITS(state->lenbits)];
40.396 - if ((unsigned)(this.bits) <= bits) break;
40.397 - PULLBYTE();
40.398 - }
40.399 - if (this.val < 16) {
40.400 - NEEDBITS(this.bits);
40.401 - DROPBITS(this.bits);
40.402 - state->lens[state->have++] = this.val;
40.403 - }
40.404 - else {
40.405 - if (this.val == 16) {
40.406 - NEEDBITS(this.bits + 2);
40.407 - DROPBITS(this.bits);
40.408 - if (state->have == 0) {
40.409 - strm->msg = (char *)"invalid bit length repeat";
40.410 - state->mode = BAD;
40.411 - break;
40.412 - }
40.413 - len = (unsigned)(state->lens[state->have - 1]);
40.414 - copy = 3 + BITS(2);
40.415 - DROPBITS(2);
40.416 - }
40.417 - else if (this.val == 17) {
40.418 - NEEDBITS(this.bits + 3);
40.419 - DROPBITS(this.bits);
40.420 - len = 0;
40.421 - copy = 3 + BITS(3);
40.422 - DROPBITS(3);
40.423 - }
40.424 - else {
40.425 - NEEDBITS(this.bits + 7);
40.426 - DROPBITS(this.bits);
40.427 - len = 0;
40.428 - copy = 11 + BITS(7);
40.429 - DROPBITS(7);
40.430 - }
40.431 - if (state->have + copy > state->nlen + state->ndist) {
40.432 - strm->msg = (char *)"invalid bit length repeat";
40.433 - state->mode = BAD;
40.434 - break;
40.435 - }
40.436 - while (copy--)
40.437 - state->lens[state->have++] = (unsigned short)len;
40.438 - }
40.439 - }
40.440 -
40.441 - /* handle error breaks in while */
40.442 - if (state->mode == BAD) break;
40.443 -
40.444 - /* build code tables */
40.445 - state->next = state->codes;
40.446 - state->lencode = (code const FAR *)(state->next);
40.447 - state->lenbits = 9;
40.448 - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
40.449 - &(state->lenbits), state->work);
40.450 - if (ret) {
40.451 - strm->msg = (char *)"invalid literal/lengths set";
40.452 - state->mode = BAD;
40.453 - break;
40.454 - }
40.455 - state->distcode = (code const FAR *)(state->next);
40.456 - state->distbits = 6;
40.457 - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
40.458 - &(state->next), &(state->distbits), state->work);
40.459 - if (ret) {
40.460 - strm->msg = (char *)"invalid distances set";
40.461 - state->mode = BAD;
40.462 - break;
40.463 - }
40.464 - Tracev((stderr, "inflate: codes ok\n"));
40.465 - state->mode = LEN;
40.466 -
40.467 - case LEN:
40.468 - /* use inflate_fast() if we have enough input and output */
40.469 - if (have >= 6 && left >= 258) {
40.470 - RESTORE();
40.471 - if (state->whave < state->wsize)
40.472 - state->whave = state->wsize - left;
40.473 - inflate_fast(strm, state->wsize);
40.474 - LOAD();
40.475 - break;
40.476 - }
40.477 -
40.478 - /* get a literal, length, or end-of-block code */
40.479 - for (;;) {
40.480 - this = state->lencode[BITS(state->lenbits)];
40.481 - if ((unsigned)(this.bits) <= bits) break;
40.482 - PULLBYTE();
40.483 - }
40.484 - if (this.op && (this.op & 0xf0) == 0) {
40.485 - last = this;
40.486 - for (;;) {
40.487 - this = state->lencode[last.val +
40.488 - (BITS(last.bits + last.op) >> last.bits)];
40.489 - if ((unsigned)(last.bits + this.bits) <= bits) break;
40.490 - PULLBYTE();
40.491 - }
40.492 - DROPBITS(last.bits);
40.493 - }
40.494 - DROPBITS(this.bits);
40.495 - state->length = (unsigned)this.val;
40.496 -
40.497 - /* process literal */
40.498 - if (this.op == 0) {
40.499 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
40.500 - "inflate: literal '%c'\n" :
40.501 - "inflate: literal 0x%02x\n", this.val));
40.502 - ROOM();
40.503 - *put++ = (unsigned char)(state->length);
40.504 - left--;
40.505 - state->mode = LEN;
40.506 - break;
40.507 - }
40.508 -
40.509 - /* process end of block */
40.510 - if (this.op & 32) {
40.511 - Tracevv((stderr, "inflate: end of block\n"));
40.512 - state->mode = TYPE;
40.513 - break;
40.514 - }
40.515 -
40.516 - /* invalid code */
40.517 - if (this.op & 64) {
40.518 - strm->msg = (char *)"invalid literal/length code";
40.519 - state->mode = BAD;
40.520 - break;
40.521 - }
40.522 -
40.523 - /* length code -- get extra bits, if any */
40.524 - state->extra = (unsigned)(this.op) & 15;
40.525 - if (state->extra != 0) {
40.526 - NEEDBITS(state->extra);
40.527 - state->length += BITS(state->extra);
40.528 - DROPBITS(state->extra);
40.529 - }
40.530 - Tracevv((stderr, "inflate: length %u\n", state->length));
40.531 -
40.532 - /* get distance code */
40.533 - for (;;) {
40.534 - this = state->distcode[BITS(state->distbits)];
40.535 - if ((unsigned)(this.bits) <= bits) break;
40.536 - PULLBYTE();
40.537 - }
40.538 - if ((this.op & 0xf0) == 0) {
40.539 - last = this;
40.540 - for (;;) {
40.541 - this = state->distcode[last.val +
40.542 - (BITS(last.bits + last.op) >> last.bits)];
40.543 - if ((unsigned)(last.bits + this.bits) <= bits) break;
40.544 - PULLBYTE();
40.545 - }
40.546 - DROPBITS(last.bits);
40.547 - }
40.548 - DROPBITS(this.bits);
40.549 - if (this.op & 64) {
40.550 - strm->msg = (char *)"invalid distance code";
40.551 - state->mode = BAD;
40.552 - break;
40.553 - }
40.554 - state->offset = (unsigned)this.val;
40.555 -
40.556 - /* get distance extra bits, if any */
40.557 - state->extra = (unsigned)(this.op) & 15;
40.558 - if (state->extra != 0) {
40.559 - NEEDBITS(state->extra);
40.560 - state->offset += BITS(state->extra);
40.561 - DROPBITS(state->extra);
40.562 - }
40.563 - if (state->offset > state->wsize - (state->whave < state->wsize ?
40.564 - left : 0)) {
40.565 - strm->msg = (char *)"invalid distance too far back";
40.566 - state->mode = BAD;
40.567 - break;
40.568 - }
40.569 - Tracevv((stderr, "inflate: distance %u\n", state->offset));
40.570 -
40.571 - /* copy match from window to output */
40.572 - do {
40.573 - ROOM();
40.574 - copy = state->wsize - state->offset;
40.575 - if (copy < left) {
40.576 - from = put + copy;
40.577 - copy = left - copy;
40.578 - }
40.579 - else {
40.580 - from = put - state->offset;
40.581 - copy = left;
40.582 - }
40.583 - if (copy > state->length) copy = state->length;
40.584 - state->length -= copy;
40.585 - left -= copy;
40.586 - do {
40.587 - *put++ = *from++;
40.588 - } while (--copy);
40.589 - } while (state->length != 0);
40.590 - break;
40.591 -
40.592 - case DONE:
40.593 - /* inflate stream terminated properly -- write leftover output */
40.594 - ret = Z_STREAM_END;
40.595 - if (left < state->wsize) {
40.596 - if (out(out_desc, state->window, state->wsize - left))
40.597 - ret = Z_BUF_ERROR;
40.598 - }
40.599 - goto inf_leave;
40.600 -
40.601 - case BAD:
40.602 - ret = Z_DATA_ERROR;
40.603 - goto inf_leave;
40.604 -
40.605 - default: /* can't happen, but makes compilers happy */
40.606 - ret = Z_STREAM_ERROR;
40.607 - goto inf_leave;
40.608 - }
40.609 -
40.610 - /* Return unused input */
40.611 - inf_leave:
40.612 - strm->next_in = next;
40.613 - strm->avail_in = have;
40.614 - return ret;
40.615 -}
40.616 -
40.617 -int ZEXPORT inflateBackEnd(strm)
40.618 -z_streamp strm;
40.619 -{
40.620 - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
40.621 - return Z_STREAM_ERROR;
40.622 - ZFREE(strm, strm->state);
40.623 - strm->state = Z_NULL;
40.624 - Tracev((stderr, "inflate: end\n"));
40.625 - return Z_OK;
40.626 -}
41.1 --- a/sourcepawn/vm/zlib/inffast.c Tue Nov 07 23:26:40 2006 +0000
41.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
41.3 @@ -1,318 +0,0 @@
41.4 -/* inffast.c -- fast decoding
41.5 - * Copyright (C) 1995-2004 Mark Adler
41.6 - * For conditions of distribution and use, see copyright notice in zlib.h
41.7 - */
41.8 -
41.9 -#include "zutil.h"
41.10 -#include "inftrees.h"
41.11 -#include "inflate.h"
41.12 -#include "inffast.h"
41.13 -
41.14 -#ifndef ASMINF
41.15 -
41.16 -/* Allow machine dependent optimization for post-increment or pre-increment.
41.17 - Based on testing to date,
41.18 - Pre-increment preferred for:
41.19 - - PowerPC G3 (Adler)
41.20 - - MIPS R5000 (Randers-Pehrson)
41.21 - Post-increment preferred for:
41.22 - - none
41.23 - No measurable difference:
41.24 - - Pentium III (Anderson)
41.25 - - M68060 (Nikl)
41.26 - */
41.27 -#ifdef POSTINC
41.28 -# define OFF 0
41.29 -# define PUP(a) *(a)++
41.30 -#else
41.31 -# define OFF 1
41.32 -# define PUP(a) *++(a)
41.33 -#endif
41.34 -
41.35 -/*
41.36 - Decode literal, length, and distance codes and write out the resulting
41.37 - literal and match bytes until either not enough input or output is
41.38 - available, an end-of-block is encountered, or a data error is encountered.
41.39 - When large enough input and output buffers are supplied to inflate(), for
41.40 - example, a 16K input buffer and a 64K output buffer, more than 95% of the
41.41 - inflate execution time is spent in this routine.
41.42 -
41.43 - Entry assumptions:
41.44 -
41.45 - state->mode == LEN
41.46 - strm->avail_in >= 6
41.47 - strm->avail_out >= 258
41.48 - start >= strm->avail_out
41.49 - state->bits < 8
41.50 -
41.51 - On return, state->mode is one of:
41.52 -
41.53 - LEN -- ran out of enough output space or enough available input
41.54 - TYPE -- reached end of block code, inflate() to interpret next block
41.55 - BAD -- error in block data
41.56 -
41.57 - Notes:
41.58 -
41.59 - - The maximum input bits used by a length/distance pair is 15 bits for the
41.60 - length code, 5 bits for the length extra, 15 bits for the distance code,
41.61 - and 13 bits for the distance extra. This totals 48 bits, or six bytes.
41.62 - Therefore if strm->avail_in >= 6, then there is enough input to avoid
41.63 - checking for available input while decoding.
41.64 -
41.65 - - The maximum bytes that a single length/distance pair can output is 258
41.66 - bytes, which is the maximum length that can be coded. inflate_fast()
41.67 - requires strm->avail_out >= 258 for each loop to avoid checking for
41.68 - output space.
41.69 - */
41.70 -void inflate_fast(strm, start)
41.71 -z_streamp strm;
41.72 -unsigned start; /* inflate()'s starting value for strm->avail_out */
41.73 -{
41.74 - struct inflate_state FAR *state;
41.75 - unsigned char FAR *in; /* local strm->next_in */
41.76 - unsigned char FAR *last; /* while in < last, enough input available */
41.77 - unsigned char FAR *out; /* local strm->next_out */
41.78 - unsigned char FAR *beg; /* inflate()'s initial strm->next_out */
41.79 - unsigned char FAR *end; /* while out < end, enough space available */
41.80 -#ifdef INFLATE_STRICT
41.81 - unsigned dmax; /* maximum distance from zlib header */
41.82 -#endif
41.83 - unsigned wsize; /* window size or zero if not using window */
41.84 - unsigned whave; /* valid bytes in the window */
41.85 - unsigned write; /* window write index */
41.86 - unsigned char FAR *window; /* allocated sliding window, if wsize != 0 */
41.87 - unsigned long hold; /* local strm->hold */
41.88 - unsigned bits; /* local strm->bits */
41.89 - code const FAR *lcode; /* local strm->lencode */
41.90 - code const FAR *dcode; /* local strm->distcode */
41.91 - unsigned lmask; /* mask for first level of length codes */
41.92 - unsigned dmask; /* mask for first level of distance codes */
41.93 - code this; /* retrieved table entry */
41.94 - unsigned op; /* code bits, operation, extra bits, or */
41.95 - /* window position, window bytes to copy */
41.96 - unsigned len; /* match length, unused bytes */
41.97 - unsigned dist; /* match distance */
41.98 - unsigned char FAR *from; /* where to copy match from */
41.99 -
41.100 - /* copy state to local variables */
41.101 - state = (struct inflate_state FAR *)strm->state;
41.102 - in = strm->next_in - OFF;
41.103 - last = in + (strm->avail_in - 5);
41.104 - out = strm->next_out - OFF;
41.105 - beg = out - (start - strm->avail_out);
41.106 - end = out + (strm->avail_out - 257);
41.107 -#ifdef INFLATE_STRICT
41.108 - dmax = state->dmax;
41.109 -#endif
41.110 - wsize = state->wsize;
41.111 - whave = state->whave;
41.112 - write = state->write;
41.113 - window = state->window;
41.114 - hold = state->hold;
41.115 - bits = state->bits;
41.116 - lcode = state->lencode;
41.117 - dcode = state->distcode;
41.118 - lmask = (1U << state->lenbits) - 1;
41.119 - dmask = (1U << state->distbits) - 1;
41.120 -
41.121 - /* decode literals and length/distances until end-of-block or not enough
41.122 - input data or output space */
41.123 - do {
41.124 - if (bits < 15) {
41.125 - hold += (unsigned long)(PUP(in)) << bits;
41.126 - bits += 8;
41.127 - hold += (unsigned long)(PUP(in)) << bits;
41.128 - bits += 8;
41.129 - }
41.130 - this = lcode[hold & lmask];
41.131 - dolen:
41.132 - op = (unsigned)(this.bits);
41.133 - hold >>= op;
41.134 - bits -= op;
41.135 - op = (unsigned)(this.op);
41.136 - if (op == 0) { /* literal */
41.137 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
41.138 - "inflate: literal '%c'\n" :
41.139 - "inflate: literal 0x%02x\n", this.val));
41.140 - PUP(out) = (unsigned char)(this.val);
41.141 - }
41.142 - else if (op & 16) { /* length base */
41.143 - len = (unsigned)(this.val);
41.144 - op &= 15; /* number of extra bits */
41.145 - if (op) {
41.146 - if (bits < op) {
41.147 - hold += (unsigned long)(PUP(in)) << bits;
41.148 - bits += 8;
41.149 - }
41.150 - len += (unsigned)hold & ((1U << op) - 1);
41.151 - hold >>= op;
41.152 - bits -= op;
41.153 - }
41.154 - Tracevv((stderr, "inflate: length %u\n", len));
41.155 - if (bits < 15) {
41.156 - hold += (unsigned long)(PUP(in)) << bits;
41.157 - bits += 8;
41.158 - hold += (unsigned long)(PUP(in)) << bits;
41.159 - bits += 8;
41.160 - }
41.161 - this = dcode[hold & dmask];
41.162 - dodist:
41.163 - op = (unsigned)(this.bits);
41.164 - hold >>= op;
41.165 - bits -= op;
41.166 - op = (unsigned)(this.op);
41.167 - if (op & 16) { /* distance base */
41.168 - dist = (unsigned)(this.val);
41.169 - op &= 15; /* number of extra bits */
41.170 - if (bits < op) {
41.171 - hold += (unsigned long)(PUP(in)) << bits;
41.172 - bits += 8;
41.173 - if (bits < op) {
41.174 - hold += (unsigned long)(PUP(in)) << bits;
41.175 - bits += 8;
41.176 - }
41.177 - }
41.178 - dist += (unsigned)hold & ((1U << op) - 1);
41.179 -#ifdef INFLATE_STRICT
41.180 - if (dist > dmax) {
41.181 - strm->msg = (char *)"invalid distance too far back";
41.182 - state->mode = BAD;
41.183 - break;
41.184 - }
41.185 -#endif
41.186 - hold >>= op;
41.187 - bits -= op;
41.188 - Tracevv((stderr, "inflate: distance %u\n", dist));
41.189 - op = (unsigned)(out - beg); /* max distance in output */
41.190 - if (dist > op) { /* see if copy from window */
41.191 - op = dist - op; /* distance back in window */
41.192 - if (op > whave) {
41.193 - strm->msg = (char *)"invalid distance too far back";
41.194 - state->mode = BAD;
41.195 - break;
41.196 - }
41.197 - from = window - OFF;
41.198 - if (write == 0) { /* very common case */
41.199 - from += wsize - op;
41.200 - if (op < len) { /* some from window */
41.201 - len -= op;
41.202 - do {
41.203 - PUP(out) = PUP(from);
41.204 - } while (--op);
41.205 - from = out - dist; /* rest from output */
41.206 - }
41.207 - }
41.208 - else if (write < op) { /* wrap around window */
41.209 - from += wsize + write - op;
41.210 - op -= write;
41.211 - if (op < len) { /* some from end of window */
41.212 - len -= op;
41.213 - do {
41.214 - PUP(out) = PUP(from);
41.215 - } while (--op);
41.216 - from = window - OFF;
41.217 - if (write < len) { /* some from start of window */
41.218 - op = write;
41.219 - len -= op;
41.220 - do {
41.221 - PUP(out) = PUP(from);
41.222 - } while (--op);
41.223 - from = out - dist; /* rest from output */
41.224 - }
41.225 - }
41.226 - }
41.227 - else { /* contiguous in window */
41.228 - from += write - op;
41.229 - if (op < len) { /* some from window */
41.230 - len -= op;
41.231 - do {
41.232 - PUP(out) = PUP(from);
41.233 - } while (--op);
41.234 - from = out - dist; /* rest from output */
41.235 - }
41.236 - }
41.237 - while (len > 2) {
41.238 - PUP(out) = PUP(from);
41.239 - PUP(out) = PUP(from);
41.240 - PUP(out) = PUP(from);
41.241 - len -= 3;
41.242 - }
41.243 - if (len) {
41.244 - PUP(out) = PUP(from);
41.245 - if (len > 1)
41.246 - PUP(out) = PUP(from);
41.247 - }
41.248 - }
41.249 - else {
41.250 - from = out - dist; /* copy direct from output */
41.251 - do { /* minimum length is three */
41.252 - PUP(out) = PUP(from);
41.253 - PUP(out) = PUP(from);
41.254 - PUP(out) = PUP(from);
41.255 - len -= 3;
41.256 - } while (len > 2);
41.257 - if (len) {
41.258 - PUP(out) = PUP(from);
41.259 - if (len > 1)
41.260 - PUP(out) = PUP(from);
41.261 - }
41.262 - }
41.263 - }
41.264 - else if ((op & 64) == 0) { /* 2nd level distance code */
41.265 - this = dcode[this.val + (hold & ((1U << op) - 1))];
41.266 - goto dodist;
41.267 - }
41.268 - else {
41.269 - strm->msg = (char *)"invalid distance code";
41.270 - state->mode = BAD;
41.271 - break;
41.272 - }
41.273 - }
41.274 - else if ((op & 64) == 0) { /* 2nd level length code */
41.275 - this = lcode[this.val + (hold & ((1U << op) - 1))];
41.276 - goto dolen;
41.277 - }
41.278 - else if (op & 32) { /* end-of-block */
41.279 - Tracevv((stderr, "inflate: end of block\n"));
41.280 - state->mode = TYPE;
41.281 - break;
41.282 - }
41.283 - else {
41.284 - strm->msg = (char *)"invalid literal/length code";
41.285 - state->mode = BAD;
41.286 - break;
41.287 - }
41.288 - } while (in < last && out < end);
41.289 -
41.290 - /* return unused bytes (on entry, bits < 8, so in won't go too far back) */
41.291 - len = bits >> 3;
41.292 - in -= len;
41.293 - bits -= len << 3;
41.294 - hold &= (1U << bits) - 1;
41.295 -
41.296 - /* update state and return */
41.297 - strm->next_in = in + OFF;
41.298 - strm->next_out = out + OFF;
41.299 - strm->avail_in = (unsigned)(in < last ? 5 + (last - in) : 5 - (in - last));
41.300 - strm->avail_out = (unsigned)(out < end ?
41.301 - 257 + (end - out) : 257 - (out - end));
41.302 - state->hold = hold;
41.303 - state->bits = bits;
41.304 - return;
41.305 -}
41.306 -
41.307 -/*
41.308 - inflate_fast() speedups that turned out slower (on a PowerPC G3 750CXe):
41.309 - - Using bit fields for code structure
41.310 - - Different op definition to avoid & for extra bits (do & for table bits)
41.311 - - Three separate decoding do-loops for direct, window, and write == 0
41.312 - - Special case for distance > 1 copies to do overlapped load and store copy
41.313 - - Explicit branch predictions (based on measured branch probabilities)
41.314 - - Deferring match copy and interspersed it with decoding subsequent codes
41.315 - - Swapping literal/length else
41.316 - - Swapping window/direct else
41.317 - - Larger unrolled copy loops (three is about right)
41.318 - - Moving len -= 3 statement into middle of loop
41.319 - */
41.320 -
41.321 -#endif /* !ASMINF */
42.1 --- a/sourcepawn/vm/zlib/inffast.h Tue Nov 07 23:26:40 2006 +0000
42.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
42.3 @@ -1,11 +0,0 @@
42.4 -/* inffast.h -- header to use inffast.c
42.5 - * Copyright (C) 1995-2003 Mark Adler
42.6 - * For conditions of distribution and use, see copyright notice in zlib.h
42.7 - */
42.8 -
42.9 -/* WARNING: this file should *not* be used by applications. It is
42.10 - part of the implementation of the compression library and is
42.11 - subject to change. Applications should only use zlib.h.
42.12 - */
42.13 -
42.14 -void inflate_fast OF((z_streamp strm, unsigned start));
43.1 --- a/sourcepawn/vm/zlib/inffixed.h Tue Nov 07 23:26:40 2006 +0000
43.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
43.3 @@ -1,94 +0,0 @@
43.4 - /* inffixed.h -- table for decoding fixed codes
43.5 - * Generated automatically by makefixed().
43.6 - */
43.7 -
43.8 - /* WARNING: this file should *not* be used by applications. It
43.9 - is part of the implementation of the compression library and
43.10 - is subject to change. Applications should only use zlib.h.
43.11 - */
43.12 -
43.13 - static const code lenfix[512] = {
43.14 - {96,7,0},{0,8,80},{0,8,16},{20,8,115},{18,7,31},{0,8,112},{0,8,48},
43.15 - {0,9,192},{16,7,10},{0,8,96},{0,8,32},{0,9,160},{0,8,0},{0,8,128},
43.16 - {0,8,64},{0,9,224},{16,7,6},{0,8,88},{0,8,24},{0,9,144},{19,7,59},
43.17 - {0,8,120},{0,8,56},{0,9,208},{17,7,17},{0,8,104},{0,8,40},{0,9,176},
43.18 - {0,8,8},{0,8,136},{0,8,72},{0,9,240},{16,7,4},{0,8,84},{0,8,20},
43.19 - {21,8,227},{19,7,43},{0,8,116},{0,8,52},{0,9,200},{17,7,13},{0,8,100},
43.20 - {0,8,36},{0,9,168},{0,8,4},{0,8,132},{0,8,68},{0,9,232},{16,7,8},
43.21 - {0,8,92},{0,8,28},{0,9,152},{20,7,83},{0,8,124},{0,8,60},{0,9,216},
43.22 - {18,7,23},{0,8,108},{0,8,44},{0,9,184},{0,8,12},{0,8,140},{0,8,76},
43.23 - {0,9,248},{16,7,3},{0,8,82},{0,8,18},{21,8,163},{19,7,35},{0,8,114},
43.24 - {0,8,50},{0,9,196},{17,7,11},{0,8,98},{0,8,34},{0,9,164},{0,8,2},
43.25 - {0,8,130},{0,8,66},{0,9,228},{16,7,7},{0,8,90},{0,8,26},{0,9,148},
43.26 - {20,7,67},{0,8,122},{0,8,58},{0,9,212},{18,7,19},{0,8,106},{0,8,42},
43.27 - {0,9,180},{0,8,10},{0,8,138},{0,8,74},{0,9,244},{16,7,5},{0,8,86},
43.28 - {0,8,22},{64,8,0},{19,7,51},{0,8,118},{0,8,54},{0,9,204},{17,7,15},
43.29 - {0,8,102},{0,8,38},{0,9,172},{0,8,6},{0,8,134},{0,8,70},{0,9,236},
43.30 - {16,7,9},{0,8,94},{0,8,30},{0,9,156},{20,7,99},{0,8,126},{0,8,62},
43.31 - {0,9,220},{18,7,27},{0,8,110},{0,8,46},{0,9,188},{0,8,14},{0,8,142},
43.32 - {0,8,78},{0,9,252},{96,7,0},{0,8,81},{0,8,17},{21,8,131},{18,7,31},
43.33 - {0,8,113},{0,8,49},{0,9,194},{16,7,10},{0,8,97},{0,8,33},{0,9,162},
43.34 - {0,8,1},{0,8,129},{0,8,65},{0,9,226},{16,7,6},{0,8,89},{0,8,25},
43.35 - {0,9,146},{19,7,59},{0,8,121},{0,8,57},{0,9,210},{17,7,17},{0,8,105},
43.36 - {0,8,41},{0,9,178},{0,8,9},{0,8,137},{0,8,73},{0,9,242},{16,7,4},
43.37 - {0,8,85},{0,8,21},{16,8,258},{19,7,43},{0,8,117},{0,8,53},{0,9,202},
43.38 - {17,7,13},{0,8,101},{0,8,37},{0,9,170},{0,8,5},{0,8,133},{0,8,69},
43.39 - {0,9,234},{16,7,8},{0,8,93},{0,8,29},{0,9,154},{20,7,83},{0,8,125},
43.40 - {0,8,61},{0,9,218},{18,7,23},{0,8,109},{0,8,45},{0,9,186},{0,8,13},
43.41 - {0,8,141},{0,8,77},{0,9,250},{16,7,3},{0,8,83},{0,8,19},{21,8,195},
43.42 - {19,7,35},{0,8,115},{0,8,51},{0,9,198},{17,7,11},{0,8,99},{0,8,35},
43.43 - {0,9,166},{0,8,3},{0,8,131},{0,8,67},{0,9,230},{16,7,7},{0,8,91},
43.44 - {0,8,27},{0,9,150},{20,7,67},{0,8,123},{0,8,59},{0,9,214},{18,7,19},
43.45 - {0,8,107},{0,8,43},{0,9,182},{0,8,11},{0,8,139},{0,8,75},{0,9,246},
43.46 - {16,7,5},{0,8,87},{0,8,23},{64,8,0},{19,7,51},{0,8,119},{0,8,55},
43.47 - {0,9,206},{17,7,15},{0,8,103},{0,8,39},{0,9,174},{0,8,7},{0,8,135},
43.48 - {0,8,71},{0,9,238},{16,7,9},{0,8,95},{0,8,31},{0,9,158},{20,7,99},
43.49 - {0,8,127},{0,8,63},{0,9,222},{18,7,27},{0,8,111},{0,8,47},{0,9,190},
43.50 - {0,8,15},{0,8,143},{0,8,79},{0,9,254},{96,7,0},{0,8,80},{0,8,16},
43.51 - {20,8,115},{18,7,31},{0,8,112},{0,8,48},{0,9,193},{16,7,10},{0,8,96},
43.52 - {0,8,32},{0,9,161},{0,8,0},{0,8,128},{0,8,64},{0,9,225},{16,7,6},
43.53 - {0,8,88},{0,8,24},{0,9,145},{19,7,59},{0,8,120},{0,8,56},{0,9,209},
43.54 - {17,7,17},{0,8,104},{0,8,40},{0,9,177},{0,8,8},{0,8,136},{0,8,72},
43.55 - {0,9,241},{16,7,4},{0,8,84},{0,8,20},{21,8,227},{19,7,43},{0,8,116},
43.56 - {0,8,52},{0,9,201},{17,7,13},{0,8,100},{0,8,36},{0,9,169},{0,8,4},
43.57 - {0,8,132},{0,8,68},{0,9,233},{16,7,8},{0,8,92},{0,8,28},{0,9,153},
43.58 - {20,7,83},{0,8,124},{0,8,60},{0,9,217},{18,7,23},{0,8,108},{0,8,44},
43.59 - {0,9,185},{0,8,12},{0,8,140},{0,8,76},{0,9,249},{16,7,3},{0,8,82},
43.60 - {0,8,18},{21,8,163},{19,7,35},{0,8,114},{0,8,50},{0,9,197},{17,7,11},
43.61 - {0,8,98},{0,8,34},{0,9,165},{0,8,2},{0,8,130},{0,8,66},{0,9,229},
43.62 - {16,7,7},{0,8,90},{0,8,26},{0,9,149},{20,7,67},{0,8,122},{0,8,58},
43.63 - {0,9,213},{18,7,19},{0,8,106},{0,8,42},{0,9,181},{0,8,10},{0,8,138},
43.64 - {0,8,74},{0,9,245},{16,7,5},{0,8,86},{0,8,22},{64,8,0},{19,7,51},
43.65 - {0,8,118},{0,8,54},{0,9,205},{17,7,15},{0,8,102},{0,8,38},{0,9,173},
43.66 - {0,8,6},{0,8,134},{0,8,70},{0,9,237},{16,7,9},{0,8,94},{0,8,30},
43.67 - {0,9,157},{20,7,99},{0,8,126},{0,8,62},{0,9,221},{18,7,27},{0,8,110},
43.68 - {0,8,46},{0,9,189},{0,8,14},{0,8,142},{0,8,78},{0,9,253},{96,7,0},
43.69 - {0,8,81},{0,8,17},{21,8,131},{18,7,31},{0,8,113},{0,8,49},{0,9,195},
43.70 - {16,7,10},{0,8,97},{0,8,33},{0,9,163},{0,8,1},{0,8,129},{0,8,65},
43.71 - {0,9,227},{16,7,6},{0,8,89},{0,8,25},{0,9,147},{19,7,59},{0,8,121},
43.72 - {0,8,57},{0,9,211},{17,7,17},{0,8,105},{0,8,41},{0,9,179},{0,8,9},
43.73 - {0,8,137},{0,8,73},{0,9,243},{16,7,4},{0,8,85},{0,8,21},{16,8,258},
43.74 - {19,7,43},{0,8,117},{0,8,53},{0,9,203},{17,7,13},{0,8,101},{0,8,37},
43.75 - {0,9,171},{0,8,5},{0,8,133},{0,8,69},{0,9,235},{16,7,8},{0,8,93},
43.76 - {0,8,29},{0,9,155},{20,7,83},{0,8,125},{0,8,61},{0,9,219},{18,7,23},
43.77 - {0,8,109},{0,8,45},{0,9,187},{0,8,13},{0,8,141},{0,8,77},{0,9,251},
43.78 - {16,7,3},{0,8,83},{0,8,19},{21,8,195},{19,7,35},{0,8,115},{0,8,51},
43.79 - {0,9,199},{17,7,11},{0,8,99},{0,8,35},{0,9,167},{0,8,3},{0,8,131},
43.80 - {0,8,67},{0,9,231},{16,7,7},{0,8,91},{0,8,27},{0,9,151},{20,7,67},
43.81 - {0,8,123},{0,8,59},{0,9,215},{18,7,19},{0,8,107},{0,8,43},{0,9,183},
43.82 - {0,8,11},{0,8,139},{0,8,75},{0,9,247},{16,7,5},{0,8,87},{0,8,23},
43.83 - {64,8,0},{19,7,51},{0,8,119},{0,8,55},{0,9,207},{17,7,15},{0,8,103},
43.84 - {0,8,39},{0,9,175},{0,8,7},{0,8,135},{0,8,71},{0,9,239},{16,7,9},
43.85 - {0,8,95},{0,8,31},{0,9,159},{20,7,99},{0,8,127},{0,8,63},{0,9,223},
43.86 - {18,7,27},{0,8,111},{0,8,47},{0,9,191},{0,8,15},{0,8,143},{0,8,79},
43.87 - {0,9,255}
43.88 - };
43.89 -
43.90 - static const code distfix[32] = {
43.91 - {16,5,1},{23,5,257},{19,5,17},{27,5,4097},{17,5,5},{25,5,1025},
43.92 - {21,5,65},{29,5,16385},{16,5,3},{24,5,513},{20,5,33},{28,5,8193},
43.93 - {18,5,9},{26,5,2049},{22,5,129},{64,5,0},{16,5,2},{23,5,385},
43.94 - {19,5,25},{27,5,6145},{17,5,7},{25,5,1537},{21,5,97},{29,5,24577},
43.95 - {16,5,4},{24,5,769},{20,5,49},{28,5,12289},{18,5,13},{26,5,3073},
43.96 - {22,5,193},{64,5,0}
43.97 - };
44.1 --- a/sourcepawn/vm/zlib/inflate.c Tue Nov 07 23:26:40 2006 +0000
44.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
44.3 @@ -1,1368 +0,0 @@
44.4 -/* inflate.c -- zlib decompression
44.5 - * Copyright (C) 1995-2005 Mark Adler
44.6 - * For conditions of distribution and use, see copyright notice in zlib.h
44.7 - */
44.8 -
44.9 -/*
44.10 - * Change history:
44.11 - *
44.12 - * 1.2.beta0 24 Nov 2002
44.13 - * - First version -- complete rewrite of inflate to simplify code, avoid
44.14 - * creation of window when not needed, minimize use of window when it is
44.15 - * needed, make inffast.c even faster, implement gzip decoding, and to
44.16 - * improve code readability and style over the previous zlib inflate code
44.17 - *
44.18 - * 1.2.beta1 25 Nov 2002
44.19 - * - Use pointers for available input and output checking in inffast.c
44.20 - * - Remove input and output counters in inffast.c
44.21 - * - Change inffast.c entry and loop from avail_in >= 7 to >= 6
44.22 - * - Remove unnecessary second byte pull from length extra in inffast.c
44.23 - * - Unroll direct copy to three copies per loop in inffast.c
44.24 - *
44.25 - * 1.2.beta2 4 Dec 2002
44.26 - * - Change external routine names to reduce potential conflicts
44.27 - * - Correct filename to inffixed.h for fixed tables in inflate.c
44.28 - * - Make hbuf[] unsigned char to match parameter type in inflate.c
44.29 - * - Change strm->next_out[-state->offset] to *(strm->next_out - state->offset)
44.30 - * to avoid negation problem on Alphas (64 bit) in inflate.c
44.31 - *
44.32 - * 1.2.beta3 22 Dec 2002
44.33 - * - Add comments on state->bits assertion in inffast.c
44.34 - * - Add comments on op field in inftrees.h
44.35 - * - Fix bug in reuse of allocated window after inflateReset()
44.36 - * - Remove bit fields--back to byte structure for speed
44.37 - * - Remove distance extra == 0 check in inflate_fast()--only helps for lengths
44.38 - * - Change post-increments to pre-increments in inflate_fast(), PPC biased?
44.39 - * - Add compile time option, POSTINC, to use post-increments instead (Intel?)
44.40 - * - Make MATCH copy in inflate() much faster for when inflate_fast() not used
44.41 - * - Use local copies of stream next and avail values, as well as local bit
44.42 - * buffer and bit count in inflate()--for speed when inflate_fast() not used
44.43 - *
44.44 - * 1.2.beta4 1 Jan 2003
44.45 - * - Split ptr - 257 statements in inflate_table() to avoid compiler warnings
44.46 - * - Move a comment on output buffer sizes from inffast.c to inflate.c
44.47 - * - Add comments in inffast.c to introduce the inflate_fast() routine
44.48 - * - Rearrange window copies in inflate_fast() for speed and simplification
44.49 - * - Unroll last copy for window match in inflate_fast()
44.50 - * - Use local copies of window variables in inflate_fast() for speed
44.51 - * - Pull out common write == 0 case for speed in inflate_fast()
44.52 - * - Make op and len in inflate_fast() unsigned for consistency
44.53 - * - Add FAR to lcode and dcode declarations in inflate_fast()
44.54 - * - Simplified bad distance check in inflate_fast()
44.55 - * - Added inflateBackInit(), inflateBack(), and inflateBackEnd() in new
44.56 - * source file infback.c to provide a call-back interface to inflate for
44.57 - * programs like gzip and unzip -- uses window as output buffer to avoid
44.58 - * window copying
44.59 - *
44.60 - * 1.2.beta5 1 Jan 2003
44.61 - * - Improved inflateBack() interface to allow the caller to provide initial
44.62 - * input in strm.
44.63 - * - Fixed stored blocks bug in inflateBack()
44.64 - *
44.65 - * 1.2.beta6 4 Jan 2003
44.66 - * - Added comments in inffast.c on effectiveness of POSTINC
44.67 - * - Typecasting all around to reduce compiler warnings
44.68 - * - Changed loops from while (1) or do {} while (1) to for (;;), again to
44.69 - * make compilers happy
44.70 - * - Changed type of window in inflateBackInit() to unsigned char *
44.71 - *
44.72 - * 1.2.beta7 27 Jan 2003
44.73 - * - Changed many types to unsigned or unsigned short to avoid warnings
44.74 - * - Added inflateCopy() function
44.75 - *
44.76 - * 1.2.0 9 Mar 2003
44.77 - * - Changed inflateBack() interface to provide separate opaque descriptors
44.78 - * for the in() and out() functions
44.79 - * - Changed inflateBack() argument and in_func typedef to swap the length
44.80 - * and buffer address return values for the input function
44.81 - * - Check next_in and next_out for Z_NULL on entry to inflate()
44.82 - *
44.83 - * The history for versions after 1.2.0 are in ChangeLog in zlib distribution.
44.84 - */
44.85 -
44.86 -#include "zutil.h"
44.87 -#include "inftrees.h"
44.88 -#include "inflate.h"
44.89 -#include "inffast.h"
44.90 -
44.91 -#ifdef MAKEFIXED
44.92 -# ifndef BUILDFIXED
44.93 -# define BUILDFIXED
44.94 -# endif
44.95 -#endif
44.96 -
44.97 -/* function prototypes */
44.98 -local void fixedtables OF((struct inflate_state FAR *state));
44.99 -local int updatewindow OF((z_streamp strm, unsigned out));
44.100 -#ifdef BUILDFIXED
44.101 - void makefixed OF((void));
44.102 -#endif
44.103 -local unsigned syncsearch OF((unsigned FAR *have, unsigned char FAR *buf,
44.104 - unsigned len));
44.105 -
44.106 -int ZEXPORT inflateReset(strm)
44.107 -z_streamp strm;
44.108 -{
44.109 - struct inflate_state FAR *state;
44.110 -
44.111 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.112 - state = (struct inflate_state FAR *)strm->state;
44.113 - strm->total_in = strm->total_out = state->total = 0;
44.114 - strm->msg = Z_NULL;
44.115 - strm->adler = 1; /* to support ill-conceived Java test suite */
44.116 - state->mode = HEAD;
44.117 - state->last = 0;
44.118 - state->havedict = 0;
44.119 - state->dmax = 32768U;
44.120 - state->head = Z_NULL;
44.121 - state->wsize = 0;
44.122 - state->whave = 0;
44.123 - state->write = 0;
44.124 - state->hold = 0;
44.125 - state->bits = 0;
44.126 - state->lencode = state->distcode = state->next = state->codes;
44.127 - Tracev((stderr, "inflate: reset\n"));
44.128 - return Z_OK;
44.129 -}
44.130 -
44.131 -int ZEXPORT inflatePrime(strm, bits, value)
44.132 -z_streamp strm;
44.133 -int bits;
44.134 -int value;
44.135 -{
44.136 - struct inflate_state FAR *state;
44.137 -
44.138 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.139 - state = (struct inflate_state FAR *)strm->state;
44.140 - if (bits > 16 || state->bits + bits > 32) return Z_STREAM_ERROR;
44.141 - value &= (1L << bits) - 1;
44.142 - state->hold += value << state->bits;
44.143 - state->bits += bits;
44.144 - return Z_OK;
44.145 -}
44.146 -
44.147 -int ZEXPORT inflateInit2_(strm, windowBits, version, stream_size)
44.148 -z_streamp strm;
44.149 -int windowBits;
44.150 -const char *version;
44.151 -int stream_size;
44.152 -{
44.153 - struct inflate_state FAR *state;
44.154 -
44.155 - if (version == Z_NULL || version[0] != ZLIB_VERSION[0] ||
44.156 - stream_size != (int)(sizeof(z_stream)))
44.157 - return Z_VERSION_ERROR;
44.158 - if (strm == Z_NULL) return Z_STREAM_ERROR;
44.159 - strm->msg = Z_NULL; /* in case we return an error */
44.160 - if (strm->zalloc == (alloc_func)0) {
44.161 - strm->zalloc = zcalloc;
44.162 - strm->opaque = (voidpf)0;
44.163 - }
44.164 - if (strm->zfree == (free_func)0) strm->zfree = zcfree;
44.165 - state = (struct inflate_state FAR *)
44.166 - ZALLOC(strm, 1, sizeof(struct inflate_state));
44.167 - if (state == Z_NULL) return Z_MEM_ERROR;
44.168 - Tracev((stderr, "inflate: allocated\n"));
44.169 - strm->state = (struct internal_state FAR *)state;
44.170 - if (windowBits < 0) {
44.171 - state->wrap = 0;
44.172 - windowBits = -windowBits;
44.173 - }
44.174 - else {
44.175 - state->wrap = (windowBits >> 4) + 1;
44.176 -#ifdef GUNZIP
44.177 - if (windowBits < 48) windowBits &= 15;
44.178 -#endif
44.179 - }
44.180 - if (windowBits < 8 || windowBits > 15) {
44.181 - ZFREE(strm, state);
44.182 - strm->state = Z_NULL;
44.183 - return Z_STREAM_ERROR;
44.184 - }
44.185 - state->wbits = (unsigned)windowBits;
44.186 - state->window = Z_NULL;
44.187 - return inflateReset(strm);
44.188 -}
44.189 -
44.190 -int ZEXPORT inflateInit_(strm, version, stream_size)
44.191 -z_streamp strm;
44.192 -const char *version;
44.193 -int stream_size;
44.194 -{
44.195 - return inflateInit2_(strm, DEF_WBITS, version, stream_size);
44.196 -}
44.197 -
44.198 -/*
44.199 - Return state with length and distance decoding tables and index sizes set to
44.200 - fixed code decoding. Normally this returns fixed tables from inffixed.h.
44.201 - If BUILDFIXED is defined, then instead this routine builds the tables the
44.202 - first time it's called, and returns those tables the first time and
44.203 - thereafter. This reduces the size of the code by about 2K bytes, in
44.204 - exchange for a little execution time. However, BUILDFIXED should not be
44.205 - used for threaded applications, since the rewriting of the tables and virgin
44.206 - may not be thread-safe.
44.207 - */
44.208 -local void fixedtables(state)
44.209 -struct inflate_state FAR *state;
44.210 -{
44.211 -#ifdef BUILDFIXED
44.212 - static int virgin = 1;
44.213 - static code *lenfix, *distfix;
44.214 - static code fixed[544];
44.215 -
44.216 - /* build fixed huffman tables if first call (may not be thread safe) */
44.217 - if (virgin) {
44.218 - unsigned sym, bits;
44.219 - static code *next;
44.220 -
44.221 - /* literal/length table */
44.222 - sym = 0;
44.223 - while (sym < 144) state->lens[sym++] = 8;
44.224 - while (sym < 256) state->lens[sym++] = 9;
44.225 - while (sym < 280) state->lens[sym++] = 7;
44.226 - while (sym < 288) state->lens[sym++] = 8;
44.227 - next = fixed;
44.228 - lenfix = next;
44.229 - bits = 9;
44.230 - inflate_table(LENS, state->lens, 288, &(next), &(bits), state->work);
44.231 -
44.232 - /* distance table */
44.233 - sym = 0;
44.234 - while (sym < 32) state->lens[sym++] = 5;
44.235 - distfix = next;
44.236 - bits = 5;
44.237 - inflate_table(DISTS, state->lens, 32, &(next), &(bits), state->work);
44.238 -
44.239 - /* do this just once */
44.240 - virgin = 0;
44.241 - }
44.242 -#else /* !BUILDFIXED */
44.243 -# include "inffixed.h"
44.244 -#endif /* BUILDFIXED */
44.245 - state->lencode = lenfix;
44.246 - state->lenbits = 9;
44.247 - state->distcode = distfix;
44.248 - state->distbits = 5;
44.249 -}
44.250 -
44.251 -#ifdef MAKEFIXED
44.252 -#include <stdio.h>
44.253 -
44.254 -/*
44.255 - Write out the inffixed.h that is #include'd above. Defining MAKEFIXED also
44.256 - defines BUILDFIXED, so the tables are built on the fly. makefixed() writes
44.257 - those tables to stdout, which would be piped to inffixed.h. A small program
44.258 - can simply call makefixed to do this:
44.259 -
44.260 - void makefixed(void);
44.261 -
44.262 - int main(void)
44.263 - {
44.264 - makefixed();
44.265 - return 0;
44.266 - }
44.267 -
44.268 - Then that can be linked with zlib built with MAKEFIXED defined and run:
44.269 -
44.270 - a.out > inffixed.h
44.271 - */
44.272 -void makefixed()
44.273 -{
44.274 - unsigned low, size;
44.275 - struct inflate_state state;
44.276 -
44.277 - fixedtables(&state);
44.278 - puts(" /* inffixed.h -- table for decoding fixed codes");
44.279 - puts(" * Generated automatically by makefixed().");
44.280 - puts(" */");
44.281 - puts("");
44.282 - puts(" /* WARNING: this file should *not* be used by applications.");
44.283 - puts(" It is part of the implementation of this library and is");
44.284 - puts(" subject to change. Applications should only use zlib.h.");
44.285 - puts(" */");
44.286 - puts("");
44.287 - size = 1U << 9;
44.288 - printf(" static const code lenfix[%u] = {", size);
44.289 - low = 0;
44.290 - for (;;) {
44.291 - if ((low % 7) == 0) printf("\n ");
44.292 - printf("{%u,%u,%d}", state.lencode[low].op, state.lencode[low].bits,
44.293 - state.lencode[low].val);
44.294 - if (++low == size) break;
44.295 - putchar(',');
44.296 - }
44.297 - puts("\n };");
44.298 - size = 1U << 5;
44.299 - printf("\n static const code distfix[%u] = {", size);
44.300 - low = 0;
44.301 - for (;;) {
44.302 - if ((low % 6) == 0) printf("\n ");
44.303 - printf("{%u,%u,%d}", state.distcode[low].op, state.distcode[low].bits,
44.304 - state.distcode[low].val);
44.305 - if (++low == size) break;
44.306 - putchar(',');
44.307 - }
44.308 - puts("\n };");
44.309 -}
44.310 -#endif /* MAKEFIXED */
44.311 -
44.312 -/*
44.313 - Update the window with the last wsize (normally 32K) bytes written before
44.314 - returning. If window does not exist yet, create it. This is only called
44.315 - when a window is already in use, or when output has been written during this
44.316 - inflate call, but the end of the deflate stream has not been reached yet.
44.317 - It is also called to create a window for dictionary data when a dictionary
44.318 - is loaded.
44.319 -
44.320 - Providing output buffers larger than 32K to inflate() should provide a speed
44.321 - advantage, since only the last 32K of output is copied to the sliding window
44.322 - upon return from inflate(), and since all distances after the first 32K of
44.323 - output will fall in the output data, making match copies simpler and faster.
44.324 - The advantage may be dependent on the size of the processor's data caches.
44.325 - */
44.326 -local int updatewindow(strm, out)
44.327 -z_streamp strm;
44.328 -unsigned out;
44.329 -{
44.330 - struct inflate_state FAR *state;
44.331 - unsigned copy, dist;
44.332 -
44.333 - state = (struct inflate_state FAR *)strm->state;
44.334 -
44.335 - /* if it hasn't been done already, allocate space for the window */
44.336 - if (state->window == Z_NULL) {
44.337 - state->window = (unsigned char FAR *)
44.338 - ZALLOC(strm, 1U << state->wbits,
44.339 - sizeof(unsigned char));
44.340 - if (state->window == Z_NULL) return 1;
44.341 - }
44.342 -
44.343 - /* if window not in use yet, initialize */
44.344 - if (state->wsize == 0) {
44.345 - state->wsize = 1U << state->wbits;
44.346 - state->write = 0;
44.347 - state->whave = 0;
44.348 - }
44.349 -
44.350 - /* copy state->wsize or less output bytes into the circular window */
44.351 - copy = out - strm->avail_out;
44.352 - if (copy >= state->wsize) {
44.353 - zmemcpy(state->window, strm->next_out - state->wsize, state->wsize);
44.354 - state->write = 0;
44.355 - state->whave = state->wsize;
44.356 - }
44.357 - else {
44.358 - dist = state->wsize - state->write;
44.359 - if (dist > copy) dist = copy;
44.360 - zmemcpy(state->window + state->write, strm->next_out - copy, dist);
44.361 - copy -= dist;
44.362 - if (copy) {
44.363 - zmemcpy(state->window, strm->next_out - copy, copy);
44.364 - state->write = copy;
44.365 - state->whave = state->wsize;
44.366 - }
44.367 - else {
44.368 - state->write += dist;
44.369 - if (state->write == state->wsize) state->write = 0;
44.370 - if (state->whave < state->wsize) state->whave += dist;
44.371 - }
44.372 - }
44.373 - return 0;
44.374 -}
44.375 -
44.376 -/* Macros for inflate(): */
44.377 -
44.378 -/* check function to use adler32() for zlib or crc32() for gzip */
44.379 -#ifdef GUNZIP
44.380 -# define UPDATE(check, buf, len) \
44.381 - (state->flags ? crc32(check, buf, len) : adler32(check, buf, len))
44.382 -#else
44.383 -# define UPDATE(check, buf, len) adler32(check, buf, len)
44.384 -#endif
44.385 -
44.386 -/* check macros for header crc */
44.387 -#ifdef GUNZIP
44.388 -# define CRC2(check, word) \
44.389 - do { \
44.390 - hbuf[0] = (unsigned char)(word); \
44.391 - hbuf[1] = (unsigned char)((word) >> 8); \
44.392 - check = crc32(check, hbuf, 2); \
44.393 - } while (0)
44.394 -
44.395 -# define CRC4(check, word) \
44.396 - do { \
44.397 - hbuf[0] = (unsigned char)(word); \
44.398 - hbuf[1] = (unsigned char)((word) >> 8); \
44.399 - hbuf[2] = (unsigned char)((word) >> 16); \
44.400 - hbuf[3] = (unsigned char)((word) >> 24); \
44.401 - check = crc32(check, hbuf, 4); \
44.402 - } while (0)
44.403 -#endif
44.404 -
44.405 -/* Load registers with state in inflate() for speed */
44.406 -#define LOAD() \
44.407 - do { \
44.408 - put = strm->next_out; \
44.409 - left = strm->avail_out; \
44.410 - next = strm->next_in; \
44.411 - have = strm->avail_in; \
44.412 - hold = state->hold; \
44.413 - bits = state->bits; \
44.414 - } while (0)
44.415 -
44.416 -/* Restore state from registers in inflate() */
44.417 -#define RESTORE() \
44.418 - do { \
44.419 - strm->next_out = put; \
44.420 - strm->avail_out = left; \
44.421 - strm->next_in = next; \
44.422 - strm->avail_in = have; \
44.423 - state->hold = hold; \
44.424 - state->bits = bits; \
44.425 - } while (0)
44.426 -
44.427 -/* Clear the input bit accumulator */
44.428 -#define INITBITS() \
44.429 - do { \
44.430 - hold = 0; \
44.431 - bits = 0; \
44.432 - } while (0)
44.433 -
44.434 -/* Get a byte of input into the bit accumulator, or return from inflate()
44.435 - if there is no input available. */
44.436 -#define PULLBYTE() \
44.437 - do { \
44.438 - if (have == 0) goto inf_leave; \
44.439 - have--; \
44.440 - hold += (unsigned long)(*next++) << bits; \
44.441 - bits += 8; \
44.442 - } while (0)
44.443 -
44.444 -/* Assure that there are at least n bits in the bit accumulator. If there is
44.445 - not enough available input to do that, then return from inflate(). */
44.446 -#define NEEDBITS(n) \
44.447 - do { \
44.448 - while (bits < (unsigned)(n)) \
44.449 - PULLBYTE(); \
44.450 - } while (0)
44.451 -
44.452 -/* Return the low n bits of the bit accumulator (n < 16) */
44.453 -#define BITS(n) \
44.454 - ((unsigned)hold & ((1U << (n)) - 1))
44.455 -
44.456 -/* Remove n bits from the bit accumulator */
44.457 -#define DROPBITS(n) \
44.458 - do { \
44.459 - hold >>= (n); \
44.460 - bits -= (unsigned)(n); \
44.461 - } while (0)
44.462 -
44.463 -/* Remove zero to seven bits as needed to go to a byte boundary */
44.464 -#define BYTEBITS() \
44.465 - do { \
44.466 - hold >>= bits & 7; \
44.467 - bits -= bits & 7; \
44.468 - } while (0)
44.469 -
44.470 -/* Reverse the bytes in a 32-bit value */
44.471 -#define REVERSE(q) \
44.472 - ((((q) >> 24) & 0xff) + (((q) >> 8) & 0xff00) + \
44.473 - (((q) & 0xff00) << 8) + (((q) & 0xff) << 24))
44.474 -
44.475 -/*
44.476 - inflate() uses a state machine to process as much input data and generate as
44.477 - much output data as possible before returning. The state machine is
44.478 - structured roughly as follows:
44.479 -
44.480 - for (;;) switch (state) {
44.481 - ...
44.482 - case STATEn:
44.483 - if (not enough input data or output space to make progress)
44.484 - return;
44.485 - ... make progress ...
44.486 - state = STATEm;
44.487 - break;
44.488 - ...
44.489 - }
44.490 -
44.491 - so when inflate() is called again, the same case is attempted again, and
44.492 - if the appropriate resources are provided, the machine proceeds to the
44.493 - next state. The NEEDBITS() macro is usually the way the state evaluates
44.494 - whether it can proceed or should return. NEEDBITS() does the return if
44.495 - the requested bits are not available. The typical use of the BITS macros
44.496 - is:
44.497 -
44.498 - NEEDBITS(n);
44.499 - ... do something with BITS(n) ...
44.500 - DROPBITS(n);
44.501 -
44.502 - where NEEDBITS(n) either returns from inflate() if there isn't enough
44.503 - input left to load n bits into the accumulator, or it continues. BITS(n)
44.504 - gives the low n bits in the accumulator. When done, DROPBITS(n) drops
44.505 - the low n bits off the accumulator. INITBITS() clears the accumulator
44.506 - and sets the number of available bits to zero. BYTEBITS() discards just
44.507 - enough bits to put the accumulator on a byte boundary. After BYTEBITS()
44.508 - and a NEEDBITS(8), then BITS(8) would return the next byte in the stream.
44.509 -
44.510 - NEEDBITS(n) uses PULLBYTE() to get an available byte of input, or to return
44.511 - if there is no input available. The decoding of variable length codes uses
44.512 - PULLBYTE() directly in order to pull just enough bytes to decode the next
44.513 - code, and no more.
44.514 -
44.515 - Some states loop until they get enough input, making sure that enough
44.516 - state information is maintained to continue the loop where it left off
44.517 - if NEEDBITS() returns in the loop. For example, want, need, and keep
44.518 - would all have to actually be part of the saved state in case NEEDBITS()
44.519 - returns:
44.520 -
44.521 - case STATEw:
44.522 - while (want < need) {
44.523 - NEEDBITS(n);
44.524 - keep[want++] = BITS(n);
44.525 - DROPBITS(n);
44.526 - }
44.527 - state = STATEx;
44.528 - case STATEx:
44.529 -
44.530 - As shown above, if the next state is also the next case, then the break
44.531 - is omitted.
44.532 -
44.533 - A state may also return if there is not enough output space available to
44.534 - complete that state. Those states are copying stored data, writing a
44.535 - literal byte, and copying a matching string.
44.536 -
44.537 - When returning, a "goto inf_leave" is used to update the total counters,
44.538 - update the check value, and determine whether any progress has been made
44.539 - during that inflate() call in order to return the proper return code.
44.540 - Progress is defined as a change in either strm->avail_in or strm->avail_out.
44.541 - When there is a window, goto inf_leave will update the window with the last
44.542 - output written. If a goto inf_leave occurs in the middle of decompression
44.543 - and there is no window currently, goto inf_leave will create one and copy
44.544 - output to the window for the next call of inflate().
44.545 -
44.546 - In this implementation, the flush parameter of inflate() only affects the
44.547 - return code (per zlib.h). inflate() always writes as much as possible to
44.548 - strm->next_out, given the space available and the provided input--the effect
44.549 - documented in zlib.h of Z_SYNC_FLUSH. Furthermore, inflate() always defers
44.550 - the allocation of and copying into a sliding window until necessary, which
44.551 - provides the effect documented in zlib.h for Z_FINISH when the entire input
44.552 - stream available. So the only thing the flush parameter actually does is:
44.553 - when flush is set to Z_FINISH, inflate() cannot return Z_OK. Instead it
44.554 - will return Z_BUF_ERROR if it has not reached the end of the stream.
44.555 - */
44.556 -
44.557 -int ZEXPORT inflate(strm, flush)
44.558 -z_streamp strm;
44.559 -int flush;
44.560 -{
44.561 - struct inflate_state FAR *state;
44.562 - unsigned char FAR *next; /* next input */
44.563 - unsigned char FAR *put; /* next output */
44.564 - unsigned have, left; /* available input and output */
44.565 - unsigned long hold; /* bit buffer */
44.566 - unsigned bits; /* bits in bit buffer */
44.567 - unsigned in, out; /* save starting available input and output */
44.568 - unsigned copy; /* number of stored or match bytes to copy */
44.569 - unsigned char FAR *from; /* where to copy match bytes from */
44.570 - code this; /* current decoding table entry */
44.571 - code last; /* parent table entry */
44.572 - unsigned len; /* length to copy for repeats, bits to drop */
44.573 - int ret; /* return code */
44.574 -#ifdef GUNZIP
44.575 - unsigned char hbuf[4]; /* buffer for gzip header crc calculation */
44.576 -#endif
44.577 - static const unsigned short order[19] = /* permutation of code lengths */
44.578 - {16, 17, 18, 0, 8, 7, 9, 6, 10, 5, 11, 4, 12, 3, 13, 2, 14, 1, 15};
44.579 -
44.580 - if (strm == Z_NULL || strm->state == Z_NULL || strm->next_out == Z_NULL ||
44.581 - (strm->next_in == Z_NULL && strm->avail_in != 0))
44.582 - return Z_STREAM_ERROR;
44.583 -
44.584 - state = (struct inflate_state FAR *)strm->state;
44.585 - if (state->mode == TYPE) state->mode = TYPEDO; /* skip check */
44.586 - LOAD();
44.587 - in = have;
44.588 - out = left;
44.589 - ret = Z_OK;
44.590 - for (;;)
44.591 - switch (state->mode) {
44.592 - case HEAD:
44.593 - if (state->wrap == 0) {
44.594 - state->mode = TYPEDO;
44.595 - break;
44.596 - }
44.597 - NEEDBITS(16);
44.598 -#ifdef GUNZIP
44.599 - if ((state->wrap & 2) && hold == 0x8b1f) { /* gzip header */
44.600 - state->check = crc32(0L, Z_NULL, 0);
44.601 - CRC2(state->check, hold);
44.602 - INITBITS();
44.603 - state->mode = FLAGS;
44.604 - break;
44.605 - }
44.606 - state->flags = 0; /* expect zlib header */
44.607 - if (state->head != Z_NULL)
44.608 - state->head->done = -1;
44.609 - if (!(state->wrap & 1) || /* check if zlib header allowed */
44.610 -#else
44.611 - if (
44.612 -#endif
44.613 - ((BITS(8) << 8) + (hold >> 8)) % 31) {
44.614 - strm->msg = (char *)"incorrect header check";
44.615 - state->mode = BAD;
44.616 - break;
44.617 - }
44.618 - if (BITS(4) != Z_DEFLATED) {
44.619 - strm->msg = (char *)"unknown compression method";
44.620 - state->mode = BAD;
44.621 - break;
44.622 - }
44.623 - DROPBITS(4);
44.624 - len = BITS(4) + 8;
44.625 - if (len > state->wbits) {
44.626 - strm->msg = (char *)"invalid window size";
44.627 - state->mode = BAD;
44.628 - break;
44.629 - }
44.630 - state->dmax = 1U << len;
44.631 - Tracev((stderr, "inflate: zlib header ok\n"));
44.632 - strm->adler = state->check = adler32(0L, Z_NULL, 0);
44.633 - state->mode = hold & 0x200 ? DICTID : TYPE;
44.634 - INITBITS();
44.635 - break;
44.636 -#ifdef GUNZIP
44.637 - case FLAGS:
44.638 - NEEDBITS(16);
44.639 - state->flags = (int)(hold);
44.640 - if ((state->flags & 0xff) != Z_DEFLATED) {
44.641 - strm->msg = (char *)"unknown compression method";
44.642 - state->mode = BAD;
44.643 - break;
44.644 - }
44.645 - if (state->flags & 0xe000) {
44.646 - strm->msg = (char *)"unknown header flags set";
44.647 - state->mode = BAD;
44.648 - break;
44.649 - }
44.650 - if (state->head != Z_NULL)
44.651 - state->head->text = (int)((hold >> 8) & 1);
44.652 - if (state->flags & 0x0200) CRC2(state->check, hold);
44.653 - INITBITS();
44.654 - state->mode = TIME;
44.655 - case TIME:
44.656 - NEEDBITS(32);
44.657 - if (state->head != Z_NULL)
44.658 - state->head->time = hold;
44.659 - if (state->flags & 0x0200) CRC4(state->check, hold);
44.660 - INITBITS();
44.661 - state->mode = OS;
44.662 - case OS:
44.663 - NEEDBITS(16);
44.664 - if (state->head != Z_NULL) {
44.665 - state->head->xflags = (int)(hold & 0xff);
44.666 - state->head->os = (int)(hold >> 8);
44.667 - }
44.668 - if (state->flags & 0x0200) CRC2(state->check, hold);
44.669 - INITBITS();
44.670 - state->mode = EXLEN;
44.671 - case EXLEN:
44.672 - if (state->flags & 0x0400) {
44.673 - NEEDBITS(16);
44.674 - state->length = (unsigned)(hold);
44.675 - if (state->head != Z_NULL)
44.676 - state->head->extra_len = (unsigned)hold;
44.677 - if (state->flags & 0x0200) CRC2(state->check, hold);
44.678 - INITBITS();
44.679 - }
44.680 - else if (state->head != Z_NULL)
44.681 - state->head->extra = Z_NULL;
44.682 - state->mode = EXTRA;
44.683 - case EXTRA:
44.684 - if (state->flags & 0x0400) {
44.685 - copy = state->length;
44.686 - if (copy > have) copy = have;
44.687 - if (copy) {
44.688 - if (state->head != Z_NULL &&
44.689 - state->head->extra != Z_NULL) {
44.690 - len = state->head->extra_len - state->length;
44.691 - zmemcpy(state->head->extra + len, next,
44.692 - len + copy > state->head->extra_max ?
44.693 - state->head->extra_max - len : copy);
44.694 - }
44.695 - if (state->flags & 0x0200)
44.696 - state->check = crc32(state->check, next, copy);
44.697 - have -= copy;
44.698 - next += copy;
44.699 - state->length -= copy;
44.700 - }
44.701 - if (state->length) goto inf_leave;
44.702 - }
44.703 - state->length = 0;
44.704 - state->mode = NAME;
44.705 - case NAME:
44.706 - if (state->flags & 0x0800) {
44.707 - if (have == 0) goto inf_leave;
44.708 - copy = 0;
44.709 - do {
44.710 - len = (unsigned)(next[copy++]);
44.711 - if (state->head != Z_NULL &&
44.712 - state->head->name != Z_NULL &&
44.713 - state->length < state->head->name_max)
44.714 - state->head->name[state->length++] = len;
44.715 - } while (len && copy < have);
44.716 - if (state->flags & 0x0200)
44.717 - state->check = crc32(state->check, next, copy);
44.718 - have -= copy;
44.719 - next += copy;
44.720 - if (len) goto inf_leave;
44.721 - }
44.722 - else if (state->head != Z_NULL)
44.723 - state->head->name = Z_NULL;
44.724 - state->length = 0;
44.725 - state->mode = COMMENT;
44.726 - case COMMENT:
44.727 - if (state->flags & 0x1000) {
44.728 - if (have == 0) goto inf_leave;
44.729 - copy = 0;
44.730 - do {
44.731 - len = (unsigned)(next[copy++]);
44.732 - if (state->head != Z_NULL &&
44.733 - state->head->comment != Z_NULL &&
44.734 - state->length < state->head->comm_max)
44.735 - state->head->comment[state->length++] = len;
44.736 - } while (len && copy < have);
44.737 - if (state->flags & 0x0200)
44.738 - state->check = crc32(state->check, next, copy);
44.739 - have -= copy;
44.740 - next += copy;
44.741 - if (len) goto inf_leave;
44.742 - }
44.743 - else if (state->head != Z_NULL)
44.744 - state->head->comment = Z_NULL;
44.745 - state->mode = HCRC;
44.746 - case HCRC:
44.747 - if (state->flags & 0x0200) {
44.748 - NEEDBITS(16);
44.749 - if (hold != (state->check & 0xffff)) {
44.750 - strm->msg = (char *)"header crc mismatch";
44.751 - state->mode = BAD;
44.752 - break;
44.753 - }
44.754 - INITBITS();
44.755 - }
44.756 - if (state->head != Z_NULL) {
44.757 - state->head->hcrc = (int)((state->flags >> 9) & 1);
44.758 - state->head->done = 1;
44.759 - }
44.760 - strm->adler = state->check = crc32(0L, Z_NULL, 0);
44.761 - state->mode = TYPE;
44.762 - break;
44.763 -#endif
44.764 - case DICTID:
44.765 - NEEDBITS(32);
44.766 - strm->adler = state->check = REVERSE(hold);
44.767 - INITBITS();
44.768 - state->mode = DICT;
44.769 - case DICT:
44.770 - if (state->havedict == 0) {
44.771 - RESTORE();
44.772 - return Z_NEED_DICT;
44.773 - }
44.774 - strm->adler = state->check = adler32(0L, Z_NULL, 0);
44.775 - state->mode = TYPE;
44.776 - case TYPE:
44.777 - if (flush == Z_BLOCK) goto inf_leave;
44.778 - case TYPEDO:
44.779 - if (state->last) {
44.780 - BYTEBITS();
44.781 - state->mode = CHECK;
44.782 - break;
44.783 - }
44.784 - NEEDBITS(3);
44.785 - state->last = BITS(1);
44.786 - DROPBITS(1);
44.787 - switch (BITS(2)) {
44.788 - case 0: /* stored block */
44.789 - Tracev((stderr, "inflate: stored block%s\n",
44.790 - state->last ? " (last)" : ""));
44.791 - state->mode = STORED;
44.792 - break;
44.793 - case 1: /* fixed block */
44.794 - fixedtables(state);
44.795 - Tracev((stderr, "inflate: fixed codes block%s\n",
44.796 - state->last ? " (last)" : ""));
44.797 - state->mode = LEN; /* decode codes */
44.798 - break;
44.799 - case 2: /* dynamic block */
44.800 - Tracev((stderr, "inflate: dynamic codes block%s\n",
44.801 - state->last ? " (last)" : ""));
44.802 - state->mode = TABLE;
44.803 - break;
44.804 - case 3:
44.805 - strm->msg = (char *)"invalid block type";
44.806 - state->mode = BAD;
44.807 - }
44.808 - DROPBITS(2);
44.809 - break;
44.810 - case STORED:
44.811 - BYTEBITS(); /* go to byte boundary */
44.812 - NEEDBITS(32);
44.813 - if ((hold & 0xffff) != ((hold >> 16) ^ 0xffff)) {
44.814 - strm->msg = (char *)"invalid stored block lengths";
44.815 - state->mode = BAD;
44.816 - break;
44.817 - }
44.818 - state->length = (unsigned)hold & 0xffff;
44.819 - Tracev((stderr, "inflate: stored length %u\n",
44.820 - state->length));
44.821 - INITBITS();
44.822 - state->mode = COPY;
44.823 - case COPY:
44.824 - copy = state->length;
44.825 - if (copy) {
44.826 - if (copy > have) copy = have;
44.827 - if (copy > left) copy = left;
44.828 - if (copy == 0) goto inf_leave;
44.829 - zmemcpy(put, next, copy);
44.830 - have -= copy;
44.831 - next += copy;
44.832 - left -= copy;
44.833 - put += copy;
44.834 - state->length -= copy;
44.835 - break;
44.836 - }
44.837 - Tracev((stderr, "inflate: stored end\n"));
44.838 - state->mode = TYPE;
44.839 - break;
44.840 - case TABLE:
44.841 - NEEDBITS(14);
44.842 - state->nlen = BITS(5) + 257;
44.843 - DROPBITS(5);
44.844 - state->ndist = BITS(5) + 1;
44.845 - DROPBITS(5);
44.846 - state->ncode = BITS(4) + 4;
44.847 - DROPBITS(4);
44.848 -#ifndef PKZIP_BUG_WORKAROUND
44.849 - if (state->nlen > 286 || state->ndist > 30) {
44.850 - strm->msg = (char *)"too many length or distance symbols";
44.851 - state->mode = BAD;
44.852 - break;
44.853 - }
44.854 -#endif
44.855 - Tracev((stderr, "inflate: table sizes ok\n"));
44.856 - state->have = 0;
44.857 - state->mode = LENLENS;
44.858 - case LENLENS:
44.859 - while (state->have < state->ncode) {
44.860 - NEEDBITS(3);
44.861 - state->lens[order[state->have++]] = (unsigned short)BITS(3);
44.862 - DROPBITS(3);
44.863 - }
44.864 - while (state->have < 19)
44.865 - state->lens[order[state->have++]] = 0;
44.866 - state->next = state->codes;
44.867 - state->lencode = (code const FAR *)(state->next);
44.868 - state->lenbits = 7;
44.869 - ret = inflate_table(CODES, state->lens, 19, &(state->next),
44.870 - &(state->lenbits), state->work);
44.871 - if (ret) {
44.872 - strm->msg = (char *)"invalid code lengths set";
44.873 - state->mode = BAD;
44.874 - break;
44.875 - }
44.876 - Tracev((stderr, "inflate: code lengths ok\n"));
44.877 - state->have = 0;
44.878 - state->mode = CODELENS;
44.879 - case CODELENS:
44.880 - while (state->have < state->nlen + state->ndist) {
44.881 - for (;;) {
44.882 - this = state->lencode[BITS(state->lenbits)];
44.883 - if ((unsigned)(this.bits) <= bits) break;
44.884 - PULLBYTE();
44.885 - }
44.886 - if (this.val < 16) {
44.887 - NEEDBITS(this.bits);
44.888 - DROPBITS(this.bits);
44.889 - state->lens[state->have++] = this.val;
44.890 - }
44.891 - else {
44.892 - if (this.val == 16) {
44.893 - NEEDBITS(this.bits + 2);
44.894 - DROPBITS(this.bits);
44.895 - if (state->have == 0) {
44.896 - strm->msg = (char *)"invalid bit length repeat";
44.897 - state->mode = BAD;
44.898 - break;
44.899 - }
44.900 - len = state->lens[state->have - 1];
44.901 - copy = 3 + BITS(2);
44.902 - DROPBITS(2);
44.903 - }
44.904 - else if (this.val == 17) {
44.905 - NEEDBITS(this.bits + 3);
44.906 - DROPBITS(this.bits);
44.907 - len = 0;
44.908 - copy = 3 + BITS(3);
44.909 - DROPBITS(3);
44.910 - }
44.911 - else {
44.912 - NEEDBITS(this.bits + 7);
44.913 - DROPBITS(this.bits);
44.914 - len = 0;
44.915 - copy = 11 + BITS(7);
44.916 - DROPBITS(7);
44.917 - }
44.918 - if (state->have + copy > state->nlen + state->ndist) {
44.919 - strm->msg = (char *)"invalid bit length repeat";
44.920 - state->mode = BAD;
44.921 - break;
44.922 - }
44.923 - while (copy--)
44.924 - state->lens[state->have++] = (unsigned short)len;
44.925 - }
44.926 - }
44.927 -
44.928 - /* handle error breaks in while */
44.929 - if (state->mode == BAD) break;
44.930 -
44.931 - /* build code tables */
44.932 - state->next = state->codes;
44.933 - state->lencode = (code const FAR *)(state->next);
44.934 - state->lenbits = 9;
44.935 - ret = inflate_table(LENS, state->lens, state->nlen, &(state->next),
44.936 - &(state->lenbits), state->work);
44.937 - if (ret) {
44.938 - strm->msg = (char *)"invalid literal/lengths set";
44.939 - state->mode = BAD;
44.940 - break;
44.941 - }
44.942 - state->distcode = (code const FAR *)(state->next);
44.943 - state->distbits = 6;
44.944 - ret = inflate_table(DISTS, state->lens + state->nlen, state->ndist,
44.945 - &(state->next), &(state->distbits), state->work);
44.946 - if (ret) {
44.947 - strm->msg = (char *)"invalid distances set";
44.948 - state->mode = BAD;
44.949 - break;
44.950 - }
44.951 - Tracev((stderr, "inflate: codes ok\n"));
44.952 - state->mode = LEN;
44.953 - case LEN:
44.954 - if (have >= 6 && left >= 258) {
44.955 - RESTORE();
44.956 - inflate_fast(strm, out);
44.957 - LOAD();
44.958 - break;
44.959 - }
44.960 - for (;;) {
44.961 - this = state->lencode[BITS(state->lenbits)];
44.962 - if ((unsigned)(this.bits) <= bits) break;
44.963 - PULLBYTE();
44.964 - }
44.965 - if (this.op && (this.op & 0xf0) == 0) {
44.966 - last = this;
44.967 - for (;;) {
44.968 - this = state->lencode[last.val +
44.969 - (BITS(last.bits + last.op) >> last.bits)];
44.970 - if ((unsigned)(last.bits + this.bits) <= bits) break;
44.971 - PULLBYTE();
44.972 - }
44.973 - DROPBITS(last.bits);
44.974 - }
44.975 - DROPBITS(this.bits);
44.976 - state->length = (unsigned)this.val;
44.977 - if ((int)(this.op) == 0) {
44.978 - Tracevv((stderr, this.val >= 0x20 && this.val < 0x7f ?
44.979 - "inflate: literal '%c'\n" :
44.980 - "inflate: literal 0x%02x\n", this.val));
44.981 - state->mode = LIT;
44.982 - break;
44.983 - }
44.984 - if (this.op & 32) {
44.985 - Tracevv((stderr, "inflate: end of block\n"));
44.986 - state->mode = TYPE;
44.987 - break;
44.988 - }
44.989 - if (this.op & 64) {
44.990 - strm->msg = (char *)"invalid literal/length code";
44.991 - state->mode = BAD;
44.992 - break;
44.993 - }
44.994 - state->extra = (unsigned)(this.op) & 15;
44.995 - state->mode = LENEXT;
44.996 - case LENEXT:
44.997 - if (state->extra) {
44.998 - NEEDBITS(state->extra);
44.999 - state->length += BITS(state->extra);
44.1000 - DROPBITS(state->extra);
44.1001 - }
44.1002 - Tracevv((stderr, "inflate: length %u\n", state->length));
44.1003 - state->mode = DIST;
44.1004 - case DIST:
44.1005 - for (;;) {
44.1006 - this = state->distcode[BITS(state->distbits)];
44.1007 - if ((unsigned)(this.bits) <= bits) break;
44.1008 - PULLBYTE();
44.1009 - }
44.1010 - if ((this.op & 0xf0) == 0) {
44.1011 - last = this;
44.1012 - for (;;) {
44.1013 - this = state->distcode[last.val +
44.1014 - (BITS(last.bits + last.op) >> last.bits)];
44.1015 - if ((unsigned)(last.bits + this.bits) <= bits) break;
44.1016 - PULLBYTE();
44.1017 - }
44.1018 - DROPBITS(last.bits);
44.1019 - }
44.1020 - DROPBITS(this.bits);
44.1021 - if (this.op & 64) {
44.1022 - strm->msg = (char *)"invalid distance code";
44.1023 - state->mode = BAD;
44.1024 - break;
44.1025 - }
44.1026 - state->offset = (unsigned)this.val;
44.1027 - state->extra = (unsigned)(this.op) & 15;
44.1028 - state->mode = DISTEXT;
44.1029 - case DISTEXT:
44.1030 - if (state->extra) {
44.1031 - NEEDBITS(state->extra);
44.1032 - state->offset += BITS(state->extra);
44.1033 - DROPBITS(state->extra);
44.1034 - }
44.1035 -#ifdef INFLATE_STRICT
44.1036 - if (state->offset > state->dmax) {
44.1037 - strm->msg = (char *)"invalid distance too far back";
44.1038 - state->mode = BAD;
44.1039 - break;
44.1040 - }
44.1041 -#endif
44.1042 - if (state->offset > state->whave + out - left) {
44.1043 - strm->msg = (char *)"invalid distance too far back";
44.1044 - state->mode = BAD;
44.1045 - break;
44.1046 - }
44.1047 - Tracevv((stderr, "inflate: distance %u\n", state->offset));
44.1048 - state->mode = MATCH;
44.1049 - case MATCH:
44.1050 - if (left == 0) goto inf_leave;
44.1051 - copy = out - left;
44.1052 - if (state->offset > copy) { /* copy from window */
44.1053 - copy = state->offset - copy;
44.1054 - if (copy > state->write) {
44.1055 - copy -= state->write;
44.1056 - from = state->window + (state->wsize - copy);
44.1057 - }
44.1058 - else
44.1059 - from = state->window + (state->write - copy);
44.1060 - if (copy > state->length) copy = state->length;
44.1061 - }
44.1062 - else { /* copy from output */
44.1063 - from = put - state->offset;
44.1064 - copy = state->length;
44.1065 - }
44.1066 - if (copy > left) copy = left;
44.1067 - left -= copy;
44.1068 - state->length -= copy;
44.1069 - do {
44.1070 - *put++ = *from++;
44.1071 - } while (--copy);
44.1072 - if (state->length == 0) state->mode = LEN;
44.1073 - break;
44.1074 - case LIT:
44.1075 - if (left == 0) goto inf_leave;
44.1076 - *put++ = (unsigned char)(state->length);
44.1077 - left--;
44.1078 - state->mode = LEN;
44.1079 - break;
44.1080 - case CHECK:
44.1081 - if (state->wrap) {
44.1082 - NEEDBITS(32);
44.1083 - out -= left;
44.1084 - strm->total_out += out;
44.1085 - state->total += out;
44.1086 - if (out)
44.1087 - strm->adler = state->check =
44.1088 - UPDATE(state->check, put - out, out);
44.1089 - out = left;
44.1090 - if ((
44.1091 -#ifdef GUNZIP
44.1092 - state->flags ? hold :
44.1093 -#endif
44.1094 - REVERSE(hold)) != state->check) {
44.1095 - strm->msg = (char *)"incorrect data check";
44.1096 - state->mode = BAD;
44.1097 - break;
44.1098 - }
44.1099 - INITBITS();
44.1100 - Tracev((stderr, "inflate: check matches trailer\n"));
44.1101 - }
44.1102 -#ifdef GUNZIP
44.1103 - state->mode = LENGTH;
44.1104 - case LENGTH:
44.1105 - if (state->wrap && state->flags) {
44.1106 - NEEDBITS(32);
44.1107 - if (hold != (state->total & 0xffffffffUL)) {
44.1108 - strm->msg = (char *)"incorrect length check";
44.1109 - state->mode = BAD;
44.1110 - break;
44.1111 - }
44.1112 - INITBITS();
44.1113 - Tracev((stderr, "inflate: length matches trailer\n"));
44.1114 - }
44.1115 -#endif
44.1116 - state->mode = DONE;
44.1117 - case DONE:
44.1118 - ret = Z_STREAM_END;
44.1119 - goto inf_leave;
44.1120 - case BAD:
44.1121 - ret = Z_DATA_ERROR;
44.1122 - goto inf_leave;
44.1123 - case MEM:
44.1124 - return Z_MEM_ERROR;
44.1125 - case SYNC:
44.1126 - default:
44.1127 - return Z_STREAM_ERROR;
44.1128 - }
44.1129 -
44.1130 - /*
44.1131 - Return from inflate(), updating the total counts and the check value.
44.1132 - If there was no progress during the inflate() call, return a buffer
44.1133 - error. Call updatewindow() to create and/or update the window state.
44.1134 - Note: a memory error from inflate() is non-recoverable.
44.1135 - */
44.1136 - inf_leave:
44.1137 - RESTORE();
44.1138 - if (state->wsize || (state->mode < CHECK && out != strm->avail_out))
44.1139 - if (updatewindow(strm, out)) {
44.1140 - state->mode = MEM;
44.1141 - return Z_MEM_ERROR;
44.1142 - }
44.1143 - in -= strm->avail_in;
44.1144 - out -= strm->avail_out;
44.1145 - strm->total_in += in;
44.1146 - strm->total_out += out;
44.1147 - state->total += out;
44.1148 - if (state->wrap && out)
44.1149 - strm->adler = state->check =
44.1150 - UPDATE(state->check, strm->next_out - out, out);
44.1151 - strm->data_type = state->bits + (state->last ? 64 : 0) +
44.1152 - (state->mode == TYPE ? 128 : 0);
44.1153 - if (((in == 0 && out == 0) || flush == Z_FINISH) && ret == Z_OK)
44.1154 - ret = Z_BUF_ERROR;
44.1155 - return ret;
44.1156 -}
44.1157 -
44.1158 -int ZEXPORT inflateEnd(strm)
44.1159 -z_streamp strm;
44.1160 -{
44.1161 - struct inflate_state FAR *state;
44.1162 - if (strm == Z_NULL || strm->state == Z_NULL || strm->zfree == (free_func)0)
44.1163 - return Z_STREAM_ERROR;
44.1164 - state = (struct inflate_state FAR *)strm->state;
44.1165 - if (state->window != Z_NULL) ZFREE(strm, state->window);
44.1166 - ZFREE(strm, strm->state);
44.1167 - strm->state = Z_NULL;
44.1168 - Tracev((stderr, "inflate: end\n"));
44.1169 - return Z_OK;
44.1170 -}
44.1171 -
44.1172 -int ZEXPORT inflateSetDictionary(strm, dictionary, dictLength)
44.1173 -z_streamp strm;
44.1174 -const Bytef *dictionary;
44.1175 -uInt dictLength;
44.1176 -{
44.1177 - struct inflate_state FAR *state;
44.1178 - unsigned long id;
44.1179 -
44.1180 - /* check state */
44.1181 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.1182 - state = (struct inflate_state FAR *)strm->state;
44.1183 - if (state->wrap != 0 && state->mode != DICT)
44.1184 - return Z_STREAM_ERROR;
44.1185 -
44.1186 - /* check for correct dictionary id */
44.1187 - if (state->mode == DICT) {
44.1188 - id = adler32(0L, Z_NULL, 0);
44.1189 - id = adler32(id, dictionary, dictLength);
44.1190 - if (id != state->check)
44.1191 - return Z_DATA_ERROR;
44.1192 - }
44.1193 -
44.1194 - /* copy dictionary to window */
44.1195 - if (updatewindow(strm, strm->avail_out)) {
44.1196 - state->mode = MEM;
44.1197 - return Z_MEM_ERROR;
44.1198 - }
44.1199 - if (dictLength > state->wsize) {
44.1200 - zmemcpy(state->window, dictionary + dictLength - state->wsize,
44.1201 - state->wsize);
44.1202 - state->whave = state->wsize;
44.1203 - }
44.1204 - else {
44.1205 - zmemcpy(state->window + state->wsize - dictLength, dictionary,
44.1206 - dictLength);
44.1207 - state->whave = dictLength;
44.1208 - }
44.1209 - state->havedict = 1;
44.1210 - Tracev((stderr, "inflate: dictionary set\n"));
44.1211 - return Z_OK;
44.1212 -}
44.1213 -
44.1214 -int ZEXPORT inflateGetHeader(strm, head)
44.1215 -z_streamp strm;
44.1216 -gz_headerp head;
44.1217 -{
44.1218 - struct inflate_state FAR *state;
44.1219 -
44.1220 - /* check state */
44.1221 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.1222 - state = (struct inflate_state FAR *)strm->state;
44.1223 - if ((state->wrap & 2) == 0) return Z_STREAM_ERROR;
44.1224 -
44.1225 - /* save header structure */
44.1226 - state->head = head;
44.1227 - head->done = 0;
44.1228 - return Z_OK;
44.1229 -}
44.1230 -
44.1231 -/*
44.1232 - Search buf[0..len-1] for the pattern: 0, 0, 0xff, 0xff. Return when found
44.1233 - or when out of input. When called, *have is the number of pattern bytes
44.1234 - found in order so far, in 0..3. On return *have is updated to the new
44.1235 - state. If on return *have equals four, then the pattern was found and the
44.1236 - return value is how many bytes were read including the last byte of the
44.1237 - pattern. If *have is less than four, then the pattern has not been found
44.1238 - yet and the return value is len. In the latter case, syncsearch() can be
44.1239 - called again with more data and the *have state. *have is initialized to
44.1240 - zero for the first call.
44.1241 - */
44.1242 -local unsigned syncsearch(have, buf, len)
44.1243 -unsigned FAR *have;
44.1244 -unsigned char FAR *buf;
44.1245 -unsigned len;
44.1246 -{
44.1247 - unsigned got;
44.1248 - unsigned next;
44.1249 -
44.1250 - got = *have;
44.1251 - next = 0;
44.1252 - while (next < len && got < 4) {
44.1253 - if ((int)(buf[next]) == (got < 2 ? 0 : 0xff))
44.1254 - got++;
44.1255 - else if (buf[next])
44.1256 - got = 0;
44.1257 - else
44.1258 - got = 4 - got;
44.1259 - next++;
44.1260 - }
44.1261 - *have = got;
44.1262 - return next;
44.1263 -}
44.1264 -
44.1265 -int ZEXPORT inflateSync(strm)
44.1266 -z_streamp strm;
44.1267 -{
44.1268 - unsigned len; /* number of bytes to look at or looked at */
44.1269 - unsigned long in, out; /* temporary to save total_in and total_out */
44.1270 - unsigned char buf[4]; /* to restore bit buffer to byte string */
44.1271 - struct inflate_state FAR *state;
44.1272 -
44.1273 - /* check parameters */
44.1274 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.1275 - state = (struct inflate_state FAR *)strm->state;
44.1276 - if (strm->avail_in == 0 && state->bits < 8) return Z_BUF_ERROR;
44.1277 -
44.1278 - /* if first time, start search in bit buffer */
44.1279 - if (state->mode != SYNC) {
44.1280 - state->mode = SYNC;
44.1281 - state->hold <<= state->bits & 7;
44.1282 - state->bits -= state->bits & 7;
44.1283 - len = 0;
44.1284 - while (state->bits >= 8) {
44.1285 - buf[len++] = (unsigned char)(state->hold);
44.1286 - state->hold >>= 8;
44.1287 - state->bits -= 8;
44.1288 - }
44.1289 - state->have = 0;
44.1290 - syncsearch(&(state->have), buf, len);
44.1291 - }
44.1292 -
44.1293 - /* search available input */
44.1294 - len = syncsearch(&(state->have), strm->next_in, strm->avail_in);
44.1295 - strm->avail_in -= len;
44.1296 - strm->next_in += len;
44.1297 - strm->total_in += len;
44.1298 -
44.1299 - /* return no joy or set up to restart inflate() on a new block */
44.1300 - if (state->have != 4) return Z_DATA_ERROR;
44.1301 - in = strm->total_in; out = strm->total_out;
44.1302 - inflateReset(strm);
44.1303 - strm->total_in = in; strm->total_out = out;
44.1304 - state->mode = TYPE;
44.1305 - return Z_OK;
44.1306 -}
44.1307 -
44.1308 -/*
44.1309 - Returns true if inflate is currently at the end of a block generated by
44.1310 - Z_SYNC_FLUSH or Z_FULL_FLUSH. This function is used by one PPP
44.1311 - implementation to provide an additional safety check. PPP uses
44.1312 - Z_SYNC_FLUSH but removes the length bytes of the resulting empty stored
44.1313 - block. When decompressing, PPP checks that at the end of input packet,
44.1314 - inflate is waiting for these length bytes.
44.1315 - */
44.1316 -int ZEXPORT inflateSyncPoint(strm)
44.1317 -z_streamp strm;
44.1318 -{
44.1319 - struct inflate_state FAR *state;
44.1320 -
44.1321 - if (strm == Z_NULL || strm->state == Z_NULL) return Z_STREAM_ERROR;
44.1322 - state = (struct inflate_state FAR *)strm->state;
44.1323 - return state->mode == STORED && state->bits == 0;
44.1324 -}
44.1325 -
44.1326 -int ZEXPORT inflateCopy(dest, source)
44.1327 -z_streamp dest;
44.1328 -z_streamp source;
44.1329 -{
44.1330 - struct inflate_state FAR *state;
44.1331 - struct inflate_state FAR *copy;
44.1332 - unsigned char FAR *window;
44.1333 - unsigned wsize;
44.1334 -
44.1335 - /* check input */
44.1336 - if (dest == Z_NULL || source == Z_NULL || source->state == Z_NULL ||
44.1337 - source->zalloc == (alloc_func)0 || source->zfree == (free_func)0)
44.1338 - return Z_STREAM_ERROR;
44.1339 - state = (struct inflate_state FAR *)source->state;
44.1340 -
44.1341 - /* allocate space */
44.1342 - copy = (struct inflate_state FAR *)
44.1343 - ZALLOC(source, 1, sizeof(struct inflate_state));
44.1344 - if (copy == Z_NULL) return Z_MEM_ERROR;
44.1345 - window = Z_NULL;
44.1346 - if (state->window != Z_NULL) {
44.1347 - window = (unsigned char FAR *)
44.1348 - ZALLOC(source, 1U << state->wbits, sizeof(unsigned char));
44.1349 - if (window == Z_NULL) {
44.1350 - ZFREE(source, copy);
44.1351 - return Z_MEM_ERROR;
44.1352 - }
44.1353 - }
44.1354 -
44.1355 - /* copy state */
44.1356 - zmemcpy(dest, source, sizeof(z_stream));
44.1357 - zmemcpy(copy, state, sizeof(struct inflate_state));
44.1358 - if (state->lencode >= state->codes &&
44.1359 - state->lencode <= state->codes + ENOUGH - 1) {
44.1360 - copy->lencode = copy->codes + (state->lencode - state->codes);
44.1361 - copy->distcode = copy->codes + (state->distcode - state->codes);
44.1362 - }
44.1363 - copy->next = copy->codes + (state->next - state->codes);
44.1364 - if (window != Z_NULL) {
44.1365 - wsize = 1U << state->wbits;
44.1366 - zmemcpy(window, state->window, wsize);
44.1367 - }
44.1368 - copy->window = window;
44.1369 - dest->state = (struct internal_state FAR *)copy;
44.1370 - return Z_OK;
44.1371 -}
45.1 --- a/sourcepawn/vm/zlib/inflate.h Tue Nov 07 23:26:40 2006 +0000
45.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
45.3 @@ -1,115 +0,0 @@
45.4 -/* inflate.h -- internal inflate state definition
45.5 - * Copyright (C) 1995-2004 Mark Adler
45.6 - * For conditions of distribution and use, see copyright notice in zlib.h
45.7 - */
45.8 -
45.9 -/* WARNING: this file should *not* be used by applications. It is
45.10 - part of the implementation of the compression library and is
45.11 - subject to change. Applications should only use zlib.h.
45.12 - */
45.13 -
45.14 -/* define NO_GZIP when compiling if you want to disable gzip header and
45.15 - trailer decoding by inflate(). NO_GZIP would be used to avoid linking in
45.16 - the crc code when it is not needed. For shared libraries, gzip decoding
45.17 - should be left enabled. */
45.18 -#ifndef NO_GZIP
45.19 -# define GUNZIP
45.20 -#endif
45.21 -
45.22 -/* Possible inflate modes between inflate() calls */
45.23 -typedef enum {
45.24 - HEAD, /* i: waiting for magic header */
45.25 - FLAGS, /* i: waiting for method and flags (gzip) */
45.26 - TIME, /* i: waiting for modification time (gzip) */
45.27 - OS, /* i: waiting for extra flags and operating system (gzip) */
45.28 - EXLEN, /* i: waiting for extra length (gzip) */
45.29 - EXTRA, /* i: waiting for extra bytes (gzip) */
45.30 - NAME, /* i: waiting for end of file name (gzip) */
45.31 - COMMENT, /* i: waiting for end of comment (gzip) */
45.32 - HCRC, /* i: waiting for header crc (gzip) */
45.33 - DICTID, /* i: waiting for dictionary check value */
45.34 - DICT, /* waiting for inflateSetDictionary() call */
45.35 - TYPE, /* i: waiting for type bits, including last-flag bit */
45.36 - TYPEDO, /* i: same, but skip check to exit inflate on new block */
45.37 - STORED, /* i: waiting for stored size (length and complement) */
45.38 - COPY, /* i/o: waiting for input or output to copy stored block */
45.39 - TABLE, /* i: waiting for dynamic block table lengths */
45.40 - LENLENS, /* i: waiting for code length code lengths */
45.41 - CODELENS, /* i: waiting for length/lit and distance code lengths */
45.42 - LEN, /* i: waiting for length/lit code */
45.43 - LENEXT, /* i: waiting for length extra bits */
45.44 - DIST, /* i: waiting for distance code */
45.45 - DISTEXT, /* i: waiting for distance extra bits */
45.46 - MATCH, /* o: waiting for output space to copy string */
45.47 - LIT, /* o: waiting for output space to write literal */
45.48 - CHECK, /* i: waiting for 32-bit check value */
45.49 - LENGTH, /* i: waiting for 32-bit length (gzip) */
45.50 - DONE, /* finished check, done -- remain here until reset */
45.51 - BAD, /* got a data error -- remain here until reset */
45.52 - MEM, /* got an inflate() memory error -- remain here until reset */
45.53 - SYNC /* looking for synchronization bytes to restart inflate() */
45.54 -} inflate_mode;
45.55 -
45.56 -/*
45.57 - State transitions between above modes -
45.58 -
45.59 - (most modes can go to the BAD or MEM mode -- not shown for clarity)
45.60 -
45.61 - Process header:
45.62 - HEAD -> (gzip) or (zlib)
45.63 - (gzip) -> FLAGS -> TIME -> OS -> EXLEN -> EXTRA -> NAME
45.64 - NAME -> COMMENT -> HCRC -> TYPE
45.65 - (zlib) -> DICTID or TYPE
45.66 - DICTID -> DICT -> TYPE
45.67 - Read deflate blocks:
45.68 - TYPE -> STORED or TABLE or LEN or CHECK
45.69 - STORED -> COPY -> TYPE
45.70 - TABLE -> LENLENS -> CODELENS -> LEN
45.71 - Read deflate codes:
45.72 - LEN -> LENEXT or LIT or TYPE
45.73 - LENEXT -> DIST -> DISTEXT -> MATCH -> LEN
45.74 - LIT -> LEN
45.75 - Process trailer:
45.76 - CHECK -> LENGTH -> DONE
45.77 - */
45.78 -
45.79 -/* state maintained between inflate() calls. Approximately 7K bytes. */
45.80 -struct inflate_state {
45.81 - inflate_mode mode; /* current inflate mode */
45.82 - int last; /* true if processing last block */
45.83 - int wrap; /* bit 0 true for zlib, bit 1 true for gzip */
45.84 - int havedict; /* true if dictionary provided */
45.85 - int flags; /* gzip header method and flags (0 if zlib) */
45.86 - unsigned dmax; /* zlib header max distance (INFLATE_STRICT) */
45.87 - unsigned long check; /* protected copy of check value */
45.88 - unsigned long total; /* protected copy of output count */
45.89 - gz_headerp head; /* where to save gzip header information */
45.90 - /* sliding window */
45.91 - unsigned wbits; /* log base 2 of requested window size */
45.92 - unsigned wsize; /* window size or zero if not using window */
45.93 - unsigned whave; /* valid bytes in the window */
45.94 - unsigned write; /* window write index */
45.95 - unsigned char FAR *window; /* allocated sliding window, if needed */
45.96 - /* bit accumulator */
45.97 - unsigned long hold; /* input bit accumulator */
45.98 - unsigned bits; /* number of bits in "in" */
45.99 - /* for string and stored block copying */
45.100 - unsigned length; /* literal or length of data to copy */
45.101 - unsigned offset; /* distance back to copy string from */
45.102 - /* for table and code decoding */
45.103 - unsigned extra; /* extra bits needed */
45.104 - /* fixed and dynamic code tables */
45.105 - code const FAR *lencode; /* starting table for length/literal codes */
45.106 - code const FAR *distcode; /* starting table for distance codes */
45.107 - unsigned lenbits; /* index bits for lencode */
45.108 - unsigned distbits; /* index bits for distcode */
45.109 - /* dynamic table building */
45.110 - unsigned ncode; /* number of code length code lengths */
45.111 - unsigned nlen; /* number of length code lengths */
45.112 - unsigned ndist; /* number of distance code lengths */
45.113 - unsigned have; /* number of code lengths in lens[] */
45.114 - code FAR *next; /* next available space in codes[] */
45.115 - unsigned short lens[320]; /* temporary storage for code lengths */
45.116 - unsigned short work[288]; /* work area for code table building */
45.117 - code codes[ENOUGH]; /* space for code tables */
45.118 -};
46.1 --- a/sourcepawn/vm/zlib/inftrees.c Tue Nov 07 23:26:40 2006 +0000
46.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
46.3 @@ -1,329 +0,0 @@
46.4 -/* inftrees.c -- generate Huffman trees for efficient decoding
46.5 - * Copyright (C) 1995-2005 Mark Adler
46.6 - * For conditions of distribution and use, see copyright notice in zlib.h
46.7 - */
46.8 -
46.9 -#include "zutil.h"
46.10 -#include "inftrees.h"
46.11 -
46.12 -#define MAXBITS 15
46.13 -
46.14 -const char inflate_copyright[] =
46.15 - " inflate 1.2.3 Copyright 1995-2005 Mark Adler ";
46.16 -/*
46.17 - If you use the zlib library in a product, an acknowledgment is welcome
46.18 - in the documentation of your product. If for some reason you cannot
46.19 - include such an acknowledgment, I would appreciate that you keep this
46.20 - copyright string in the executable of your product.
46.21 - */
46.22 -
46.23 -/*
46.24 - Build a set of tables to decode the provided canonical Huffman code.
46.25 - The code lengths are lens[0..codes-1]. The result starts at *table,
46.26 - whose indices are 0..2^bits-1. work is a writable array of at least
46.27 - lens shorts, which is used as a work area. type is the type of code
46.28 - to be generated, CODES, LENS, or DISTS. On return, zero is success,
46.29 - -1 is an invalid code, and +1 means that ENOUGH isn't enough. table
46.30 - on return points to the next available entry's address. bits is the
46.31 - requested root table index bits, and on return it is the actual root
46.32 - table index bits. It will differ if the request is greater than the
46.33 - longest code or if it is less than the shortest code.
46.34 - */
46.35 -int inflate_table(type, lens, codes, table, bits, work)
46.36 -codetype type;
46.37 -unsigned short FAR *lens;
46.38 -unsigned codes;
46.39 -code FAR * FAR *table;
46.40 -unsigned FAR *bits;
46.41 -unsigned short FAR *work;
46.42 -{
46.43 - unsigned len; /* a code's length in bits */
46.44 - unsigned sym; /* index of code symbols */
46.45 - unsigned min, max; /* minimum and maximum code lengths */
46.46 - unsigned root; /* number of index bits for root table */
46.47 - unsigned curr; /* number of index bits for current table */
46.48 - unsigned drop; /* code bits to drop for sub-table */
46.49 - int left; /* number of prefix codes available */
46.50 - unsigned used; /* code entries in table used */
46.51 - unsigned huff; /* Huffman code */
46.52 - unsigned incr; /* for incrementing code, index */
46.53 - unsigned fill; /* index for replicating entries */
46.54 - unsigned low; /* low bits for current root entry */
46.55 - unsigned mask; /* mask for low root bits */
46.56 - code this; /* table entry for duplication */
46.57 - code FAR *next; /* next available space in table */
46.58 - const unsigned short FAR *base; /* base value table to use */
46.59 - const unsigned short FAR *extra; /* extra bits table to use */
46.60 - int end; /* use base and extra for symbol > end */
46.61 - unsigned short count[MAXBITS+1]; /* number of codes of each length */
46.62 - unsigned short offs[MAXBITS+1]; /* offsets in table for each length */
46.63 - static const unsigned short lbase[31] = { /* Length codes 257..285 base */
46.64 - 3, 4, 5, 6, 7, 8, 9, 10, 11, 13, 15, 17, 19, 23, 27, 31,
46.65 - 35, 43, 51, 59, 67, 83, 99, 115, 131, 163, 195, 227, 258, 0, 0};
46.66 - static const unsigned short lext[31] = { /* Length codes 257..285 extra */
46.67 - 16, 16, 16, 16, 16, 16, 16, 16, 17, 17, 17, 17, 18, 18, 18, 18,
46.68 - 19, 19, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 16, 201, 196};
46.69 - static const unsigned short dbase[32] = { /* Distance codes 0..29 base */
46.70 - 1, 2, 3, 4, 5, 7, 9, 13, 17, 25, 33, 49, 65, 97, 129, 193,
46.71 - 257, 385, 513, 769, 1025, 1537, 2049, 3073, 4097, 6145,
46.72 - 8193, 12289, 16385, 24577, 0, 0};
46.73 - static const unsigned short dext[32] = { /* Distance codes 0..29 extra */
46.74 - 16, 16, 16, 16, 17, 17, 18, 18, 19, 19, 20, 20, 21, 21, 22, 22,
46.75 - 23, 23, 24, 24, 25, 25, 26, 26, 27, 27,
46.76 - 28, 28, 29, 29, 64, 64};
46.77 -
46.78 - /*
46.79 - Process a set of code lengths to create a canonical Huffman code. The
46.80 - code lengths are lens[0..codes-1]. Each length corresponds to the
46.81 - symbols 0..codes-1. The Huffman code is generated by first sorting the
46.82 - symbols by length from short to long, and retaining the symbol order
46.83 - for codes with equal lengths. Then the code starts with all zero bits
46.84 - for the first code of the shortest length, and the codes are integer
46.85 - increments for the same length, and zeros are appended as the length
46.86 - increases. For the deflate format, these bits are stored backwards
46.87 - from their more natural integer increment ordering, and so when the
46.88 - decoding tables are built in the large loop below, the integer codes
46.89 - are incremented backwards.
46.90 -
46.91 - This routine assumes, but does not check, that all of the entries in
46.92 - lens[] are in the range 0..MAXBITS. The caller must assure this.
46.93 - 1..MAXBITS is interpreted as that code length. zero means that that
46.94 - symbol does not occur in this code.
46.95 -
46.96 - The codes are sorted by computing a count of codes for each length,
46.97 - creating from that a table of starting indices for each length in the
46.98 - sorted table, and then entering the symbols in order in the sorted
46.99 - table. The sorted table is work[], with that space being provided by
46.100 - the caller.
46.101 -
46.102 - The length counts are used for other purposes as well, i.e. finding
46.103 - the minimum and maximum length codes, determining if there are any
46.104 - codes at all, checking for a valid set of lengths, and looking ahead
46.105 - at length counts to determine sub-table sizes when building the
46.106 - decoding tables.
46.107 - */
46.108 -
46.109 - /* accumulate lengths for codes (assumes lens[] all in 0..MAXBITS) */
46.110 - for (len = 0; len <= MAXBITS; len++)
46.111 - count[len] = 0;
46.112 - for (sym = 0; sym < codes; sym++)
46.113 - count[lens[sym]]++;
46.114 -
46.115 - /* bound code lengths, force root to be within code lengths */
46.116 - root = *bits;
46.117 - for (max = MAXBITS; max >= 1; max--)
46.118 - if (count[max] != 0) break;
46.119 - if (root > max) root = max;
46.120 - if (max == 0) { /* no symbols to code at all */
46.121 - this.op = (unsigned char)64; /* invalid code marker */
46.122 - this.bits = (unsigned char)1;
46.123 - this.val = (unsigned short)0;
46.124 - *(*table)++ = this; /* make a table to force an error */
46.125 - *(*table)++ = this;
46.126 - *bits = 1;
46.127 - return 0; /* no symbols, but wait for decoding to report error */
46.128 - }
46.129 - for (min = 1; min <= MAXBITS; min++)
46.130 - if (count[min] != 0) break;
46.131 - if (root < min) root = min;
46.132 -
46.133 - /* check for an over-subscribed or incomplete set of lengths */
46.134 - left = 1;
46.135 - for (len = 1; len <= MAXBITS; len++) {
46.136 - left <<= 1;
46.137 - left -= count[len];
46.138 - if (left < 0) return -1; /* over-subscribed */
46.139 - }
46.140 - if (left > 0 && (type == CODES || max != 1))
46.141 - return -1; /* incomplete set */
46.142 -
46.143 - /* generate offsets into symbol table for each length for sorting */
46.144 - offs[1] = 0;
46.145 - for (len = 1; len < MAXBITS; len++)
46.146 - offs[len + 1] = offs[len] + count[len];
46.147 -
46.148 - /* sort symbols by length, by symbol order within each length */
46.149 - for (sym = 0; sym < codes; sym++)
46.150 - if (lens[sym] != 0) work[offs[lens[sym]]++] = (unsigned short)sym;
46.151 -
46.152 - /*
46.153 - Create and fill in decoding tables. In this loop, the table being
46.154 - filled is at next and has curr index bits. The code being used is huff
46.155 - with length len. That code is converted to an index by dropping drop
46.156 - bits off of the bottom. For codes where len is less than drop + curr,
46.157 - those top drop + curr - len bits are incremented through all values to
46.158 - fill the table with replicated entries.
46.159 -
46.160 - root is the number of index bits for the root table. When len exceeds
46.161 - root, sub-tables are created pointed to by the root entry with an index
46.162 - of the low root bits of huff. This is saved in low to check for when a
46.163 - new sub-table should be started. drop is zero when the root table is
46.164 - being filled, and drop is root when sub-tables are being filled.
46.165 -
46.166 - When a new sub-table is needed, it is necessary to look ahead in the
46.167 - code lengths to determine what size sub-table is needed. The length
46.168 - counts are used for this, and so count[] is decremented as codes are
46.169 - entered in the tables.
46.170 -
46.171 - used keeps track of how many table entries have been allocated from the
46.172 - provided *table space. It is checked when a LENS table is being made
46.173 - against the space in *table, ENOUGH, minus the maximum space needed by
46.174 - the worst case distance code, MAXD. This should never happen, but the
46.175 - sufficiency of ENOUGH has not been proven exhaustively, hence the check.
46.176 - This assumes that when type == LENS, bits == 9.
46.177 -
46.178 - sym increments through all symbols, and the loop terminates when
46.179 - all codes of length max, i.e. all codes, have been processed. This
46.180 - routine permits incomplete codes, so another loop after this one fills
46.181 - in the rest of the decoding tables with invalid code markers.
46.182 - */
46.183 -
46.184 - /* set up for code type */
46.185 - switch (type) {
46.186 - case CODES:
46.187 - base = extra = work; /* dummy value--not used */
46.188 - end = 19;
46.189 - break;
46.190 - case LENS:
46.191 - base = lbase;
46.192 - base -= 257;
46.193 - extra = lext;
46.194 - extra -= 257;
46.195 - end = 256;
46.196 - break;
46.197 - default: /* DISTS */
46.198 - base = dbase;
46.199 - extra = dext;
46.200 - end = -1;
46.201 - }
46.202 -
46.203 - /* initialize state for loop */
46.204 - huff = 0; /* starting code */
46.205 - sym = 0; /* starting code symbol */
46.206 - len = min; /* starting code length */
46.207 - next = *table; /* current table to fill in */
46.208 - curr = root; /* current table index bits */
46.209 - drop = 0; /* current bits to drop from code for index */
46.210 - low = (unsigned)(-1); /* trigger new sub-table when len > root */
46.211 - used = 1U << root; /* use root table entries */
46.212 - mask = used - 1; /* mask for comparing low */
46.213 -
46.214 - /* check available table space */
46.215 - if (type == LENS && used >= ENOUGH - MAXD)
46.216 - return 1;
46.217 -
46.218 - /* process all codes and make table entries */
46.219 - for (;;) {
46.220 - /* create table entry */
46.221 - this.bits = (unsigned char)(len - drop);
46.222 - if ((int)(work[sym]) < end) {
46.223 - this.op = (unsigned char)0;
46.224 - this.val = work[sym];
46.225 - }
46.226 - else if ((int)(work[sym]) > end) {
46.227 - this.op = (unsigned char)(extra[work[sym]]);
46.228 - this.val = base[work[sym]];
46.229 - }
46.230 - else {
46.231 - this.op = (unsigned char)(32 + 64); /* end of block */
46.232 - this.val = 0;
46.233 - }
46.234 -
46.235 - /* replicate for those indices with low len bits equal to huff */
46.236 - incr = 1U << (len - drop);
46.237 - fill = 1U << curr;
46.238 - min = fill; /* save offset to next table */
46.239 - do {
46.240 - fill -= incr;
46.241 - next[(huff >> drop) + fill] = this;
46.242 - } while (fill != 0);
46.243 -
46.244 - /* backwards increment the len-bit code huff */
46.245 - incr = 1U << (len - 1);
46.246 - while (huff & incr)
46.247 - incr >>= 1;
46.248 - if (incr != 0) {
46.249 - huff &= incr - 1;
46.250 - huff += incr;
46.251 - }
46.252 - else
46.253 - huff = 0;
46.254 -
46.255 - /* go to next symbol, update count, len */
46.256 - sym++;
46.257 - if (--(count[len]) == 0) {
46.258 - if (len == max) break;
46.259 - len = lens[work[sym]];
46.260 - }
46.261 -
46.262 - /* create new sub-table if needed */
46.263 - if (len > root && (huff & mask) != low) {
46.264 - /* if first time, transition to sub-tables */
46.265 - if (drop == 0)
46.266 - drop = root;
46.267 -
46.268 - /* increment past last table */
46.269 - next += min; /* here min is 1 << curr */
46.270 -
46.271 - /* determine length of next table */
46.272 - curr = len - drop;
46.273 - left = (int)(1 << curr);
46.274 - while (curr + drop < max) {
46.275 - left -= count[curr + drop];
46.276 - if (left <= 0) break;
46.277 - curr++;
46.278 - left <<= 1;
46.279 - }
46.280 -
46.281 - /* check for enough space */
46.282 - used += 1U << curr;
46.283 - if (type == LENS && used >= ENOUGH - MAXD)
46.284 - return 1;
46.285 -
46.286 - /* point entry in root table to sub-table */
46.287 - low = huff & mask;
46.288 - (*table)[low].op = (unsigned char)curr;
46.289 - (*table)[low].bits = (unsigned char)root;
46.290 - (*table)[low].val = (unsigned short)(next - *table);
46.291 - }
46.292 - }
46.293 -
46.294 - /*
46.295 - Fill in rest of table for incomplete codes. This loop is similar to the
46.296 - loop above in incrementing huff for table indices. It is assumed that
46.297 - len is equal to curr + drop, so there is no loop needed to increment
46.298 - through high index bits. When the current sub-table is filled, the loop
46.299 - drops back to the root table to fill in any remaining entries there.
46.300 - */
46.301 - this.op = (unsigned char)64; /* invalid code marker */
46.302 - this.bits = (unsigned char)(len - drop);
46.303 - this.val = (unsigned short)0;
46.304 - while (huff != 0) {
46.305 - /* when done with sub-table, drop back to root table */
46.306 - if (drop != 0 && (huff & mask) != low) {
46.307 - drop = 0;
46.308 - len = root;
46.309 - next = *table;
46.310 - this.bits = (unsigned char)len;
46.311 - }
46.312 -
46.313 - /* put invalid code marker in table */
46.314 - next[huff >> drop] = this;
46.315 -
46.316 - /* backwards increment the len-bit code huff */
46.317 - incr = 1U << (len - 1);
46.318 - while (huff & incr)
46.319 - incr >>= 1;
46.320 - if (incr != 0) {
46.321 - huff &= incr - 1;
46.322 - huff += incr;
46.323 - }
46.324 - else
46.325 - huff = 0;
46.326 - }
46.327 -
46.328 - /* set return parameters */
46.329 - *table += used;
46.330 - *bits = root;
46.331 - return 0;
46.332 -}
47.1 --- a/sourcepawn/vm/zlib/inftrees.h Tue Nov 07 23:26:40 2006 +0000
47.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
47.3 @@ -1,55 +0,0 @@
47.4 -/* inftrees.h -- header to use inftrees.c
47.5 - * Copyright (C) 1995-2005 Mark Adler
47.6 - * For conditions of distribution and use, see copyright notice in zlib.h
47.7 - */
47.8 -
47.9 -/* WARNING: this file should *not* be used by applications. It is
47.10 - part of the implementation of the compression library and is
47.11 - subject to change. Applications should only use zlib.h.
47.12 - */
47.13 -
47.14 -/* Structure for decoding tables. Each entry provides either the
47.15 - information needed to do the operation requested by the code that
47.16 - indexed that table entry, or it provides a pointer to another
47.17 - table that indexes more bits of the code. op indicates whether
47.18 - the entry is a pointer to another table, a literal, a length or
47.19 - distance, an end-of-block, or an invalid code. For a table
47.20 - pointer, the low four bits of op is the number of index bits of
47.21 - that table. For a length or distance, the low four bits of op
47.22 - is the number of extra bits to get after the code. bits is
47.23 - the number of bits in this code or part of the code to drop off
47.24 - of the bit buffer. val is the actual byte to output in the case
47.25 - of a literal, the base length or distance, or the offset from
47.26 - the current table to the next table. Each entry is four bytes. */
47.27 -typedef struct {
47.28 - unsigned char op; /* operation, extra bits, table bits */
47.29 - unsigned char bits; /* bits in this part of the code */
47.30 - unsigned short val; /* offset in table or code value */
47.31 -} code;
47.32 -
47.33 -/* op values as set by inflate_table():
47.34 - 00000000 - literal
47.35 - 0000tttt - table link, tttt != 0 is the number of table index bits
47.36 - 0001eeee - length or distance, eeee is the number of extra bits
47.37 - 01100000 - end of block
47.38 - 01000000 - invalid code
47.39 - */
47.40 -
47.41 -/* Maximum size of dynamic tree. The maximum found in a long but non-
47.42 - exhaustive search was 1444 code structures (852 for length/literals
47.43 - and 592 for distances, the latter actually the result of an
47.44 - exhaustive search). The true maximum is not known, but the value
47.45 - below is more than safe. */
47.46 -#define ENOUGH 2048
47.47 -#define MAXD 592
47.48 -
47.49 -/* Type of code to build for inftable() */
47.50 -typedef enum {
47.51 - CODES,
47.52 - LENS,
47.53 - DISTS
47.54 -} codetype;
47.55 -
47.56 -extern int inflate_table OF((codetype type, unsigned short FAR *lens,
47.57 - unsigned codes, code FAR * FAR *table,
47.58 - unsigned FAR *bits, unsigned short FAR *work));
48.1 --- a/sourcepawn/vm/zlib/trees.c Tue Nov 07 23:26:40 2006 +0000
48.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
48.3 @@ -1,1219 +0,0 @@
48.4 -/* trees.c -- output deflated data using Huffman coding
48.5 - * Copyright (C) 1995-2005 Jean-loup Gailly
48.6 - * For conditions of distribution and use, see copyright notice in zlib.h
48.7 - */
48.8 -
48.9 -/*
48.10 - * ALGORITHM
48.11 - *
48.12 - * The "deflation" process uses several Huffman trees. The more
48.13 - * common source values are represented by shorter bit sequences.
48.14 - *
48.15 - * Each code tree is stored in a compressed form which is itself
48.16 - * a Huffman encoding of the lengths of all the code strings (in
48.17 - * ascending order by source values). The actual code strings are
48.18 - * reconstructed from the lengths in the inflate process, as described
48.19 - * in the deflate specification.
48.20 - *
48.21 - * REFERENCES
48.22 - *
48.23 - * Deutsch, L.P.,"'Deflate' Compressed Data Format Specification".
48.24 - * Available in ftp.uu.net:/pub/archiving/zip/doc/deflate-1.1.doc
48.25 - *
48.26 - * Storer, James A.
48.27 - * Data Compression: Methods and Theory, pp. 49-50.
48.28 - * Computer Science Press, 1988. ISBN 0-7167-8156-5.
48.29 - *
48.30 - * Sedgewick, R.
48.31 - * Algorithms, p290.
48.32 - * Addison-Wesley, 1983. ISBN 0-201-06672-6.
48.33 - */
48.34 -
48.35 -/* @(#) $Id$ */
48.36 -
48.37 -/* #define GEN_TREES_H */
48.38 -
48.39 -#include "deflate.h"
48.40 -
48.41 -#ifdef DEBUG
48.42 -# include <ctype.h>
48.43 -#endif
48.44 -
48.45 -/* ===========================================================================
48.46 - * Constants
48.47 - */
48.48 -
48.49 -#define MAX_BL_BITS 7
48.50 -/* Bit length codes must not exceed MAX_BL_BITS bits */
48.51 -
48.52 -#define END_BLOCK 256
48.53 -/* end of block literal code */
48.54 -
48.55 -#define REP_3_6 16
48.56 -/* repeat previous bit length 3-6 times (2 bits of repeat count) */
48.57 -
48.58 -#define REPZ_3_10 17
48.59 -/* repeat a zero length 3-10 times (3 bits of repeat count) */
48.60 -
48.61 -#define REPZ_11_138 18
48.62 -/* repeat a zero length 11-138 times (7 bits of repeat count) */
48.63 -
48.64 -local const int extra_lbits[LENGTH_CODES] /* extra bits for each length code */
48.65 - = {0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0};
48.66 -
48.67 -local const int extra_dbits[D_CODES] /* extra bits for each distance code */
48.68 - = {0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13};
48.69 -
48.70 -local const int extra_blbits[BL_CODES]/* extra bits for each bit length code */
48.71 - = {0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,3,7};
48.72 -
48.73 -local const uch bl_order[BL_CODES]
48.74 - = {16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15};
48.75 -/* The lengths of the bit length codes are sent in order of decreasing
48.76 - * probability, to avoid transmitting the lengths for unused bit length codes.
48.77 - */
48.78 -
48.79 -#define Buf_size (8 * 2*sizeof(char))
48.80 -/* Number of bits used within bi_buf. (bi_buf might be implemented on
48.81 - * more than 16 bits on some systems.)
48.82 - */
48.83 -
48.84 -/* ===========================================================================
48.85 - * Local data. These are initialized only once.
48.86 - */
48.87 -
48.88 -#define DIST_CODE_LEN 512 /* see definition of array dist_code below */
48.89 -
48.90 -#if defined(GEN_TREES_H) || !defined(STDC)
48.91 -/* non ANSI compilers may not accept trees.h */
48.92 -
48.93 -local ct_data static_ltree[L_CODES+2];
48.94 -/* The static literal tree. Since the bit lengths are imposed, there is no
48.95 - * need for the L_CODES extra codes used during heap construction. However
48.96 - * The codes 286 and 287 are needed to build a canonical tree (see _tr_init
48.97 - * below).
48.98 - */
48.99 -
48.100 -local ct_data static_dtree[D_CODES];
48.101 -/* The static distance tree. (Actually a trivial tree since all codes use
48.102 - * 5 bits.)
48.103 - */
48.104 -
48.105 -uch _dist_code[DIST_CODE_LEN];
48.106 -/* Distance codes. The first 256 values correspond to the distances
48.107 - * 3 .. 258, the last 256 values correspond to the top 8 bits of
48.108 - * the 15 bit distances.
48.109 - */
48.110 -
48.111 -uch _length_code[MAX_MATCH-MIN_MATCH+1];
48.112 -/* length code for each normalized match length (0 == MIN_MATCH) */
48.113 -
48.114 -local int base_length[LENGTH_CODES];
48.115 -/* First normalized length for each code (0 = MIN_MATCH) */
48.116 -
48.117 -local int base_dist[D_CODES];
48.118 -/* First normalized distance for each code (0 = distance of 1) */
48.119 -
48.120 -#else
48.121 -# include "trees.h"
48.122 -#endif /* GEN_TREES_H */
48.123 -
48.124 -struct static_tree_desc_s {
48.125 - const ct_data *static_tree; /* static tree or NULL */
48.126 - const intf *extra_bits; /* extra bits for each code or NULL */
48.127 - int extra_base; /* base index for extra_bits */
48.128 - int elems; /* max number of elements in the tree */
48.129 - int max_length; /* max bit length for the codes */
48.130 -};
48.131 -
48.132 -local static_tree_desc static_l_desc =
48.133 -{static_ltree, extra_lbits, LITERALS+1, L_CODES, MAX_BITS};
48.134 -
48.135 -local static_tree_desc static_d_desc =
48.136 -{static_dtree, extra_dbits, 0, D_CODES, MAX_BITS};
48.137 -
48.138 -local static_tree_desc static_bl_desc =
48.139 -{(const ct_data *)0, extra_blbits, 0, BL_CODES, MAX_BL_BITS};
48.140 -
48.141 -/* ===========================================================================
48.142 - * Local (static) routines in this file.
48.143 - */
48.144 -
48.145 -local void tr_static_init OF((void));
48.146 -local void init_block OF((deflate_state *s));
48.147 -local void pqdownheap OF((deflate_state *s, ct_data *tree, int k));
48.148 -local void gen_bitlen OF((deflate_state *s, tree_desc *desc));
48.149 -local void gen_codes OF((ct_data *tree, int max_code, ushf *bl_count));
48.150 -local void build_tree OF((deflate_state *s, tree_desc *desc));
48.151 -local void scan_tree OF((deflate_state *s, ct_data *tree, int max_code));
48.152 -local void send_tree OF((deflate_state *s, ct_data *tree, int max_code));
48.153 -local int build_bl_tree OF((deflate_state *s));
48.154 -local void send_all_trees OF((deflate_state *s, int lcodes, int dcodes,
48.155 - int blcodes));
48.156 -local void compress_block OF((deflate_state *s, ct_data *ltree,
48.157 - ct_data *dtree));
48.158 -local void set_data_type OF((deflate_state *s));
48.159 -local unsigned bi_reverse OF((unsigned value, int length));
48.160 -local void bi_windup OF((deflate_state *s));
48.161 -local void bi_flush OF((deflate_state *s));
48.162 -local void copy_block OF((deflate_state *s, charf *buf, unsigned len,
48.163 - int header));
48.164 -
48.165 -#ifdef GEN_TREES_H
48.166 -local void gen_trees_header OF((void));
48.167 -#endif
48.168 -
48.169 -#ifndef DEBUG
48.170 -# define send_code(s, c, tree) send_bits(s, tree[c].Code, tree[c].Len)
48.171 - /* Send a code of the given tree. c and tree must not have side effects */
48.172 -
48.173 -#else /* DEBUG */
48.174 -# define send_code(s, c, tree) \
48.175 - { if (z_verbose>2) fprintf(stderr,"\ncd %3d ",(c)); \
48.176 - send_bits(s, tree[c].Code, tree[c].Len); }
48.177 -#endif
48.178 -
48.179 -/* ===========================================================================
48.180 - * Output a short LSB first on the stream.
48.181 - * IN assertion: there is enough room in pendingBuf.
48.182 - */
48.183 -#define put_short(s, w) { \
48.184 - put_byte(s, (uch)((w) & 0xff)); \
48.185 - put_byte(s, (uch)((ush)(w) >> 8)); \
48.186 -}
48.187 -
48.188 -/* ===========================================================================
48.189 - * Send a value on a given number of bits.
48.190 - * IN assertion: length <= 16 and value fits in length bits.
48.191 - */
48.192 -#ifdef DEBUG
48.193 -local void send_bits OF((deflate_state *s, int value, int length));
48.194 -
48.195 -local void send_bits(s, value, length)
48.196 - deflate_state *s;
48.197 - int value; /* value to send */
48.198 - int length; /* number of bits */
48.199 -{
48.200 - Tracevv((stderr," l %2d v %4x ", length, value));
48.201 - Assert(length > 0 && length <= 15, "invalid length");
48.202 - s->bits_sent += (ulg)length;
48.203 -
48.204 - /* If not enough room in bi_buf, use (valid) bits from bi_buf and
48.205 - * (16 - bi_valid) bits from value, leaving (width - (16-bi_valid))
48.206 - * unused bits in value.
48.207 - */
48.208 - if (s->bi_valid > (int)Buf_size - length) {
48.209 - s->bi_buf |= (value << s->bi_valid);
48.210 - put_short(s, s->bi_buf);
48.211 - s->bi_buf = (ush)value >> (Buf_size - s->bi_valid);
48.212 - s->bi_valid += length - Buf_size;
48.213 - } else {
48.214 - s->bi_buf |= value << s->bi_valid;
48.215 - s->bi_valid += length;
48.216 - }
48.217 -}
48.218 -#else /* !DEBUG */
48.219 -
48.220 -#define send_bits(s, value, length) \
48.221 -{ int len = length;\
48.222 - if (s->bi_valid > (int)Buf_size - len) {\
48.223 - int val = value;\
48.224 - s->bi_buf |= (val << s->bi_valid);\
48.225 - put_short(s, s->bi_buf);\
48.226 - s->bi_buf = (ush)val >> (Buf_size - s->bi_valid);\
48.227 - s->bi_valid += len - Buf_size;\
48.228 - } else {\
48.229 - s->bi_buf |= (value) << s->bi_valid;\
48.230 - s->bi_valid += len;\
48.231 - }\
48.232 -}
48.233 -#endif /* DEBUG */
48.234 -
48.235 -
48.236 -/* the arguments must not have side effects */
48.237 -
48.238 -/* ===========================================================================
48.239 - * Initialize the various 'constant' tables.
48.240 - */
48.241 -local void tr_static_init()
48.242 -{
48.243 -#if defined(GEN_TREES_H) || !defined(STDC)
48.244 - static int static_init_done = 0;
48.245 - int n; /* iterates over tree elements */
48.246 - int bits; /* bit counter */
48.247 - int length; /* length value */
48.248 - int code; /* code value */
48.249 - int dist; /* distance index */
48.250 - ush bl_count[MAX_BITS+1];
48.251 - /* number of codes at each bit length for an optimal tree */
48.252 -
48.253 - if (static_init_done) return;
48.254 -
48.255 - /* For some embedded targets, global variables are not initialized: */
48.256 - static_l_desc.static_tree = static_ltree;
48.257 - static_l_desc.extra_bits = extra_lbits;
48.258 - static_d_desc.static_tree = static_dtree;
48.259 - static_d_desc.extra_bits = extra_dbits;
48.260 - static_bl_desc.extra_bits = extra_blbits;
48.261 -
48.262 - /* Initialize the mapping length (0..255) -> length code (0..28) */
48.263 - length = 0;
48.264 - for (code = 0; code < LENGTH_CODES-1; code++) {
48.265 - base_length[code] = length;
48.266 - for (n = 0; n < (1<<extra_lbits[code]); n++) {
48.267 - _length_code[length++] = (uch)code;
48.268 - }
48.269 - }
48.270 - Assert (length == 256, "tr_static_init: length != 256");
48.271 - /* Note that the length 255 (match length 258) can be represented
48.272 - * in two different ways: code 284 + 5 bits or code 285, so we
48.273 - * overwrite length_code[255] to use the best encoding:
48.274 - */
48.275 - _length_code[length-1] = (uch)code;
48.276 -
48.277 - /* Initialize the mapping dist (0..32K) -> dist code (0..29) */
48.278 - dist = 0;
48.279 - for (code = 0 ; code < 16; code++) {
48.280 - base_dist[code] = dist;
48.281 - for (n = 0; n < (1<<extra_dbits[code]); n++) {
48.282 - _dist_code[dist++] = (uch)code;
48.283 - }
48.284 - }
48.285 - Assert (dist == 256, "tr_static_init: dist != 256");
48.286 - dist >>= 7; /* from now on, all distances are divided by 128 */
48.287 - for ( ; code < D_CODES; code++) {
48.288 - base_dist[code] = dist << 7;
48.289 - for (n = 0; n < (1<<(extra_dbits[code]-7)); n++) {
48.290 - _dist_code[256 + dist++] = (uch)code;
48.291 - }
48.292 - }
48.293 - Assert (dist == 256, "tr_static_init: 256+dist != 512");
48.294 -
48.295 - /* Construct the codes of the static literal tree */
48.296 - for (bits = 0; bits <= MAX_BITS; bits++) bl_count[bits] = 0;
48.297 - n = 0;
48.298 - while (n <= 143) static_ltree[n++].Len = 8, bl_count[8]++;
48.299 - while (n <= 255) static_ltree[n++].Len = 9, bl_count[9]++;
48.300 - while (n <= 279) static_ltree[n++].Len = 7, bl_count[7]++;
48.301 - while (n <= 287) static_ltree[n++].Len = 8, bl_count[8]++;
48.302 - /* Codes 286 and 287 do not exist, but we must include them in the
48.303 - * tree construction to get a canonical Huffman tree (longest code
48.304 - * all ones)
48.305 - */
48.306 - gen_codes((ct_data *)static_ltree, L_CODES+1, bl_count);
48.307 -
48.308 - /* The static distance tree is trivial: */
48.309 - for (n = 0; n < D_CODES; n++) {
48.310 - static_dtree[n].Len = 5;
48.311 - static_dtree[n].Code = bi_reverse((unsigned)n, 5);
48.312 - }
48.313 - static_init_done = 1;
48.314 -
48.315 -# ifdef GEN_TREES_H
48.316 - gen_trees_header();
48.317 -# endif
48.318 -#endif /* defined(GEN_TREES_H) || !defined(STDC) */
48.319 -}
48.320 -
48.321 -/* ===========================================================================
48.322 - * Genererate the file trees.h describing the static trees.
48.323 - */
48.324 -#ifdef GEN_TREES_H
48.325 -# ifndef DEBUG
48.326 -# include <stdio.h>
48.327 -# endif
48.328 -
48.329 -# define SEPARATOR(i, last, width) \
48.330 - ((i) == (last)? "\n};\n\n" : \
48.331 - ((i) % (width) == (width)-1 ? ",\n" : ", "))
48.332 -
48.333 -void gen_trees_header()
48.334 -{
48.335 - FILE *header = fopen("trees.h", "w");
48.336 - int i;
48.337 -
48.338 - Assert (header != NULL, "Can't open trees.h");
48.339 - fprintf(header,
48.340 - "/* header created automatically with -DGEN_TREES_H */\n\n");
48.341 -
48.342 - fprintf(header, "local const ct_data static_ltree[L_CODES+2] = {\n");
48.343 - for (i = 0; i < L_CODES+2; i++) {
48.344 - fprintf(header, "{{%3u},{%3u}}%s", static_ltree[i].Code,
48.345 - static_ltree[i].Len, SEPARATOR(i, L_CODES+1, 5));
48.346 - }
48.347 -
48.348 - fprintf(header, "local const ct_data static_dtree[D_CODES] = {\n");
48.349 - for (i = 0; i < D_CODES; i++) {
48.350 - fprintf(header, "{{%2u},{%2u}}%s", static_dtree[i].Code,
48.351 - static_dtree[i].Len, SEPARATOR(i, D_CODES-1, 5));
48.352 - }
48.353 -
48.354 - fprintf(header, "const uch _dist_code[DIST_CODE_LEN] = {\n");
48.355 - for (i = 0; i < DIST_CODE_LEN; i++) {
48.356 - fprintf(header, "%2u%s", _dist_code[i],
48.357 - SEPARATOR(i, DIST_CODE_LEN-1, 20));
48.358 - }
48.359 -
48.360 - fprintf(header, "const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {\n");
48.361 - for (i = 0; i < MAX_MATCH-MIN_MATCH+1; i++) {
48.362 - fprintf(header, "%2u%s", _length_code[i],
48.363 - SEPARATOR(i, MAX_MATCH-MIN_MATCH, 20));
48.364 - }
48.365 -
48.366 - fprintf(header, "local const int base_length[LENGTH_CODES] = {\n");
48.367 - for (i = 0; i < LENGTH_CODES; i++) {
48.368 - fprintf(header, "%1u%s", base_length[i],
48.369 - SEPARATOR(i, LENGTH_CODES-1, 20));
48.370 - }
48.371 -
48.372 - fprintf(header, "local const int base_dist[D_CODES] = {\n");
48.373 - for (i = 0; i < D_CODES; i++) {
48.374 - fprintf(header, "%5u%s", base_dist[i],
48.375 - SEPARATOR(i, D_CODES-1, 10));
48.376 - }
48.377 -
48.378 - fclose(header);
48.379 -}
48.380 -#endif /* GEN_TREES_H */
48.381 -
48.382 -/* ===========================================================================
48.383 - * Initialize the tree data structures for a new zlib stream.
48.384 - */
48.385 -void _tr_init(s)
48.386 - deflate_state *s;
48.387 -{
48.388 - tr_static_init();
48.389 -
48.390 - s->l_desc.dyn_tree = s->dyn_ltree;
48.391 - s->l_desc.stat_desc = &static_l_desc;
48.392 -
48.393 - s->d_desc.dyn_tree = s->dyn_dtree;
48.394 - s->d_desc.stat_desc = &static_d_desc;
48.395 -
48.396 - s->bl_desc.dyn_tree = s->bl_tree;
48.397 - s->bl_desc.stat_desc = &static_bl_desc;
48.398 -
48.399 - s->bi_buf = 0;
48.400 - s->bi_valid = 0;
48.401 - s->last_eob_len = 8; /* enough lookahead for inflate */
48.402 -#ifdef DEBUG
48.403 - s->compressed_len = 0L;
48.404 - s->bits_sent = 0L;
48.405 -#endif
48.406 -
48.407 - /* Initialize the first block of the first file: */
48.408 - init_block(s);
48.409 -}
48.410 -
48.411 -/* ===========================================================================
48.412 - * Initialize a new block.
48.413 - */
48.414 -local void init_block(s)
48.415 - deflate_state *s;
48.416 -{
48.417 - int n; /* iterates over tree elements */
48.418 -
48.419 - /* Initialize the trees. */
48.420 - for (n = 0; n < L_CODES; n++) s->dyn_ltree[n].Freq = 0;
48.421 - for (n = 0; n < D_CODES; n++) s->dyn_dtree[n].Freq = 0;
48.422 - for (n = 0; n < BL_CODES; n++) s->bl_tree[n].Freq = 0;
48.423 -
48.424 - s->dyn_ltree[END_BLOCK].Freq = 1;
48.425 - s->opt_len = s->static_len = 0L;
48.426 - s->last_lit = s->matches = 0;
48.427 -}
48.428 -
48.429 -#define SMALLEST 1
48.430 -/* Index within the heap array of least frequent node in the Huffman tree */
48.431 -
48.432 -
48.433 -/* ===========================================================================
48.434 - * Remove the smallest element from the heap and recreate the heap with
48.435 - * one less element. Updates heap and heap_len.
48.436 - */
48.437 -#define pqremove(s, tree, top) \
48.438 -{\
48.439 - top = s->heap[SMALLEST]; \
48.440 - s->heap[SMALLEST] = s->heap[s->heap_len--]; \
48.441 - pqdownheap(s, tree, SMALLEST); \
48.442 -}
48.443 -
48.444 -/* ===========================================================================
48.445 - * Compares to subtrees, using the tree depth as tie breaker when
48.446 - * the subtrees have equal frequency. This minimizes the worst case length.
48.447 - */
48.448 -#define smaller(tree, n, m, depth) \
48.449 - (tree[n].Freq < tree[m].Freq || \
48.450 - (tree[n].Freq == tree[m].Freq && depth[n] <= depth[m]))
48.451 -
48.452 -/* ===========================================================================
48.453 - * Restore the heap property by moving down the tree starting at node k,
48.454 - * exchanging a node with the smallest of its two sons if necessary, stopping
48.455 - * when the heap property is re-established (each father smaller than its
48.456 - * two sons).
48.457 - */
48.458 -local void pqdownheap(s, tree, k)
48.459 - deflate_state *s;
48.460 - ct_data *tree; /* the tree to restore */
48.461 - int k; /* node to move down */
48.462 -{
48.463 - int v = s->heap[k];
48.464 - int j = k << 1; /* left son of k */
48.465 - while (j <= s->heap_len) {
48.466 - /* Set j to the smallest of the two sons: */
48.467 - if (j < s->heap_len &&
48.468 - smaller(tree, s->heap[j+1], s->heap[j], s->depth)) {
48.469 - j++;
48.470 - }
48.471 - /* Exit if v is smaller than both sons */
48.472 - if (smaller(tree, v, s->heap[j], s->depth)) break;
48.473 -
48.474 - /* Exchange v with the smallest son */
48.475 - s->heap[k] = s->heap[j]; k = j;
48.476 -
48.477 - /* And continue down the tree, setting j to the left son of k */
48.478 - j <<= 1;
48.479 - }
48.480 - s->heap[k] = v;
48.481 -}
48.482 -
48.483 -/* ===========================================================================
48.484 - * Compute the optimal bit lengths for a tree and update the total bit length
48.485 - * for the current block.
48.486 - * IN assertion: the fields freq and dad are set, heap[heap_max] and
48.487 - * above are the tree nodes sorted by increasing frequency.
48.488 - * OUT assertions: the field len is set to the optimal bit length, the
48.489 - * array bl_count contains the frequencies for each bit length.
48.490 - * The length opt_len is updated; static_len is also updated if stree is
48.491 - * not null.
48.492 - */
48.493 -local void gen_bitlen(s, desc)
48.494 - deflate_state *s;
48.495 - tree_desc *desc; /* the tree descriptor */
48.496 -{
48.497 - ct_data *tree = desc->dyn_tree;
48.498 - int max_code = desc->max_code;
48.499 - const ct_data *stree = desc->stat_desc->static_tree;
48.500 - const intf *extra = desc->stat_desc->extra_bits;
48.501 - int base = desc->stat_desc->extra_base;
48.502 - int max_length = desc->stat_desc->max_length;
48.503 - int h; /* heap index */
48.504 - int n, m; /* iterate over the tree elements */
48.505 - int bits; /* bit length */
48.506 - int xbits; /* extra bits */
48.507 - ush f; /* frequency */
48.508 - int overflow = 0; /* number of elements with bit length too large */
48.509 -
48.510 - for (bits = 0; bits <= MAX_BITS; bits++) s->bl_count[bits] = 0;
48.511 -
48.512 - /* In a first pass, compute the optimal bit lengths (which may
48.513 - * overflow in the case of the bit length tree).
48.514 - */
48.515 - tree[s->heap[s->heap_max]].Len = 0; /* root of the heap */
48.516 -
48.517 - for (h = s->heap_max+1; h < HEAP_SIZE; h++) {
48.518 - n = s->heap[h];
48.519 - bits = tree[tree[n].Dad].Len + 1;
48.520 - if (bits > max_length) bits = max_length, overflow++;
48.521 - tree[n].Len = (ush)bits;
48.522 - /* We overwrite tree[n].Dad which is no longer needed */
48.523 -
48.524 - if (n > max_code) continue; /* not a leaf node */
48.525 -
48.526 - s->bl_count[bits]++;
48.527 - xbits = 0;
48.528 - if (n >= base) xbits = extra[n-base];
48.529 - f = tree[n].Freq;
48.530 - s->opt_len += (ulg)f * (bits + xbits);
48.531 - if (stree) s->static_len += (ulg)f * (stree[n].Len + xbits);
48.532 - }
48.533 - if (overflow == 0) return;
48.534 -
48.535 - Trace((stderr,"\nbit length overflow\n"));
48.536 - /* This happens for example on obj2 and pic of the Calgary corpus */
48.537 -
48.538 - /* Find the first bit length which could increase: */
48.539 - do {
48.540 - bits = max_length-1;
48.541 - while (s->bl_count[bits] == 0) bits--;
48.542 - s->bl_count[bits]--; /* move one leaf down the tree */
48.543 - s->bl_count[bits+1] += 2; /* move one overflow item as its brother */
48.544 - s->bl_count[max_length]--;
48.545 - /* The brother of the overflow item also moves one step up,
48.546 - * but this does not affect bl_count[max_length]
48.547 - */
48.548 - overflow -= 2;
48.549 - } while (overflow > 0);
48.550 -
48.551 - /* Now recompute all bit lengths, scanning in increasing frequency.
48.552 - * h is still equal to HEAP_SIZE. (It is simpler to reconstruct all
48.553 - * lengths instead of fixing only the wrong ones. This idea is taken
48.554 - * from 'ar' written by Haruhiko Okumura.)
48.555 - */
48.556 - for (bits = max_length; bits != 0; bits--) {
48.557 - n = s->bl_count[bits];
48.558 - while (n != 0) {
48.559 - m = s->heap[--h];
48.560 - if (m > max_code) continue;
48.561 - if ((unsigned) tree[m].Len != (unsigned) bits) {
48.562 - Trace((stderr,"code %d bits %d->%d\n", m, tree[m].Len, bits));
48.563 - s->opt_len += ((long)bits - (long)tree[m].Len)
48.564 - *(long)tree[m].Freq;
48.565 - tree[m].Len = (ush)bits;
48.566 - }
48.567 - n--;
48.568 - }
48.569 - }
48.570 -}
48.571 -
48.572 -/* ===========================================================================
48.573 - * Generate the codes for a given tree and bit counts (which need not be
48.574 - * optimal).
48.575 - * IN assertion: the array bl_count contains the bit length statistics for
48.576 - * the given tree and the field len is set for all tree elements.
48.577 - * OUT assertion: the field code is set for all tree elements of non
48.578 - * zero code length.
48.579 - */
48.580 -local void gen_codes (tree, max_code, bl_count)
48.581 - ct_data *tree; /* the tree to decorate */
48.582 - int max_code; /* largest code with non zero frequency */
48.583 - ushf *bl_count; /* number of codes at each bit length */
48.584 -{
48.585 - ush next_code[MAX_BITS+1]; /* next code value for each bit length */
48.586 - ush code = 0; /* running code value */
48.587 - int bits; /* bit index */
48.588 - int n; /* code index */
48.589 -
48.590 - /* The distribution counts are first used to generate the code values
48.591 - * without bit reversal.
48.592 - */
48.593 - for (bits = 1; bits <= MAX_BITS; bits++) {
48.594 - next_code[bits] = code = (code + bl_count[bits-1]) << 1;
48.595 - }
48.596 - /* Check that the bit counts in bl_count are consistent. The last code
48.597 - * must be all ones.
48.598 - */
48.599 - Assert (code + bl_count[MAX_BITS]-1 == (1<<MAX_BITS)-1,
48.600 - "inconsistent bit counts");
48.601 - Tracev((stderr,"\ngen_codes: max_code %d ", max_code));
48.602 -
48.603 - for (n = 0; n <= max_code; n++) {
48.604 - int len = tree[n].Len;
48.605 - if (len == 0) continue;
48.606 - /* Now reverse the bits */
48.607 - tree[n].Code = bi_reverse(next_code[len]++, len);
48.608 -
48.609 - Tracecv(tree != static_ltree, (stderr,"\nn %3d %c l %2d c %4x (%x) ",
48.610 - n, (isgraph(n) ? n : ' '), len, tree[n].Code, next_code[len]-1));
48.611 - }
48.612 -}
48.613 -
48.614 -/* ===========================================================================
48.615 - * Construct one Huffman tree and assigns the code bit strings and lengths.
48.616 - * Update the total bit length for the current block.
48.617 - * IN assertion: the field freq is set for all tree elements.
48.618 - * OUT assertions: the fields len and code are set to the optimal bit length
48.619 - * and corresponding code. The length opt_len is updated; static_len is
48.620 - * also updated if stree is not null. The field max_code is set.
48.621 - */
48.622 -local void build_tree(s, desc)
48.623 - deflate_state *s;
48.624 - tree_desc *desc; /* the tree descriptor */
48.625 -{
48.626 - ct_data *tree = desc->dyn_tree;
48.627 - const ct_data *stree = desc->stat_desc->static_tree;
48.628 - int elems = desc->stat_desc->elems;
48.629 - int n, m; /* iterate over heap elements */
48.630 - int max_code = -1; /* largest code with non zero frequency */
48.631 - int node; /* new node being created */
48.632 -
48.633 - /* Construct the initial heap, with least frequent element in
48.634 - * heap[SMALLEST]. The sons of heap[n] are heap[2*n] and heap[2*n+1].
48.635 - * heap[0] is not used.
48.636 - */
48.637 - s->heap_len = 0, s->heap_max = HEAP_SIZE;
48.638 -
48.639 - for (n = 0; n < elems; n++) {
48.640 - if (tree[n].Freq != 0) {
48.641 - s->heap[++(s->heap_len)] = max_code = n;
48.642 - s->depth[n] = 0;
48.643 - } else {
48.644 - tree[n].Len = 0;
48.645 - }
48.646 - }
48.647 -
48.648 - /* The pkzip format requires that at least one distance code exists,
48.649 - * and that at least one bit should be sent even if there is only one
48.650 - * possible code. So to avoid special checks later on we force at least
48.651 - * two codes of non zero frequency.
48.652 - */
48.653 - while (s->heap_len < 2) {
48.654 - node = s->heap[++(s->heap_len)] = (max_code < 2 ? ++max_code : 0);
48.655 - tree[node].Freq = 1;
48.656 - s->depth[node] = 0;
48.657 - s->opt_len--; if (stree) s->static_len -= stree[node].Len;
48.658 - /* node is 0 or 1 so it does not have extra bits */
48.659 - }
48.660 - desc->max_code = max_code;
48.661 -
48.662 - /* The elements heap[heap_len/2+1 .. heap_len] are leaves of the tree,
48.663 - * establish sub-heaps of increasing lengths:
48.664 - */
48.665 - for (n = s->heap_len/2; n >= 1; n--) pqdownheap(s, tree, n);
48.666 -
48.667 - /* Construct the Huffman tree by repeatedly combining the least two
48.668 - * frequent nodes.
48.669 - */
48.670 - node = elems; /* next internal node of the tree */
48.671 - do {
48.672 - pqremove(s, tree, n); /* n = node of least frequency */
48.673 - m = s->heap[SMALLEST]; /* m = node of next least frequency */
48.674 -
48.675 - s->heap[--(s->heap_max)] = n; /* keep the nodes sorted by frequency */
48.676 - s->heap[--(s->heap_max)] = m;
48.677 -
48.678 - /* Create a new node father of n and m */
48.679 - tree[node].Freq = tree[n].Freq + tree[m].Freq;
48.680 - s->depth[node] = (uch)((s->depth[n] >= s->depth[m] ?
48.681 - s->depth[n] : s->depth[m]) + 1);
48.682 - tree[n].Dad = tree[m].Dad = (ush)node;
48.683 -#ifdef DUMP_BL_TREE
48.684 - if (tree == s->bl_tree) {
48.685 - fprintf(stderr,"\nnode %d(%d), sons %d(%d) %d(%d)",
48.686 - node, tree[node].Freq, n, tree[n].Freq, m, tree[m].Freq);
48.687 - }
48.688 -#endif
48.689 - /* and insert the new node in the heap */
48.690 - s->heap[SMALLEST] = node++;
48.691 - pqdownheap(s, tree, SMALLEST);
48.692 -
48.693 - } while (s->heap_len >= 2);
48.694 -
48.695 - s->heap[--(s->heap_max)] = s->heap[SMALLEST];
48.696 -
48.697 - /* At this point, the fields freq and dad are set. We can now
48.698 - * generate the bit lengths.
48.699 - */
48.700 - gen_bitlen(s, (tree_desc *)desc);
48.701 -
48.702 - /* The field len is now set, we can generate the bit codes */
48.703 - gen_codes ((ct_data *)tree, max_code, s->bl_count);
48.704 -}
48.705 -
48.706 -/* ===========================================================================
48.707 - * Scan a literal or distance tree to determine the frequencies of the codes
48.708 - * in the bit length tree.
48.709 - */
48.710 -local void scan_tree (s, tree, max_code)
48.711 - deflate_state *s;
48.712 - ct_data *tree; /* the tree to be scanned */
48.713 - int max_code; /* and its largest code of non zero frequency */
48.714 -{
48.715 - int n; /* iterates over all tree elements */
48.716 - int prevlen = -1; /* last emitted length */
48.717 - int curlen; /* length of current code */
48.718 - int nextlen = tree[0].Len; /* length of next code */
48.719 - int count = 0; /* repeat count of the current code */
48.720 - int max_count = 7; /* max repeat count */
48.721 - int min_count = 4; /* min repeat count */
48.722 -
48.723 - if (nextlen == 0) max_count = 138, min_count = 3;
48.724 - tree[max_code+1].Len = (ush)0xffff; /* guard */
48.725 -
48.726 - for (n = 0; n <= max_code; n++) {
48.727 - curlen = nextlen; nextlen = tree[n+1].Len;
48.728 - if (++count < max_count && curlen == nextlen) {
48.729 - continue;
48.730 - } else if (count < min_count) {
48.731 - s->bl_tree[curlen].Freq += count;
48.732 - } else if (curlen != 0) {
48.733 - if (curlen != prevlen) s->bl_tree[curlen].Freq++;
48.734 - s->bl_tree[REP_3_6].Freq++;
48.735 - } else if (count <= 10) {
48.736 - s->bl_tree[REPZ_3_10].Freq++;
48.737 - } else {
48.738 - s->bl_tree[REPZ_11_138].Freq++;
48.739 - }
48.740 - count = 0; prevlen = curlen;
48.741 - if (nextlen == 0) {
48.742 - max_count = 138, min_count = 3;
48.743 - } else if (curlen == nextlen) {
48.744 - max_count = 6, min_count = 3;
48.745 - } else {
48.746 - max_count = 7, min_count = 4;
48.747 - }
48.748 - }
48.749 -}
48.750 -
48.751 -/* ===========================================================================
48.752 - * Send a literal or distance tree in compressed form, using the codes in
48.753 - * bl_tree.
48.754 - */
48.755 -local void send_tree (s, tree, max_code)
48.756 - deflate_state *s;
48.757 - ct_data *tree; /* the tree to be scanned */
48.758 - int max_code; /* and its largest code of non zero frequency */
48.759 -{
48.760 - int n; /* iterates over all tree elements */
48.761 - int prevlen = -1; /* last emitted length */
48.762 - int curlen; /* length of current code */
48.763 - int nextlen = tree[0].Len; /* length of next code */
48.764 - int count = 0; /* repeat count of the current code */
48.765 - int max_count = 7; /* max repeat count */
48.766 - int min_count = 4; /* min repeat count */
48.767 -
48.768 - /* tree[max_code+1].Len = -1; */ /* guard already set */
48.769 - if (nextlen == 0) max_count = 138, min_count = 3;
48.770 -
48.771 - for (n = 0; n <= max_code; n++) {
48.772 - curlen = nextlen; nextlen = tree[n+1].Len;
48.773 - if (++count < max_count && curlen == nextlen) {
48.774 - continue;
48.775 - } else if (count < min_count) {
48.776 - do { send_code(s, curlen, s->bl_tree); } while (--count != 0);
48.777 -
48.778 - } else if (curlen != 0) {
48.779 - if (curlen != prevlen) {
48.780 - send_code(s, curlen, s->bl_tree); count--;
48.781 - }
48.782 - Assert(count >= 3 && count <= 6, " 3_6?");
48.783 - send_code(s, REP_3_6, s->bl_tree); send_bits(s, count-3, 2);
48.784 -
48.785 - } else if (count <= 10) {
48.786 - send_code(s, REPZ_3_10, s->bl_tree); send_bits(s, count-3, 3);
48.787 -
48.788 - } else {
48.789 - send_code(s, REPZ_11_138, s->bl_tree); send_bits(s, count-11, 7);
48.790 - }
48.791 - count = 0; prevlen = curlen;
48.792 - if (nextlen == 0) {
48.793 - max_count = 138, min_count = 3;
48.794 - } else if (curlen == nextlen) {
48.795 - max_count = 6, min_count = 3;
48.796 - } else {
48.797 - max_count = 7, min_count = 4;
48.798 - }
48.799 - }
48.800 -}
48.801 -
48.802 -/* ===========================================================================
48.803 - * Construct the Huffman tree for the bit lengths and return the index in
48.804 - * bl_order of the last bit length code to send.
48.805 - */
48.806 -local int build_bl_tree(s)
48.807 - deflate_state *s;
48.808 -{
48.809 - int max_blindex; /* index of last bit length code of non zero freq */
48.810 -
48.811 - /* Determine the bit length frequencies for literal and distance trees */
48.812 - scan_tree(s, (ct_data *)s->dyn_ltree, s->l_desc.max_code);
48.813 - scan_tree(s, (ct_data *)s->dyn_dtree, s->d_desc.max_code);
48.814 -
48.815 - /* Build the bit length tree: */
48.816 - build_tree(s, (tree_desc *)(&(s->bl_desc)));
48.817 - /* opt_len now includes the length of the tree representations, except
48.818 - * the lengths of the bit lengths codes and the 5+5+4 bits for the counts.
48.819 - */
48.820 -
48.821 - /* Determine the number of bit length codes to send. The pkzip format
48.822 - * requires that at least 4 bit length codes be sent. (appnote.txt says
48.823 - * 3 but the actual value used is 4.)
48.824 - */
48.825 - for (max_blindex = BL_CODES-1; max_blindex >= 3; max_blindex--) {
48.826 - if (s->bl_tree[bl_order[max_blindex]].Len != 0) break;
48.827 - }
48.828 - /* Update opt_len to include the bit length tree and counts */
48.829 - s->opt_len += 3*(max_blindex+1) + 5+5+4;
48.830 - Tracev((stderr, "\ndyn trees: dyn %ld, stat %ld",
48.831 - s->opt_len, s->static_len));
48.832 -
48.833 - return max_blindex;
48.834 -}
48.835 -
48.836 -/* ===========================================================================
48.837 - * Send the header for a block using dynamic Huffman trees: the counts, the
48.838 - * lengths of the bit length codes, the literal tree and the distance tree.
48.839 - * IN assertion: lcodes >= 257, dcodes >= 1, blcodes >= 4.
48.840 - */
48.841 -local void send_all_trees(s, lcodes, dcodes, blcodes)
48.842 - deflate_state *s;
48.843 - int lcodes, dcodes, blcodes; /* number of codes for each tree */
48.844 -{
48.845 - int rank; /* index in bl_order */
48.846 -
48.847 - Assert (lcodes >= 257 && dcodes >= 1 && blcodes >= 4, "not enough codes");
48.848 - Assert (lcodes <= L_CODES && dcodes <= D_CODES && blcodes <= BL_CODES,
48.849 - "too many codes");
48.850 - Tracev((stderr, "\nbl counts: "));
48.851 - send_bits(s, lcodes-257, 5); /* not +255 as stated in appnote.txt */
48.852 - send_bits(s, dcodes-1, 5);
48.853 - send_bits(s, blcodes-4, 4); /* not -3 as stated in appnote.txt */
48.854 - for (rank = 0; rank < blcodes; rank++) {
48.855 - Tracev((stderr, "\nbl code %2d ", bl_order[rank]));
48.856 - send_bits(s, s->bl_tree[bl_order[rank]].Len, 3);
48.857 - }
48.858 - Tracev((stderr, "\nbl tree: sent %ld", s->bits_sent));
48.859 -
48.860 - send_tree(s, (ct_data *)s->dyn_ltree, lcodes-1); /* literal tree */
48.861 - Tracev((stderr, "\nlit tree: sent %ld", s->bits_sent));
48.862 -
48.863 - send_tree(s, (ct_data *)s->dyn_dtree, dcodes-1); /* distance tree */
48.864 - Tracev((stderr, "\ndist tree: sent %ld", s->bits_sent));
48.865 -}
48.866 -
48.867 -/* ===========================================================================
48.868 - * Send a stored block
48.869 - */
48.870 -void _tr_stored_block(s, buf, stored_len, eof)
48.871 - deflate_state *s;
48.872 - charf *buf; /* input block */
48.873 - ulg stored_len; /* length of input block */
48.874 - int eof; /* true if this is the last block for a file */
48.875 -{
48.876 - send_bits(s, (STORED_BLOCK<<1)+eof, 3); /* send block type */
48.877 -#ifdef DEBUG
48.878 - s->compressed_len = (s->compressed_len + 3 + 7) & (ulg)~7L;
48.879 - s->compressed_len += (stored_len + 4) << 3;
48.880 -#endif
48.881 - copy_block(s, buf, (unsigned)stored_len, 1); /* with header */
48.882 -}
48.883 -
48.884 -/* ===========================================================================
48.885 - * Send one empty static block to give enough lookahead for inflate.
48.886 - * This takes 10 bits, of which 7 may remain in the bit buffer.
48.887 - * The current inflate code requires 9 bits of lookahead. If the
48.888 - * last two codes for the previous block (real code plus EOB) were coded
48.889 - * on 5 bits or less, inflate may have only 5+3 bits of lookahead to decode
48.890 - * the last real code. In this case we send two empty static blocks instead
48.891 - * of one. (There are no problems if the previous block is stored or fixed.)
48.892 - * To simplify the code, we assume the worst case of last real code encoded
48.893 - * on one bit only.
48.894 - */
48.895 -void _tr_align(s)
48.896 - deflate_state *s;
48.897 -{
48.898 - send_bits(s, STATIC_TREES<<1, 3);
48.899 - send_code(s, END_BLOCK, static_ltree);
48.900 -#ifdef DEBUG
48.901 - s->compressed_len += 10L; /* 3 for block type, 7 for EOB */
48.902 -#endif
48.903 - bi_flush(s);
48.904 - /* Of the 10 bits for the empty block, we have already sent
48.905 - * (10 - bi_valid) bits. The lookahead for the last real code (before
48.906 - * the EOB of the previous block) was thus at least one plus the length
48.907 - * of the EOB plus what we have just sent of the empty static block.
48.908 - */
48.909 - if (1 + s->last_eob_len + 10 - s->bi_valid < 9) {
48.910 - send_bits(s, STATIC_TREES<<1, 3);
48.911 - send_code(s, END_BLOCK, static_ltree);
48.912 -#ifdef DEBUG
48.913 - s->compressed_len += 10L;
48.914 -#endif
48.915 - bi_flush(s);
48.916 - }
48.917 - s->last_eob_len = 7;
48.918 -}
48.919 -
48.920 -/* ===========================================================================
48.921 - * Determine the best encoding for the current block: dynamic trees, static
48.922 - * trees or store, and output the encoded block to the zip file.
48.923 - */
48.924 -void _tr_flush_block(s, buf, stored_len, eof)
48.925 - deflate_state *s;
48.926 - charf *buf; /* input block, or NULL if too old */
48.927 - ulg stored_len; /* length of input block */
48.928 - int eof; /* true if this is the last block for a file */
48.929 -{
48.930 - ulg opt_lenb, static_lenb; /* opt_len and static_len in bytes */
48.931 - int max_blindex = 0; /* index of last bit length code of non zero freq */
48.932 -
48.933 - /* Build the Huffman trees unless a stored block is forced */
48.934 - if (s->level > 0) {
48.935 -
48.936 - /* Check if the file is binary or text */
48.937 - if (stored_len > 0 && s->strm->data_type == Z_UNKNOWN)
48.938 - set_data_type(s);
48.939 -
48.940 - /* Construct the literal and distance trees */
48.941 - build_tree(s, (tree_desc *)(&(s->l_desc)));
48.942 - Tracev((stderr, "\nlit data: dyn %ld, stat %ld", s->opt_len,
48.943 - s->static_len));
48.944 -
48.945 - build_tree(s, (tree_desc *)(&(s->d_desc)));
48.946 - Tracev((stderr, "\ndist data: dyn %ld, stat %ld", s->opt_len,
48.947 - s->static_len));
48.948 - /* At this point, opt_len and static_len are the total bit lengths of
48.949 - * the compressed block data, excluding the tree representations.
48.950 - */
48.951 -
48.952 - /* Build the bit length tree for the above two trees, and get the index
48.953 - * in bl_order of the last bit length code to send.
48.954 - */
48.955 - max_blindex = build_bl_tree(s);
48.956 -
48.957 - /* Determine the best encoding. Compute the block lengths in bytes. */
48.958 - opt_lenb = (s->opt_len+3+7)>>3;
48.959 - static_lenb = (s->static_len+3+7)>>3;
48.960 -
48.961 - Tracev((stderr, "\nopt %lu(%lu) stat %lu(%lu) stored %lu lit %u ",
48.962 - opt_lenb, s->opt_len, static_lenb, s->static_len, stored_len,
48.963 - s->last_lit));
48.964 -
48.965 - if (static_lenb <= opt_lenb) opt_lenb = static_lenb;
48.966 -
48.967 - } else {
48.968 - Assert(buf != (char*)0, "lost buf");
48.969 - opt_lenb = static_lenb = stored_len + 5; /* force a stored block */
48.970 - }
48.971 -
48.972 -#ifdef FORCE_STORED
48.973 - if (buf != (char*)0) { /* force stored block */
48.974 -#else
48.975 - if (stored_len+4 <= opt_lenb && buf != (char*)0) {
48.976 - /* 4: two words for the lengths */
48.977 -#endif
48.978 - /* The test buf != NULL is only necessary if LIT_BUFSIZE > WSIZE.
48.979 - * Otherwise we can't have processed more than WSIZE input bytes since
48.980 - * the last block flush, because compression would have been
48.981 - * successful. If LIT_BUFSIZE <= WSIZE, it is never too late to
48.982 - * transform a block into a stored block.
48.983 - */
48.984 - _tr_stored_block(s, buf, stored_len, eof);
48.985 -
48.986 -#ifdef FORCE_STATIC
48.987 - } else if (static_lenb >= 0) { /* force static trees */
48.988 -#else
48.989 - } else if (s->strategy == Z_FIXED || static_lenb == opt_lenb) {
48.990 -#endif
48.991 - send_bits(s, (STATIC_TREES<<1)+eof, 3);
48.992 - compress_block(s, (ct_data *)static_ltree, (ct_data *)static_dtree);
48.993 -#ifdef DEBUG
48.994 - s->compressed_len += 3 + s->static_len;
48.995 -#endif
48.996 - } else {
48.997 - send_bits(s, (DYN_TREES<<1)+eof, 3);
48.998 - send_all_trees(s, s->l_desc.max_code+1, s->d_desc.max_code+1,
48.999 - max_blindex+1);
48.1000 - compress_block(s, (ct_data *)s->dyn_ltree, (ct_data *)s->dyn_dtree);
48.1001 -#ifdef DEBUG
48.1002 - s->compressed_len += 3 + s->opt_len;
48.1003 -#endif
48.1004 - }
48.1005 - Assert (s->compressed_len == s->bits_sent, "bad compressed size");
48.1006 - /* The above check is made mod 2^32, for files larger than 512 MB
48.1007 - * and uLong implemented on 32 bits.
48.1008 - */
48.1009 - init_block(s);
48.1010 -
48.1011 - if (eof) {
48.1012 - bi_windup(s);
48.1013 -#ifdef DEBUG
48.1014 - s->compressed_len += 7; /* align on byte boundary */
48.1015 -#endif
48.1016 - }
48.1017 - Tracev((stderr,"\ncomprlen %lu(%lu) ", s->compressed_len>>3,
48.1018 - s->compressed_len-7*eof));
48.1019 -}
48.1020 -
48.1021 -/* ===========================================================================
48.1022 - * Save the match info and tally the frequency counts. Return true if
48.1023 - * the current block must be flushed.
48.1024 - */
48.1025 -int _tr_tally (s, dist, lc)
48.1026 - deflate_state *s;
48.1027 - unsigned dist; /* distance of matched string */
48.1028 - unsigned lc; /* match length-MIN_MATCH or unmatched char (if dist==0) */
48.1029 -{
48.1030 - s->d_buf[s->last_lit] = (ush)dist;
48.1031 - s->l_buf[s->last_lit++] = (uch)lc;
48.1032 - if (dist == 0) {
48.1033 - /* lc is the unmatched char */
48.1034 - s->dyn_ltree[lc].Freq++;
48.1035 - } else {
48.1036 - s->matches++;
48.1037 - /* Here, lc is the match length - MIN_MATCH */
48.1038 - dist--; /* dist = match distance - 1 */
48.1039 - Assert((ush)dist < (ush)MAX_DIST(s) &&
48.1040 - (ush)lc <= (ush)(MAX_MATCH-MIN_MATCH) &&
48.1041 - (ush)d_code(dist) < (ush)D_CODES, "_tr_tally: bad match");
48.1042 -
48.1043 - s->dyn_ltree[_length_code[lc]+LITERALS+1].Freq++;
48.1044 - s->dyn_dtree[d_code(dist)].Freq++;
48.1045 - }
48.1046 -
48.1047 -#ifdef TRUNCATE_BLOCK
48.1048 - /* Try to guess if it is profitable to stop the current block here */
48.1049 - if ((s->last_lit & 0x1fff) == 0 && s->level > 2) {
48.1050 - /* Compute an upper bound for the compressed length */
48.1051 - ulg out_length = (ulg)s->last_lit*8L;
48.1052 - ulg in_length = (ulg)((long)s->strstart - s->block_start);
48.1053 - int dcode;
48.1054 - for (dcode = 0; dcode < D_CODES; dcode++) {
48.1055 - out_length += (ulg)s->dyn_dtree[dcode].Freq *
48.1056 - (5L+extra_dbits[dcode]);
48.1057 - }
48.1058 - out_length >>= 3;
48.1059 - Tracev((stderr,"\nlast_lit %u, in %ld, out ~%ld(%ld%%) ",
48.1060 - s->last_lit, in_length, out_length,
48.1061 - 100L - out_length*100L/in_length));
48.1062 - if (s->matches < s->last_lit/2 && out_length < in_length/2) return 1;
48.1063 - }
48.1064 -#endif
48.1065 - return (s->last_lit == s->lit_bufsize-1);
48.1066 - /* We avoid equality with lit_bufsize because of wraparound at 64K
48.1067 - * on 16 bit machines and because stored blocks are restricted to
48.1068 - * 64K-1 bytes.
48.1069 - */
48.1070 -}
48.1071 -
48.1072 -/* ===========================================================================
48.1073 - * Send the block data compressed using the given Huffman trees
48.1074 - */
48.1075 -local void compress_block(s, ltree, dtree)
48.1076 - deflate_state *s;
48.1077 - ct_data *ltree; /* literal tree */
48.1078 - ct_data *dtree; /* distance tree */
48.1079 -{
48.1080 - unsigned dist; /* distance of matched string */
48.1081 - int lc; /* match length or unmatched char (if dist == 0) */
48.1082 - unsigned lx = 0; /* running index in l_buf */
48.1083 - unsigned code; /* the code to send */
48.1084 - int extra; /* number of extra bits to send */
48.1085 -
48.1086 - if (s->last_lit != 0) do {
48.1087 - dist = s->d_buf[lx];
48.1088 - lc = s->l_buf[lx++];
48.1089 - if (dist == 0) {
48.1090 - send_code(s, lc, ltree); /* send a literal byte */
48.1091 - Tracecv(isgraph(lc), (stderr," '%c' ", lc));
48.1092 - } else {
48.1093 - /* Here, lc is the match length - MIN_MATCH */
48.1094 - code = _length_code[lc];
48.1095 - send_code(s, code+LITERALS+1, ltree); /* send the length code */
48.1096 - extra = extra_lbits[code];
48.1097 - if (extra != 0) {
48.1098 - lc -= base_length[code];
48.1099 - send_bits(s, lc, extra); /* send the extra length bits */
48.1100 - }
48.1101 - dist--; /* dist is now the match distance - 1 */
48.1102 - code = d_code(dist);
48.1103 - Assert (code < D_CODES, "bad d_code");
48.1104 -
48.1105 - send_code(s, code, dtree); /* send the distance code */
48.1106 - extra = extra_dbits[code];
48.1107 - if (extra != 0) {
48.1108 - dist -= base_dist[code];
48.1109 - send_bits(s, dist, extra); /* send the extra distance bits */
48.1110 - }
48.1111 - } /* literal or match pair ? */
48.1112 -
48.1113 - /* Check that the overlay between pending_buf and d_buf+l_buf is ok: */
48.1114 - Assert((uInt)(s->pending) < s->lit_bufsize + 2*lx,
48.1115 - "pendingBuf overflow");
48.1116 -
48.1117 - } while (lx < s->last_lit);
48.1118 -
48.1119 - send_code(s, END_BLOCK, ltree);
48.1120 - s->last_eob_len = ltree[END_BLOCK].Len;
48.1121 -}
48.1122 -
48.1123 -/* ===========================================================================
48.1124 - * Set the data type to BINARY or TEXT, using a crude approximation:
48.1125 - * set it to Z_TEXT if all symbols are either printable characters (33 to 255)
48.1126 - * or white spaces (9 to 13, or 32); or set it to Z_BINARY otherwise.
48.1127 - * IN assertion: the fields Freq of dyn_ltree are set.
48.1128 - */
48.1129 -local void set_data_type(s)
48.1130 - deflate_state *s;
48.1131 -{
48.1132 - int n;
48.1133 -
48.1134 - for (n = 0; n < 9; n++)
48.1135 - if (s->dyn_ltree[n].Freq != 0)
48.1136 - break;
48.1137 - if (n == 9)
48.1138 - for (n = 14; n < 32; n++)
48.1139 - if (s->dyn_ltree[n].Freq != 0)
48.1140 - break;
48.1141 - s->strm->data_type = (n == 32) ? Z_TEXT : Z_BINARY;
48.1142 -}
48.1143 -
48.1144 -/* ===========================================================================
48.1145 - * Reverse the first len bits of a code, using straightforward code (a faster
48.1146 - * method would use a table)
48.1147 - * IN assertion: 1 <= len <= 15
48.1148 - */
48.1149 -local unsigned bi_reverse(code, len)
48.1150 - unsigned code; /* the value to invert */
48.1151 - int len; /* its bit length */
48.1152 -{
48.1153 - register unsigned res = 0;
48.1154 - do {
48.1155 - res |= code & 1;
48.1156 - code >>= 1, res <<= 1;
48.1157 - } while (--len > 0);
48.1158 - return res >> 1;
48.1159 -}
48.1160 -
48.1161 -/* ===========================================================================
48.1162 - * Flush the bit buffer, keeping at most 7 bits in it.
48.1163 - */
48.1164 -local void bi_flush(s)
48.1165 - deflate_state *s;
48.1166 -{
48.1167 - if (s->bi_valid == 16) {
48.1168 - put_short(s, s->bi_buf);
48.1169 - s->bi_buf = 0;
48.1170 - s->bi_valid = 0;
48.1171 - } else if (s->bi_valid >= 8) {
48.1172 - put_byte(s, (Byte)s->bi_buf);
48.1173 - s->bi_buf >>= 8;
48.1174 - s->bi_valid -= 8;
48.1175 - }
48.1176 -}
48.1177 -
48.1178 -/* ===========================================================================
48.1179 - * Flush the bit buffer and align the output on a byte boundary
48.1180 - */
48.1181 -local void bi_windup(s)
48.1182 - deflate_state *s;
48.1183 -{
48.1184 - if (s->bi_valid > 8) {
48.1185 - put_short(s, s->bi_buf);
48.1186 - } else if (s->bi_valid > 0) {
48.1187 - put_byte(s, (Byte)s->bi_buf);
48.1188 - }
48.1189 - s->bi_buf = 0;
48.1190 - s->bi_valid = 0;
48.1191 -#ifdef DEBUG
48.1192 - s->bits_sent = (s->bits_sent+7) & ~7;
48.1193 -#endif
48.1194 -}
48.1195 -
48.1196 -/* ===========================================================================
48.1197 - * Copy a stored block, storing first the length and its
48.1198 - * one's complement if requested.
48.1199 - */
48.1200 -local void copy_block(s, buf, len, header)
48.1201 - deflate_state *s;
48.1202 - charf *buf; /* the input data */
48.1203 - unsigned len; /* its length */
48.1204 - int header; /* true if block header must be written */
48.1205 -{
48.1206 - bi_windup(s); /* align on byte boundary */
48.1207 - s->last_eob_len = 8; /* enough lookahead for inflate */
48.1208 -
48.1209 - if (header) {
48.1210 - put_short(s, (ush)len);
48.1211 - put_short(s, (ush)~len);
48.1212 -#ifdef DEBUG
48.1213 - s->bits_sent += 2*16;
48.1214 -#endif
48.1215 - }
48.1216 -#ifdef DEBUG
48.1217 - s->bits_sent += (ulg)len<<3;
48.1218 -#endif
48.1219 - while (len--) {
48.1220 - put_byte(s, *buf++);
48.1221 - }
48.1222 -}
49.1 --- a/sourcepawn/vm/zlib/trees.h Tue Nov 07 23:26:40 2006 +0000
49.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
49.3 @@ -1,128 +0,0 @@
49.4 -/* header created automatically with -DGEN_TREES_H */
49.5 -
49.6 -local const ct_data static_ltree[L_CODES+2] = {
49.7 -{{ 12},{ 8}}, {{140},{ 8}}, {{ 76},{ 8}}, {{204},{ 8}}, {{ 44},{ 8}},
49.8 -{{172},{ 8}}, {{108},{ 8}}, {{236},{ 8}}, {{ 28},{ 8}}, {{156},{ 8}},
49.9 -{{ 92},{ 8}}, {{220},{ 8}}, {{ 60},{ 8}}, {{188},{ 8}}, {{124},{ 8}},
49.10 -{{252},{ 8}}, {{ 2},{ 8}}, {{130},{ 8}}, {{ 66},{ 8}}, {{194},{ 8}},
49.11 -{{ 34},{ 8}}, {{162},{ 8}}, {{ 98},{ 8}}, {{226},{ 8}}, {{ 18},{ 8}},
49.12 -{{146},{ 8}}, {{ 82},{ 8}}, {{210},{ 8}}, {{ 50},{ 8}}, {{178},{ 8}},
49.13 -{{114},{ 8}}, {{242},{ 8}}, {{ 10},{ 8}}, {{138},{ 8}}, {{ 74},{ 8}},
49.14 -{{202},{ 8}}, {{ 42},{ 8}}, {{170},{ 8}}, {{106},{ 8}}, {{234},{ 8}},
49.15 -{{ 26},{ 8}}, {{154},{ 8}}, {{ 90},{ 8}}, {{218},{ 8}}, {{ 58},{ 8}},
49.16 -{{186},{ 8}}, {{122},{ 8}}, {{250},{ 8}}, {{ 6},{ 8}}, {{134},{ 8}},
49.17 -{{ 70},{ 8}}, {{198},{ 8}}, {{ 38},{ 8}}, {{166},{ 8}}, {{102},{ 8}},
49.18 -{{230},{ 8}}, {{ 22},{ 8}}, {{150},{ 8}}, {{ 86},{ 8}}, {{214},{ 8}},
49.19 -{{ 54},{ 8}}, {{182},{ 8}}, {{118},{ 8}}, {{246},{ 8}}, {{ 14},{ 8}},
49.20 -{{142},{ 8}}, {{ 78},{ 8}}, {{206},{ 8}}, {{ 46},{ 8}}, {{174},{ 8}},
49.21 -{{110},{ 8}}, {{238},{ 8}}, {{ 30},{ 8}}, {{158},{ 8}}, {{ 94},{ 8}},
49.22 -{{222},{ 8}}, {{ 62},{ 8}}, {{190},{ 8}}, {{126},{ 8}}, {{254},{ 8}},
49.23 -{{ 1},{ 8}}, {{129},{ 8}}, {{ 65},{ 8}}, {{193},{ 8}}, {{ 33},{ 8}},
49.24 -{{161},{ 8}}, {{ 97},{ 8}}, {{225},{ 8}}, {{ 17},{ 8}}, {{145},{ 8}},
49.25 -{{ 81},{ 8}}, {{209},{ 8}}, {{ 49},{ 8}}, {{177},{ 8}}, {{113},{ 8}},
49.26 -{{241},{ 8}}, {{ 9},{ 8}}, {{137},{ 8}}, {{ 73},{ 8}}, {{201},{ 8}},
49.27 -{{ 41},{ 8}}, {{169},{ 8}}, {{105},{ 8}}, {{233},{ 8}}, {{ 25},{ 8}},
49.28 -{{153},{ 8}}, {{ 89},{ 8}}, {{217},{ 8}}, {{ 57},{ 8}}, {{185},{ 8}},
49.29 -{{121},{ 8}}, {{249},{ 8}}, {{ 5},{ 8}}, {{133},{ 8}}, {{ 69},{ 8}},
49.30 -{{197},{ 8}}, {{ 37},{ 8}}, {{165},{ 8}}, {{101},{ 8}}, {{229},{ 8}},
49.31 -{{ 21},{ 8}}, {{149},{ 8}}, {{ 85},{ 8}}, {{213},{ 8}}, {{ 53},{ 8}},
49.32 -{{181},{ 8}}, {{117},{ 8}}, {{245},{ 8}}, {{ 13},{ 8}}, {{141},{ 8}},
49.33 -{{ 77},{ 8}}, {{205},{ 8}}, {{ 45},{ 8}}, {{173},{ 8}}, {{109},{ 8}},
49.34 -{{237},{ 8}}, {{ 29},{ 8}}, {{157},{ 8}}, {{ 93},{ 8}}, {{221},{ 8}},
49.35 -{{ 61},{ 8}}, {{189},{ 8}}, {{125},{ 8}}, {{253},{ 8}}, {{ 19},{ 9}},
49.36 -{{275},{ 9}}, {{147},{ 9}}, {{403},{ 9}}, {{ 83},{ 9}}, {{339},{ 9}},
49.37 -{{211},{ 9}}, {{467},{ 9}}, {{ 51},{ 9}}, {{307},{ 9}}, {{179},{ 9}},
49.38 -{{435},{ 9}}, {{115},{ 9}}, {{371},{ 9}}, {{243},{ 9}}, {{499},{ 9}},
49.39 -{{ 11},{ 9}}, {{267},{ 9}}, {{139},{ 9}}, {{395},{ 9}}, {{ 75},{ 9}},
49.40 -{{331},{ 9}}, {{203},{ 9}}, {{459},{ 9}}, {{ 43},{ 9}}, {{299},{ 9}},
49.41 -{{171},{ 9}}, {{427},{ 9}}, {{107},{ 9}}, {{363},{ 9}}, {{235},{ 9}},
49.42 -{{491},{ 9}}, {{ 27},{ 9}}, {{283},{ 9}}, {{155},{ 9}}, {{411},{ 9}},
49.43 -{{ 91},{ 9}}, {{347},{ 9}}, {{219},{ 9}}, {{475},{ 9}}, {{ 59},{ 9}},
49.44 -{{315},{ 9}}, {{187},{ 9}}, {{443},{ 9}}, {{123},{ 9}}, {{379},{ 9}},
49.45 -{{251},{ 9}}, {{507},{ 9}}, {{ 7},{ 9}}, {{263},{ 9}}, {{135},{ 9}},
49.46 -{{391},{ 9}}, {{ 71},{ 9}}, {{327},{ 9}}, {{199},{ 9}}, {{455},{ 9}},
49.47 -{{ 39},{ 9}}, {{295},{ 9}}, {{167},{ 9}}, {{423},{ 9}}, {{103},{ 9}},
49.48 -{{359},{ 9}}, {{231},{ 9}}, {{487},{ 9}}, {{ 23},{ 9}}, {{279},{ 9}},
49.49 -{{151},{ 9}}, {{407},{ 9}}, {{ 87},{ 9}}, {{343},{ 9}}, {{215},{ 9}},
49.50 -{{471},{ 9}}, {{ 55},{ 9}}, {{311},{ 9}}, {{183},{ 9}}, {{439},{ 9}},
49.51 -{{119},{ 9}}, {{375},{ 9}}, {{247},{ 9}}, {{503},{ 9}}, {{ 15},{ 9}},
49.52 -{{271},{ 9}}, {{143},{ 9}}, {{399},{ 9}}, {{ 79},{ 9}}, {{335},{ 9}},
49.53 -{{207},{ 9}}, {{463},{ 9}}, {{ 47},{ 9}}, {{303},{ 9}}, {{175},{ 9}},
49.54 -{{431},{ 9}}, {{111},{ 9}}, {{367},{ 9}}, {{239},{ 9}}, {{495},{ 9}},
49.55 -{{ 31},{ 9}}, {{287},{ 9}}, {{159},{ 9}}, {{415},{ 9}}, {{ 95},{ 9}},
49.56 -{{351},{ 9}}, {{223},{ 9}}, {{479},{ 9}}, {{ 63},{ 9}}, {{319},{ 9}},
49.57 -{{191},{ 9}}, {{447},{ 9}}, {{127},{ 9}}, {{383},{ 9}}, {{255},{ 9}},
49.58 -{{511},{ 9}}, {{ 0},{ 7}}, {{ 64},{ 7}}, {{ 32},{ 7}}, {{ 96},{ 7}},
49.59 -{{ 16},{ 7}}, {{ 80},{ 7}}, {{ 48},{ 7}}, {{112},{ 7}}, {{ 8},{ 7}},
49.60 -{{ 72},{ 7}}, {{ 40},{ 7}}, {{104},{ 7}}, {{ 24},{ 7}}, {{ 88},{ 7}},
49.61 -{{ 56},{ 7}}, {{120},{ 7}}, {{ 4},{ 7}}, {{ 68},{ 7}}, {{ 36},{ 7}},
49.62 -{{100},{ 7}}, {{ 20},{ 7}}, {{ 84},{ 7}}, {{ 52},{ 7}}, {{116},{ 7}},
49.63 -{{ 3},{ 8}}, {{131},{ 8}}, {{ 67},{ 8}}, {{195},{ 8}}, {{ 35},{ 8}},
49.64 -{{163},{ 8}}, {{ 99},{ 8}}, {{227},{ 8}}
49.65 -};
49.66 -
49.67 -local const ct_data static_dtree[D_CODES] = {
49.68 -{{ 0},{ 5}}, {{16},{ 5}}, {{ 8},{ 5}}, {{24},{ 5}}, {{ 4},{ 5}},
49.69 -{{20},{ 5}}, {{12},{ 5}}, {{28},{ 5}}, {{ 2},{ 5}}, {{18},{ 5}},
49.70 -{{10},{ 5}}, {{26},{ 5}}, {{ 6},{ 5}}, {{22},{ 5}}, {{14},{ 5}},
49.71 -{{30},{ 5}}, {{ 1},{ 5}}, {{17},{ 5}}, {{ 9},{ 5}}, {{25},{ 5}},
49.72 -{{ 5},{ 5}}, {{21},{ 5}}, {{13},{ 5}}, {{29},{ 5}}, {{ 3},{ 5}},
49.73 -{{19},{ 5}}, {{11},{ 5}}, {{27},{ 5}}, {{ 7},{ 5}}, {{23},{ 5}}
49.74 -};
49.75 -
49.76 -const uch _dist_code[DIST_CODE_LEN] = {
49.77 - 0, 1, 2, 3, 4, 4, 5, 5, 6, 6, 6, 6, 7, 7, 7, 7, 8, 8, 8, 8,
49.78 - 8, 8, 8, 8, 9, 9, 9, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 10, 10,
49.79 -10, 10, 10, 10, 10, 10, 10, 10, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11, 11,
49.80 -11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12,
49.81 -12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 12, 13, 13, 13, 13,
49.82 -13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13, 13,
49.83 -13, 13, 13, 13, 13, 13, 13, 13, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
49.84 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
49.85 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14,
49.86 -14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 14, 15, 15, 15, 15, 15, 15, 15, 15,
49.87 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
49.88 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15,
49.89 -15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 16, 17,
49.90 -18, 18, 19, 19, 20, 20, 20, 20, 21, 21, 21, 21, 22, 22, 22, 22, 22, 22, 22, 22,
49.91 -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
49.92 -24, 24, 24, 24, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
49.93 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
49.94 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27,
49.95 -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
49.96 -27, 27, 27, 27, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
49.97 -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
49.98 -28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28, 28,
49.99 -28, 28, 28, 28, 28, 28, 28, 28, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
49.100 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
49.101 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29,
49.102 -29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29, 29
49.103 -};
49.104 -
49.105 -const uch _length_code[MAX_MATCH-MIN_MATCH+1]= {
49.106 - 0, 1, 2, 3, 4, 5, 6, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 12, 12,
49.107 -13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 15, 15, 16, 16, 16, 16, 16, 16, 16, 16,
49.108 -17, 17, 17, 17, 17, 17, 17, 17, 18, 18, 18, 18, 18, 18, 18, 18, 19, 19, 19, 19,
49.109 -19, 19, 19, 19, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20, 20,
49.110 -21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 22, 22, 22, 22,
49.111 -22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 22, 23, 23, 23, 23, 23, 23, 23, 23,
49.112 -23, 23, 23, 23, 23, 23, 23, 23, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
49.113 -24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24, 24,
49.114 -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25,
49.115 -25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 25, 26, 26, 26, 26, 26, 26, 26, 26,
49.116 -26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26, 26,
49.117 -26, 26, 26, 26, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27,
49.118 -27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 27, 28
49.119 -};
49.120 -
49.121 -local const int base_length[LENGTH_CODES] = {
49.122 -0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 32, 40, 48, 56,
49.123 -64, 80, 96, 112, 128, 160, 192, 224, 0
49.124 -};
49.125 -
49.126 -local const int base_dist[D_CODES] = {
49.127 - 0, 1, 2, 3, 4, 6, 8, 12, 16, 24,
49.128 - 32, 48, 64, 96, 128, 192, 256, 384, 512, 768,
49.129 - 1024, 1536, 2048, 3072, 4096, 6144, 8192, 12288, 16384, 24576
49.130 -};
49.131 -
50.1 --- a/sourcepawn/vm/zlib/uncompr.c Tue Nov 07 23:26:40 2006 +0000
50.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
50.3 @@ -1,61 +0,0 @@
50.4 -/* uncompr.c -- decompress a memory buffer
50.5 - * Copyright (C) 1995-2003 Jean-loup Gailly.
50.6 - * For conditions of distribution and use, see copyright notice in zlib.h
50.7 - */
50.8 -
50.9 -/* @(#) $Id$ */
50.10 -
50.11 -#define ZLIB_INTERNAL
50.12 -#include "zlib.h"
50.13 -
50.14 -/* ===========================================================================
50.15 - Decompresses the source buffer into the destination buffer. sourceLen is
50.16 - the byte length of the source buffer. Upon entry, destLen is the total
50.17 - size of the destination buffer, which must be large enough to hold the
50.18 - entire uncompressed data. (The size of the uncompressed data must have
50.19 - been saved previously by the compressor and transmitted to the decompressor
50.20 - by some mechanism outside the scope of this compression library.)
50.21 - Upon exit, destLen is the actual size of the compressed buffer.
50.22 - This function can be used to decompress a whole file at once if the
50.23 - input file is mmap'ed.
50.24 -
50.25 - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
50.26 - enough memory, Z_BUF_ERROR if there was not enough room in the output
50.27 - buffer, or Z_DATA_ERROR if the input data was corrupted.
50.28 -*/
50.29 -int ZEXPORT uncompress (dest, destLen, source, sourceLen)
50.30 - Bytef *dest;
50.31 - uLongf *destLen;
50.32 - const Bytef *source;
50.33 - uLong sourceLen;
50.34 -{
50.35 - z_stream stream;
50.36 - int err;
50.37 -
50.38 - stream.next_in = (Bytef*)source;
50.39 - stream.avail_in = (uInt)sourceLen;
50.40 - /* Check for source > 64K on 16-bit machine: */
50.41 - if ((uLong)stream.avail_in != sourceLen) return Z_BUF_ERROR;
50.42 -
50.43 - stream.next_out = dest;
50.44 - stream.avail_out = (uInt)*destLen;
50.45 - if ((uLong)stream.avail_out != *destLen) return Z_BUF_ERROR;
50.46 -
50.47 - stream.zalloc = (alloc_func)0;
50.48 - stream.zfree = (free_func)0;
50.49 -
50.50 - err = inflateInit(&stream);
50.51 - if (err != Z_OK) return err;
50.52 -
50.53 - err = inflate(&stream, Z_FINISH);
50.54 - if (err != Z_STREAM_END) {
50.55 - inflateEnd(&stream);
50.56 - if (err == Z_NEED_DICT || (err == Z_BUF_ERROR && stream.avail_in == 0))
50.57 - return Z_DATA_ERROR;
50.58 - return err;
50.59 - }
50.60 - *destLen = stream.total_out;
50.61 -
50.62 - err = inflateEnd(&stream);
50.63 - return err;
50.64 -}
51.1 --- a/sourcepawn/vm/zlib/zconf.h Tue Nov 07 23:26:40 2006 +0000
51.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
51.3 @@ -1,281 +0,0 @@
51.4 -/* zconf.h -- configuration of the zlib compression library
51.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
51.6 - * For conditions of distribution and use, see copyright notice in zlib.h
51.7 - */
51.8 -
51.9 -/* @(#) $Id$ */
51.10 -
51.11 -#ifndef ZCONF_H
51.12 -#define ZCONF_H
51.13 -
51.14 -#if defined(__MSDOS__) && !defined(MSDOS)
51.15 -# define MSDOS
51.16 -#endif
51.17 -#if (defined(OS_2) || defined(__OS2__)) && !defined(OS2)
51.18 -# define OS2
51.19 -#endif
51.20 -#if defined(_WINDOWS) && !defined(WINDOWS)
51.21 -# define WINDOWS
51.22 -#endif
51.23 -#if defined(_WIN32) || defined(_WIN32_WCE) || defined(__WIN32__)
51.24 -# ifndef WIN32
51.25 -# define WIN32
51.26 -# endif
51.27 -#endif
51.28 -#if (defined(MSDOS) || defined(OS2) || defined(WINDOWS)) && !defined(WIN32)
51.29 -# if !defined(__GNUC__) && !defined(__FLAT__) && !defined(__386__)
51.30 -# ifndef SYS16BIT
51.31 -# define SYS16BIT
51.32 -# endif
51.33 -# endif
51.34 -#endif
51.35 -
51.36 -/*
51.37 - * Compile with -DMAXSEG_64K if the alloc function cannot allocate more
51.38 - * than 64k bytes at a time (needed on systems with 16-bit int).
51.39 - */
51.40 -#ifdef SYS16BIT
51.41 -# define MAXSEG_64K
51.42 -#endif
51.43 -#ifdef MSDOS
51.44 -# define UNALIGNED_OK
51.45 -#endif
51.46 -
51.47 -#ifdef __STDC_VERSION__
51.48 -# ifndef STDC
51.49 -# define STDC
51.50 -# endif
51.51 -# if __STDC_VERSION__ >= 199901L
51.52 -# ifndef STDC99
51.53 -# define STDC99
51.54 -# endif
51.55 -# endif
51.56 -#endif
51.57 -#if !defined(STDC) && (defined(__STDC__) || defined(__cplusplus))
51.58 -# define STDC
51.59 -#endif
51.60 -#if !defined(STDC) && (defined(__GNUC__) || defined(__BORLANDC__))
51.61 -# define STDC
51.62 -#endif
51.63 -#if !defined(STDC) && (defined(MSDOS) || defined(WINDOWS) || defined(WIN32))
51.64 -# define STDC
51.65 -#endif
51.66 -#if !defined(STDC) && (defined(OS2) || defined(__HOS_AIX__))
51.67 -# define STDC
51.68 -#endif
51.69 -
51.70 -#if defined(__OS400__) && !defined(STDC) /* iSeries (formerly AS/400). */
51.71 -# define STDC
51.72 -#endif
51.73 -
51.74 -#ifndef STDC
51.75 -# ifndef const /* cannot use !defined(STDC) && !defined(const) on Mac */
51.76 -# define const /* note: need a more gentle solution here */
51.77 -# endif
51.78 -#endif
51.79 -
51.80 -/* Some Mac compilers merge all .h files incorrectly: */
51.81 -#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
51.82 -# define NO_DUMMY_DECL
51.83 -#endif
51.84 -
51.85 -/* Maximum value for memLevel in deflateInit2 */
51.86 -#ifndef MAX_MEM_LEVEL
51.87 -# ifdef MAXSEG_64K
51.88 -# define MAX_MEM_LEVEL 8
51.89 -# else
51.90 -# define MAX_MEM_LEVEL 9
51.91 -# endif
51.92 -#endif
51.93 -
51.94 -/* Maximum value for windowBits in deflateInit2 and inflateInit2.
51.95 - * WARNING: reducing MAX_WBITS makes minigzip unable to extract .gz files
51.96 - * created by gzip. (Files created by minigzip can still be extracted by
51.97 - * gzip.)
51.98 - */
51.99 -#ifndef MAX_WBITS
51.100 -# define MAX_WBITS 15 /* 32K LZ77 window */
51.101 -#endif
51.102 -
51.103 -/* The memory requirements for deflate are (in bytes):
51.104 - (1 << (windowBits+2)) + (1 << (memLevel+9))
51.105 - that is: 128K for windowBits=15 + 128K for memLevel = 8 (default values)
51.106 - plus a few kilobytes for small objects. For example, if you want to reduce
51.107 - the default memory requirements from 256K to 128K, compile with
51.108 - make CFLAGS="-O -DMAX_WBITS=14 -DMAX_MEM_LEVEL=7"
51.109 - Of course this will generally degrade compression (there's no free lunch).
51.110 -
51.111 - The memory requirements for inflate are (in bytes) 1 << windowBits
51.112 - that is, 32K for windowBits=15 (default value) plus a few kilobytes
51.113 - for small objects.
51.114 -*/
51.115 -
51.116 - /* Type declarations */
51.117 -
51.118 -#ifndef OF /* function prototypes */
51.119 -# ifdef STDC
51.120 -# define OF(args) args
51.121 -# else
51.122 -# define OF(args) ()
51.123 -# endif
51.124 -#endif
51.125 -
51.126 -/* The following definitions for FAR are needed only for MSDOS mixed
51.127 - * model programming (small or medium model with some far allocations).
51.128 - * This was tested only with MSC; for other MSDOS compilers you may have
51.129 - * to define NO_MEMCPY in zutil.h. If you don't need the mixed model,
51.130 - * just define FAR to be empty.
51.131 - */
51.132 -#ifdef SYS16BIT
51.133 -# if defined(M_I86SM) || defined(M_I86MM)
51.134 - /* MSC small or medium model */
51.135 -# define SMALL_MEDIUM
51.136 -# ifdef _MSC_VER
51.137 -# define FAR _far
51.138 -# else
51.139 -# define FAR far
51.140 -# endif
51.141 -# endif
51.142 -# if (defined(__SMALL__) || defined(__MEDIUM__))
51.143 - /* Turbo C small or medium model */
51.144 -# define SMALL_MEDIUM
51.145 -# ifdef __BORLANDC__
51.146 -# define FAR _far
51.147 -# else
51.148 -# define FAR far
51.149 -# endif
51.150 -# endif
51.151 -#endif
51.152 -
51.153 -#if defined(WINDOWS) || defined(WIN32)
51.154 - /* If building or using zlib as a DLL, define ZLIB_DLL.
51.155 - * This is not mandatory, but it offers a little performance increase.
51.156 - */
51.157 -# ifdef ZLIB_DLL
51.158 -# if defined(WIN32) && (!defined(__BORLANDC__) || (__BORLANDC__ >= 0x500))
51.159 -# ifdef ZLIB_INTERNAL
51.160 -# define ZEXTERN extern __declspec(dllexport)
51.161 -# else
51.162 -# define ZEXTERN extern __declspec(dllimport)
51.163 -# endif
51.164 -# endif
51.165 -# endif /* ZLIB_DLL */
51.166 - /* If building or using zlib with the WINAPI/WINAPIV calling convention,
51.167 - * define ZLIB_WINAPI.
51.168 - * Caution: the standard ZLIB1.DLL is NOT compiled using ZLIB_WINAPI.
51.169 - */
51.170 -# ifdef ZLIB_WINAPI
51.171 -# ifdef FAR
51.172 -# undef FAR
51.173 -# endif
51.174 -# include <windows.h>
51.175 - /* No need for _export, use ZLIB.DEF instead. */
51.176 - /* For complete Windows compatibility, use WINAPI, not __stdcall. */
51.177 -# define ZEXPORT WINAPI
51.178 -# ifdef WIN32
51.179 -# define ZEXPORTVA WINAPIV
51.180 -# else
51.181 -# define ZEXPORTVA FAR CDECL
51.182 -# endif
51.183 -# endif
51.184 -#endif
51.185 -
51.186 -#if defined (__BEOS__)
51.187 -# ifdef ZLIB_DLL
51.188 -# ifdef ZLIB_INTERNAL
51.189 -# define ZEXPORT __declspec(dllexport)
51.190 -# define ZEXPORTVA __declspec(dllexport)
51.191 -# else
51.192 -# define ZEXPORT __declspec(dllimport)
51.193 -# define ZEXPORTVA __declspec(dllimport)
51.194 -# endif
51.195 -# endif
51.196 -#endif
51.197 -
51.198 -#ifndef ZEXTERN
51.199 -# define ZEXTERN extern
51.200 -#endif
51.201 -#ifndef ZEXPORT
51.202 -# define ZEXPORT
51.203 -#endif
51.204 -#ifndef ZEXPORTVA
51.205 -# define ZEXPORTVA
51.206 -#endif
51.207 -
51.208 -#ifndef FAR
51.209 -# define FAR
51.210 -#endif
51.211 -
51.212 -#if !defined(__MACTYPES__)
51.213 -typedef unsigned char Byte; /* 8 bits */
51.214 -#endif
51.215 -typedef unsigned int uInt; /* 16 bits or more */
51.216 -typedef unsigned long uLong; /* 32 bits or more */
51.217 -
51.218 -#ifdef SMALL_MEDIUM
51.219 - /* Borland C/C++ and some old MSC versions ignore FAR inside typedef */
51.220 -# define Bytef Byte FAR
51.221 -#else
51.222 - typedef Byte FAR Bytef;
51.223 -#endif
51.224 -typedef char FAR charf;
51.225 -typedef int FAR intf;
51.226 -typedef uInt FAR uIntf;
51.227 -typedef uLong FAR uLongf;
51.228 -
51.229 -#ifdef STDC
51.230 - typedef void const *voidpc;
51.231 - typedef void FAR *voidpf;
51.232 - typedef void *voidp;
51.233 -#else
51.234 - typedef Byte const *voidpc;
51.235 - typedef Byte FAR *voidpf;
51.236 - typedef Byte *voidp;
51.237 -#endif
51.238 -
51.239 -#if 0 /* HAVE_UNISTD_H -- this line is updated by ./configure */
51.240 -# include <sys/types.h> /* for off_t */
51.241 -# include <unistd.h> /* for SEEK_* and off_t */
51.242 -# ifdef VMS
51.243 -# include <unixio.h> /* for off_t */
51.244 -# endif
51.245 -# define z_off_t off_t
51.246 -#endif
51.247 -#ifndef SEEK_SET
51.248 -# define SEEK_SET 0 /* Seek from beginning of file. */
51.249 -# define SEEK_CUR 1 /* Seek from current position. */
51.250 -# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
51.251 -#endif
51.252 -#ifndef z_off_t
51.253 -# define z_off_t long
51.254 -#endif
51.255 -
51.256 -#if defined(__OS400__)
51.257 -# define NO_vsnprintf
51.258 -#endif
51.259 -
51.260 -#if defined(__MVS__)
51.261 -# define NO_vsnprintf
51.262 -# ifdef FAR
51.263 -# undef FAR
51.264 -# endif
51.265 -#endif
51.266 -
51.267 -/* MVS linker does not support external names larger than 8 bytes */
51.268 -#if defined(__MVS__)
51.269 -# pragma map(deflateInit_,"DEIN")
51.270 -# pragma map(deflateInit2_,"DEIN2")
51.271 -# pragma map(deflateEnd,"DEEND")
51.272 -# pragma map(deflateBound,"DEBND")
51.273 -# pragma map(inflateInit_,"ININ")
51.274 -# pragma map(inflateInit2_,"ININ2")
51.275 -# pragma map(inflateEnd,"INEND")
51.276 -# pragma map(inflateSync,"INSY")
51.277 -# pragma map(inflateSetDictionary,"INSEDI")
51.278 -# pragma map(compressBound,"CMBND")
51.279 -# pragma map(inflate_table,"INTABL")
51.280 -# pragma map(inflate_fast,"INFA")
51.281 -# pragma map(inflate_copyright,"INCOPY")
51.282 -#endif
51.283 -
51.284 -#endif /* ZCONF_H */
52.1 --- a/sourcepawn/vm/zlib/zlib.h Tue Nov 07 23:26:40 2006 +0000
52.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
52.3 @@ -1,1357 +0,0 @@
52.4 -/* zlib.h -- interface of the 'zlib' general purpose compression library
52.5 - version 1.2.3, July 18th, 2005
52.6 -
52.7 - Copyright (C) 1995-2005 Jean-loup Gailly and Mark Adler
52.8 -
52.9 - This software is provided 'as-is', without any express or implied
52.10 - warranty. In no event will the authors be held liable for any damages
52.11 - arising from the use of this software.
52.12 -
52.13 - Permission is granted to anyone to use this software for any purpose,
52.14 - including commercial applications, and to alter it and redistribute it
52.15 - freely, subject to the following restrictions:
52.16 -
52.17 - 1. The origin of this software must not be misrepresented; you must not
52.18 - claim that you wrote the original software. If you use this software
52.19 - in a product, an acknowledgment in the product documentation would be
52.20 - appreciated but is not required.
52.21 - 2. Altered source versions must be plainly marked as such, and must not be
52.22 - misrepresented as being the original software.
52.23 - 3. This notice may not be removed or altered from any source distribution.
52.24 -
52.25 - Jean-loup Gailly Mark Adler
52.26 - [email protected] [email protected]
52.27 -
52.28 -
52.29 - The data format used by the zlib library is described by RFCs (Request for
52.30 - Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
52.31 - (zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
52.32 -*/
52.33 -
52.34 -#ifndef ZLIB_H
52.35 -#define ZLIB_H
52.36 -
52.37 -#include "zconf.h"
52.38 -
52.39 -#ifdef __cplusplus
52.40 -extern "C" {
52.41 -#endif
52.42 -
52.43 -#define ZLIB_VERSION "1.2.3"
52.44 -#define ZLIB_VERNUM 0x1230
52.45 -
52.46 -/*
52.47 - The 'zlib' compression library provides in-memory compression and
52.48 - decompression functions, including integrity checks of the uncompressed
52.49 - data. This version of the library supports only one compression method
52.50 - (deflation) but other algorithms will be added later and will have the same
52.51 - stream interface.
52.52 -
52.53 - Compression can be done in a single step if the buffers are large
52.54 - enough (for example if an input file is mmap'ed), or can be done by
52.55 - repeated calls of the compression function. In the latter case, the
52.56 - application must provide more input and/or consume the output
52.57 - (providing more output space) before each call.
52.58 -
52.59 - The compressed data format used by default by the in-memory functions is
52.60 - the zlib format, which is a zlib wrapper documented in RFC 1950, wrapped
52.61 - around a deflate stream, which is itself documented in RFC 1951.
52.62 -
52.63 - The library also supports reading and writing files in gzip (.gz) format
52.64 - with an interface similar to that of stdio using the functions that start
52.65 - with "gz". The gzip format is different from the zlib format. gzip is a
52.66 - gzip wrapper, documented in RFC 1952, wrapped around a deflate stream.
52.67 -
52.68 - This library can optionally read and write gzip streams in memory as well.
52.69 -
52.70 - The zlib format was designed to be compact and fast for use in memory
52.71 - and on communications channels. The gzip format was designed for single-
52.72 - file compression on file systems, has a larger header than zlib to maintain
52.73 - directory information, and uses a different, slower check method than zlib.
52.74 -
52.75 - The library does not install any signal handler. The decoder checks
52.76 - the consistency of the compressed data, so the library should never
52.77 - crash even in case of corrupted input.
52.78 -*/
52.79 -
52.80 -typedef voidpf (*alloc_func) OF((voidpf opaque, uInt items, uInt size));
52.81 -typedef void (*free_func) OF((voidpf opaque, voidpf address));
52.82 -
52.83 -struct internal_state;
52.84 -
52.85 -typedef struct z_stream_s {
52.86 - Bytef *next_in; /* next input byte */
52.87 - uInt avail_in; /* number of bytes available at next_in */
52.88 - uLong total_in; /* total nb of input bytes read so far */
52.89 -
52.90 - Bytef *next_out; /* next output byte should be put there */
52.91 - uInt avail_out; /* remaining free space at next_out */
52.92 - uLong total_out; /* total nb of bytes output so far */
52.93 -
52.94 - char *msg; /* last error message, NULL if no error */
52.95 - struct internal_state FAR *state; /* not visible by applications */
52.96 -
52.97 - alloc_func zalloc; /* used to allocate the internal state */
52.98 - free_func zfree; /* used to free the internal state */
52.99 - voidpf opaque; /* private data object passed to zalloc and zfree */
52.100 -
52.101 - int data_type; /* best guess about the data type: binary or text */
52.102 - uLong adler; /* adler32 value of the uncompressed data */
52.103 - uLong reserved; /* reserved for future use */
52.104 -} z_stream;
52.105 -
52.106 -typedef z_stream FAR *z_streamp;
52.107 -
52.108 -/*
52.109 - gzip header information passed to and from zlib routines. See RFC 1952
52.110 - for more details on the meanings of these fields.
52.111 -*/
52.112 -typedef struct gz_header_s {
52.113 - int text; /* true if compressed data believed to be text */
52.114 - uLong time; /* modification time */
52.115 - int xflags; /* extra flags (not used when writing a gzip file) */
52.116 - int os; /* operating system */
52.117 - Bytef *extra; /* pointer to extra field or Z_NULL if none */
52.118 - uInt extra_len; /* extra field length (valid if extra != Z_NULL) */
52.119 - uInt extra_max; /* space at extra (only when reading header) */
52.120 - Bytef *name; /* pointer to zero-terminated file name or Z_NULL */
52.121 - uInt name_max; /* space at name (only when reading header) */
52.122 - Bytef *comment; /* pointer to zero-terminated comment or Z_NULL */
52.123 - uInt comm_max; /* space at comment (only when reading header) */
52.124 - int hcrc; /* true if there was or will be a header crc */
52.125 - int done; /* true when done reading gzip header (not used
52.126 - when writing a gzip file) */
52.127 -} gz_header;
52.128 -
52.129 -typedef gz_header FAR *gz_headerp;
52.130 -
52.131 -/*
52.132 - The application must update next_in and avail_in when avail_in has
52.133 - dropped to zero. It must update next_out and avail_out when avail_out
52.134 - has dropped to zero. The application must initialize zalloc, zfree and
52.135 - opaque before calling the init function. All other fields are set by the
52.136 - compression library and must not be updated by the application.
52.137 -
52.138 - The opaque value provided by the application will be passed as the first
52.139 - parameter for calls of zalloc and zfree. This can be useful for custom
52.140 - memory management. The compression library attaches no meaning to the
52.141 - opaque value.
52.142 -
52.143 - zalloc must return Z_NULL if there is not enough memory for the object.
52.144 - If zlib is used in a multi-threaded application, zalloc and zfree must be
52.145 - thread safe.
52.146 -
52.147 - On 16-bit systems, the functions zalloc and zfree must be able to allocate
52.148 - exactly 65536 bytes, but will not be required to allocate more than this
52.149 - if the symbol MAXSEG_64K is defined (see zconf.h). WARNING: On MSDOS,
52.150 - pointers returned by zalloc for objects of exactly 65536 bytes *must*
52.151 - have their offset normalized to zero. The default allocation function
52.152 - provided by this library ensures this (see zutil.c). To reduce memory
52.153 - requirements and avoid any allocation of 64K objects, at the expense of
52.154 - compression ratio, compile the library with -DMAX_WBITS=14 (see zconf.h).
52.155 -
52.156 - The fields total_in and total_out can be used for statistics or
52.157 - progress reports. After compression, total_in holds the total size of
52.158 - the uncompressed data and may be saved for use in the decompressor
52.159 - (particularly if the decompressor wants to decompress everything in
52.160 - a single step).
52.161 -*/
52.162 -
52.163 - /* constants */
52.164 -
52.165 -#define Z_NO_FLUSH 0
52.166 -#define Z_PARTIAL_FLUSH 1 /* will be removed, use Z_SYNC_FLUSH instead */
52.167 -#define Z_SYNC_FLUSH 2
52.168 -#define Z_FULL_FLUSH 3
52.169 -#define Z_FINISH 4
52.170 -#define Z_BLOCK 5
52.171 -/* Allowed flush values; see deflate() and inflate() below for details */
52.172 -
52.173 -#define Z_OK 0
52.174 -#define Z_STREAM_END 1
52.175 -#define Z_NEED_DICT 2
52.176 -#define Z_ERRNO (-1)
52.177 -#define Z_STREAM_ERROR (-2)
52.178 -#define Z_DATA_ERROR (-3)
52.179 -#define Z_MEM_ERROR (-4)
52.180 -#define Z_BUF_ERROR (-5)
52.181 -#define Z_VERSION_ERROR (-6)
52.182 -/* Return codes for the compression/decompression functions. Negative
52.183 - * values are errors, positive values are used for special but normal events.
52.184 - */
52.185 -
52.186 -#define Z_NO_COMPRESSION 0
52.187 -#define Z_BEST_SPEED 1
52.188 -#define Z_BEST_COMPRESSION 9
52.189 -#define Z_DEFAULT_COMPRESSION (-1)
52.190 -/* compression levels */
52.191 -
52.192 -#define Z_FILTERED 1
52.193 -#define Z_HUFFMAN_ONLY 2
52.194 -#define Z_RLE 3
52.195 -#define Z_FIXED 4
52.196 -#define Z_DEFAULT_STRATEGY 0
52.197 -/* compression strategy; see deflateInit2() below for details */
52.198 -
52.199 -#define Z_BINARY 0
52.200 -#define Z_TEXT 1
52.201 -#define Z_ASCII Z_TEXT /* for compatibility with 1.2.2 and earlier */
52.202 -#define Z_UNKNOWN 2
52.203 -/* Possible values of the data_type field (though see inflate()) */
52.204 -
52.205 -#define Z_DEFLATED 8
52.206 -/* The deflate compression method (the only one supported in this version) */
52.207 -
52.208 -#define Z_NULL 0 /* for initializing zalloc, zfree, opaque */
52.209 -
52.210 -#define zlib_version zlibVersion()
52.211 -/* for compatibility with versions < 1.0.2 */
52.212 -
52.213 - /* basic functions */
52.214 -
52.215 -ZEXTERN const char * ZEXPORT zlibVersion OF((void));
52.216 -/* The application can compare zlibVersion and ZLIB_VERSION for consistency.
52.217 - If the first character differs, the library code actually used is
52.218 - not compatible with the zlib.h header file used by the application.
52.219 - This check is automatically made by deflateInit and inflateInit.
52.220 - */
52.221 -
52.222 -/*
52.223 -ZEXTERN int ZEXPORT deflateInit OF((z_streamp strm, int level));
52.224 -
52.225 - Initializes the internal stream state for compression. The fields
52.226 - zalloc, zfree and opaque must be initialized before by the caller.
52.227 - If zalloc and zfree are set to Z_NULL, deflateInit updates them to
52.228 - use default allocation functions.
52.229 -
52.230 - The compression level must be Z_DEFAULT_COMPRESSION, or between 0 and 9:
52.231 - 1 gives best speed, 9 gives best compression, 0 gives no compression at
52.232 - all (the input data is simply copied a block at a time).
52.233 - Z_DEFAULT_COMPRESSION requests a default compromise between speed and
52.234 - compression (currently equivalent to level 6).
52.235 -
52.236 - deflateInit returns Z_OK if success, Z_MEM_ERROR if there was not
52.237 - enough memory, Z_STREAM_ERROR if level is not a valid compression level,
52.238 - Z_VERSION_ERROR if the zlib library version (zlib_version) is incompatible
52.239 - with the version assumed by the caller (ZLIB_VERSION).
52.240 - msg is set to null if there is no error message. deflateInit does not
52.241 - perform any compression: this will be done by deflate().
52.242 -*/
52.243 -
52.244 -
52.245 -ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
52.246 -/*
52.247 - deflate compresses as much data as possible, and stops when the input
52.248 - buffer becomes empty or the output buffer becomes full. It may introduce some
52.249 - output latency (reading input without producing any output) except when
52.250 - forced to flush.
52.251 -
52.252 - The detailed semantics are as follows. deflate performs one or both of the
52.253 - following actions:
52.254 -
52.255 - - Compress more input starting at next_in and update next_in and avail_in
52.256 - accordingly. If not all input can be processed (because there is not
52.257 - enough room in the output buffer), next_in and avail_in are updated and
52.258 - processing will resume at this point for the next call of deflate().
52.259 -
52.260 - - Provide more output starting at next_out and update next_out and avail_out
52.261 - accordingly. This action is forced if the parameter flush is non zero.
52.262 - Forcing flush frequently degrades the compression ratio, so this parameter
52.263 - should be set only when necessary (in interactive applications).
52.264 - Some output may be provided even if flush is not set.
52.265 -
52.266 - Before the call of deflate(), the application should ensure that at least
52.267 - one of the actions is possible, by providing more input and/or consuming
52.268 - more output, and updating avail_in or avail_out accordingly; avail_out
52.269 - should never be zero before the call. The application can consume the
52.270 - compressed output when it wants, for example when the output buffer is full
52.271 - (avail_out == 0), or after each call of deflate(). If deflate returns Z_OK
52.272 - and with zero avail_out, it must be called again after making room in the
52.273 - output buffer because there might be more output pending.
52.274 -
52.275 - Normally the parameter flush is set to Z_NO_FLUSH, which allows deflate to
52.276 - decide how much data to accumualte before producing output, in order to
52.277 - maximize compression.
52.278 -
52.279 - If the parameter flush is set to Z_SYNC_FLUSH, all pending output is
52.280 - flushed to the output buffer and the output is aligned on a byte boundary, so
52.281 - that the decompressor can get all input data available so far. (In particular
52.282 - avail_in is zero after the call if enough output space has been provided
52.283 - before the call.) Flushing may degrade compression for some compression
52.284 - algorithms and so it should be used only when necessary.
52.285 -
52.286 - If flush is set to Z_FULL_FLUSH, all output is flushed as with
52.287 - Z_SYNC_FLUSH, and the compression state is reset so that decompression can
52.288 - restart from this point if previous compressed data has been damaged or if
52.289 - random access is desired. Using Z_FULL_FLUSH too often can seriously degrade
52.290 - compression.
52.291 -
52.292 - If deflate returns with avail_out == 0, this function must be called again
52.293 - with the same value of the flush parameter and more output space (updated
52.294 - avail_out), until the flush is complete (deflate returns with non-zero
52.295 - avail_out). In the case of a Z_FULL_FLUSH or Z_SYNC_FLUSH, make sure that
52.296 - avail_out is greater than six to avoid repeated flush markers due to
52.297 - avail_out == 0 on return.
52.298 -
52.299 - If the parameter flush is set to Z_FINISH, pending input is processed,
52.300 - pending output is flushed and deflate returns with Z_STREAM_END if there
52.301 - was enough output space; if deflate returns with Z_OK, this function must be
52.302 - called again with Z_FINISH and more output space (updated avail_out) but no
52.303 - more input data, until it returns with Z_STREAM_END or an error. After
52.304 - deflate has returned Z_STREAM_END, the only possible operations on the
52.305 - stream are deflateReset or deflateEnd.
52.306 -
52.307 - Z_FINISH can be used immediately after deflateInit if all the compression
52.308 - is to be done in a single step. In this case, avail_out must be at least
52.309 - the value returned by deflateBound (see below). If deflate does not return
52.310 - Z_STREAM_END, then it must be called again as described above.
52.311 -
52.312 - deflate() sets strm->adler to the adler32 checksum of all input read
52.313 - so far (that is, total_in bytes).
52.314 -
52.315 - deflate() may update strm->data_type if it can make a good guess about
52.316 - the input data type (Z_BINARY or Z_TEXT). In doubt, the data is considered
52.317 - binary. This field is only for information purposes and does not affect
52.318 - the compression algorithm in any manner.
52.319 -
52.320 - deflate() returns Z_OK if some progress has been made (more input
52.321 - processed or more output produced), Z_STREAM_END if all input has been
52.322 - consumed and all output has been produced (only when flush is set to
52.323 - Z_FINISH), Z_STREAM_ERROR if the stream state was inconsistent (for example
52.324 - if next_in or next_out was NULL), Z_BUF_ERROR if no progress is possible
52.325 - (for example avail_in or avail_out was zero). Note that Z_BUF_ERROR is not
52.326 - fatal, and deflate() can be called again with more input and more output
52.327 - space to continue compressing.
52.328 -*/
52.329 -
52.330 -
52.331 -ZEXTERN int ZEXPORT deflateEnd OF((z_streamp strm));
52.332 -/*
52.333 - All dynamically allocated data structures for this stream are freed.
52.334 - This function discards any unprocessed input and does not flush any
52.335 - pending output.
52.336 -
52.337 - deflateEnd returns Z_OK if success, Z_STREAM_ERROR if the
52.338 - stream state was inconsistent, Z_DATA_ERROR if the stream was freed
52.339 - prematurely (some input or output was discarded). In the error case,
52.340 - msg may be set but then points to a static string (which must not be
52.341 - deallocated).
52.342 -*/
52.343 -
52.344 -
52.345 -/*
52.346 -ZEXTERN int ZEXPORT inflateInit OF((z_streamp strm));
52.347 -
52.348 - Initializes the internal stream state for decompression. The fields
52.349 - next_in, avail_in, zalloc, zfree and opaque must be initialized before by
52.350 - the caller. If next_in is not Z_NULL and avail_in is large enough (the exact
52.351 - value depends on the compression method), inflateInit determines the
52.352 - compression method from the zlib header and allocates all data structures
52.353 - accordingly; otherwise the allocation will be deferred to the first call of
52.354 - inflate. If zalloc and zfree are set to Z_NULL, inflateInit updates them to
52.355 - use default allocation functions.
52.356 -
52.357 - inflateInit returns Z_OK if success, Z_MEM_ERROR if there was not enough
52.358 - memory, Z_VERSION_ERROR if the zlib library version is incompatible with the
52.359 - version assumed by the caller. msg is set to null if there is no error
52.360 - message. inflateInit does not perform any decompression apart from reading
52.361 - the zlib header if present: this will be done by inflate(). (So next_in and
52.362 - avail_in may be modified, but next_out and avail_out are unchanged.)
52.363 -*/
52.364 -
52.365 -
52.366 -ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
52.367 -/*
52.368 - inflate decompresses as much data as possible, and stops when the input
52.369 - buffer becomes empty or the output buffer becomes full. It may introduce
52.370 - some output latency (reading input without producing any output) except when
52.371 - forced to flush.
52.372 -
52.373 - The detailed semantics are as follows. inflate performs one or both of the
52.374 - following actions:
52.375 -
52.376 - - Decompress more input starting at next_in and update next_in and avail_in
52.377 - accordingly. If not all input can be processed (because there is not
52.378 - enough room in the output buffer), next_in is updated and processing
52.379 - will resume at this point for the next call of inflate().
52.380 -
52.381 - - Provide more output starting at next_out and update next_out and avail_out
52.382 - accordingly. inflate() provides as much output as possible, until there
52.383 - is no more input data or no more space in the output buffer (see below
52.384 - about the flush parameter).
52.385 -
52.386 - Before the call of inflate(), the application should ensure that at least
52.387 - one of the actions is possible, by providing more input and/or consuming
52.388 - more output, and updating the next_* and avail_* values accordingly.
52.389 - The application can consume the uncompressed output when it wants, for
52.390 - example when the output buffer is full (avail_out == 0), or after each
52.391 - call of inflate(). If inflate returns Z_OK and with zero avail_out, it
52.392 - must be called again after making room in the output buffer because there
52.393 - might be more output pending.
52.394 -
52.395 - The flush parameter of inflate() can be Z_NO_FLUSH, Z_SYNC_FLUSH,
52.396 - Z_FINISH, or Z_BLOCK. Z_SYNC_FLUSH requests that inflate() flush as much
52.397 - output as possible to the output buffer. Z_BLOCK requests that inflate() stop
52.398 - if and when it gets to the next deflate block boundary. When decoding the
52.399 - zlib or gzip format, this will cause inflate() to return immediately after
52.400 - the header and before the first block. When doing a raw inflate, inflate()
52.401 - will go ahead and process the first block, and will return when it gets to
52.402 - the end of that block, or when it runs out of data.
52.403 -
52.404 - The Z_BLOCK option assists in appending to or combining deflate streams.
52.405 - Also to assist in this, on return inflate() will set strm->data_type to the
52.406 - number of unused bits in the last byte taken from strm->next_in, plus 64
52.407 - if inflate() is currently decoding the last block in the deflate stream,
52.408 - plus 128 if inflate() returned immediately after decoding an end-of-block
52.409 - code or decoding the complete header up to just before the first byte of the
52.410 - deflate stream. The end-of-block will not be indicated until all of the
52.411 - uncompressed data from that block has been written to strm->next_out. The
52.412 - number of unused bits may in general be greater than seven, except when
52.413 - bit 7 of data_type is set, in which case the number of unused bits will be
52.414 - less than eight.
52.415 -
52.416 - inflate() should normally be called until it returns Z_STREAM_END or an
52.417 - error. However if all decompression is to be performed in a single step
52.418 - (a single call of inflate), the parameter flush should be set to
52.419 - Z_FINISH. In this case all pending input is processed and all pending
52.420 - output is flushed; avail_out must be large enough to hold all the
52.421 - uncompressed data. (The size of the uncompressed data may have been saved
52.422 - by the compressor for this purpose.) The next operation on this stream must
52.423 - be inflateEnd to deallocate the decompression state. The use of Z_FINISH
52.424 - is never required, but can be used to inform inflate that a faster approach
52.425 - may be used for the single inflate() call.
52.426 -
52.427 - In this implementation, inflate() always flushes as much output as
52.428 - possible to the output buffer, and always uses the faster approach on the
52.429 - first call. So the only effect of the flush parameter in this implementation
52.430 - is on the return value of inflate(), as noted below, or when it returns early
52.431 - because Z_BLOCK is used.
52.432 -
52.433 - If a preset dictionary is needed after this call (see inflateSetDictionary
52.434 - below), inflate sets strm->adler to the adler32 checksum of the dictionary
52.435 - chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
52.436 - strm->adler to the adler32 checksum of all output produced so far (that is,
52.437 - total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
52.438 - below. At the end of the stream, inflate() checks that its computed adler32
52.439 - checksum is equal to that saved by the compressor and returns Z_STREAM_END
52.440 - only if the checksum is correct.
52.441 -
52.442 - inflate() will decompress and check either zlib-wrapped or gzip-wrapped
52.443 - deflate data. The header type is detected automatically. Any information
52.444 - contained in the gzip header is not retained, so applications that need that
52.445 - information should instead use raw inflate, see inflateInit2() below, or
52.446 - inflateBack() and perform their own processing of the gzip header and
52.447 - trailer.
52.448 -
52.449 - inflate() returns Z_OK if some progress has been made (more input processed
52.450 - or more output produced), Z_STREAM_END if the end of the compressed data has
52.451 - been reached and all uncompressed output has been produced, Z_NEED_DICT if a
52.452 - preset dictionary is needed at this point, Z_DATA_ERROR if the input data was
52.453 - corrupted (input stream not conforming to the zlib format or incorrect check
52.454 - value), Z_STREAM_ERROR if the stream structure was inconsistent (for example
52.455 - if next_in or next_out was NULL), Z_MEM_ERROR if there was not enough memory,
52.456 - Z_BUF_ERROR if no progress is possible or if there was not enough room in the
52.457 - output buffer when Z_FINISH is used. Note that Z_BUF_ERROR is not fatal, and
52.458 - inflate() can be called again with more input and more output space to
52.459 - continue decompressing. If Z_DATA_ERROR is returned, the application may then
52.460 - call inflateSync() to look for a good compression block if a partial recovery
52.461 - of the data is desired.
52.462 -*/
52.463 -
52.464 -
52.465 -ZEXTERN int ZEXPORT inflateEnd OF((z_streamp strm));
52.466 -/*
52.467 - All dynamically allocated data structures for this stream are freed.
52.468 - This function discards any unprocessed input and does not flush any
52.469 - pending output.
52.470 -
52.471 - inflateEnd returns Z_OK if success, Z_STREAM_ERROR if the stream state
52.472 - was inconsistent. In the error case, msg may be set but then points to a
52.473 - static string (which must not be deallocated).
52.474 -*/
52.475 -
52.476 - /* Advanced functions */
52.477 -
52.478 -/*
52.479 - The following functions are needed only in some special applications.
52.480 -*/
52.481 -
52.482 -/*
52.483 -ZEXTERN int ZEXPORT deflateInit2 OF((z_streamp strm,
52.484 - int level,
52.485 - int method,
52.486 - int windowBits,
52.487 - int memLevel,
52.488 - int strategy));
52.489 -
52.490 - This is another version of deflateInit with more compression options. The
52.491 - fields next_in, zalloc, zfree and opaque must be initialized before by
52.492 - the caller.
52.493 -
52.494 - The method parameter is the compression method. It must be Z_DEFLATED in
52.495 - this version of the library.
52.496 -
52.497 - The windowBits parameter is the base two logarithm of the window size
52.498 - (the size of the history buffer). It should be in the range 8..15 for this
52.499 - version of the library. Larger values of this parameter result in better
52.500 - compression at the expense of memory usage. The default value is 15 if
52.501 - deflateInit is used instead.
52.502 -
52.503 - windowBits can also be -8..-15 for raw deflate. In this case, -windowBits
52.504 - determines the window size. deflate() will then generate raw deflate data
52.505 - with no zlib header or trailer, and will not compute an adler32 check value.
52.506 -
52.507 - windowBits can also be greater than 15 for optional gzip encoding. Add
52.508 - 16 to windowBits to write a simple gzip header and trailer around the
52.509 - compressed data instead of a zlib wrapper. The gzip header will have no
52.510 - file name, no extra data, no comment, no modification time (set to zero),
52.511 - no header crc, and the operating system will be set to 255 (unknown). If a
52.512 - gzip stream is being written, strm->adler is a crc32 instead of an adler32.
52.513 -
52.514 - The memLevel parameter specifies how much memory should be allocated
52.515 - for the internal compression state. memLevel=1 uses minimum memory but
52.516 - is slow and reduces compression ratio; memLevel=9 uses maximum memory
52.517 - for optimal speed. The default value is 8. See zconf.h for total memory
52.518 - usage as a function of windowBits and memLevel.
52.519 -
52.520 - The strategy parameter is used to tune the compression algorithm. Use the
52.521 - value Z_DEFAULT_STRATEGY for normal data, Z_FILTERED for data produced by a
52.522 - filter (or predictor), Z_HUFFMAN_ONLY to force Huffman encoding only (no
52.523 - string match), or Z_RLE to limit match distances to one (run-length
52.524 - encoding). Filtered data consists mostly of small values with a somewhat
52.525 - random distribution. In this case, the compression algorithm is tuned to
52.526 - compress them better. The effect of Z_FILTERED is to force more Huffman
52.527 - coding and less string matching; it is somewhat intermediate between
52.528 - Z_DEFAULT and Z_HUFFMAN_ONLY. Z_RLE is designed to be almost as fast as
52.529 - Z_HUFFMAN_ONLY, but give better compression for PNG image data. The strategy
52.530 - parameter only affects the compression ratio but not the correctness of the
52.531 - compressed output even if it is not set appropriately. Z_FIXED prevents the
52.532 - use of dynamic Huffman codes, allowing for a simpler decoder for special
52.533 - applications.
52.534 -
52.535 - deflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
52.536 - memory, Z_STREAM_ERROR if a parameter is invalid (such as an invalid
52.537 - method). msg is set to null if there is no error message. deflateInit2 does
52.538 - not perform any compression: this will be done by deflate().
52.539 -*/
52.540 -
52.541 -ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
52.542 - const Bytef *dictionary,
52.543 - uInt dictLength));
52.544 -/*
52.545 - Initializes the compression dictionary from the given byte sequence
52.546 - without producing any compressed output. This function must be called
52.547 - immediately after deflateInit, deflateInit2 or deflateReset, before any
52.548 - call of deflate. The compressor and decompressor must use exactly the same
52.549 - dictionary (see inflateSetDictionary).
52.550 -
52.551 - The dictionary should consist of strings (byte sequences) that are likely
52.552 - to be encountered later in the data to be compressed, with the most commonly
52.553 - used strings preferably put towards the end of the dictionary. Using a
52.554 - dictionary is most useful when the data to be compressed is short and can be
52.555 - predicted with good accuracy; the data can then be compressed better than
52.556 - with the default empty dictionary.
52.557 -
52.558 - Depending on the size of the compression data structures selected by
52.559 - deflateInit or deflateInit2, a part of the dictionary may in effect be
52.560 - discarded, for example if the dictionary is larger than the window size in
52.561 - deflate or deflate2. Thus the strings most likely to be useful should be
52.562 - put at the end of the dictionary, not at the front. In addition, the
52.563 - current implementation of deflate will use at most the window size minus
52.564 - 262 bytes of the provided dictionary.
52.565 -
52.566 - Upon return of this function, strm->adler is set to the adler32 value
52.567 - of the dictionary; the decompressor may later use this value to determine
52.568 - which dictionary has been used by the compressor. (The adler32 value
52.569 - applies to the whole dictionary even if only a subset of the dictionary is
52.570 - actually used by the compressor.) If a raw deflate was requested, then the
52.571 - adler32 value is not computed and strm->adler is not set.
52.572 -
52.573 - deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
52.574 - parameter is invalid (such as NULL dictionary) or the stream state is
52.575 - inconsistent (for example if deflate has already been called for this stream
52.576 - or if the compression method is bsort). deflateSetDictionary does not
52.577 - perform any compression: this will be done by deflate().
52.578 -*/
52.579 -
52.580 -ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
52.581 - z_streamp source));
52.582 -/*
52.583 - Sets the destination stream as a complete copy of the source stream.
52.584 -
52.585 - This function can be useful when several compression strategies will be
52.586 - tried, for example when there are several ways of pre-processing the input
52.587 - data with a filter. The streams that will be discarded should then be freed
52.588 - by calling deflateEnd. Note that deflateCopy duplicates the internal
52.589 - compression state which can be quite large, so this strategy is slow and
52.590 - can consume lots of memory.
52.591 -
52.592 - deflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
52.593 - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
52.594 - (such as zalloc being NULL). msg is left unchanged in both source and
52.595 - destination.
52.596 -*/
52.597 -
52.598 -ZEXTERN int ZEXPORT deflateReset OF((z_streamp strm));
52.599 -/*
52.600 - This function is equivalent to deflateEnd followed by deflateInit,
52.601 - but does not free and reallocate all the internal compression state.
52.602 - The stream will keep the same compression level and any other attributes
52.603 - that may have been set by deflateInit2.
52.604 -
52.605 - deflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
52.606 - stream state was inconsistent (such as zalloc or state being NULL).
52.607 -*/
52.608 -
52.609 -ZEXTERN int ZEXPORT deflateParams OF((z_streamp strm,
52.610 - int level,
52.611 - int strategy));
52.612 -/*
52.613 - Dynamically update the compression level and compression strategy. The
52.614 - interpretation of level and strategy is as in deflateInit2. This can be
52.615 - used to switch between compression and straight copy of the input data, or
52.616 - to switch to a different kind of input data requiring a different
52.617 - strategy. If the compression level is changed, the input available so far
52.618 - is compressed with the old level (and may be flushed); the new level will
52.619 - take effect only at the next call of deflate().
52.620 -
52.621 - Before the call of deflateParams, the stream state must be set as for
52.622 - a call of deflate(), since the currently available input may have to
52.623 - be compressed and flushed. In particular, strm->avail_out must be non-zero.
52.624 -
52.625 - deflateParams returns Z_OK if success, Z_STREAM_ERROR if the source
52.626 - stream state was inconsistent or if a parameter was invalid, Z_BUF_ERROR
52.627 - if strm->avail_out was zero.
52.628 -*/
52.629 -
52.630 -ZEXTERN int ZEXPORT deflateTune OF((z_streamp strm,
52.631 - int good_length,
52.632 - int max_lazy,
52.633 - int nice_length,
52.634 - int max_chain));
52.635 -/*
52.636 - Fine tune deflate's internal compression parameters. This should only be
52.637 - used by someone who understands the algorithm used by zlib's deflate for
52.638 - searching for the best matching string, and even then only by the most
52.639 - fanatic optimizer trying to squeeze out the last compressed bit for their
52.640 - specific input data. Read the deflate.c source code for the meaning of the
52.641 - max_lazy, good_length, nice_length, and max_chain parameters.
52.642 -
52.643 - deflateTune() can be called after deflateInit() or deflateInit2(), and
52.644 - returns Z_OK on success, or Z_STREAM_ERROR for an invalid deflate stream.
52.645 - */
52.646 -
52.647 -ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
52.648 - uLong sourceLen));
52.649 -/*
52.650 - deflateBound() returns an upper bound on the compressed size after
52.651 - deflation of sourceLen bytes. It must be called after deflateInit()
52.652 - or deflateInit2(). This would be used to allocate an output buffer
52.653 - for deflation in a single pass, and so would be called before deflate().
52.654 -*/
52.655 -
52.656 -ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
52.657 - int bits,
52.658 - int value));
52.659 -/*
52.660 - deflatePrime() inserts bits in the deflate output stream. The intent
52.661 - is that this function is used to start off the deflate output with the
52.662 - bits leftover from a previous deflate stream when appending to it. As such,
52.663 - this function can only be used for raw deflate, and must be used before the
52.664 - first deflate() call after a deflateInit2() or deflateReset(). bits must be
52.665 - less than or equal to 16, and that many of the least significant bits of
52.666 - value will be inserted in the output.
52.667 -
52.668 - deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
52.669 - stream state was inconsistent.
52.670 -*/
52.671 -
52.672 -ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
52.673 - gz_headerp head));
52.674 -/*
52.675 - deflateSetHeader() provides gzip header information for when a gzip
52.676 - stream is requested by deflateInit2(). deflateSetHeader() may be called
52.677 - after deflateInit2() or deflateReset() and before the first call of
52.678 - deflate(). The text, time, os, extra field, name, and comment information
52.679 - in the provided gz_header structure are written to the gzip header (xflag is
52.680 - ignored -- the extra flags are set according to the compression level). The
52.681 - caller must assure that, if not Z_NULL, name and comment are terminated with
52.682 - a zero byte, and that if extra is not Z_NULL, that extra_len bytes are
52.683 - available there. If hcrc is true, a gzip header crc is included. Note that
52.684 - the current versions of the command-line version of gzip (up through version
52.685 - 1.3.x) do not support header crc's, and will report that it is a "multi-part
52.686 - gzip file" and give up.
52.687 -
52.688 - If deflateSetHeader is not used, the default gzip header has text false,
52.689 - the time set to zero, and os set to 255, with no extra, name, or comment
52.690 - fields. The gzip header is returned to the default state by deflateReset().
52.691 -
52.692 - deflateSetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
52.693 - stream state was inconsistent.
52.694 -*/
52.695 -
52.696 -/*
52.697 -ZEXTERN int ZEXPORT inflateInit2 OF((z_streamp strm,
52.698 - int windowBits));
52.699 -
52.700 - This is another version of inflateInit with an extra parameter. The
52.701 - fields next_in, avail_in, zalloc, zfree and opaque must be initialized
52.702 - before by the caller.
52.703 -
52.704 - The windowBits parameter is the base two logarithm of the maximum window
52.705 - size (the size of the history buffer). It should be in the range 8..15 for
52.706 - this version of the library. The default value is 15 if inflateInit is used
52.707 - instead. windowBits must be greater than or equal to the windowBits value
52.708 - provided to deflateInit2() while compressing, or it must be equal to 15 if
52.709 - deflateInit2() was not used. If a compressed stream with a larger window
52.710 - size is given as input, inflate() will return with the error code
52.711 - Z_DATA_ERROR instead of trying to allocate a larger window.
52.712 -
52.713 - windowBits can also be -8..-15 for raw inflate. In this case, -windowBits
52.714 - determines the window size. inflate() will then process raw deflate data,
52.715 - not looking for a zlib or gzip header, not generating a check value, and not
52.716 - looking for any check values for comparison at the end of the stream. This
52.717 - is for use with other formats that use the deflate compressed data format
52.718 - such as zip. Those formats provide their own check values. If a custom
52.719 - format is developed using the raw deflate format for compressed data, it is
52.720 - recommended that a check value such as an adler32 or a crc32 be applied to
52.721 - the uncompressed data as is done in the zlib, gzip, and zip formats. For
52.722 - most applications, the zlib format should be used as is. Note that comments
52.723 - above on the use in deflateInit2() applies to the magnitude of windowBits.
52.724 -
52.725 - windowBits can also be greater than 15 for optional gzip decoding. Add
52.726 - 32 to windowBits to enable zlib and gzip decoding with automatic header
52.727 - detection, or add 16 to decode only the gzip format (the zlib format will
52.728 - return a Z_DATA_ERROR). If a gzip stream is being decoded, strm->adler is
52.729 - a crc32 instead of an adler32.
52.730 -
52.731 - inflateInit2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
52.732 - memory, Z_STREAM_ERROR if a parameter is invalid (such as a null strm). msg
52.733 - is set to null if there is no error message. inflateInit2 does not perform
52.734 - any decompression apart from reading the zlib header if present: this will
52.735 - be done by inflate(). (So next_in and avail_in may be modified, but next_out
52.736 - and avail_out are unchanged.)
52.737 -*/
52.738 -
52.739 -ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
52.740 - const Bytef *dictionary,
52.741 - uInt dictLength));
52.742 -/*
52.743 - Initializes the decompression dictionary from the given uncompressed byte
52.744 - sequence. This function must be called immediately after a call of inflate,
52.745 - if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
52.746 - can be determined from the adler32 value returned by that call of inflate.
52.747 - The compressor and decompressor must use exactly the same dictionary (see
52.748 - deflateSetDictionary). For raw inflate, this function can be called
52.749 - immediately after inflateInit2() or inflateReset() and before any call of
52.750 - inflate() to set the dictionary. The application must insure that the
52.751 - dictionary that was used for compression is provided.
52.752 -
52.753 - inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
52.754 - parameter is invalid (such as NULL dictionary) or the stream state is
52.755 - inconsistent, Z_DATA_ERROR if the given dictionary doesn't match the
52.756 - expected one (incorrect adler32 value). inflateSetDictionary does not
52.757 - perform any decompression: this will be done by subsequent calls of
52.758 - inflate().
52.759 -*/
52.760 -
52.761 -ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
52.762 -/*
52.763 - Skips invalid compressed data until a full flush point (see above the
52.764 - description of deflate with Z_FULL_FLUSH) can be found, or until all
52.765 - available input is skipped. No output is provided.
52.766 -
52.767 - inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
52.768 - if no more input was provided, Z_DATA_ERROR if no flush point has been found,
52.769 - or Z_STREAM_ERROR if the stream structure was inconsistent. In the success
52.770 - case, the application may save the current current value of total_in which
52.771 - indicates where valid compressed data was found. In the error case, the
52.772 - application may repeatedly call inflateSync, providing more input each time,
52.773 - until success or end of the input data.
52.774 -*/
52.775 -
52.776 -ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
52.777 - z_streamp source));
52.778 -/*
52.779 - Sets the destination stream as a complete copy of the source stream.
52.780 -
52.781 - This function can be useful when randomly accessing a large stream. The
52.782 - first pass through the stream can periodically record the inflate state,
52.783 - allowing restarting inflate at those points when randomly accessing the
52.784 - stream.
52.785 -
52.786 - inflateCopy returns Z_OK if success, Z_MEM_ERROR if there was not
52.787 - enough memory, Z_STREAM_ERROR if the source stream state was inconsistent
52.788 - (such as zalloc being NULL). msg is left unchanged in both source and
52.789 - destination.
52.790 -*/
52.791 -
52.792 -ZEXTERN int ZEXPORT inflateReset OF((z_streamp strm));
52.793 -/*
52.794 - This function is equivalent to inflateEnd followed by inflateInit,
52.795 - but does not free and reallocate all the internal decompression state.
52.796 - The stream will keep attributes that may have been set by inflateInit2.
52.797 -
52.798 - inflateReset returns Z_OK if success, or Z_STREAM_ERROR if the source
52.799 - stream state was inconsistent (such as zalloc or state being NULL).
52.800 -*/
52.801 -
52.802 -ZEXTERN int ZEXPORT inflatePrime OF((z_streamp strm,
52.803 - int bits,
52.804 - int value));
52.805 -/*
52.806 - This function inserts bits in the inflate input stream. The intent is
52.807 - that this function is used to start inflating at a bit position in the
52.808 - middle of a byte. The provided bits will be used before any bytes are used
52.809 - from next_in. This function should only be used with raw inflate, and
52.810 - should be used before the first inflate() call after inflateInit2() or
52.811 - inflateReset(). bits must be less than or equal to 16, and that many of the
52.812 - least significant bits of value will be inserted in the input.
52.813 -
52.814 - inflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
52.815 - stream state was inconsistent.
52.816 -*/
52.817 -
52.818 -ZEXTERN int ZEXPORT inflateGetHeader OF((z_streamp strm,
52.819 - gz_headerp head));
52.820 -/*
52.821 - inflateGetHeader() requests that gzip header information be stored in the
52.822 - provided gz_header structure. inflateGetHeader() may be called after
52.823 - inflateInit2() or inflateReset(), and before the first call of inflate().
52.824 - As inflate() processes the gzip stream, head->done is zero until the header
52.825 - is completed, at which time head->done is set to one. If a zlib stream is
52.826 - being decoded, then head->done is set to -1 to indicate that there will be
52.827 - no gzip header information forthcoming. Note that Z_BLOCK can be used to
52.828 - force inflate() to return immediately after header processing is complete
52.829 - and before any actual data is decompressed.
52.830 -
52.831 - The text, time, xflags, and os fields are filled in with the gzip header
52.832 - contents. hcrc is set to true if there is a header CRC. (The header CRC
52.833 - was valid if done is set to one.) If extra is not Z_NULL, then extra_max
52.834 - contains the maximum number of bytes to write to extra. Once done is true,
52.835 - extra_len contains the actual extra field length, and extra contains the
52.836 - extra field, or that field truncated if extra_max is less than extra_len.
52.837 - If name is not Z_NULL, then up to name_max characters are written there,
52.838 - terminated with a zero unless the length is greater than name_max. If
52.839 - comment is not Z_NULL, then up to comm_max characters are written there,
52.840 - terminated with a zero unless the length is greater than comm_max. When
52.841 - any of extra, name, or comment are not Z_NULL and the respective field is
52.842 - not present in the header, then that field is set to Z_NULL to signal its
52.843 - absence. This allows the use of deflateSetHeader() with the returned
52.844 - structure to duplicate the header. However if those fields are set to
52.845 - allocated memory, then the application will need to save those pointers
52.846 - elsewhere so that they can be eventually freed.
52.847 -
52.848 - If inflateGetHeader is not used, then the header information is simply
52.849 - discarded. The header is always checked for validity, including the header
52.850 - CRC if present. inflateReset() will reset the process to discard the header
52.851 - information. The application would need to call inflateGetHeader() again to
52.852 - retrieve the header from the next gzip stream.
52.853 -
52.854 - inflateGetHeader returns Z_OK if success, or Z_STREAM_ERROR if the source
52.855 - stream state was inconsistent.
52.856 -*/
52.857 -
52.858 -/*
52.859 -ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
52.860 - unsigned char FAR *window));
52.861 -
52.862 - Initialize the internal stream state for decompression using inflateBack()
52.863 - calls. The fields zalloc, zfree and opaque in strm must be initialized
52.864 - before the call. If zalloc and zfree are Z_NULL, then the default library-
52.865 - derived memory allocation routines are used. windowBits is the base two
52.866 - logarithm of the window size, in the range 8..15. window is a caller
52.867 - supplied buffer of that size. Except for special applications where it is
52.868 - assured that deflate was used with small window sizes, windowBits must be 15
52.869 - and a 32K byte window must be supplied to be able to decompress general
52.870 - deflate streams.
52.871 -
52.872 - See inflateBack() for the usage of these routines.
52.873 -
52.874 - inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
52.875 - the paramaters are invalid, Z_MEM_ERROR if the internal state could not
52.876 - be allocated, or Z_VERSION_ERROR if the version of the library does not
52.877 - match the version of the header file.
52.878 -*/
52.879 -
52.880 -typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
52.881 -typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
52.882 -
52.883 -ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
52.884 - in_func in, void FAR *in_desc,
52.885 - out_func out, void FAR *out_desc));
52.886 -/*
52.887 - inflateBack() does a raw inflate with a single call using a call-back
52.888 - interface for input and output. This is more efficient than inflate() for
52.889 - file i/o applications in that it avoids copying between the output and the
52.890 - sliding window by simply making the window itself the output buffer. This
52.891 - function trusts the application to not change the output buffer passed by
52.892 - the output function, at least until inflateBack() returns.
52.893 -
52.894 - inflateBackInit() must be called first to allocate the internal state
52.895 - and to initialize the state with the user-provided window buffer.
52.896 - inflateBack() may then be used multiple times to inflate a complete, raw
52.897 - deflate stream with each call. inflateBackEnd() is then called to free
52.898 - the allocated state.
52.899 -
52.900 - A raw deflate stream is one with no zlib or gzip header or trailer.
52.901 - This routine would normally be used in a utility that reads zip or gzip
52.902 - files and writes out uncompressed files. The utility would decode the
52.903 - header and process the trailer on its own, hence this routine expects
52.904 - only the raw deflate stream to decompress. This is different from the
52.905 - normal behavior of inflate(), which expects either a zlib or gzip header and
52.906 - trailer around the deflate stream.
52.907 -
52.908 - inflateBack() uses two subroutines supplied by the caller that are then
52.909 - called by inflateBack() for input and output. inflateBack() calls those
52.910 - routines until it reads a complete deflate stream and writes out all of the
52.911 - uncompressed data, or until it encounters an error. The function's
52.912 - parameters and return types are defined above in the in_func and out_func
52.913 - typedefs. inflateBack() will call in(in_desc, &buf) which should return the
52.914 - number of bytes of provided input, and a pointer to that input in buf. If
52.915 - there is no input available, in() must return zero--buf is ignored in that
52.916 - case--and inflateBack() will return a buffer error. inflateBack() will call
52.917 - out(out_desc, buf, len) to write the uncompressed data buf[0..len-1]. out()
52.918 - should return zero on success, or non-zero on failure. If out() returns
52.919 - non-zero, inflateBack() will return with an error. Neither in() nor out()
52.920 - are permitted to change the contents of the window provided to
52.921 - inflateBackInit(), which is also the buffer that out() uses to write from.
52.922 - The length written by out() will be at most the window size. Any non-zero
52.923 - amount of input may be provided by in().
52.924 -
52.925 - For convenience, inflateBack() can be provided input on the first call by
52.926 - setting strm->next_in and strm->avail_in. If that input is exhausted, then
52.927 - in() will be called. Therefore strm->next_in must be initialized before
52.928 - calling inflateBack(). If strm->next_in is Z_NULL, then in() will be called
52.929 - immediately for input. If strm->next_in is not Z_NULL, then strm->avail_in
52.930 - must also be initialized, and then if strm->avail_in is not zero, input will
52.931 - initially be taken from strm->next_in[0 .. strm->avail_in - 1].
52.932 -
52.933 - The in_desc and out_desc parameters of inflateBack() is passed as the
52.934 - first parameter of in() and out() respectively when they are called. These
52.935 - descriptors can be optionally used to pass any information that the caller-
52.936 - supplied in() and out() functions need to do their job.
52.937 -
52.938 - On return, inflateBack() will set strm->next_in and strm->avail_in to
52.939 - pass back any unused input that was provided by the last in() call. The
52.940 - return values of inflateBack() can be Z_STREAM_END on success, Z_BUF_ERROR
52.941 - if in() or out() returned an error, Z_DATA_ERROR if there was a format
52.942 - error in the deflate stream (in which case strm->msg is set to indicate the
52.943 - nature of the error), or Z_STREAM_ERROR if the stream was not properly
52.944 - initialized. In the case of Z_BUF_ERROR, an input or output error can be
52.945 - distinguished using strm->next_in which will be Z_NULL only if in() returned
52.946 - an error. If strm->next is not Z_NULL, then the Z_BUF_ERROR was due to
52.947 - out() returning non-zero. (in() will always be called before out(), so
52.948 - strm->next_in is assured to be defined if out() returns non-zero.) Note
52.949 - that inflateBack() cannot return Z_OK.
52.950 -*/
52.951 -
52.952 -ZEXTERN int ZEXPORT inflateBackEnd OF((z_streamp strm));
52.953 -/*
52.954 - All memory allocated by inflateBackInit() is freed.
52.955 -
52.956 - inflateBackEnd() returns Z_OK on success, or Z_STREAM_ERROR if the stream
52.957 - state was inconsistent.
52.958 -*/
52.959 -
52.960 -ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
52.961 -/* Return flags indicating compile-time options.
52.962 -
52.963 - Type sizes, two bits each, 00 = 16 bits, 01 = 32, 10 = 64, 11 = other:
52.964 - 1.0: size of uInt
52.965 - 3.2: size of uLong
52.966 - 5.4: size of voidpf (pointer)
52.967 - 7.6: size of z_off_t
52.968 -
52.969 - Compiler, assembler, and debug options:
52.970 - 8: DEBUG
52.971 - 9: ASMV or ASMINF -- use ASM code
52.972 - 10: ZLIB_WINAPI -- exported functions use the WINAPI calling convention
52.973 - 11: 0 (reserved)
52.974 -
52.975 - One-time table building (smaller code, but not thread-safe if true):
52.976 - 12: BUILDFIXED -- build static block decoding tables when needed
52.977 - 13: DYNAMIC_CRC_TABLE -- build CRC calculation tables when needed
52.978 - 14,15: 0 (reserved)
52.979 -
52.980 - Library content (indicates missing functionality):
52.981 - 16: NO_GZCOMPRESS -- gz* functions cannot compress (to avoid linking
52.982 - deflate code when not needed)
52.983 - 17: NO_GZIP -- deflate can't write gzip streams, and inflate can't detect
52.984 - and decode gzip streams (to avoid linking crc code)
52.985 - 18-19: 0 (reserved)
52.986 -
52.987 - Operation variations (changes in library functionality):
52.988 - 20: PKZIP_BUG_WORKAROUND -- slightly more permissive inflate
52.989 - 21: FASTEST -- deflate algorithm with only one, lowest compression level
52.990 - 22,23: 0 (reserved)
52.991 -
52.992 - The sprintf variant used by gzprintf (zero is best):
52.993 - 24: 0 = vs*, 1 = s* -- 1 means limited to 20 arguments after the format
52.994 - 25: 0 = *nprintf, 1 = *printf -- 1 means gzprintf() not secure!
52.995 - 26: 0 = returns value, 1 = void -- 1 means inferred string length returned
52.996 -
52.997 - Remainder:
52.998 - 27-31: 0 (reserved)
52.999 - */
52.1000 -
52.1001 -
52.1002 - /* utility functions */
52.1003 -
52.1004 -/*
52.1005 - The following utility functions are implemented on top of the
52.1006 - basic stream-oriented functions. To simplify the interface, some
52.1007 - default options are assumed (compression level and memory usage,
52.1008 - standard memory allocation functions). The source code of these
52.1009 - utility functions can easily be modified if you need special options.
52.1010 -*/
52.1011 -
52.1012 -ZEXTERN int ZEXPORT compress OF((Bytef *dest, uLongf *destLen,
52.1013 - const Bytef *source, uLong sourceLen));
52.1014 -/*
52.1015 - Compresses the source buffer into the destination buffer. sourceLen is
52.1016 - the byte length of the source buffer. Upon entry, destLen is the total
52.1017 - size of the destination buffer, which must be at least the value returned
52.1018 - by compressBound(sourceLen). Upon exit, destLen is the actual size of the
52.1019 - compressed buffer.
52.1020 - This function can be used to compress a whole file at once if the
52.1021 - input file is mmap'ed.
52.1022 - compress returns Z_OK if success, Z_MEM_ERROR if there was not
52.1023 - enough memory, Z_BUF_ERROR if there was not enough room in the output
52.1024 - buffer.
52.1025 -*/
52.1026 -
52.1027 -ZEXTERN int ZEXPORT compress2 OF((Bytef *dest, uLongf *destLen,
52.1028 - const Bytef *source, uLong sourceLen,
52.1029 - int level));
52.1030 -/*
52.1031 - Compresses the source buffer into the destination buffer. The level
52.1032 - parameter has the same meaning as in deflateInit. sourceLen is the byte
52.1033 - length of the source buffer. Upon entry, destLen is the total size of the
52.1034 - destination buffer, which must be at least the value returned by
52.1035 - compressBound(sourceLen). Upon exit, destLen is the actual size of the
52.1036 - compressed buffer.
52.1037 -
52.1038 - compress2 returns Z_OK if success, Z_MEM_ERROR if there was not enough
52.1039 - memory, Z_BUF_ERROR if there was not enough room in the output buffer,
52.1040 - Z_STREAM_ERROR if the level parameter is invalid.
52.1041 -*/
52.1042 -
52.1043 -ZEXTERN uLong ZEXPORT compressBound OF((uLong sourceLen));
52.1044 -/*
52.1045 - compressBound() returns an upper bound on the compressed size after
52.1046 - compress() or compress2() on sourceLen bytes. It would be used before
52.1047 - a compress() or compress2() call to allocate the destination buffer.
52.1048 -*/
52.1049 -
52.1050 -ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
52.1051 - const Bytef *source, uLong sourceLen));
52.1052 -/*
52.1053 - Decompresses the source buffer into the destination buffer. sourceLen is
52.1054 - the byte length of the source buffer. Upon entry, destLen is the total
52.1055 - size of the destination buffer, which must be large enough to hold the
52.1056 - entire uncompressed data. (The size of the uncompressed data must have
52.1057 - been saved previously by the compressor and transmitted to the decompressor
52.1058 - by some mechanism outside the scope of this compression library.)
52.1059 - Upon exit, destLen is the actual size of the compressed buffer.
52.1060 - This function can be used to decompress a whole file at once if the
52.1061 - input file is mmap'ed.
52.1062 -
52.1063 - uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
52.1064 - enough memory, Z_BUF_ERROR if there was not enough room in the output
52.1065 - buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
52.1066 -*/
52.1067 -
52.1068 -
52.1069 -typedef voidp gzFile;
52.1070 -
52.1071 -ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
52.1072 -/*
52.1073 - Opens a gzip (.gz) file for reading or writing. The mode parameter
52.1074 - is as in fopen ("rb" or "wb") but can also include a compression level
52.1075 - ("wb9") or a strategy: 'f' for filtered data as in "wb6f", 'h' for
52.1076 - Huffman only compression as in "wb1h", or 'R' for run-length encoding
52.1077 - as in "wb1R". (See the description of deflateInit2 for more information
52.1078 - about the strategy parameter.)
52.1079 -
52.1080 - gzopen can be used to read a file which is not in gzip format; in this
52.1081 - case gzread will directly read from the file without decompression.
52.1082 -
52.1083 - gzopen returns NULL if the file could not be opened or if there was
52.1084 - insufficient memory to allocate the (de)compression state; errno
52.1085 - can be checked to distinguish the two cases (if errno is zero, the
52.1086 - zlib error is Z_MEM_ERROR). */
52.1087 -
52.1088 -ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
52.1089 -/*
52.1090 - gzdopen() associates a gzFile with the file descriptor fd. File
52.1091 - descriptors are obtained from calls like open, dup, creat, pipe or
52.1092 - fileno (in the file has been previously opened with fopen).
52.1093 - The mode parameter is as in gzopen.
52.1094 - The next call of gzclose on the returned gzFile will also close the
52.1095 - file descriptor fd, just like fclose(fdopen(fd), mode) closes the file
52.1096 - descriptor fd. If you want to keep fd open, use gzdopen(dup(fd), mode).
52.1097 - gzdopen returns NULL if there was insufficient memory to allocate
52.1098 - the (de)compression state.
52.1099 -*/
52.1100 -
52.1101 -ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
52.1102 -/*
52.1103 - Dynamically update the compression level or strategy. See the description
52.1104 - of deflateInit2 for the meaning of these parameters.
52.1105 - gzsetparams returns Z_OK if success, or Z_STREAM_ERROR if the file was not
52.1106 - opened for writing.
52.1107 -*/
52.1108 -
52.1109 -ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
52.1110 -/*
52.1111 - Reads the given number of uncompressed bytes from the compressed file.
52.1112 - If the input file was not in gzip format, gzread copies the given number
52.1113 - of bytes into the buffer.
52.1114 - gzread returns the number of uncompressed bytes actually read (0 for
52.1115 - end of file, -1 for error). */
52.1116 -
52.1117 -ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
52.1118 - voidpc buf, unsigned len));
52.1119 -/*
52.1120 - Writes the given number of uncompressed bytes into the compressed file.
52.1121 - gzwrite returns the number of uncompressed bytes actually written
52.1122 - (0 in case of error).
52.1123 -*/
52.1124 -
52.1125 -ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
52.1126 -/*
52.1127 - Converts, formats, and writes the args to the compressed file under
52.1128 - control of the format string, as in fprintf. gzprintf returns the number of
52.1129 - uncompressed bytes actually written (0 in case of error). The number of
52.1130 - uncompressed bytes written is limited to 4095. The caller should assure that
52.1131 - this limit is not exceeded. If it is exceeded, then gzprintf() will return
52.1132 - return an error (0) with nothing written. In this case, there may also be a
52.1133 - buffer overflow with unpredictable consequences, which is possible only if
52.1134 - zlib was compiled with the insecure functions sprintf() or vsprintf()
52.1135 - because the secure snprintf() or vsnprintf() functions were not available.
52.1136 -*/
52.1137 -
52.1138 -ZEXTERN int ZEXPORT gzputs OF((gzFile file, const char *s));
52.1139 -/*
52.1140 - Writes the given null-terminated string to the compressed file, excluding
52.1141 - the terminating null character.
52.1142 - gzputs returns the number of characters written, or -1 in case of error.
52.1143 -*/
52.1144 -
52.1145 -ZEXTERN char * ZEXPORT gzgets OF((gzFile file, char *buf, int len));
52.1146 -/*
52.1147 - Reads bytes from the compressed file until len-1 characters are read, or
52.1148 - a newline character is read and transferred to buf, or an end-of-file
52.1149 - condition is encountered. The string is then terminated with a null
52.1150 - character.
52.1151 - gzgets returns buf, or Z_NULL in case of error.
52.1152 -*/
52.1153 -
52.1154 -ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
52.1155 -/*
52.1156 - Writes c, converted to an unsigned char, into the compressed file.
52.1157 - gzputc returns the value that was written, or -1 in case of error.
52.1158 -*/
52.1159 -
52.1160 -ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
52.1161 -/*
52.1162 - Reads one byte from the compressed file. gzgetc returns this byte
52.1163 - or -1 in case of end of file or error.
52.1164 -*/
52.1165 -
52.1166 -ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
52.1167 -/*
52.1168 - Push one character back onto the stream to be read again later.
52.1169 - Only one character of push-back is allowed. gzungetc() returns the
52.1170 - character pushed, or -1 on failure. gzungetc() will fail if a
52.1171 - character has been pushed but not read yet, or if c is -1. The pushed
52.1172 - character will be discarded if the stream is repositioned with gzseek()
52.1173 - or gzrewind().
52.1174 -*/
52.1175 -
52.1176 -ZEXTERN int ZEXPORT gzflush OF((gzFile file, int flush));
52.1177 -/*
52.1178 - Flushes all pending output into the compressed file. The parameter
52.1179 - flush is as in the deflate() function. The return value is the zlib
52.1180 - error number (see function gzerror below). gzflush returns Z_OK if
52.1181 - the flush parameter is Z_FINISH and all output could be flushed.
52.1182 - gzflush should be called only when strictly necessary because it can
52.1183 - degrade compression.
52.1184 -*/
52.1185 -
52.1186 -ZEXTERN z_off_t ZEXPORT gzseek OF((gzFile file,
52.1187 - z_off_t offset, int whence));
52.1188 -/*
52.1189 - Sets the starting position for the next gzread or gzwrite on the
52.1190 - given compressed file. The offset represents a number of bytes in the
52.1191 - uncompressed data stream. The whence parameter is defined as in lseek(2);
52.1192 - the value SEEK_END is not supported.
52.1193 - If the file is opened for reading, this function is emulated but can be
52.1194 - extremely slow. If the file is opened for writing, only forward seeks are
52.1195 - supported; gzseek then compresses a sequence of zeroes up to the new
52.1196 - starting position.
52.1197 -
52.1198 - gzseek returns the resulting offset location as measured in bytes from
52.1199 - the beginning of the uncompressed stream, or -1 in case of error, in
52.1200 - particular if the file is opened for writing and the new starting position
52.1201 - would be before the current position.
52.1202 -*/
52.1203 -
52.1204 -ZEXTERN int ZEXPORT gzrewind OF((gzFile file));
52.1205 -/*
52.1206 - Rewinds the given file. This function is supported only for reading.
52.1207 -
52.1208 - gzrewind(file) is equivalent to (int)gzseek(file, 0L, SEEK_SET)
52.1209 -*/
52.1210 -
52.1211 -ZEXTERN z_off_t ZEXPORT gztell OF((gzFile file));
52.1212 -/*
52.1213 - Returns the starting position for the next gzread or gzwrite on the
52.1214 - given compressed file. This position represents a number of bytes in the
52.1215 - uncompressed data stream.
52.1216 -
52.1217 - gztell(file) is equivalent to gzseek(file, 0L, SEEK_CUR)
52.1218 -*/
52.1219 -
52.1220 -ZEXTERN int ZEXPORT gzeof OF((gzFile file));
52.1221 -/*
52.1222 - Returns 1 when EOF has previously been detected reading the given
52.1223 - input stream, otherwise zero.
52.1224 -*/
52.1225 -
52.1226 -ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
52.1227 -/*
52.1228 - Returns 1 if file is being read directly without decompression, otherwise
52.1229 - zero.
52.1230 -*/
52.1231 -
52.1232 -ZEXTERN int ZEXPORT gzclose OF((gzFile file));
52.1233 -/*
52.1234 - Flushes all pending output if necessary, closes the compressed file
52.1235 - and deallocates all the (de)compression state. The return value is the zlib
52.1236 - error number (see function gzerror below).
52.1237 -*/
52.1238 -
52.1239 -ZEXTERN const char * ZEXPORT gzerror OF((gzFile file, int *errnum));
52.1240 -/*
52.1241 - Returns the error message for the last error which occurred on the
52.1242 - given compressed file. errnum is set to zlib error number. If an
52.1243 - error occurred in the file system and not in the compression library,
52.1244 - errnum is set to Z_ERRNO and the application may consult errno
52.1245 - to get the exact error code.
52.1246 -*/
52.1247 -
52.1248 -ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
52.1249 -/*
52.1250 - Clears the error and end-of-file flags for file. This is analogous to the
52.1251 - clearerr() function in stdio. This is useful for continuing to read a gzip
52.1252 - file that is being written concurrently.
52.1253 -*/
52.1254 -
52.1255 - /* checksum functions */
52.1256 -
52.1257 -/*
52.1258 - These functions are not related to compression but are exported
52.1259 - anyway because they might be useful in applications using the
52.1260 - compression library.
52.1261 -*/
52.1262 -
52.1263 -ZEXTERN uLong ZEXPORT adler32 OF((uLong adler, const Bytef *buf, uInt len));
52.1264 -/*
52.1265 - Update a running Adler-32 checksum with the bytes buf[0..len-1] and
52.1266 - return the updated checksum. If buf is NULL, this function returns
52.1267 - the required initial value for the checksum.
52.1268 - An Adler-32 checksum is almost as reliable as a CRC32 but can be computed
52.1269 - much faster. Usage example:
52.1270 -
52.1271 - uLong adler = adler32(0L, Z_NULL, 0);
52.1272 -
52.1273 - while (read_buffer(buffer, length) != EOF) {
52.1274 - adler = adler32(adler, buffer, length);
52.1275 - }
52.1276 - if (adler != original_adler) error();
52.1277 -*/
52.1278 -
52.1279 -ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
52.1280 - z_off_t len2));
52.1281 -/*
52.1282 - Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
52.1283 - and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
52.1284 - each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
52.1285 - seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
52.1286 -*/
52.1287 -
52.1288 -ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
52.1289 -/*
52.1290 - Update a running CRC-32 with the bytes buf[0..len-1] and return the
52.1291 - updated CRC-32. If buf is NULL, this function returns the required initial
52.1292 - value for the for the crc. Pre- and post-conditioning (one's complement) is
52.1293 - performed within this function so it shouldn't be done by the application.
52.1294 - Usage example:
52.1295 -
52.1296 - uLong crc = crc32(0L, Z_NULL, 0);
52.1297 -
52.1298 - while (read_buffer(buffer, length) != EOF) {
52.1299 - crc = crc32(crc, buffer, length);
52.1300 - }
52.1301 - if (crc != original_crc) error();
52.1302 -*/
52.1303 -
52.1304 -ZEXTERN uLong ZEXPORT crc32_combine OF((uLong crc1, uLong crc2, z_off_t len2));
52.1305 -
52.1306 -/*
52.1307 - Combine two CRC-32 check values into one. For two sequences of bytes,
52.1308 - seq1 and seq2 with lengths len1 and len2, CRC-32 check values were
52.1309 - calculated for each, crc1 and crc2. crc32_combine() returns the CRC-32
52.1310 - check value of seq1 and seq2 concatenated, requiring only crc1, crc2, and
52.1311 - len2.
52.1312 -*/
52.1313 -
52.1314 -
52.1315 - /* various hacks, don't look :) */
52.1316 -
52.1317 -/* deflateInit and inflateInit are macros to allow checking the zlib version
52.1318 - * and the compiler's view of z_stream:
52.1319 - */
52.1320 -ZEXTERN int ZEXPORT deflateInit_ OF((z_streamp strm, int level,
52.1321 - const char *version, int stream_size));
52.1322 -ZEXTERN int ZEXPORT inflateInit_ OF((z_streamp strm,
52.1323 - const char *version, int stream_size));
52.1324 -ZEXTERN int ZEXPORT deflateInit2_ OF((z_streamp strm, int level, int method,
52.1325 - int windowBits, int memLevel,
52.1326 - int strategy, const char *version,
52.1327 - int stream_size));
52.1328 -ZEXTERN int ZEXPORT inflateInit2_ OF((z_streamp strm, int windowBits,
52.1329 - const char *version, int stream_size));
52.1330 -ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
52.1331 - unsigned char FAR *window,
52.1332 - const char *version,
52.1333 - int stream_size));
52.1334 -#define deflateInit(strm, level) \
52.1335 - deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
52.1336 -#define inflateInit(strm) \
52.1337 - inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
52.1338 -#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
52.1339 - deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
52.1340 - (strategy), ZLIB_VERSION, sizeof(z_stream))
52.1341 -#define inflateInit2(strm, windowBits) \
52.1342 - inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
52.1343 -#define inflateBackInit(strm, windowBits, window) \
52.1344 - inflateBackInit_((strm), (windowBits), (window), \
52.1345 - ZLIB_VERSION, sizeof(z_stream))
52.1346 -
52.1347 -
52.1348 -#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
52.1349 - struct internal_state {int dummy;}; /* hack for buggy compilers */
52.1350 -#endif
52.1351 -
52.1352 -ZEXTERN const char * ZEXPORT zError OF((int));
52.1353 -ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp z));
52.1354 -ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
52.1355 -
52.1356 -#ifdef __cplusplus
52.1357 -}
52.1358 -#endif
52.1359 -
52.1360 -#endif /* ZLIB_H */
53.1 --- a/sourcepawn/vm/zlib/zutil.c Tue Nov 07 23:26:40 2006 +0000
53.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
53.3 @@ -1,318 +0,0 @@
53.4 -/* zutil.c -- target dependent utility functions for the compression library
53.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
53.6 - * For conditions of distribution and use, see copyright notice in zlib.h
53.7 - */
53.8 -
53.9 -/* @(#) $Id$ */
53.10 -
53.11 -#include "zutil.h"
53.12 -
53.13 -#ifndef NO_DUMMY_DECL
53.14 -struct internal_state {int dummy;}; /* for buggy compilers */
53.15 -#endif
53.16 -
53.17 -const char * const z_errmsg[10] = {
53.18 -"need dictionary", /* Z_NEED_DICT 2 */
53.19 -"stream end", /* Z_STREAM_END 1 */
53.20 -"", /* Z_OK 0 */
53.21 -"file error", /* Z_ERRNO (-1) */
53.22 -"stream error", /* Z_STREAM_ERROR (-2) */
53.23 -"data error", /* Z_DATA_ERROR (-3) */
53.24 -"insufficient memory", /* Z_MEM_ERROR (-4) */
53.25 -"buffer error", /* Z_BUF_ERROR (-5) */
53.26 -"incompatible version",/* Z_VERSION_ERROR (-6) */
53.27 -""};
53.28 -
53.29 -
53.30 -const char * ZEXPORT zlibVersion()
53.31 -{
53.32 - return ZLIB_VERSION;
53.33 -}
53.34 -
53.35 -uLong ZEXPORT zlibCompileFlags()
53.36 -{
53.37 - uLong flags;
53.38 -
53.39 - flags = 0;
53.40 - switch (sizeof(uInt)) {
53.41 - case 2: break;
53.42 - case 4: flags += 1; break;
53.43 - case 8: flags += 2; break;
53.44 - default: flags += 3;
53.45 - }
53.46 - switch (sizeof(uLong)) {
53.47 - case 2: break;
53.48 - case 4: flags += 1 << 2; break;
53.49 - case 8: flags += 2 << 2; break;
53.50 - default: flags += 3 << 2;
53.51 - }
53.52 - switch (sizeof(voidpf)) {
53.53 - case 2: break;
53.54 - case 4: flags += 1 << 4; break;
53.55 - case 8: flags += 2 << 4; break;
53.56 - default: flags += 3 << 4;
53.57 - }
53.58 - switch (sizeof(z_off_t)) {
53.59 - case 2: break;
53.60 - case 4: flags += 1 << 6; break;
53.61 - case 8: flags += 2 << 6; break;
53.62 - default: flags += 3 << 6;
53.63 - }
53.64 -#ifdef DEBUG
53.65 - flags += 1 << 8;
53.66 -#endif
53.67 -#if defined(ASMV) || defined(ASMINF)
53.68 - flags += 1 << 9;
53.69 -#endif
53.70 -#ifdef ZLIB_WINAPI
53.71 - flags += 1 << 10;
53.72 -#endif
53.73 -#ifdef BUILDFIXED
53.74 - flags += 1 << 12;
53.75 -#endif
53.76 -#ifdef DYNAMIC_CRC_TABLE
53.77 - flags += 1 << 13;
53.78 -#endif
53.79 -#ifdef NO_GZCOMPRESS
53.80 - flags += 1L << 16;
53.81 -#endif
53.82 -#ifdef NO_GZIP
53.83 - flags += 1L << 17;
53.84 -#endif
53.85 -#ifdef PKZIP_BUG_WORKAROUND
53.86 - flags += 1L << 20;
53.87 -#endif
53.88 -#ifdef FASTEST
53.89 - flags += 1L << 21;
53.90 -#endif
53.91 -#ifdef STDC
53.92 -# ifdef NO_vsnprintf
53.93 - flags += 1L << 25;
53.94 -# ifdef HAS_vsprintf_void
53.95 - flags += 1L << 26;
53.96 -# endif
53.97 -# else
53.98 -# ifdef HAS_vsnprintf_void
53.99 - flags += 1L << 26;
53.100 -# endif
53.101 -# endif
53.102 -#else
53.103 - flags += 1L << 24;
53.104 -# ifdef NO_snprintf
53.105 - flags += 1L << 25;
53.106 -# ifdef HAS_sprintf_void
53.107 - flags += 1L << 26;
53.108 -# endif
53.109 -# else
53.110 -# ifdef HAS_snprintf_void
53.111 - flags += 1L << 26;
53.112 -# endif
53.113 -# endif
53.114 -#endif
53.115 - return flags;
53.116 -}
53.117 -
53.118 -#ifdef DEBUG
53.119 -
53.120 -# ifndef verbose
53.121 -# define verbose 0
53.122 -# endif
53.123 -int z_verbose = verbose;
53.124 -
53.125 -void z_error (m)
53.126 - char *m;
53.127 -{
53.128 - fprintf(stderr, "%s\n", m);
53.129 - exit(1);
53.130 -}
53.131 -#endif
53.132 -
53.133 -/* exported to allow conversion of error code to string for compress() and
53.134 - * uncompress()
53.135 - */
53.136 -const char * ZEXPORT zError(err)
53.137 - int err;
53.138 -{
53.139 - return ERR_MSG(err);
53.140 -}
53.141 -
53.142 -#if defined(_WIN32_WCE)
53.143 - /* The Microsoft C Run-Time Library for Windows CE doesn't have
53.144 - * errno. We define it as a global variable to simplify porting.
53.145 - * Its value is always 0 and should not be used.
53.146 - */
53.147 - int errno = 0;
53.148 -#endif
53.149 -
53.150 -#ifndef HAVE_MEMCPY
53.151 -
53.152 -void zmemcpy(dest, source, len)
53.153 - Bytef* dest;
53.154 - const Bytef* source;
53.155 - uInt len;
53.156 -{
53.157 - if (len == 0) return;
53.158 - do {
53.159 - *dest++ = *source++; /* ??? to be unrolled */
53.160 - } while (--len != 0);
53.161 -}
53.162 -
53.163 -int zmemcmp(s1, s2, len)
53.164 - const Bytef* s1;
53.165 - const Bytef* s2;
53.166 - uInt len;
53.167 -{
53.168 - uInt j;
53.169 -
53.170 - for (j = 0; j < len; j++) {
53.171 - if (s1[j] != s2[j]) return 2*(s1[j] > s2[j])-1;
53.172 - }
53.173 - return 0;
53.174 -}
53.175 -
53.176 -void zmemzero(dest, len)
53.177 - Bytef* dest;
53.178 - uInt len;
53.179 -{
53.180 - if (len == 0) return;
53.181 - do {
53.182 - *dest++ = 0; /* ??? to be unrolled */
53.183 - } while (--len != 0);
53.184 -}
53.185 -#endif
53.186 -
53.187 -
53.188 -#ifdef SYS16BIT
53.189 -
53.190 -#ifdef __TURBOC__
53.191 -/* Turbo C in 16-bit mode */
53.192 -
53.193 -# define MY_ZCALLOC
53.194 -
53.195 -/* Turbo C malloc() does not allow dynamic allocation of 64K bytes
53.196 - * and farmalloc(64K) returns a pointer with an offset of 8, so we
53.197 - * must fix the pointer. Warning: the pointer must be put back to its
53.198 - * original form in order to free it, use zcfree().
53.199 - */
53.200 -
53.201 -#define MAX_PTR 10
53.202 -/* 10*64K = 640K */
53.203 -
53.204 -local int next_ptr = 0;
53.205 -
53.206 -typedef struct ptr_table_s {
53.207 - voidpf org_ptr;
53.208 - voidpf new_ptr;
53.209 -} ptr_table;
53.210 -
53.211 -local ptr_table table[MAX_PTR];
53.212 -/* This table is used to remember the original form of pointers
53.213 - * to large buffers (64K). Such pointers are normalized with a zero offset.
53.214 - * Since MSDOS is not a preemptive multitasking OS, this table is not
53.215 - * protected from concurrent access. This hack doesn't work anyway on
53.216 - * a protected system like OS/2. Use Microsoft C instead.
53.217 - */
53.218 -
53.219 -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
53.220 -{
53.221 - voidpf buf = opaque; /* just to make some compilers happy */
53.222 - ulg bsize = (ulg)items*size;
53.223 -
53.224 - /* If we allocate less than 65520 bytes, we assume that farmalloc
53.225 - * will return a usable pointer which doesn't have to be normalized.
53.226 - */
53.227 - if (bsize < 65520L) {
53.228 - buf = farmalloc(bsize);
53.229 - if (*(ush*)&buf != 0) return buf;
53.230 - } else {
53.231 - buf = farmalloc(bsize + 16L);
53.232 - }
53.233 - if (buf == NULL || next_ptr >= MAX_PTR) return NULL;
53.234 - table[next_ptr].org_ptr = buf;
53.235 -
53.236 - /* Normalize the pointer to seg:0 */
53.237 - *((ush*)&buf+1) += ((ush)((uch*)buf-0) + 15) >> 4;
53.238 - *(ush*)&buf = 0;
53.239 - table[next_ptr++].new_ptr = buf;
53.240 - return buf;
53.241 -}
53.242 -
53.243 -void zcfree (voidpf opaque, voidpf ptr)
53.244 -{
53.245 - int n;
53.246 - if (*(ush*)&ptr != 0) { /* object < 64K */
53.247 - farfree(ptr);
53.248 - return;
53.249 - }
53.250 - /* Find the original pointer */
53.251 - for (n = 0; n < next_ptr; n++) {
53.252 - if (ptr != table[n].new_ptr) continue;
53.253 -
53.254 - farfree(table[n].org_ptr);
53.255 - while (++n < next_ptr) {
53.256 - table[n-1] = table[n];
53.257 - }
53.258 - next_ptr--;
53.259 - return;
53.260 - }
53.261 - ptr = opaque; /* just to make some compilers happy */
53.262 - Assert(0, "zcfree: ptr not found");
53.263 -}
53.264 -
53.265 -#endif /* __TURBOC__ */
53.266 -
53.267 -
53.268 -#ifdef M_I86
53.269 -/* Microsoft C in 16-bit mode */
53.270 -
53.271 -# define MY_ZCALLOC
53.272 -
53.273 -#if (!defined(_MSC_VER) || (_MSC_VER <= 600))
53.274 -# define _halloc halloc
53.275 -# define _hfree hfree
53.276 -#endif
53.277 -
53.278 -voidpf zcalloc (voidpf opaque, unsigned items, unsigned size)
53.279 -{
53.280 - if (opaque) opaque = 0; /* to make compiler happy */
53.281 - return _halloc((long)items, size);
53.282 -}
53.283 -
53.284 -void zcfree (voidpf opaque, voidpf ptr)
53.285 -{
53.286 - if (opaque) opaque = 0; /* to make compiler happy */
53.287 - _hfree(ptr);
53.288 -}
53.289 -
53.290 -#endif /* M_I86 */
53.291 -
53.292 -#endif /* SYS16BIT */
53.293 -
53.294 -
53.295 -#ifndef MY_ZCALLOC /* Any system without a special alloc function */
53.296 -
53.297 -#ifndef STDC
53.298 -extern voidp malloc OF((uInt size));
53.299 -extern voidp calloc OF((uInt items, uInt size));
53.300 -extern void free OF((voidpf ptr));
53.301 -#endif
53.302 -
53.303 -voidpf zcalloc (opaque, items, size)
53.304 - voidpf opaque;
53.305 - unsigned items;
53.306 - unsigned size;
53.307 -{
53.308 - if (opaque) items += size - size; /* make compiler happy */
53.309 - return sizeof(uInt) > 2 ? (voidpf)malloc(items * size) :
53.310 - (voidpf)calloc(items, size);
53.311 -}
53.312 -
53.313 -void zcfree (opaque, ptr)
53.314 - voidpf opaque;
53.315 - voidpf ptr;
53.316 -{
53.317 - free(ptr);
53.318 - if (opaque) return; /* make compiler happy */
53.319 -}
53.320 -
53.321 -#endif /* MY_ZCALLOC */
54.1 --- a/sourcepawn/vm/zlib/zutil.h Tue Nov 07 23:26:40 2006 +0000
54.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
54.3 @@ -1,269 +0,0 @@
54.4 -/* zutil.h -- internal interface and configuration of the compression library
54.5 - * Copyright (C) 1995-2005 Jean-loup Gailly.
54.6 - * For conditions of distribution and use, see copyright notice in zlib.h
54.7 - */
54.8 -
54.9 -/* WARNING: this file should *not* be used by applications. It is
54.10 - part of the implementation of the compression library and is
54.11 - subject to change. Applications should only use zlib.h.
54.12 - */
54.13 -
54.14 -/* @(#) $Id$ */
54.15 -
54.16 -#ifndef ZUTIL_H
54.17 -#define ZUTIL_H
54.18 -
54.19 -#define ZLIB_INTERNAL
54.20 -#include "zlib.h"
54.21 -
54.22 -#ifdef STDC
54.23 -# ifndef _WIN32_WCE
54.24 -# include <stddef.h>
54.25 -# endif
54.26 -# include <string.h>
54.27 -# include <stdlib.h>
54.28 -#endif
54.29 -#ifdef NO_ERRNO_H
54.30 -# ifdef _WIN32_WCE
54.31 - /* The Microsoft C Run-Time Library for Windows CE doesn't have
54.32 - * errno. We define it as a global variable to simplify porting.
54.33 - * Its value is always 0 and should not be used. We rename it to
54.34 - * avoid conflict with other libraries that use the same workaround.
54.35 - */
54.36 -# define errno z_errno
54.37 -# endif
54.38 - extern int errno;
54.39 -#else
54.40 -# ifndef _WIN32_WCE
54.41 -# include <errno.h>
54.42 -# endif
54.43 -#endif
54.44 -
54.45 -#ifndef local
54.46 -# define local static
54.47 -#endif
54.48 -/* compile with -Dlocal if your debugger can't find static symbols */
54.49 -
54.50 -typedef unsigned char uch;
54.51 -typedef uch FAR uchf;
54.52 -typedef unsigned short ush;
54.53 -typedef ush FAR ushf;
54.54 -typedef unsigned long ulg;
54.55 -
54.56 -extern const char * const z_errmsg[10]; /* indexed by 2-zlib_error */
54.57 -/* (size given to avoid silly warnings with Visual C++) */
54.58 -
54.59 -#define ERR_MSG(err) z_errmsg[Z_NEED_DICT-(err)]
54.60 -
54.61 -#define ERR_RETURN(strm,err) \
54.62 - return (strm->msg = (char*)ERR_MSG(err), (err))
54.63 -/* To be used only when the state is known to be valid */
54.64 -
54.65 - /* common constants */
54.66 -
54.67 -#ifndef DEF_WBITS
54.68 -# define DEF_WBITS MAX_WBITS
54.69 -#endif
54.70 -/* default windowBits for decompression. MAX_WBITS is for compression only */
54.71 -
54.72 -#if MAX_MEM_LEVEL >= 8
54.73 -# define DEF_MEM_LEVEL 8
54.74 -#else
54.75 -# define DEF_MEM_LEVEL MAX_MEM_LEVEL
54.76 -#endif
54.77 -/* default memLevel */
54.78 -
54.79 -#define STORED_BLOCK 0
54.80 -#define STATIC_TREES 1
54.81 -#define DYN_TREES 2
54.82 -/* The three kinds of block type */
54.83 -
54.84 -#define MIN_MATCH 3
54.85 -#define MAX_MATCH 258
54.86 -/* The minimum and maximum match lengths */
54.87 -
54.88 -#define PRESET_DICT 0x20 /* preset dictionary flag in zlib header */
54.89 -
54.90 - /* target dependencies */
54.91 -
54.92 -#if defined(MSDOS) || (defined(WINDOWS) && !defined(WIN32))
54.93 -# define OS_CODE 0x00
54.94 -# if defined(__TURBOC__) || defined(__BORLANDC__)
54.95 -# if(__STDC__ == 1) && (defined(__LARGE__) || defined(__COMPACT__))
54.96 - /* Allow compilation with ANSI keywords only enabled */
54.97 - void _Cdecl farfree( void *block );
54.98 - void *_Cdecl farmalloc( unsigned long nbytes );
54.99 -# else
54.100 -# include <alloc.h>
54.101 -# endif
54.102 -# else /* MSC or DJGPP */
54.103 -# include <malloc.h>
54.104 -# endif
54.105 -#endif
54.106 -
54.107 -#ifdef AMIGA
54.108 -# define OS_CODE 0x01
54.109 -#endif
54.110 -
54.111 -#if defined(VAXC) || defined(VMS)
54.112 -# define OS_CODE 0x02
54.113 -# define F_OPEN(name, mode) \
54.114 - fopen((name), (mode), "mbc=60", "ctx=stm", "rfm=fix", "mrs=512")
54.115 -#endif
54.116 -
54.117 -#if defined(ATARI) || defined(atarist)
54.118 -# define OS_CODE 0x05
54.119 -#endif
54.120 -
54.121 -#ifdef OS2
54.122 -# define OS_CODE 0x06
54.123 -# ifdef M_I86
54.124 - #include <malloc.h>
54.125 -# endif
54.126 -#endif
54.127 -
54.128 -#if defined(MACOS) || defined(TARGET_OS_MAC)
54.129 -# define OS_CODE 0x07
54.130 -# if defined(__MWERKS__) && __dest_os != __be_os && __dest_os != __win32_os
54.131 -# include <unix.h> /* for fdopen */
54.132 -# else
54.133 -# ifndef fdopen
54.134 -# define fdopen(fd,mode) NULL /* No fdopen() */
54.135 -# endif
54.136 -# endif
54.137 -#endif
54.138 -
54.139 -#ifdef TOPS20
54.140 -# define OS_CODE 0x0a
54.141 -#endif
54.142 -
54.143 -#ifdef WIN32
54.144 -# ifndef __CYGWIN__ /* Cygwin is Unix, not Win32 */
54.145 -# define OS_CODE 0x0b
54.146 -# endif
54.147 -#endif
54.148 -
54.149 -#ifdef __50SERIES /* Prime/PRIMOS */
54.150 -# define OS_CODE 0x0f
54.151 -#endif
54.152 -
54.153 -#if defined(_BEOS_) || defined(RISCOS)
54.154 -# define fdopen(fd,mode) NULL /* No fdopen() */
54.155 -#endif
54.156 -
54.157 -#if (defined(_MSC_VER) && (_MSC_VER > 600))
54.158 -# if defined(_WIN32_WCE)
54.159 -# define fdopen(fd,mode) NULL /* No fdopen() */
54.160 -# ifndef _PTRDIFF_T_DEFINED
54.161 - typedef int ptrdiff_t;
54.162 -# define _PTRDIFF_T_DEFINED
54.163 -# endif
54.164 -# else
54.165 -# define fdopen(fd,type) _fdopen(fd,type)
54.166 -# endif
54.167 -#endif
54.168 -
54.169 - /* common defaults */
54.170 -
54.171 -#ifndef OS_CODE
54.172 -# define OS_CODE 0x03 /* assume Unix */
54.173 -#endif
54.174 -
54.175 -#ifndef F_OPEN
54.176 -# define F_OPEN(name, mode) fopen((name), (mode))
54.177 -#endif
54.178 -
54.179 - /* functions */
54.180 -
54.181 -#if defined(STDC99) || (defined(__TURBOC__) && __TURBOC__ >= 0x550)
54.182 -# ifndef HAVE_VSNPRINTF
54.183 -# define HAVE_VSNPRINTF
54.184 -# endif
54.185 -#endif
54.186 -#if defined(__CYGWIN__)
54.187 -# ifndef HAVE_VSNPRINTF
54.188 -# define HAVE_VSNPRINTF
54.189 -# endif
54.190 -#endif
54.191 -#ifndef HAVE_VSNPRINTF
54.192 -# ifdef MSDOS
54.193 - /* vsnprintf may exist on some MS-DOS compilers (DJGPP?),
54.194 - but for now we just assume it doesn't. */
54.195 -# define NO_vsnprintf
54.196 -# endif
54.197 -# ifdef __TURBOC__
54.198 -# define NO_vsnprintf
54.199 -# endif
54.200 -# ifdef WIN32
54.201 - /* In Win32, vsnprintf is available as the "non-ANSI" _vsnprintf. */
54.202 -# if !defined(vsnprintf) && !defined(NO_vsnprintf)
54.203 -# define vsnprintf _vsnprintf
54.204 -# endif
54.205 -# endif
54.206 -# ifdef __SASC
54.207 -# define NO_vsnprintf
54.208 -# endif
54.209 -#endif
54.210 -#ifdef VMS
54.211 -# define NO_vsnprintf
54.212 -#endif
54.213 -
54.214 -#if defined(pyr)
54.215 -# define NO_MEMCPY
54.216 -#endif
54.217 -#if defined(SMALL_MEDIUM) && !defined(_MSC_VER) && !defined(__SC__)
54.218 - /* Use our own functions for small and medium model with MSC <= 5.0.
54.219 - * You may have to use the same strategy for Borland C (untested).
54.220 - * The __SC__ check is for Symantec.
54.221 - */
54.222 -# define NO_MEMCPY
54.223 -#endif
54.224 -#if defined(STDC) && !defined(HAVE_MEMCPY) && !defined(NO_MEMCPY)
54.225 -# define HAVE_MEMCPY
54.226 -#endif
54.227 -#ifdef HAVE_MEMCPY
54.228 -# ifdef SMALL_MEDIUM /* MSDOS small or medium model */
54.229 -# define zmemcpy _fmemcpy
54.230 -# define zmemcmp _fmemcmp
54.231 -# define zmemzero(dest, len) _fmemset(dest, 0, len)
54.232 -# else
54.233 -# define zmemcpy memcpy
54.234 -# define zmemcmp memcmp
54.235 -# define zmemzero(dest, len) memset(dest, 0, len)
54.236 -# endif
54.237 -#else
54.238 - extern void zmemcpy OF((Bytef* dest, const Bytef* source, uInt len));
54.239 - extern int zmemcmp OF((const Bytef* s1, const Bytef* s2, uInt len));
54.240 - extern void zmemzero OF((Bytef* dest, uInt len));
54.241 -#endif
54.242 -
54.243 -/* Diagnostic functions */
54.244 -#ifdef DEBUG
54.245 -# include <stdio.h>
54.246 - extern int z_verbose;
54.247 - extern void z_error OF((char *m));
54.248 -# define Assert(cond,msg) {if(!(cond)) z_error(msg);}
54.249 -# define Trace(x) {if (z_verbose>=0) fprintf x ;}
54.250 -# define Tracev(x) {if (z_verbose>0) fprintf x ;}
54.251 -# define Tracevv(x) {if (z_verbose>1) fprintf x ;}
54.252 -# define Tracec(c,x) {if (z_verbose>0 && (c)) fprintf x ;}
54.253 -# define Tracecv(c,x) {if (z_verbose>1 && (c)) fprintf x ;}
54.254 -#else
54.255 -# define Assert(cond,msg)
54.256 -# define Trace(x)
54.257 -# define Tracev(x)
54.258 -# define Tracevv(x)
54.259 -# define Tracec(c,x)
54.260 -# define Tracecv(c,x)
54.261 -#endif
54.262 -
54.263 -
54.264 -voidpf zcalloc OF((voidpf opaque, unsigned items, unsigned size));
54.265 -void zcfree OF((voidpf opaque, voidpf ptr));
54.266 -
54.267 -#define ZALLOC(strm, items, size) \
54.268 - (*((strm)->zalloc))((strm)->opaque, (items), (size))
54.269 -#define ZFREE(strm, addr) (*((strm)->zfree))((strm)->opaque, (voidpf)(addr))
54.270 -#define TRY_FREE(s, p) {if (p) ZFREE(s, p);}
54.271 -
54.272 -#endif /* ZUTIL_H */