dvander@163: /* vim: set ts=4 sw=4 tw=99 et: dvander@163: * dvander@71: * Copyright (C) 2012 David Anderson dvander@71: * dvander@163: * This file is part of SourcePawn. dvander@71: * dvander@163: * SourcePawn is free software: you can redistribute it and/or modify it under dvander@71: * the terms of the GNU General Public License as published by the Free dvander@71: * Software Foundation, either version 3 of the License, or (at your option) dvander@71: * any later version. dvander@71: * dvander@163: * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY dvander@71: * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS dvander@71: * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. dvander@71: * dvander@71: * You should have received a copy of the GNU General Public License along with dvander@163: * SourcePawn. If not, see http://www.gnu.org/licenses/. dvander@71: */ dvander@71: #include dvander@161: #include dvander@163: #include dvander@71: #include "../include/keima.h" dvander@71: dvander@161: using namespace Ke; dvander@71: dvander@161: class MessageReporter : public IMessageReporter dvander@69: { dvander@69: public: dvander@69: void onOutOfMemory() { dvander@69: fprintf(stderr, "Out of memory!\n"); dvander@69: } dvander@69: void onUncaughtException(const char *message) { dvander@69: fprintf(stderr, "Uncaught exception: %s\n", message); dvander@69: dvander@161: IStackFrameIterator *iter = Keima::NewStackFrameIterator(); dvander@69: unsigned index = 0; dvander@174: while (!iter->done() && index < 10) { dvander@69: fprintf(stderr, "[%d] %s (%s line %d)\n", dvander@69: index, dvander@69: iter->function(), dvander@69: iter->source(), dvander@69: iter->lineNumber()); dvander@69: iter->prev(); dvander@69: index++; dvander@69: } dvander@69: } dvander@71: virtual void beginCompilationErrors(const char *file) { dvander@71: fprintf(stderr, "\nDisplaying compilation errors for \"%s\"\n", file); dvander@71: } dvander@71: virtual void reportCompilationError(const char *message, unsigned line, unsigned col) { dvander@71: fprintf(stderr, " line %d, col %d: %s\n", line, col, message); dvander@71: } dvander@71: virtual void endCompilationErrors() { dvander@71: } dvander@71: } s_Reporter; dvander@71: dvander@163: intptr_t PrintFloat(void *blah, intptr_t *params) dvander@71: { dvander@163: fprintf(stdout, "%f", *reinterpret_cast(¶ms[1])); dvander@163: return 0; dvander@163: } dvander@71: dvander@163: intptr_t PrintNum(void *blah, intptr_t *params) dvander@163: { dvander@163: fprintf(stdout, "%i", *reinterpret_cast(¶ms[1])); dvander@163: return 0; dvander@163: } dvander@71: dvander@163: intptr_t PrintString(void *blah, intptr_t *params) dvander@71: { dvander@163: fprintf(stdout, "%s", *reinterpret_cast(¶ms[1])); dvander@163: return 0; dvander@71: } dvander@71: dvander@71: int main(int argc, char **argv) dvander@71: { dvander@71: if (argc < 2) { dvander@71: fprintf(stderr, "Usage: \n"); dvander@71: return 1; dvander@71: } dvander@71: dvander@161: if (!Keima::Initialize()) dvander@71: return 1; dvander@163: dvander@163: int rval = 0; dvander@163: dvander@161: Keima::InstallMessageReporter(&s_Reporter); dvander@71: { dvander@161: HandleScope scope; dvander@161: Local module = Compile(argv[1]); dvander@71: if (!module) dvander@71: return 1; dvander@71: dvander@163: Keima::CollectGarbage(); dvander@163: dvander@163: // Look for a public named "main". dvander@163: Local fun; dvander@163: for (unsigned i = 0; i < module->numPublics(); i++) { dvander@163: if (strcmp(module->getPublic(i)->name()->chars(), "main") == 0) { dvander@163: fun = module->getPublic(i); dvander@163: break; dvander@163: } dvander@163: } dvander@163: dvander@163: for (unsigned i = 0; i < module->numNatives(); i++) { dvander@163: Local native = module->getNative(i); dvander@161: dvander@163: if (strcmp(native->name()->chars(), "PrintFloat") == 0) dvander@163: native->bind(reinterpret_cast(PrintFloat)); dvander@163: else if (strcmp(native->name()->chars(), "PrintNum") == 0) dvander@163: native->bind(reinterpret_cast(PrintNum)); dvander@163: else if (strcmp(native->name()->chars(), "PrintString") == 0) dvander@163: native->bind(reinterpret_cast(PrintString)); dvander@163: } dvander@71: dvander@163: dvander@163: if (!fun) { dvander@163: fprintf(stdout, "Plugin compiles!\nNot running; no public 'main'.\n"); dvander@163: } else { dvander@163: if (!Keima::Invoke(fun, NULL, 0, true, &rval)) dvander@163: rval = 1; dvander@163: } dvander@71: } dvander@71: dvander@161: Keima::Shutdown(); dvander@163: dvander@163: return rval; dvander@71: } danderson@92: danderson@92: /* Overload a few things to prevent libstdc++ linking */ danderson@92: #if defined __linux__ || defined __APPLE__ danderson@92: extern "C" void __cxa_pure_virtual(void) danderson@92: { danderson@92: } danderson@92: danderson@92: void *operator new(size_t size) danderson@92: { dvander@163: return malloc(size); danderson@92: } danderson@92: danderson@92: void *operator new[](size_t size) danderson@92: { dvander@163: return malloc(size); danderson@92: } danderson@92: danderson@92: void operator delete(void *ptr) danderson@92: { dvander@163: free(ptr); danderson@92: } danderson@92: danderson@92: void operator delete[](void * ptr) danderson@92: { dvander@163: free(ptr); danderson@92: } danderson@92: #endif danderson@92: