sourcepawn/jit/dll_exports.cpp
author Nicholas Hastings <skamonkey@gmail.com>
Wed Aug 14 14:20:57 2013 -0400 (2013-08-14)
changeset 4008 490b01aa0683
parent 3983 46f4122981c2
child 4013 6201c1180e0e
permissions -rw-r--r--
Updated some CS:GO gamedata.
danderson@3977
     1
/**
danderson@3977
     2
 * vim: set ts=4 sts=4 sw=4 tw=99 noet:
danderson@3977
     3
 * =============================================================================
danderson@3977
     4
 * SourceMod
danderson@3977
     5
 * Copyright (C) 2004-2008 AlliedModders LLC.  All rights reserved.
danderson@3977
     6
 * =============================================================================
danderson@3977
     7
 *
danderson@3977
     8
 * This program is free software; you can redistribute it and/or modify it under
danderson@3977
     9
 * the terms of the GNU General Public License, version 3.0, as published by the
danderson@3977
    10
 * Free Software Foundation.
danderson@3977
    11
 * 
danderson@3977
    12
 * This program is distributed in the hope that it will be useful, but WITHOUT
danderson@3977
    13
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
danderson@3977
    14
 * FOR A PARTICULAR PURPOSE.  See the GNU General Public License for more
danderson@3977
    15
 * details.
danderson@3977
    16
 *
danderson@3977
    17
 * You should have received a copy of the GNU General Public License along with
danderson@3977
    18
 * this program.  If not, see <http://www.gnu.org/licenses/>.
danderson@3977
    19
 *
danderson@3977
    20
 * As a special exception, AlliedModders LLC gives you permission to link the
danderson@3977
    21
 * code of this program (as well as its derivative works) to "Half-Life 2," the
danderson@3977
    22
 * "Source Engine," the "SourcePawn JIT," and any Game MODs that run on software
danderson@3977
    23
 * by the Valve Corporation.  You must obey the GNU General Public License in
danderson@3977
    24
 * all respects for all other code used.  Additionally, AlliedModders LLC grants
danderson@3977
    25
 * this exception to all derivative works.  AlliedModders LLC defines further
danderson@3977
    26
 * exceptions, found in LICENSE.txt (as of this writing, version JULY-31-2007),
danderson@3977
    27
 * or <http://www.sourcemod.net/license.php>.
danderson@3977
    28
 *
danderson@3977
    29
 * Version: $Id$
danderson@3977
    30
 */
danderson@3977
    31
danderson@3977
    32
#include <sp_vm_api.h>
danderson@3977
    33
#include <stdlib.h>
danderson@3977
    34
#include <stdarg.h>
danderson@3977
    35
#include "x86/jit_x86.h"
danderson@3977
    36
#include "dll_exports.h"
danderson@3977
    37
#include "sp_vm_engine.h"
danderson@3977
    38
#include "engine2.h"
danderson@3977
    39
danderson@3977
    40
using namespace SourcePawn;
danderson@3977
    41
danderson@3977
    42
SourcePawnEngine2 g_engine2;
danderson@3977
    43
danderson@3977
    44
#ifdef SPSHELL
danderson@3977
    45
template <typename T> class AutoT
danderson@3977
    46
{
danderson@3977
    47
public:
danderson@3977
    48
	AutoT(T *t)
danderson@3977
    49
	: t_(t)
danderson@3977
    50
	{
danderson@3977
    51
	}
danderson@3977
    52
	~AutoT()
danderson@3977
    53
	{
danderson@3977
    54
		delete t_;
danderson@3977
    55
	}
danderson@3977
    56
danderson@3977
    57
	operator T *() const {
danderson@3977
    58
		return t_;
danderson@3977
    59
	}
danderson@3977
    60
	bool operator !() const {
danderson@3977
    61
		return !t_;
danderson@3977
    62
	}
danderson@3977
    63
	T * operator ->() const {
danderson@3977
    64
		return t_;
danderson@3977
    65
	}
danderson@3977
    66
private:
danderson@3977
    67
	T *t_;
danderson@3977
    68
};
danderson@3977
    69
danderson@3977
    70
