Modernize the smx headers.

This commit is contained in:
David Anderson 2014-08-21 22:16:07 -07:00
parent d91d69f72e
commit 225954a27c
17 changed files with 1029 additions and 250 deletions

View File

@ -36,8 +36,8 @@
* @file sp_vm_types.h
* @brief Contains all run-time SourcePawn structures.
*/
#include "sp_file_headers.h"
#include <stddef.h>
#include <stdint.h>
typedef uint32_t ucell_t; /**< Unsigned 32bit integer */
typedef int32_t cell_t; /**< Basic 32bit signed integer type for plugins */
@ -189,10 +189,25 @@ typedef struct sp_debug_line_s
uint32_t line; /**< Line number */
} sp_debug_line_t;
/**
* @brief These structures are equivalent.
*/
typedef sp_fdbg_arraydim_t sp_debug_arraydim_t;
// Occurs after an fdbg_symbol entry, for each dimension.
typedef struct sp_debug_arraydim_s
{
int16_t tagid; /**< Tag id */
uint32_t size; /**< Size of dimension */
} sp_debug_arraydim_t;
// Same as from <smx/smx-v1-headers.h>.
typedef struct sp_debug_symbol_raw_s
{
int32_t addr; /**< Address rel to DAT or stack frame */
int16_t tagid; /**< Tag id */
uint32_t codestart; /**< Start scope validity in code */
uint32_t codeend; /**< End scope validity in code */
uint8_t ident; /**< Variable type */
uint8_t vclass; /**< Scope class (local vs global) */
uint16_t dimcount; /**< Dimension count (for arrays) */
uint32_t name; /**< Offset into debug nametable */
} sp_debug_symbol_raw_t;
/**
* @brief The majority of this struct is already located in the parent
@ -200,11 +215,11 @@ typedef sp_fdbg_arraydim_t sp_debug_arraydim_t;
*/
typedef struct sp_debug_symbol_s
{
uint32_t codestart; /**< Relocated code address */
uint32_t codeend; /**< Relocated code end address */
const char * name; /**< Relocated name */
sp_debug_arraydim_t *dims; /**< Relocated dimension struct, if any */
sp_fdbg_symbol_t *sym; /**< Pointer to original symbol */
uint32_t codestart; /**< Relocated code address */
uint32_t codeend; /**< Relocated code end address */
const char * name; /**< Relocated name */
sp_debug_arraydim_t *dims; /**< Relocated dimension struct, if any */
sp_debug_symbol_raw_t *sym; /**< Pointer to original symbol */
} sp_debug_symbol_t;
#endif //_INCLUDE_SOURCEPAWN_VM_TYPES_H

View File

@ -0,0 +1,164 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
// =============================================================================
// SourcePawn
// Copyright (C) 2004-2008 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _INCLUDE_SPFILE_HEADERS_H
#define _INCLUDE_SPFILE_HEADERS_H
#include <stddef.h>
#include <stdint.h>
namespace sp {
struct SmxConsts
{
// SourcePawn File Format (SPFF) magic number.
static const uint32_t FILE_MAGIC = 0x53504646;
// File format verison number.
// 0x0101 - Initial version used by spcomp1 and SourceMod 1.0.
// 0x0102 - Used by spcomp1 and SourceMod 1.1+.
// 0x0103 - Used by SourceMod 1.7+.
// 0x0200 - Used by spcomp2.
//
// The major version bits (8-15) indicate a product number. Consumers should
// reject any version for a different product.
//
// The minor version bits (0-7) indicate a compatibility revision. Any minor
// version higher than the current version should be rejected.
static const uint16_t SP1_VERSION_MIN = 0x0101;
static const uint16_t SP1_VERSION_MAX = 0x0103;
static const uint16_t SP2_VERSION_MIN = 0x0200;
static const uint16_t SP2_VERSION_MAX = 0x0200;
// Compression types.
static const uint8_t FILE_COMPRESSION_NONE = 0;
static const uint8_t FILE_COMPRESSION_GZ = 1;
// SourcePawn 1.0.
static const uint8_t CODE_VERSION_JIT1 = 9;
// SourcePawn 1.1.
static const uint8_t CODE_VERSION_JIT2 = 10;
// For SP1 consumers, the container version may not be checked, but usually
// the code version is. This constant allows newer containers to be rejected
// in those applications.
static const uint8_t CODE_VERSION_REJECT = 0x7F;
};
// These structures are byte-packed.
#if defined __GNUC__
# pragma pack(1)
#else
# pragma pack(push)
# pragma pack(1)
#endif
// The very first bytes in a .smx file. The .smx file format is a container for
// arbitrary sections, though to actually load a .smx file certain sections
// must be present. The on-disk format has four major regions, in order:
// 1. The header (sp_file_hdr_t).
// 2. The section list (sp_file_section_t).
// 3. The string table.
// 4. The section contents.
//
// Although any part of the file after the header can be compressed, by default
// only the section contents are, and the section list and string table are not.
typedef struct sp_file_hdr_s
{
// Magic number and version number.
uint32_t magic;
uint16_t version;
// Compression algorithm. If the file is not compressed, then imagesize and
// disksize are the same value, and dataoffs is 0.
//
// The start of the compressed region is indicated by dataoffs. The length
// of the compressed region is (disksize - dataoffs). The amount of memory
// required to hold the decompressed bytes is (imagesize - dataoffs). The
// compressed region should be expanded in-place. That is, bytes before
// "dataoffs" should be retained, and the decompressed region should be
// appended.
//
// |imagesize| is the amount of memory required to hold the entire container
// in memory.
//
// Note: This scheme may seem odd. It's a combination of historical debt and
// previously unspecified behavior. The original .amx file format contained
// an on-disk structure that supported an endian-agnostic variable-length
// encoding of its data section, and this structure was loaded directly into
// memory and used as the VM context. AMX Mod X later developed a container
// format called ".amxx" as a "universal binary" for 32-bit and 64-bit
// plugins. This format dropped compact encoding, but supported gzip. The
// disksize/imagesize oddness made its way to this file format. When .smx
// was created for SourceMod, it persisted even though AMX was dropped
// entirely. So it goes.
uint8_t compression;
uint32_t disksize;
uint32_t imagesize;
// Number of named file sections.
uint8_t sections;
// Offset to the string table. Each string is null-terminated. The string
// table is only used for strings related to parsing the container itself.
// For SourcePawn, a separate ".names" section exists for Pawn-specific data.
uint32_t stringtab;
// Offset to where compression begins.
uint32_t dataoffs;
} sp_file_hdr_t;
// Each section is written immediately after the header.
typedef struct sp_file_section_s
{
uint32_t nameoffs; /**< Offset into the string table. */
uint32_t dataoffs; /**< Offset into the file for the section contents. */
uint32_t size; /**< Size of this section's contents. */
} sp_file_section_t;
// Code section. This is used only in SP1, but is emitted by default for legacy
// systems which check |codeversion| but not the SMX file version.
typedef struct sp_file_code_s
{
uint32_t codesize; /**< Size of the code section. */
uint8_t cellsize; /**< Cellsize in bytes. */
uint8_t codeversion; /**< Version of opcodes supported. */
uint16_t flags; /**< Flags. */
uint32_t main; /**< Address to "main". */
uint32_t code; /**< Offset to bytecode, relative to the start of this section. */
} sp_file_code_t;
#if defined __GNUC__
# pragma pack()
#else
# pragma pack(pop)
#endif
} // namespace sp
#endif //_INCLUDE_SPFILE_HEADERS_H

View File

@ -0,0 +1,266 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
// =============================================================================
// SourcePawn
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _INCLUDE_SPFILE_HEADERS_v1_opcodes_H
#define _INCLUDE_SPFILE_HEADERS_v1_opcodes_H
#include <stddef.h>
#include <stdint.h>
namespace sp {
// Opcodes labelled "UNGEN" cannot be generated by the compiler. Quite a few,
// if they could, make little sense in the context of a JIT and could not
// work anyway. Opcodes technically present in sc4.c/sc7.c (respectively,
// the code emitter and peephole optimizer) are not necessarily ever generated.
// For example, lref.pri and lref.alt would be used if a reference could be
// stored in the global scope; but they can't, so they are unreachable.
//
// Most opcodes have been manually verified. A few have not, as they are only
// produced by the peephole optimizer, or not produced at all, or eliminated
// during optimization. We generate them anyway, just in case, but they have
// not been tested.
// lref.s.alt (phopt only)
// stor.alt (never)
// stor.s.alt (never)
// sref.s.alt (never)
// lidx.b (phopt only, probably impossible)
// idxaddr.b (phopt only, looks difficult)
// move.pri (eliminated in phopt)
// shl.c.pri (eliminated in phopt)
// shl.c.alt (eliminated in phopt)
// shr.c.pri (eliminated in phopt)
// shr.c.alt (eliminated in phopt)
// eq.c.alt (never)
// inc.alt (never)
// dec.alt (never)
// sdiv (never)
// nop (never in function bodies)
//
// Additionally, some opcodes which were supported in the earlier JIT are no
// longer supported because of the above:
// lref.pri/alt
// sref.pri/alt
// sign.pri/alt
#define OPCODE_LIST(_) \
_(NONE, "none") \
_(LOAD_PRI, "load.pri") \
_(LOAD_ALT, "load.alt") \
_(LOAD_S_PRI, "load.s.pri") \
_(LOAD_S_ALT, "load.s.alt") \
_(UNGEN_LREF_PRI, "lref.pri") \
_(UNGEN_LREF_ALT, "lref.alt") \
_(LREF_S_PRI, "lref.s.pri") \
_(LREF_S_ALT, "lref.s.alt") \
_(LOAD_I, "load.i") \
_(LODB_I, "lodb.i") \
_(CONST_PRI, "const.pri") \
_(CONST_ALT, "const.alt") \
_(ADDR_PRI, "addr.pri") \
_(ADDR_ALT, "addr.alt") \
_(STOR_PRI, "stor.pri") \
_(STOR_ALT, "stor.alt") \
_(STOR_S_PRI, "stor.s.pri") \
_(STOR_S_ALT, "stor.s.alt") \
_(UNGEN_SREF_PRI, "sref.pri") \
_(UNGEN_SREF_ALT, "sref.alt") \
_(SREF_S_PRI, "sref.s.pri") \
_(SREF_S_ALT, "sref.s.alt") \
_(STOR_I, "stor.i") \
_(STRB_I, "strb.i") \
_(LIDX, "lidx") \
_(LIDX_B, "lidx.b") \
_(IDXADDR, "idxaddr") \
_(IDXADDR_B, "idxaddr.b") \
_(UNGEN_ALIGN_PRI,"align.pri") \
_(UNGEN_ALIGN_ALT,"align.alt") \
_(UNGEN_LCTRL, "lctrl") \
_(UNGEN_SCTRL, "sctrl") \
_(MOVE_PRI, "move.pri") \
_(MOVE_ALT, "move.alt") \
_(XCHG, "xchg") \
_(PUSH_PRI, "push.pri") \
_(PUSH_ALT, "push.alt") \
_(UNGEN_PUSH_R, "push.r") \
_(PUSH_C, "push.c") \
_(PUSH, "push") \
_(PUSH_S, "push.s") \
_(POP_PRI, "pop.pri") \
_(POP_ALT, "pop.alt") \
_(STACK, "stack") \
_(HEAP, "heap") \
_(PROC, "proc") \
_(UNGEN_RET, "ret") \
_(RETN, "retn") \
_(CALL, "call") \
_(UNGEN_CALL_PRI, "call.pri") \
_(JUMP, "jump") \
_(UNGEN_JREL, "jrel") \
_(JZER, "jzer") \
_(JNZ, "jnz") \
_(JEQ, "jeq") \
_(JNEQ, "jneq") \
_(UNGEN_JLESS, "jsless") \
_(UNGEN_JLEQ, "jleq") \
_(UNGEN_JGRTR, "jgrtr") \
_(UNGEN_JGEQ, "jgeq") \
_(JSLESS, "jsless") \
_(JSLEQ, "jsleq") \
_(JSGRTR, "jsgrtr") \
_(JSGEQ, "jsgeq") \
_(SHL, "shl") \
_(SHR, "shr") \
_(SSHR, "sshr") \
_(SHL_C_PRI, "shl.c.pri") \
_(SHL_C_ALT, "shl.c.alt") \
_(SHR_C_PRI, "shr.c.pri") \
_(SHR_C_ALT, "shr.c.alt") \
_(SMUL, "smul") \
_(SDIV, "sdiv") \
_(SDIV_ALT, "sdiv.alt") \
_(UNGEN_UMUL, "umul") \
_(UNGEN_UDIV, "udiv") \
_(UNGEN_UDIV_ALT, "udiv.alt") \
_(ADD, "add") \
_(SUB, "sub") \
_(SUB_ALT, "sub.alt") \
_(AND, "and") \
_(OR, "or") \
_(XOR, "xor") \
_(NOT, "not") \
_(NEG, "neg") \
_(INVERT, "invert") \
_(ADD_C, "add.c") \
_(SMUL_C, "smul.c") \
_(ZERO_PRI, "zero.pri") \
_(ZERO_ALT, "zero.alt") \
_(ZERO, "zero") \
_(ZERO_S, "zero.s") \
_(UNGEN_SIGN_PRI, "sign.pri") \
_(UNGEN_SIGN_ALT, "sign.alt") \
_(EQ, "eq") \
_(NEQ, "neq") \
_(UNGEN_LESS, "less") \
_(UNGEN_LEQ, "leq") \
_(UNGEN_GRTR, "grtr") \
_(UNGEN_GEQ, "geq") \
_(SLESS, "sless") \
_(SLEQ, "sleq") \
_(SGRTR, "sgrtr") \
_(SGEQ, "sgeq") \
_(EQ_C_PRI, "eq.c.pri") \
_(EQ_C_ALT, "eq.c.alt") \
_(INC_PRI, "inc.pri") \
_(INC_ALT, "inc.alt") \
_(INC, "inc") \
_(INC_S, "inc.s") \
_(INC_I, "inc.i") \
_(DEC_PRI, "dec.pri") \
_(DEC_ALT, "dec.alt") \
_(DEC, "dec") \
_(DEC_S, "dec.s") \
_(DEC_I, "dec.i") \
_(MOVS, "movs") \
_(UNGEN_CMPS, "cmps") \
_(FILL, "fill") \
_(HALT, "halt") \
_(BOUNDS, "bounds") \
_(UNGEN_SYSREQ_PRI,"sysreq.pri") \
_(SYSREQ_C, "sysreq.c") \
_(UNGEN_FILE, "file") \
_(UNGEN_LINE, "line") \
_(UNGEN_SYMBOL, "symbol") \
_(UNGEN_SRANGE, "srange") \
_(UNGEN_JUMP_PRI, "jump.pri") \
_(SWITCH, "switch") \
_(CASETBL, "casetbl") \
_(SWAP_PRI, "swap.pri") \
_(SWAP_ALT, "swap.alt") \
_(PUSH_ADR, "push.adr") \
_(NOP, "nop") \
_(SYSREQ_N, "sysreq.n") \
_(UNGEN_SYMTAG, "symtag") \
_(BREAK, "break") \
_(PUSH2_C, "push2.c") \
_(PUSH2, "push2") \
_(PUSH2_S, "push2.s") \
_(PUSH2_ADR, "push2.adr") \
_(PUSH3_C, "push3.c") \
_(PUSH3, "push3") \
_(PUSH3_S, "push3.s") \
_(PUSH3_ADR, "push3.adr") \
_(PUSH4_C, "push4.c") \
_(PUSH4, "push4") \
_(PUSH4_S, "push4.s") \
_(PUSH4_ADR, "push4.adr") \
_(PUSH5_C, "push5.c") \
_(PUSH5, "push5") \
_(PUSH5_S, "push5.s") \
_(PUSH5_ADR, "push5.adr") \
_(LOAD_BOTH, "load.both") \
_(LOAD_S_BOTH, "load.s.both") \
_(CONST, "const") \
_(CONST_S, "const.s") \
_(UNGEN_SYSREQ_D, "sysreq.d") \
_(UNGEB_SYSREQ_ND,"sysreq.nd") \
_(TRACKER_PUSH_C, "trk.push.c") \
_(TRACKER_POP_SETHEAP,"trk.pop") \
_(GENARRAY, "genarray") \
_(GENARRAY_Z, "genarray.z") \
_(STRADJUST_PRI, "stradjust.pri") \
_(UNGEN_STKADJUST,"stackadjust") \
_(ENDPROC, "endproc") \
_(FABS, "fabs") \
_(FLOAT, "float") \
_(FLOATADD, "float.add") \
_(FLOATSUB, "float.sub") \
_(FLOATMUL, "float.mul") \
_(FLOATDIV, "float.div") \
_(RND_TO_NEAREST, "round") \
_(RND_TO_FLOOR, "floor") \
_(RND_TO_CEIL, "ceil") \
_(RND_TO_ZERO, "rndtozero") \
_(FLOATCMP, "float.cmp") \
_(FLOAT_GT, "float.gt") \
_(FLOAT_GE, "float.ge") \
_(FLOAT_LT, "float.lt") \
_(FLOAT_LE, "float.le") \
_(FLOAT_NE, "float.ne") \
_(FLOAT_EQ, "float.eq") \
_(FLOAT_NOT, "float.not")
enum OPCODE {
#define _(op, text) OP_##op,
OPCODE_LIST(_)
#undef _
OPCODES_TOTAL
};
} // namespace sp
#endif // _INCLUDE_SPFILE_HEADERS_v1_opcodes_H

