04827466b0
This removes one the last remnants of the SourceMod 1.0 VM implementation. The new parser introduces a number of design changes in the VM. First, the VM now takes greater responsibility for validating and sanity checking the structure of the SMX container format. Previously, malformed SMX files could easily crash SourcePawn. The loader now rejects files that have out-of-bounds offsets or incomplete sections. Complex sections, like debug info or the code stream, are verified lazily. Internally, the sp_plugin_t structure has been removed. It has been replaced by a new LegacyImage class, designed to be independent from the SPVM API. This potentially lets us load code streams from non-.smx containers. More importantly, it removes a lot of bookkeeping and pre-computed state from PluginRuntime. The LegacyImage class is now responsible for handling debug info as well. PluginRuntime is now intended to hold only cached or immutable data, and PluginContext holds all VM state. As such PluginContext is now responsible for allocating a plugin's runtime memory, not PluginRuntime. Finally, some aspects of the loading process have been cleaned up. The decompression and image handoff logic should now be easier to understand.
142 lines
3.8 KiB
C++
142 lines
3.8 KiB
C++
/**
|
|
* vim: set ts=8 sw=2 tw=99 sts=2 et:
|
|
* =============================================================================
|
|
* SourceMod
|
|
* 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>.
|
|
*
|
|
* Version: $Id$
|
|
*/
|
|
#include "opcodes.h"
|
|
|
|
using namespace sp;
|
|
using namespace SourcePawn;
|
|
|
|
const char *OpcodeNames[] = {
|
|
#define _(op, text) text,
|
|
OPCODE_LIST(_)
|
|
#undef _
|
|
NULL
|
|
};
|
|
|
|
#ifdef JIT_SPEW
|
|
void
|
|
SourcePawn::SpewOpcode(const sp_plugin_t *plugin, cell_t *start, cell_t *cip)
|
|
{
|
|
fprintf(stdout, " [%05d:%04d]", cip - (cell_t *)plugin->pcode, cip - start);
|
|
|
|
if (*cip >= OPCODES_TOTAL) {
|
|
fprintf(stdout, " unknown-opcode\n");
|
|
return;
|
|
}
|
|
|
|
OPCODE op = (OPCODE)*cip;
|
|
fprintf(stdout, " %s ", OpcodeNames[op]);
|
|
|
|
switch (op) {
|
|
case OP_PUSH_C:
|
|
case OP_PUSH_ADR:
|
|
case OP_SHL_C_PRI:
|
|
case OP_SHL_C_ALT:
|
|
case OP_SHR_C_PRI:
|
|
case OP_SHR_C_ALT:
|
|
case OP_ADD_C:
|
|
case OP_SMUL_C:
|
|
case OP_EQ_C_PRI:
|
|
case OP_EQ_C_ALT:
|
|
case OP_TRACKER_PUSH_C:
|
|
case OP_STACK:
|
|
case OP_PUSH_S:
|
|
case OP_HEAP:
|
|
case OP_GENARRAY:
|
|
case OP_GENARRAY_Z:
|
|
case OP_CONST_PRI:
|
|
case OP_CONST_ALT:
|
|
fprintf(stdout, "%d", cip[1]);
|
|
break;
|
|
|
|
case OP_JUMP:
|
|
case OP_JZER:
|
|
case OP_JNZ:
|
|
case OP_JEQ:
|
|
case OP_JNEQ:
|
|
case OP_JSLESS:
|
|
case OP_JSGRTR:
|
|
case OP_JSGEQ:
|
|
case OP_JSLEQ:
|
|
fprintf(stdout, "%05d:%04d",
|
|
cip[1] / 4,
|
|
((cell_t *)plugin->pcode + cip[1] / 4) - start);
|
|
break;
|
|
|
|
case OP_SYSREQ_C:
|
|
case OP_SYSREQ_N:
|
|
{
|
|
uint32_t index = cip[1];
|
|
if (index < plugin->num_natives)
|
|
fprintf(stdout, "%s", plugin->natives[index].name);
|
|
if (op == OP_SYSREQ_N)
|
|
fprintf(stdout, " ; (%d args, index %d)", cip[2], index);
|
|
else
|
|
fprintf(stdout, " ; (index %d)", index);
|
|
break;
|
|
}
|
|
|
|
case OP_PUSH2_C:
|
|
case OP_PUSH2:
|
|
case OP_PUSH2_S:
|
|
case OP_PUSH2_ADR:
|
|
fprintf(stdout, "%d, %d", cip[1], cip[2]);
|
|
break;
|
|
|
|
case OP_PUSH3_C:
|
|
case OP_PUSH3:
|
|
case OP_PUSH3_S:
|
|
case OP_PUSH3_ADR:
|
|
fprintf(stdout, "%d, %d, %d", cip[1], cip[2], cip[3]);
|
|
break;
|
|
|
|
case OP_PUSH4_C:
|
|
case OP_PUSH4:
|
|
case OP_PUSH4_S:
|
|
case OP_PUSH4_ADR:
|
|
fprintf(stdout, "%d, %d, %d, %d", cip[1], cip[2], cip[3], cip[4]);
|
|
break;
|
|
|
|
case OP_PUSH5_C:
|
|
case OP_PUSH5:
|
|
case OP_PUSH5_S:
|
|
case OP_PUSH5_ADR:
|
|
fprintf(stdout, "%d, %d, %d, %d, %d", cip[1], cip[2], cip[3], cip[4], cip[5]);
|
|
break;
|
|
|
|
default:
|
|
break;
|
|
}
|
|
|
|
fprintf(stdout, "\n");
|
|
}
|
|
#endif
|
|
|