class ShellDebugListener : public IDebugListener
danderson@3977
    71
{
danderson@3977
    72
public:
danderson@3977
    73
	void OnContextExecuteError(IPluginContext *ctx, IContextTrace *error) {
danderson@3977
    74
		int n_err = error->GetErrorCode();
danderson@3977
    75
danderson@3977
    76
		if (n_err != SP_ERROR_NATIVE)
danderson@3977
    77
		{
danderson@3977
    78
			fprintf(stderr, "plugin error: %s\n", error->GetErrorString());
danderson@3977
    79
		}
danderson@3977
    80
danderson@3977
    81
		if (const char *lastname = error->GetLastNative(NULL))
danderson@3977
    82
		{
danderson@3977
    83
			if (const char *custerr = error->GetCustomErrorString())
danderson@3977
    84
			{
danderson@3977
    85
				fprintf(stderr, "Native \"%s\" reported: %s", lastname, custerr);
danderson@3977
    86
			} else {
danderson@3977
    87
				fprintf(stderr, "Native \"%s\" encountered a generic error.", lastname);
danderson@3977
    88
			}
danderson@3977
    89
		}
danderson@3977
    90
danderson@3977
    91
		if (!error->DebugInfoAvailable())
danderson@3977
    92
		{
danderson@3977
    93
			fprintf(stderr, "Debug info not available!\n");
danderson@3977
    94
			return;
danderson@3977
    95
		}
danderson@3977
    96
danderson@3977
    97
		CallStackInfo stk_info;
danderson@3977
    98
		int i = 0;
danderson@3977
    99
		fprintf(stderr, "Displaying call stack trace:\n");
danderson@3977
   100
		while (error->GetTraceInfo(&stk_info))
danderson@3977
   101
		{
danderson@3977
   102
			fprintf(stderr,
danderson@3977
   103
			    "   [%d]  Line %d, %s::%s()",
danderson@3977
   104
				i++,
danderson@3977
   105
				stk_info.line,
danderson@3977
   106
				stk_info.filename,
danderson@3977
   107
				stk_info.function);
danderson@3977
   108
		}
danderson@3977
   109
	}
danderson@3977
   110
danderson@3977
   111
	void OnDebugSpew(const char *msg, ...) {
danderson@3977
   112
#if !defined(NDEBUG) && defined(DEBUG)
danderson@3977
   113
		va_list ap;
danderson@3977
   114
		va_start(ap, msg);
danderson@3977
   115
		vfprintf(stderr, msg, ap);
danderson@3977
   116
		va_end(ap);
danderson@3977
   117
#endif
danderson@3977
   118
	}
danderson@3977
   119
};
danderson@3977
   120
danderson@3977
   121
static cell_t Print(IPluginContext *cx, const cell_t *params)
danderson@3977
   122
{
danderson@3977
   123
	char *p;
danderson@3977
   124
	cx->LocalToString(params[1], &p);
danderson@3977
   125
danderson@3977
   126
	return printf("%s", p);
danderson@3977
   127
}
danderson@3977
   128
danderson@3977
   129
static cell_t PrintNum(IPluginContext *cx, const cell_t *params)
danderson@3977
   130
{
danderson@3977
   131
	return printf("%d\n", params[1]);
danderson@3977
   132
}
danderson@3977
   133
danderson@3977
   134
static cell_t PrintNums(IPluginContext *cx, const cell_t *params)
danderson@3977
   135
{
danderson@3977
   136
	for (size_t i = 1; i <= size_t(params[0]); i++) {
danderson@3977
   137
		int err;
danderson@3977
   138
		cell_t *addr;
danderson@3977
   139
		if ((err = cx->LocalToPhysAddr(params[i], &addr)) != SP_ERROR_NONE)
danderson@3977
   140
			return cx->ThrowNativeErrorEx(err, "Could not read argument");
danderson@3977
   141
		fprintf(stdout, "%d", *addr);
danderson@3977
   142
		if (i != size_t(params[0]))
danderson@3977
   143
			fprintf(stdout, ", ");
danderson@3977
   144
	}
danderson@3977
   145
	fprintf(stdout, "\n");
danderson@3977
   146
	return 1;
danderson@3977
   147
}
danderson@3977
   148
dvander@3983
   149
static cell_t DoNothing(IPluginContext *cx, const cell_t *params)
dvander@3983
   150
{
dvander@3983
   151
	return 1;
dvander@3983
   152
}
dvander@3983
   153
danderson@3977
   154
static void BindNative(IPluginRuntime *rt, const char *name, SPVM_NATIVE_FUNC fn)
danderson@3977
   155
{
danderson@3977
   156
	int err;
danderson@3977
   157
	uint32_t index;
danderson@3977
   158
	if ((err = rt->FindNativeByName(name, &index)) != SP_ERROR_NONE)
danderson@3977
   159
		return;
danderson@3977
   160
danderson@3977
   161
	sp_native_t *native;
danderson@3977
   162
	if (rt->GetNativeByIndex(index, &native) != SP_ERROR_NONE)
danderson@3977
   163
		return;
danderson@3977
   164
danderson@3977
   165
	native->pfn = fn;
danderson@3977
   166
	native->status = SP_NATIVE_BOUND;
danderson@3977
   167
}
danderson@3977
   168
danderson@3977
   169
static cell_t PrintFloat(IPluginContext *cx, const cell_t *params)
danderson@3977
   170
{
danderson@3977
   171
	return printf("%f\n", sp_ctof(params[1]));
danderson@3977
   172
}
danderson@3977
   173