View File

@ -0,0 +1,205 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
// =============================================================================
// SourcePawn
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _INCLUDE_SPFILE_HEADERS_v1_H
#define _INCLUDE_SPFILE_HEADERS_v1_H
#include <stddef.h>
#include <stdint.h>
#include <smx/smx-headers.h>
namespace sp {
// These structures are byte-packed.
#if defined __GNUC__
# pragma pack(1)
#else
# pragma pack(push)
# pragma pack(1)
#endif
// (Obsolete) debug-information is present.
static const uint16_t CODEFLAG_DEBUG = 0x1;
// The ".data" section.
typedef struct sp_file_data_s
{
uint32_t datasize; /**< Size of data section in memory */
uint32_t memsize; /**< Total mem required (includes data) */
uint32_t data; /**< File offset to data (helper) */
} sp_file_data_t;
// The ".publics" section.
typedef struct sp_file_publics_s
{
uint32_t address; /**< Address relative to code section */
uint32_t name; /**< Index into nametable */
} sp_file_publics_t;
// The ".natives" section.
typedef struct sp_file_natives_s
{
uint32_t name; /**< Index into nametable */
} sp_file_natives_t;
// The ".pubvars" section.
typedef struct sp_file_pubvars_s
{
uint32_t address; /**< Address relative to the DAT section */
uint32_t name; /**< Index into nametable */
} sp_file_pubvars_t;
// The ".tags" section.
typedef struct sp_file_tag_s
{
uint32_t tag_id; /**< Tag ID from compiler */
uint32_t name; /**< Index into nametable */
} sp_file_tag_t;
// The ".dbg.info" section.
typedef struct sp_fdbg_info_s
{
uint32_t num_files; /**< number of files */
uint32_t num_lines; /**< number of lines */
uint32_t num_syms; /**< number of symbols */
uint32_t num_arrays; /**< number of symbols which are arrays */
} sp_fdbg_info_t;
// The ".dbg.files" section.
typedef struct sp_fdbg_file_s
{
uint32_t addr; /**< Address into code */
uint32_t name; /**< Offset into debug nametable */
} sp_fdbg_file_t;
// The ".dbg.lines" section.
typedef struct sp_fdbg_line_s
{
uint32_t addr; /**< Address into code */
uint32_t line; /**< Line number */
} sp_fdbg_line_t;
static const uint8_t IDENT_VARIABLE = 1; // Scalar local variable.
static const uint8_t IDENT_REFERENCE = 2; // Reference to a scalar argument.
static const uint8_t IDENT_ARRAY = 3; // Array with known dimensions.
static const uint8_t IDENT_REFARRAY = 4; // Array with unknown dimensions.
static const uint8_t IDENT_FUNCTION = 9; // Symbolic function.
static const uint8_t IDENT_VARARGS = 11; // Variadic argument (...).
// The ".dbg.symbols" table.
typedef struct sp_fdbg_symbol_s
{
int32_t addr; /**< Address rel to DAT or stack frame */
int16_t tagid; /**< Tag id */
uint32_t codestart; /**< Start scope validity in code */
uint32_t codeend; /**< End scope validity in code */
uint8_t ident; /**< Variable type */
uint8_t vclass; /**< Scope class (local vs global) */
uint16_t dimcount; /**< Dimension count (for arrays) */
uint32_t name; /**< Offset into debug nametable */
} sp_fdbg_symbol_t;
// Occurs after an fdbg_symbol entry, for each dimension.
typedef struct sp_fdbg_arraydim_s
{
int16_t tagid; /**< Tag id */
uint32_t size; /**< Size of dimension */
} sp_fdbg_arraydim_t;
// Typedef for the ".names" section.
typedef char * sp_file_nametab_t;
// Header for the ".dbg.natives" section. It is followed by a number of
// sp_fdbg_native_t entries.
typedef struct sp_fdbg_ntvtab_s
{
uint32_t num_entries; /**< Number of entries. */
} sp_fdbg_ntvtab_t;
// An entry in the .dbg.natives section. Each is followed by an
// sp_fdbg_ntvarg_t for each argument.
typedef struct sp_fdbg_native_s
{
uint32_t index; /**< Native index in the plugin. */
uint32_t name; /**< Offset into debug nametable. */
int16_t tagid; /**< Return tag. */
uint16_t nargs; /**< Number of formal arguments. */
} sp_fdbg_native_t;
static const uint8_t IDENT_NATIVE_VARARGS = 1;
// Each entry is followed by an sp_fdbg_arraydim_t for each dimcount.
typedef struct sp_fdbg_ntvarg_s
{
uint8_t ident; /**< Variable type */
int16_t tagid; /**< Tag id */
uint16_t dimcount; /**< Dimension count (for arrays) */
uint32_t name; /**< Offset into debug nametable */
} sp_fdbg_ntvarg_t;
#if defined __GNUC__
# pragma pack() /* reset default packing */
#else
# pragma pack(pop) /* reset previous packing */
#endif
// The packing for files changed by accident for a small window of time, and
// some files may have unparsable debug information using sp_fdbg_arraydim_t or
// sp_fdbg_symbol_t.
//
// If the file version is >= 0x0102, all structures will be packed. If the
// file version is < 0x0101, and the ".dbg.natives" table is present,
// all structures will be packed.
//
// If the version is 0x0101 and ".dbg.natives" is not present, then you must
// use the unpacked versions of those structures below. There is an extremely
// small chance, if the plugin used no natives, that the packing is
// indeterminate. This case is unlikely to be interesting, but if such a file
// exists, the only solution is to re-parse if the data looks corrupt.
typedef struct sp_u_fdbg_arraydim_s
{
int16_t tagid; /**< Tag id */
uint32_t size; /**< Size of dimension */
} sp_u_fdbg_arraydim_t;
typedef struct sp_u_fdbg_symbol_s
{
int32_t addr; /**< Address rel to DAT or stack frame */
int16_t tagid; /**< Tag id */
uint32_t codestart; /**< Start scope validity in code */
uint32_t codeend; /**< End scope validity in code */
uint8_t ident; /**< Variable type */
uint8_t vclass; /**< Scope class (local vs global) */
uint16_t dimcount; /**< Dimension count (for arrays) */
uint32_t name; /**< Offset into debug nametable */
} sp_u_fdbg_symbol_t;
} // namespace sp
#endif //_INCLUDE_SPFILE_HEADERS_v1_H

