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