// 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 . // // 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 . #ifndef _INCLUDE_SPFILE_HEADERS_v2_H #define _INCLUDE_SPFILE_HEADERS_v2_H #include 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