View File

@ -0,0 +1,128 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
// =============================================================================
// SourcePawn
// Copyright (C) 2004-2014 AlliedModders LLC. All rights reserved.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _include_spfile_headers_v2_opcodes_h_
#define _include_spfile_headers_v2_opcodes_h_
namespace sp {
// Opcode definitions:
// number symbol name pops pushes length flags
OPDEF(0x00, NOP, "nop", 0, 0, 1, 0)
// Basic stack ops.
OPDEF(0x01, POP, "pop", 1, 0, 1, 0)
OPDEF(0x02, PUSH_TRUE, "push.true", 0, 1, 1, 0)
OPDEF(0x03, PUSH_FALSE, "push.false", 0, 1, 1, 0)
OPDEF(0x04, PUSH_NULL, "push.null", 0, 1, 1, 0)
OPDEF(0x05, PUSH_I8, "push.i8", 0, 1, 2, 0)
OPDEF(0x06, PUSH_I32, "push.i32", 0, 1, 5, 0)
OPDEF(0x07, PUSH_I64, "push.i64", 0, 1, 9, 0)
ODPEF(0x08, PUSH_F32, "push.f32", 0, 1, 5, 0)
OPDEF(0x09, PUSH_F64, "push.f64", 0, 1, 9, 0)
OPDEF(0x0A, PUSH_STR, "push.s", 0, 1, 5, 0)
// Get/set local variables.
OPDEF(0x10, GETLOCAL, "getlocal", 0, 1, 2, 0)
OPDEF(0x11, GETLOCAL_W, "getlocal.w", 0, 1, 3, 0)
OPDEF(0x12, GETLOCAL_0, "getlocal.0", 0, 1, 1, 0)
OPDEF(0x13, GETLOCAL_1, "getlocal.1", 0, 1, 1, 0)
OPDEF(0x14, GETLOCAL_2, "getlocal.2", 0, 1, 1, 0)
OPDEF(0x15, GETLOCAL_3, "getlocal.3", 0, 1, 1, 0)
OPDEF(0x18, SETLOCAL, "setlocal", 1, 0, 2, 0)
OPDEF(0x19, SETLOCAL_W, "setlocal.w", 1, 0, 3, 0)
OPDEF(0x1A, SETLOCAL_0, "setlocal.0", 1, 0, 1, 0)
OPDEF(0x1B, SETLOCAL_1, "setlocal.1", 1, 0, 1, 0)
OPDEF(0x1C, SETLOCAL_2, "setlocal.2", 1, 0, 1, 0)
OPDEF(0x1D, SETLOCAL_3, "setlocal.3", 1, 0, 1, 0)
// Local variable references.
OPDEF(0x1E, REFLOCAL, "reflocal", 0, 1, 3, 0)
OPDEF(0x1F, LDREF, "ldref", 1, 1, 1, 0)
OPDEF(0x20, STREF, "stref", 1, 0, 1, 0)
// Math operators.
OPDEF(0x40, ADD, "add", 2, 1, 1, 0)
OPDEF(0x41, SUB, "sub", 2, 1, 1, 0)
OPDEF(0x42, MUL, "mul", 2, 1, 1, 0)
OPDEF(0x43, DIV, "div", 2, 1, 1, 0)
OPDEF(0x44, MOD, "mod", 2, 1, 1, 0)
OPDEF(0x45, NEG, "neg", 1, 1, 1, 0)
OPDEF(0x46, SHR, "shr", 2, 1, 1, 0)
OPDEF(0x47, USHR, "ushr", 2, 1, 1, 0)
OPDEF(0x48, SHL, "shl", 2, 1, 1, 0)
OPDEF(0x49, BITOR, "bitor", 2, 1, 1, 0)
OPDEF(0x4A, BITAND, "bitand", 2, 1, 1, 0)
OPDEF(0x4B, BITXOR, "bitxor", 2, 1, 1, 0)
OPDEF(0x4C, BITNOT, "bitnot", 1, 1, 1, 0)
// Logical operators.
OPDEF(0x60, AND, "and", 2, 1, 1, 0)
OPDEF(0x61, OR, "or", 2, 1, 1, 0)
OPDEF(0x62, NOT, "not", 1, 1, 1, 0)
OPDEF(0x63, LT, "lt", 2, 1, 1, 0)
OPDEF(0x64, LE, "le", 2, 1, 1, 0)
OPDEF(0x65, GT, "gt", 2, 1, 1, 0)
OPDEF(0x66, GE, "ge", 2, 1, 1, 0)
OPDEF(0x67, EQ, "eq", 2, 1, 1, 0)
OPDEF(0x68, NE, "ne", 2, 1, 1, 0)
// Branching operators.
OPDEF(0x70, JUMP, "jump", 0, 0, 1, 0)
OPDEF(0x71, JT, "jt", 1, 0, 1, 0)
OPDEF(0x72, JF, "jf", 1, 0, 1, 0)
OPDEF(0x73, JLT, "jlt", 2, 0, 1, 0)
OPDEF(0x74, JLE, "jle", 2, 0, 1, 0)
OPDEF(0x75, JGT, "jgt", 2, 0, 1, 0)
OPDEF(0x76, JGE, "jge", 2, 0, 1, 0)
OPDEF(0x77, JEQ, "jeq", 2, 0, 1, 0)
OPDEF(0x78, JNE, "jne", 2, 0, 1, 0)
// Function calling.
//
// The low 4 bits of the index for OP_CALL and OP_CALL_A indicate the type
// of call:
// 0000 - 0x0 : Invoke a method constant such as a native or global function.
// Bits 4-31 are an index into the .methods table.
//
// Call is followed by a method identifier.
OPDEF(0x90, CALL, "call", -1, -1, 5, 0)
// Same as call.a but followed with a variadic argument count.
OPDEF(0x91, CALL_A, "call.a", -1, -1, 9, 0)
// Array has a typeid and pops a length off the stack.
OPDEF(0x96, ARRAY, "newarray", 1, 1, 5, 0)
// Fixedarray has an offset into the .types table.
OPDEF(0x97, FIXEDARRAY, "fixedarray", 0, 1, 5, 0)
// Advanced stack operations.
OPDEF(0xB0, DUP, "dup", 1, 2, 1, 0)
} // namespace sp
#endif // _include_spfile_headers_v2_opcodes_h_