danderson@3977
   174
static int Execute(const char *file)
danderson@3977
   175
{
danderson@3977
   176
	ICompilation *co = g_engine2.StartCompilation();
danderson@3977
   177
	if (!co) {
danderson@3977
   178
		fprintf(stderr, "Could not create a compilation context\n");
danderson@3977
   179
		return 1;
danderson@3977
   180
	}
danderson@3977
   181
danderson@3977
   182
	int err;
danderson@3977
   183
	AutoT<IPluginRuntime> rt(g_engine2.LoadPlugin(co, file, &err));
danderson@3977
   184
	if (!rt) {
danderson@3977
   185
		fprintf(stderr, "Could not load plugin: %s\n", g_engine1.GetErrorString(err));
danderson@3977
   186
		return 1;
danderson@3977
   187
	}
danderson@3977
   188
danderson@3977
   189
	BindNative(rt, "print", Print);
danderson@3977
   190
	BindNative(rt, "printnum", PrintNum);
danderson@3977
   191
	BindNative(rt, "printnums", PrintNums);
danderson@3977
   192
	BindNative(rt, "printfloat", PrintFloat);
dvander@3983
   193
	BindNative(rt, "donothing", DoNothing);
danderson@3977
   194
danderson@3977
   195
	IPluginFunction *fun = rt->GetFunctionByName("main");
danderson@3977
   196
	if (!fun)
danderson@3977
   197
		return 0;
danderson@3977
   198
danderson@3977
   199
	IPluginContext *cx = rt->GetDefaultContext();
danderson@3977
   200
danderson@3977
   201
	int result = fun->Execute2(cx, &err);
danderson@3977
   202
	if (err != SP_ERROR_NONE) {
danderson@3977
   203
		fprintf(stderr, "Error executing main(): %s\n", g_engine1.GetErrorString(err));
danderson@3977
   204
		return 1;
danderson@3977
   205
	}
danderson@3977
   206
danderson@3977
   207
	return result;
danderson@3977
   208
}
danderson@3977
   209
danderson@3977
   210
int main(int argc, char **argv)
danderson@3977
   211
{
danderson@3977
   212
	if (argc != 2) {
danderson@3977
   213
		fprintf(stderr, "Usage: <file>\n");
danderson@3977
   214
		return 1;
danderson@3977
   215
	}
danderson@3977
   216
danderson@3977
   217
	if (!g_engine2.Initialize()) {
danderson@3977
   218
		fprintf(stderr, "Could not initialize ISourcePawnEngine2\n");
danderson@3977
   219
		return 1;
danderson@3977
   220
	}
danderson@3977
   221
danderson@3977
   222
	ShellDebugListener debug;
danderson@3977
   223
	g_engine1.SetDebugListener(&debug);
danderson@3977
   224
danderson@3977
   225
	int errcode = Execute(argv[1]);
danderson@3977
   226
danderson@3977
   227
	g_engine1.SetDebugListener(NULL);
danderson@3977
   228
	g_engine2.Shutdown();
danderson@3977
   229
	return errcode;
danderson@3977
   230
}
danderson@3977
   231
danderson@3977
   232
#else
danderson@3977
   233
EXPORTFUNC ISourcePawnEngine *GetSourcePawnEngine1()
danderson@3977
   234
{
danderson@3977
   235
	return &g_engine1;
danderson@3977
   236
}
danderson@3977
   237
danderson@3977
   238
EXPORTFUNC ISourcePawnEngine2 *GetSourcePawnEngine2()
danderson@3977
   239
{
danderson@3977
   240
	return &g_engine2;
danderson@3977
   241
}
danderson@3977
   242
#endif
danderson@3977
   243
danderson@3977
   244
#if defined __linux__ || defined __APPLE__
danderson@3977
   245
extern "C" void __cxa_pure_virtual(void)
danderson@3977
   246
{
danderson@3977
   247
}
danderson@3977
   248
danderson@3977
   249
void *operator new(size_t size)
danderson@3977
   250
{
danderson@3977
   251
	return malloc(size);
danderson@3977
   252
}
danderson@3977
   253
danderson@3977
   254
void *operator new[](size_t size) 
danderson@3977
   255
{
danderson@3977
   256
	return malloc(size);
danderson@3977
   257
}
danderson@3977
   258
danderson@3977
   259
void operator delete(void *ptr) 
danderson@3977
   260
{
danderson@3977
   261
	free(ptr);
danderson@3977
   262
}
danderson@3977
   263
danderson@3977
   264
void operator delete[](void * ptr)
danderson@3977
   265
{
danderson@3977
   266
	free(ptr);
danderson@3977
   267
}
danderson@3977
   268
#endif
danderson@3977
   269