Merge branch 'calli-2'

This commit is contained in:
David Anderson 2014-08-22 09:58:14 -07:00
commit f42651a813
16 changed files with 901 additions and 250 deletions

View File

@ -36,8 +36,8 @@
* @file sp_vm_types.h * @file sp_vm_types.h
* @brief Contains all run-time SourcePawn structures. * @brief Contains all run-time SourcePawn structures.
*/ */
#include <stddef.h>
#include "sp_file_headers.h" #include <stdint.h>
typedef uint32_t ucell_t; /**< Unsigned 32bit integer */ typedef uint32_t ucell_t; /**< Unsigned 32bit integer */
typedef int32_t cell_t; /**< Basic 32bit signed integer type for plugins */ 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 */ uint32_t line; /**< Line number */
} sp_debug_line_t; } sp_debug_line_t;
/** // Occurs after an fdbg_symbol entry, for each dimension.
* @brief These structures are equivalent. typedef struct sp_debug_arraydim_s
*/ {
typedef sp_fdbg_arraydim_t sp_debug_arraydim_t; 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 * @brief The majority of this struct is already located in the parent
@ -204,7 +219,7 @@ typedef struct sp_debug_symbol_s
uint32_t codeend; /**< Relocated code end address */ uint32_t codeend; /**< Relocated code end address */
const char * name; /**< Relocated name */ const char * name; /**< Relocated name */
sp_debug_arraydim_t *dims; /**< Relocated dimension struct, if any */ sp_debug_arraydim_t *dims; /**< Relocated dimension struct, if any */
sp_fdbg_symbol_t *sym; /**< Pointer to original symbol */ sp_debug_symbol_raw_t *sym; /**< Pointer to original symbol */
} sp_debug_symbol_t; } sp_debug_symbol_t;
#endif //_INCLUDE_SOURCEPAWN_VM_TYPES_H #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,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'),
os.path.join(builder.sourcePath, 'public', 'jit', 'x86'), os.path.join(builder.sourcePath, 'public', 'jit', 'x86'),
os.path.join(builder.sourcePath, 'knight', 'shared'), 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': if builder.target_platform == 'linux':

View File

@ -11,6 +11,7 @@
#include "md5/md5.h" #include "md5/md5.h"
using namespace sp;
using namespace SourcePawn; using namespace SourcePawn;
static inline bool 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")) { if (!(m_plugin.pcode) && !strcmp(nameptr, ".code")) {
sp_file_code_t *cod = (sp_file_code_t *)(base + secptr->dataoffs); 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; 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; return SP_ERROR_CODE_TOO_NEW;
m_plugin.pcode = base + secptr->dataoffs + cod->code; 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) if (m_plugin.pcode == NULL || m_plugin.data == NULL)
return SP_ERROR_FILE_FORMAT; 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.files) ||
!(m_plugin.debug.lines) || !(m_plugin.debug.lines) ||
!(m_plugin.debug.symbols) || !(m_plugin.debug.symbols) ||

View File

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

View File

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

View File

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

View File

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

View File

@ -32,235 +32,10 @@
#ifndef _INCLUDE_SOURCEPAWN_JIT_X86_OPCODES_H_ #ifndef _INCLUDE_SOURCEPAWN_JIT_X86_OPCODES_H_
#define _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, typedef sp::OPCODE OPCODE;
// 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 SourcePawn { namespace SourcePawn {
void SpewOpcode(const sp_plugin_t *plugin, cell_t *start, cell_t *cip); 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; sym = (sp_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION if (sym->ident == sp::IDENT_FUNCTION
&& sym->codestart <= addr && sym->codestart <= addr
&& sym->codeend > addr) && sym->codeend > addr)
{ {
@ -769,7 +769,7 @@ int DebugInfo::LookupFunction(ucell_t addr, const char **name)
{ {
sym = (sp_u_fdbg_symbol_t *)cursor; sym = (sp_u_fdbg_symbol_t *)cursor;
if (sym->ident == SP_SYM_FUNCTION if (sym->ident == sp::IDENT_FUNCTION
&& sym->codestart <= addr && sym->codestart <= addr
&& sym->codeend > addr) && sym->codeend > addr)
{ {

View File

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

View File

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