View File

@ -0,0 +1,218 @@
// vim: set sts=2 ts=8 sw=2 tw=99 et:
// =============================================================================
// SourcePawn
// Copyright (C) 2004-2014 AlliedModders LLC. All rights RESERVED.
// =============================================================================
//
// This program is free software; you can redistribute it and/or modify it under
// the terms of the GNU General Public License, version 3.0, as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along with
// this program. If not, see <http://www.gnu.org/licenses/>.
//
// As a special exception, AlliedModders LLC gives you permission to link the
// code of this program (as well as its derivative works) to "Half-Life 2," the
// "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
// by the Valve Corporation. You must obey the GNU General Public License in
// all respects for all other code used. Additionally, AlliedModders LLC grants
// this exception to all derivative works. AlliedModders LLC defines further
// exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
// or <http://www.sourcemod.net/license.php>.
#ifndef _INCLUDE_SPFILE_HEADERS_v2_H
#define _INCLUDE_SPFILE_HEADERS_v2_H
#include <smx-headers.h>
namespace sp {
// These structures are byte-packed.
#if defined __GNUC__
# pragma pack(1)
#else
# pragma pack(push)
# pragma pack(1)
#endif
// Tables present in smx v2:
// .names Blob of null-terminated strings.
// .methods Table of smx_method_t entries.
// .pcode Blob of smx_pcode_header_t entries.
// .globals Table of smx_global_var_t entries.
// .types Blob of type information.
// TypeSpec is a variable-length encoding referenced anywhere that "typespec"
// is specified.
//
// Whenever a TypeSpec is referenced from outside the .types table, specifically
// as a "typeid", it has an encoding to save space: If the id is < 0x20, then
// the id is a single-byte TypeSpec. Otherwise, the |id - 0x20| is an offset
// into the .types section.
enum class TypeSpec : uint8_t
{
// The void type is special in that it is not a storable type.
void_t = 0x0,
// Standard C++ datatypes.
boolean = 0x1,
RESERVED_int8 = 0x2,
RESERVED_uint8 = 0x3,
RESERVED_int16 = 0x4,
RESERVED_uint16 = 0x5,
int32 = 0x6,
RESERVED_uint32 = 0x7,
RESERVED_int64 = 0x8,
RESERVED_uint64 = 0x9,
// platform-width int and uint.
RESERVED_intptr = 0xA,
RESERVED_uintptr = 0xB,
float32 = 0xC,
RESERVED_float64 = 0xD,
// char8 is semantically an alias for int8.
char8 = 0xE,
RESERVED_char32 = 0xF, // Full unicode point.
RESERVED_string = 0x16, // String reference.
RESERVED_object = 0x17, // Opaque object reference.
// Followed by an int32 index into the .classes table.
RESERVED_classdef = 0x40,
// Followed by an int32 index into the .structs table.
RESERVED_structdef = 0x41,
// Followed by:
// [int8 formalCount] ; Number of formal parameters, counting varargs.
// [typespec *formals] ; Sequence of formal parameter specifications.
//
// When the type spec is for a method definition (for example, the .method
// table), then each type in |formals| must begin with "named" (0x7e) or,
// if it is the last formal, may be "variadic" (0x7a).
method = 0x50,
// Fixed arrays have their size as part of their type, are copied by-value,
// and passed by-reference.
//
// Followed by:
// typespec type ; Type specification of innermost elements.
// uint8 rank ; Number of dimensions
// int32* dims ; One dimension for each rank.
fixedarray = 0x60,
// Arrays are true arrays. They are copied by-reference and passed by-
// reference.
//
// Followed by:
// typesec type ; Type specification of innermost elements.
// uint8 rank ; Number of dimensions.
RESERVED_array = 0x61,
// Only legal as the initial byte or byte following "named" (0x7e) in a
// parameter for a method signature.
//
// Followed by a typespec. Only typespecs < 0x60 ar elegal.
byref = 0x70,
// Only legal as the initial byte or byte following "named" (0x7e) in a
// parameter for a method signature.
//
// Followed by a typespec.
variadic = 0x7A,
// Only legal as the initial byte in a parameter or local variable signature.
//
// Followed by:
// uint32 name ; Index into the .names section.
// typespec type ; Type.
named = 0x7E,
// For readability, this may be emitted at the end of typespec lists. It must
// not be emitted at the end of nested typespecs.
terminator = 0x7F
};
// Flags for method definitions.
enum class MethodFlags : uint32_t
{
STATIC = 0x1,
VARIADIC = 0x2,
PUBLIC = 0x4,
NATIVE = 0x8,
OPTIONAL = 0x10
};
// Specifies an entry in the .methods table.
struct smx_method_t
{
// Offset into the .names section.
uint32_t name;
MethodFlags flags;
// Offset into .types, which must point at a TypeSpec::method.
uint32_t typespec;
// Offset into .pcode. If flags contains NATIVE, this must be 0.
uint32_t address;
};
enum class GlobalVarFlags : uint32_t
{
PUBLIC = 0x04,
CONST = 0x08
};
// Specifies an entry in the .globals table.
struct smx_global_var_t
{
// Offset into the .names section.
uint32_t name;
GlobalVarFlags flags;
// TypeId of the global.
uint32_t type_id;
};
// Specifies the layout we expect at a valid pcode starting position.
struct smx_pcode_header_t
{
// Must be 0.
uint32_t reserved;
// Number of local variables.
uint16_t nlocals;
// Maximum depth of the operand stack.
uint16_t max_depth;
// Pointer to .types section where local information begins.
uint32_t local_specs;
// Number of bytes of pcode in the method.
uint32_t length;
};
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
// DO NOT DEFINE NEW STRUCTURES BELOW.
// !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
#if defined __GNUC__
# pragma pack()
#else
# pragma pack(pop)
#endif
} // namespace sp
#endif // _INCLUDE_SPFILE_HEADERS_v2_H

View File

@ -12,6 +12,9 @@ binary.compiler.includes += [
os.path.join(builder.sourcePath, 'public', 'jit'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
os.path.join(builder.sourcePath, 'knight', 'shared'),
# The include path for SP v2 stuff.
os.path.join(builder.sourcePath, 'sourcepawn', 'include'),
]
if builder.target_platform == 'linux':

View File

@ -11,6 +11,7 @@
#include "md5/md5.h"
using namespace sp;
using namespace SourcePawn;
static inline bool
@ -171,9 +172,9 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
if (!(m_plugin.pcode) && !strcmp(nameptr, ".code")) {
sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs);
if (cod->codeversion < SP_CODEVERS_JIT1)
if (cod->codeversion < SmxConsts::CODE_VERSION_JIT1)
return SP_ERROR_CODE_TOO_OLD;
if (cod->codeversion > SP_CODEVERS_JIT2)
if (cod->codeversion > SmxConsts::CODE_VERSION_JIT2)
return SP_ERROR_CODE_TOO_NEW;
m_plugin.pcode = base + secptr->dataoffs + cod->code;
@ -266,7 +267,7 @@ int BaseRuntime::CreateFromMemory(sp_file_hdr_t *hdr, uint8_t *base)
if (m_plugin.pcode == NULL || m_plugin.data == NULL)
return SP_ERROR_FILE_FORMAT;
if ((m_plugin.flags & SP_FLAG_DEBUG) && (
if ((m_plugin.flags & sp::CODEFLAG_DEBUG) && (
!(m_plugin.debug.files) ||
!(m_plugin.debug.lines) ||
!(m_plugin.debug.symbols) ||

View File

@ -37,7 +37,7 @@ IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file
/* Rewind for safety */
fread(&hdr, sizeof(sp_file_hdr_t), 1, fp);
if (hdr.magic != SPFILE_MAGIC)
if (hdr.magic != SmxConsts::FILE_MAGIC)
{
error = SP_ERROR_FILE_FORMAT;
goto return_error;
@ -45,7 +45,7 @@ IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file
switch (hdr.compression)
{
case SPFILE_COMPRESSION_GZ:
case SmxConsts::FILE_COMPRESSION_GZ:
{
uint32_t uncompsize = hdr.imagesize - hdr.dataoffs;
uint32_t compsize = hdr.disksize - hdr.dataoffs;
@ -77,7 +77,7 @@ IPluginRuntime *SourcePawnEngine2::LoadPlugin(ICompilation *co, const char *file
free(uncompdata);
break;
}
case SPFILE_COMPRESSION_NONE:
case SmxConsts::FILE_COMPRESSION_NONE:
{
base = (uint8_t *)malloc(hdr.imagesize);
rewind(fp);

View File

@ -22,6 +22,7 @@
#define STACK_MARGIN 64
using namespace sp;
using namespace SourcePawn;
static inline bool

View File

@ -3,7 +3,9 @@
#define _INCLUDE_SOURCEPAWN_JIT_SHARED_H_
#include <sp_vm_api.h>
#include <smx/smx-v1.h>
using namespace sp;
using namespace SourcePawn;
#define SP_MAX_RETURN_STACK 1024

View File

@ -31,6 +31,7 @@
#include "opcodes.h"
#include "jit_shared.h"
using namespace sp;
using namespace SourcePawn;
const char *OpcodeNames[] = {

View File

@ -32,235 +32,10 @@
#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_OPCODES_H_
#define _INCLUDE_SOURCEPAWN_JIT_X86_OPCODES_H_
#include <sp_vm_api.h>
#include <smx/smx-v1-opcodes.h>
#include "jit_shared.h"
// Opcodes labelled "UNGEN" cannot be generated by the compiler. Quite a few,
// if they could, make little sense in the context of a JIT and could not
// work anyway. Opcodes technically present in sc4.c/sc7.c (respectively,
// the code emitter and peephole optimizer) are not necessarily ever generated.
// For example, lref.pri and lref.alt would be used if a reference could be
// stored in the global scope; but they can't, so they are unreachable.
//
// Most opcodes have been manually verified. A few have not, as they are only
// produced by the peephole optimizer, or not produced at all, or eliminated
// during optimization. We generate them anyway, just in case, but they have
// not been tested.
// lref.s.alt (phopt only)
// stor.alt (never)
// stor.s.alt (never)
// sref.s.alt (never)
// lidx.b (phopt only, probably impossible)
// idxaddr.b (phopt only, looks difficult)
// move.pri (eliminated in phopt)
// shl.c.pri (eliminated in phopt)
// shl.c.alt (eliminated in phopt)
// shr.c.pri (eliminated in phopt)
// shr.c.alt (eliminated in phopt)
// eq.c.alt (never)
// inc.alt (never)
// dec.alt (never)
// sdiv (never)
// nop (never in function bodies)
//
// Additionally, some opcodes which were supported in the earlier JIT are no
// longer supported because of the above:
// lref.pri/alt
// sref.pri/alt
// sign.pri/alt
#define OPCODE_LIST(_) \
_(NONE, "none") \
_(LOAD_PRI, "load.pri") \
_(LOAD_ALT, "load.alt") \
_(LOAD_S_PRI, "load.s.pri") \
_(LOAD_S_ALT, "load.s.alt") \
_(UNGEN_LREF_PRI, "lref.pri") \
_(UNGEN_LREF_ALT, "lref.alt") \
_(LREF_S_PRI, "lref.s.pri") \
_(LREF_S_ALT, "lref.s.alt") \
_(LOAD_I, "load.i") \
_(LODB_I, "lodb.i") \
_(CONST_PRI, "const.pri") \
_(CONST_ALT, "const.alt") \
_(ADDR_PRI, "addr.pri") \
_(ADDR_ALT, "addr.alt") \
_(STOR_PRI, "stor.pri") \
_(STOR_ALT, "stor.alt") \
_(STOR_S_PRI, "stor.s.pri") \
_(STOR_S_ALT, "stor.s.alt") \
_(UNGEN_SREF_PRI, "sref.pri") \
_(UNGEN_SREF_ALT, "sref.alt") \
_(SREF_S_PRI, "sref.s.pri") \
_(SREF_S_ALT, "sref.s.alt") \
_(STOR_I, "stor.i") \
_(STRB_I, "strb.i") \
_(LIDX, "lidx") \
_(LIDX_B, "lidx.b") \
_(IDXADDR, "idxaddr") \
_(IDXADDR_B, "idxaddr.b") \
_(UNGEN_ALIGN_PRI,"align.pri") \
_(UNGEN_ALIGN_ALT,"align.alt") \
_(UNGEN_LCTRL, "lctrl") \
_(UNGEN_SCTRL, "sctrl") \
_(MOVE_PRI, "move.pri") \
_(MOVE_ALT, "move.alt") \
_(XCHG, "xchg") \
_(PUSH_PRI, "push.pri") \
_(PUSH_ALT, "push.alt") \
_(UNGEN_PUSH_R, "push.r") \
_(PUSH_C, "push.c") \
_(PUSH, "push") \
_(PUSH_S, "push.s") \
_(POP_PRI, "pop.pri") \
_(POP_ALT, "pop.alt") \
_(STACK, "stack") \
_(HEAP, "heap") \
_(PROC, "proc") \
_(UNGEN_RET, "ret") \
_(RETN, "retn") \
_(CALL, "call") \
_(UNGEN_CALL_PRI, "call.pri") \
_(JUMP, "jump") \
_(UNGEN_JREL, "jrel") \
_(JZER, "jzer") \
_(JNZ, "jnz") \
_(JEQ, "jeq") \
_(JNEQ, "jneq") \
_(UNGEN_JLESS, "jsless") \
_(UNGEN_JLEQ, "jleq") \
_(UNGEN_JGRTR, "jgrtr") \
_(UNGEN_JGEQ, "jgeq") \
_(JSLESS, "jsless") \
_(JSLEQ, "jsleq") \
_(JSGRTR, "jsgrtr") \
_(JSGEQ, "jsgeq") \
_(SHL, "shl") \
_(SHR, "shr") \
_(SSHR, "sshr") \
_(SHL_C_PRI, "shl.c.pri") \
_(SHL_C_ALT, "shl.c.alt") \
_(SHR_C_PRI, "shr.c.pri") \
_(SHR_C_ALT, "shr.c.alt") \
_(SMUL, "smul") \
_(SDIV, "sdiv") \
_(SDIV_ALT, "sdiv.alt") \
_(UNGEN_UMUL, "umul") \
_(UNGEN_UDIV, "udiv") \
_(UNGEN_UDIV_ALT, "udiv.alt") \
_(ADD, "add") \
_(SUB, "sub") \
_(SUB_ALT, "sub.alt") \
_(AND, "and") \
_(OR, "or") \
_(XOR, "xor") \
_(NOT, "not") \
_(NEG, "neg") \
_(INVERT, "invert") \
_(ADD_C, "add.c") \
_(SMUL_C, "smul.c") \
_(ZERO_PRI, "zero.pri") \
_(ZERO_ALT, "zero.alt") \
_(ZERO, "zero") \
_(ZERO_S, "zero.s") \
_(UNGEN_SIGN_PRI, "sign.pri") \
_(UNGEN_SIGN_ALT, "sign.alt") \
_(EQ, "eq") \
_(NEQ, "neq") \
_(UNGEN_LESS, "less") \
_(UNGEN_LEQ, "leq") \
_(UNGEN_GRTR, "grtr") \
_(UNGEN_GEQ, "geq") \
_(SLESS, "sless") \
_(SLEQ, "sleq") \
_(SGRTR, "sgrtr") \
_(SGEQ, "sgeq") \
_(EQ_C_PRI, "eq.c.pri") \
_(EQ_C_ALT, "eq.c.alt") \
_(INC_PRI, "inc.pri") \
_(INC_ALT, "inc.alt") \
_(INC, "inc") \
_(INC_S, "inc.s") \
_(INC_I, "inc.i") \
_(DEC_PRI, "dec.pri") \
_(DEC_ALT, "dec.alt") \
_(DEC, "dec") \
_(DEC_S, "dec.s") \
_(DEC_I, "dec.i") \
_(MOVS, "movs") \
_(UNGEN_CMPS, "cmps") \
_(FILL, "fill") \
_(HALT, "halt") \
_(BOUNDS, "bounds") \
_(UNGEN_SYSREQ_PRI,"sysreq.pri") \
_(SYSREQ_C, "sysreq.c") \
_(UNGEN_FILE, "file") \
_(UNGEN_LINE, "line") \
_(UNGEN_SYMBOL, "symbol") \
_(UNGEN_SRANGE, "srange") \
_(UNGEN_JUMP_PRI, "jump.pri") \
_(SWITCH, "switch") \
_(CASETBL, "casetbl") \
_(SWAP_PRI, "swap.pri") \
_(SWAP_ALT, "swap.alt") \
_(PUSH_ADR, "push.adr") \
_(NOP, "nop") \
_(SYSREQ_N, "sysreq.n") \
_(UNGEN_SYMTAG, "symtag") \
_(BREAK, "break") \
_(PUSH2_C, "push2.c") \
_(PUSH2, "push2") \
_(PUSH2_S, "push2.s") \
_(PUSH2_ADR, "push2.adr") \
_(PUSH3_C, "push3.c") \
_(PUSH3, "push3") \
_(PUSH3_S, "push3.s") \
_(PUSH3_ADR, "push3.adr") \
_(PUSH4_C, "push4.c") \
_(PUSH4, "push4") \
_(PUSH4_S, "push4.s") \
_(PUSH4_ADR, "push4.adr") \
_(PUSH5_C, "push5.c") \
_(PUSH5, "push5") \
_(PUSH5_S, "push5.s") \
_(PUSH5_ADR, "push5.adr") \
_(LOAD_BOTH, "load.both") \
_(LOAD_S_BOTH, "load.s.both") \
_(CONST, "const") \
_(CONST_S, "const.s") \
_(UNGEN_SYSREQ_D, "sysreq.d") \
_(UNGEB_SYSREQ_ND,"sysreq.nd") \
_(TRACKER_PUSH_C, "trk.push.c") \
_(TRACKER_POP_SETHEAP,"trk.pop") \
_(GENARRAY, "genarray") \
_(GENARRAY_Z, "genarray.z") \
_(STRADJUST_PRI, "stradjust.pri") \
_(UNGEN_STKADJUST,"stackadjust") \
_(ENDPROC, "endproc") \
_(FABS, "fabs") \
_(FLOAT, "float") \
_(FLOATADD, "float.add") \
_(FLOATSUB, "float.sub") \
_(FLOATMUL, "float.mul") \
_(FLOATDIV, "float.div") \
_(RND_TO_NEAREST, "round") \
_(RND_TO_FLOOR, "floor") \
_(RND_TO_CEIL, "ceil") \
_(RND_TO_ZERO, "rndtozero") \
_(FLOATCMP, "float.cmp") \
_(FLOAT_GT, "float.gt") \
_(FLOAT_GE, "float.ge") \
_(FLOAT_LT, "float.lt") \
_(FLOAT_LE, "float.le") \
_(FLOAT_NE, "float.ne") \
_(FLOAT_EQ, "float.eq") \
_(FLOAT_NOT, "float.not")
enum OPCODE {
#define _(op, text) OP_##op,
OPCODE_LIST(_)
#undef _
OPCODES_TOTAL
};
typedef sp::OPCODE OPCODE;
namespace SourcePawn {
void SpewOpcode(const sp_plugin_t *plugin, cell_t *start, cell_t *cip);

View File

@ -738,7 +738,7 @@ int DebugInfo::LookupFunction(ucell_t addr, const char **name)
{
sym = (sp_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION
if (sym->ident == sp::IDENT_FUNCTION
&& sym->codestart <= addr
&& sym->codeend > addr)
{
@ -769,7 +769,7 @@ int DebugInfo::LookupFunction(ucell_t addr, const char **name)
{
sym = (sp_u_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION
if (sym->ident == sp::IDENT_FUNCTION
&& sym->codestart <= addr
&& sym->codeend > addr)
{

View File

@ -34,7 +34,6 @@
#include <assert.h>
#include "sp_vm_types.h"
#include <KeCodeAllocator.h>
#include "sp_file_headers.h"
#include "sp_vm_engine.h"
#include "zlib/zlib.h"
#include "sp_vm_basecontext.h"

View File

@ -40,6 +40,7 @@
#include "watchdog_timer.h"
#include "interpreter.h"
using namespace sp;
using namespace Knight;
#if defined USE_UNGEN_OPCODES
@ -230,7 +231,7 @@ GetFunctionName(const sp_plugin_t *plugin, uint32_t offs)
for (iter = 0; iter < max; iter++) {
sym = (sp_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION && sym->codestart <= offs && sym->codeend > offs)
if (sym->ident == sp::IDENT_FUNCTION && sym->codestart <= offs && sym->codeend > offs)
return plugin->debug.stringbase + sym->name;
if (sym->dimcount > 0) {
@ -252,7 +253,7 @@ GetFunctionName(const sp_plugin_t *plugin, uint32_t offs)
for (iter = 0; iter < max; iter++) {
sym = (sp_u_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION && sym->codestart <= offs && sym->codeend > offs)
if (sym->ident == sp::IDENT_FUNCTION && sym->codestart <= offs && sym->codeend > offs)
return plugin->debug.stringbase + sym->name;
if (sym->dimcount > 0) {