src/main.cpp
author David Anderson <dvander@alliedmods.net>
Sat Dec 22 18:22:14 2012 -0800 (2012-12-22)
changeset 230 fb3cd08bc7fb
parent 196 9904633b1dfc
child 232 2b8512340180
permissions -rw-r--r--
Re-add LIFO stack optimizations.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include <stdio.h>
    20 #include <stdlib.h>
    21 #include <string.h>
    22 #include "../include/keima.h"
    23 
    24 using namespace Ke;
    25 
    26 class MessageReporter : public IMessageReporter
    27 {
    28   public:
    29     void onOutOfMemory() {
    30         fprintf(stderr, "Out of memory!\n");
    31     }
    32     void onUncaughtException(const char *message) {
    33         fprintf(stderr, "Uncaught exception: %s\n", message);
    34 
    35         IStackFrameIterator *iter = Keima::NewStackFrameIterator();
    36         unsigned index = 0;
    37         while (!iter->done() && index < 10) {
    38             fprintf(stderr, "[%d] %s (%s line %d)\n",
    39                     index,
    40                     iter->function(),
    41                     iter->source(),
    42                     iter->lineNumber());
    43             iter->prev();
    44             index++;
    45         }
    46     }
    47     virtual void beginCompilationErrors(const char *file) {
    48         fprintf(stderr, "\nDisplaying compilation errors for \"%s\"\n", file);
    49     }
    50     virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
    51         fprintf(stderr, "  line %d, col %d: %s\n", line, col, message);
    52     }
    53     virtual void endCompilationErrors() {
    54     }
    55 } s_Reporter;
    56 
    57 class MainCollector : public Ke::IPublicFunctionListener
    58 {
    59   public:
    60     MainCollector()
    61     {
    62     }
    63     void registerPublic(Handle<Function> fun) {
    64         Local<String> str = fun->name();
    65         if (str && strcmp(str->chars(), "main") == 0)
    66             fun_ = fun;
    67     }
    68 
    69     void unregisterPublic(Handle<Function> fun) {
    70         if (fun_ == fun)
    71             fun_ = Handle<Function>();
    72     }
    73 
    74     Handle<Function> fun() const {
    75         return fun_;
    76     }
    77 
    78   private:
    79     Root<Function> fun_;
    80 };
    81 
    82 intptr_t PrintFloat(void *blah, intptr_t *params)
    83 {
    84     fprintf(stdout, "%f", *reinterpret_cast<float *>(&params[1]));
    85     return 0;
    86 }
    87 
    88 intptr_t PrintNum(void *blah, intptr_t *params)
    89 {
    90     fprintf(stdout, "%i", *reinterpret_cast<int *>(&params[1]));
    91     return 0;
    92 }
    93 
    94 intptr_t PrintString(void *blah, intptr_t *params)
    95 {
    96     fprintf(stdout, "%s", *reinterpret_cast<const char **>(&params[1]));
    97     return 0;
    98 }
    99 
   100 int main(int argc, char **argv)
   101 {
   102     if (argc < 2) {
   103         fprintf(stderr, "Usage: <file>\n");
   104         return 1;
   105     }
   106 
   107     if (!Keima::Initialize())
   108         return 1;
   109 
   110     int rval = 0;
   111 
   112     Keima::InstallMessageReporter(&s_Reporter);
   113     {
   114         MainCollector entry;
   115         Keima::SetPublicFunctionListener(&entry);
   116 
   117         HandleScope scope;
   118         Compile(argv[1]);
   119 
   120         Keima::CollectGarbage();
   121 
   122         Keima::BindNative("PrintFloat", (void *)PrintFloat);
   123         Keima::BindNative("PrintNum", (void *)PrintNum);
   124         Keima::BindNative("PrintString", (void *)PrintString);
   125 
   126         Handle<Function> fun = entry.fun();
   127 
   128         if (!fun) {
   129             fprintf(stdout, "Not running; no public 'main'.\n");
   130         } else {
   131             if (!Keima::Invoke(fun, NULL, 0, true, &rval))
   132                 rval = 1;
   133         }
   134     }
   135 
   136     Keima::Shutdown();
   137 
   138     return rval;
   139 }
   140 
   141 /* Overload a few things to prevent libstdc++ linking */
   142 #if defined __linux__ || defined __APPLE__
   143 extern "C" void __cxa_pure_virtual(void)
   144 {
   145 }
   146 
   147 void *operator new(size_t size)
   148 {
   149     return malloc(size);
   150 }
   151 
   152 void *operator new[](size_t size) 
   153 {
   154     return malloc(size);
   155 }
   156 
   157 void operator delete(void *ptr) 
   158 {
   159     free(ptr);
   160 }
   161 
   162 void operator delete[](void * ptr)
   163 {
   164     free(ptr);
   165 }
   166 #endif
   167