Added global root API.
authorDavid Anderson <dvander@alliedmods.net>
Sun Jul 08 11:33:12 2012 -0700 (2012-07-08)
changeset 61864e4b02a4c1
parent 60 581a9c793062
child 62 e04c5be84792
Added global root API.
include/keima.h
jitcraft/API.cpp
jitcraft/GlobalRoots.cpp
jitcraft/GlobalRoots.h
jitcraft/InlineList.h
jitcraft/Zone.cpp
jitcraft/Zone.h
jitcraft/jitcraft.vcxproj
jitcraft/main.cpp
     1.1 --- a/include/keima.h	Sun Jul 08 01:54:08 2012 -0700
     1.2 +++ b/include/keima.h	Sun Jul 08 11:33:12 2012 -0700
     1.3 @@ -125,13 +125,13 @@
     1.4          incref();
     1.5      }
     1.6  
     1.7 -    explicit Root(ke::HeapRoot **obj)
     1.8 +    explicit Root(ke::HeapRoot *obj)
     1.9        : Handle<T>(reinterpret_cast<T *>(obj))
    1.10      {
    1.11          incref();
    1.12      }
    1.13  
    1.14 -    static Root<T> New(Handle<T> other);
    1.15 +    static inline Root<T> New(Handle<T> other);
    1.16  
    1.17      ~Root() {
    1.18          decref();
    1.19 @@ -201,6 +201,43 @@
    1.20   */
    1.21  extern Local<Module> Compile(const char *path);
    1.22  
    1.23 +class Internals
    1.24 +{
    1.25 +    template <typename T> friend class Root;
    1.26 +
    1.27 +  private:
    1.28 +    static ke::HeapRoot *NewHeapRoot(ke::Object **objp);
    1.29 +    static void IncRef(ke::HeapRoot *root);
    1.30 +    static void DecRef(ke::HeapRoot *root);
    1.31 +};
    1.32 +
    1.33 +template <typename T> Root<T>
    1.34 +Root<T>::New(Handle<T> other)
    1.35 +{
    1.36 +    if (!other)
    1.37 +        return Root<T>(NULL);
    1.38 +    ke::Object **ptr = reinterpret_cast<ke::Object **>(*other);
    1.39 +    return Root<T>(Internals::NewHeapRoot(ptr));
    1.40 +}
    1.41 +
    1.42 +template <typename T> void
    1.43 +Root<T>::incref()
    1.44 +{
    1.45 +    if (!*this)
    1.46 +        return;
    1.47 +    ke::HeapRoot *ptr = reinterpret_cast<ke::HeapRoot *>(**this);
    1.48 +    Internals::IncRef(ptr);
    1.49 +}
    1.50 +
    1.51 +template <typename T> void
    1.52 +Root<T>::decref()
    1.53 +{
    1.54 +    if (!*this)
    1.55 +        return;
    1.56 +    ke::HeapRoot *ptr = reinterpret_cast<ke::HeapRoot *>(**this);
    1.57 +    Internals::DecRef(ptr);
    1.58 +}
    1.59 +
    1.60  }
    1.61  
    1.62  #endif // _include_sourcepawn3_api_h_
     2.1 --- a/jitcraft/API.cpp	Sun Jul 08 01:54:08 2012 -0700
     2.2 +++ b/jitcraft/API.cpp	Sun Jul 08 11:33:12 2012 -0700
     2.3 @@ -1,49 +1,50 @@
     2.4 -/* vim: set ts=4 sw=4 tw=99 et:
     2.5 - *
     2.6 - * Copyright (C) 2012 David Anderson
     2.7 - *
     2.8 - * This file is part of JITCraft.
     2.9 - *
    2.10 - * JITCraft is free software: you can redistribute it and/or modify it under
    2.11 - * the terms of the GNU General Public License as published by the Free
    2.12 - * Software Foundation, either version 3 of the License, or (at your option)
    2.13 - * any later version.
    2.14 - * 
    2.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    2.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    2.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    2.18 - *
    2.19 - * You should have received a copy of the GNU General Public License along with
    2.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    2.21 - */
    2.22 -#include "../include/keima.h"
    2.23 -#include "Zone.h"
    2.24 -#include "RootScopes.h"
    2.25 -#include "CompileContext.h"
    2.26 -#include "Parser.h"
    2.27 -#include "Scopes.h"
    2.28 -#include "SemanticAnalysis.h"
    2.29 -#include "BytecodeCompiler.h"
    2.30 -#include "Modules.h"
    2.31 -
    2.32 -using namespace ke;
    2.33 -
    2.34 -bool
    2.35 -Ke::Initialize()
    2.36 -{
    2.37 -    SingleThreadedZone = new Zone();
    2.38 -    if (!SingleThreadedZone || !SingleThreadedZone->initialize())
    2.39 -        return false;
    2.40 -    return true;
    2.41 -}
    2.42 -
    2.43 -void
    2.44 -Ke::Shutdown()
    2.45 -{
    2.46 -    delete SingleThreadedZone;
    2.47 -    SingleThreadedZone = NULL;
    2.48 -}
    2.49 -
    2.50 +/* vim: set ts=4 sw=4 tw=99 et:
    2.51 + *
    2.52 + * Copyright (C) 2012 David Anderson
    2.53 + *
    2.54 + * This file is part of JITCraft.
    2.55 + *
    2.56 + * JITCraft is free software: you can redistribute it and/or modify it under
    2.57 + * the terms of the GNU General Public License as published by the Free
    2.58 + * Software Foundation, either version 3 of the License, or (at your option)
    2.59 + * any later version.
    2.60 + * 
    2.61 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    2.62 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    2.63 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    2.64 + *
    2.65 + * You should have received a copy of the GNU General Public License along with
    2.66 + * JITCraft. If not, see http://www.gnu.org/licenses/.
    2.67 + */
    2.68 +#include "../include/keima.h"
    2.69 +#include "Zone.h"
    2.70 +#include "RootScopes.h"
    2.71 +#include "CompileContext.h"
    2.72 +#include "Parser.h"
    2.73 +#include "Scopes.h"
    2.74 +#include "SemanticAnalysis.h"
    2.75 +#include "BytecodeCompiler.h"
    2.76 +#include "Modules.h"
    2.77 +#include "GlobalRoots.h"
    2.78 +
    2.79 +using namespace ke;
    2.80 +
    2.81 +bool
    2.82 +Ke::Initialize()
    2.83 +{
    2.84 +    SingleThreadedZone = new Zone();
    2.85 +    if (!SingleThreadedZone || !SingleThreadedZone->initialize())
    2.86 +        return false;
    2.87 +    return true;
    2.88 +}
    2.89 +
    2.90 +void
    2.91 +Ke::Shutdown()
    2.92 +{
    2.93 +    delete SingleThreadedZone;
    2.94 +    SingleThreadedZone = NULL;
    2.95 +}
    2.96 +
    2.97  Ke::HandleScope::HandleScope()
    2.98    : zone_(ke::ZONE()),
    2.99      position_(zone_->rootScopes().position()),
   2.100 @@ -52,91 +53,123 @@
   2.101      *zone_->rootScopes().scope() = this;
   2.102  }
   2.103  
   2.104 -Ke::HandleScope::~HandleScope()
   2.105 -{
   2.106 -    zone_->rootScopes().unwind(position_);
   2.107 -    *zone_->rootScopes().scope() = prev_;
   2.108 -}
   2.109 -
   2.110 -ke::Object **
   2.111 -Ke::HandleScope::CreateHandle(ke::Object *obj)
   2.112 -{
   2.113 -    if (!obj)
   2.114 -        return NULL;
   2.115 -
   2.116 -    return ZONE()->rootScopes().make(obj);
   2.117 -}
   2.118 -
   2.119 -template <typename From, typename To> static inline Ke::Local<To>
   2.120 -ToLocal(Handle<From> from)
   2.121 -{
   2.122 -    return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
   2.123 -}
   2.124 -
   2.125 -static ke::Module *
   2.126 -CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
   2.127 -{
   2.128 -    Parser parser(ZONE(), cc, stream, length);
   2.129 -    ParseTree *tree = parser.parse();
   2.130 -    if (!tree)
   2.131 -        return NULL;
   2.132 -    tree->dump(stdout);
   2.133 -
   2.134 -    if (!Scope::Bind(tree))
   2.135 -        return NULL;
   2.136 -
   2.137 -    SemanticAnalysis semantics(ZONE(), cc, tree);
   2.138 -    if (!semantics.analyze())
   2.139 -        return NULL;
   2.140 -
   2.141 -    Scope::Allocate(tree);
   2.142 -
   2.143 -    BytecodeCompiler compiler(ZONE(), tree, NULL);
   2.144 -    return compiler.compile();
   2.145 -}
   2.146 -
   2.147 -Ke::Local<Ke::Module>
   2.148 -Ke::Compile(const char *path)
   2.149 -{
   2.150 -    RootScope roots(ZONE());
   2.151 -    CompileContext cc(ZONE());
   2.152 -
   2.153 -    char *bytes = NULL;
   2.154 -    size_t length;
   2.155 -    {
   2.156 -        FILE *fp = fopen(path, "rb");
   2.157 -        if (!fp) {
   2.158 -            cc.reportError(SourcePosition(), Message_CantOpenFile);
   2.159 -            return Ke::Local<Ke::Module>();
   2.160 -        }
   2.161 -
   2.162 -        if (fseek(fp, 0, SEEK_END)) {
   2.163 -            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.164 -            fclose(fp);
   2.165 -            return Ke::Local<Ke::Module>();;
   2.166 -        }
   2.167 -        long size = ftell(fp);
   2.168 -        if (size < 0) {
   2.169 -            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.170 -            fclose(fp);
   2.171 -            return Ke::Local<Ke::Module>();;
   2.172 -        }
   2.173 -        rewind(fp);
   2.174 -        length = size_t(size);
   2.175 -        bytes = new char[length + 1];
   2.176 -        if (fread(bytes, 1, length, fp) != length) {
   2.177 -            cc.reportError(SourcePosition(), Message_ErrorReadingFile);
   2.178 -            fclose(fp);
   2.179 -            delete [] bytes;
   2.180 -            return Ke::Local<Ke::Module>();;
   2.181 -        }
   2.182 -        fclose(fp);
   2.183 -    }
   2.184 -
   2.185 -    ke::Local<ke::Module> module(ZONE(),  CompileFromSource(cc, path, bytes, length));
   2.186 -    delete [] bytes;
   2.187 -    if (!module)
   2.188 -        return Ke::Local<Ke::Module>();
   2.189 -
   2.190 -    return ToLocal<ke::Module, Ke::Module>(module);
   2.191 -}
   2.192 +Ke::HandleScope::~HandleScope()
   2.193 +{
   2.194 +    zone_->rootScopes().unwind(position_);
   2.195 +    *zone_->rootScopes().scope() = prev_;
   2.196 +}
   2.197 +
   2.198 +ke::Object **
   2.199 +Ke::HandleScope::CreateHandle(ke::Object *obj)
   2.200 +{
   2.201 +    if (!obj)
   2.202 +        return NULL;
   2.203 +
   2.204 +    return ZONE()->rootScopes().make(obj);
   2.205 +}
   2.206 +
   2.207 +template <typename From, typename To> static inline Ke::Local<To>
   2.208 +ToLocal(Handle<From> from)
   2.209 +{
   2.210 +    return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
   2.211 +}
   2.212 +
   2.213 +static ke::Module *
   2.214 +CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
   2.215 +{
   2.216 +    Parser parser(ZONE(), cc, stream, length);
   2.217 +    ParseTree *tree = parser.parse();
   2.218 +    if (!tree)
   2.219 +        return NULL;
   2.220 +    tree->dump(stdout);
   2.221 +
   2.222 +    if (!Scope::Bind(tree))
   2.223 +        return NULL;
   2.224 +
   2.225 +    SemanticAnalysis semantics(ZONE(), cc, tree);
   2.226 +    if (!semantics.analyze())
   2.227 +        return NULL;
   2.228 +
   2.229 +    Scope::Allocate(tree);
   2.230 +
   2.231 +    BytecodeCompiler compiler(ZONE(), tree, NULL);
   2.232 +    return compiler.compile();
   2.233 +}
   2.234 +
   2.235 +Ke::Local<Ke::Module>
   2.236 +Ke::Compile(const char *path)
   2.237 +{
   2.238 +    RootScope roots(ZONE());
   2.239 +    CompileContext cc(ZONE());
   2.240 +
   2.241 +    char *bytes = NULL;
   2.242 +    size_t length;
   2.243 +    {
   2.244 +        FILE *fp = fopen(path, "rb");
   2.245 +        if (!fp) {
   2.246 +            cc.reportError(SourcePosition(), Message_CantOpenFile);
   2.247 +            return Ke::Local<Ke::Module>();
   2.248 +        }
   2.249 +
   2.250 +        if (fseek(fp, 0, SEEK_END)) {
   2.251 +            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.252 +            fclose(fp);
   2.253 +            return Ke::Local<Ke::Module>();;
   2.254 +        }
   2.255 +        long size = ftell(fp);
   2.256 +        if (size < 0) {
   2.257 +            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.258 +            fclose(fp);
   2.259 +            return Ke::Local<Ke::Module>();;
   2.260 +        }
   2.261 +        rewind(fp);
   2.262 +        length = size_t(size);
   2.263 +        bytes = new char[length + 1];
   2.264 +        if (fread(bytes, 1, length, fp) != length) {
   2.265 +            cc.reportError(SourcePosition(), Message_ErrorReadingFile);
   2.266 +            fclose(fp);
   2.267 +            delete [] bytes;
   2.268 +            return Ke::Local<Ke::Module>();;
   2.269 +        }
   2.270 +        fclose(fp);
   2.271 +    }
   2.272 +
   2.273 +    ke::Local<ke::Module> module(ZONE(),  CompileFromSource(cc, path, bytes, length));
   2.274 +    delete [] bytes;
   2.275 +    if (!module)
   2.276 +        return Ke::Local<Ke::Module>();
   2.277 +
   2.278 +    return ToLocal<ke::Module, Ke::Module>(module);
   2.279 +}
   2.280 +
   2.281 +static inline ke::HeapRoot *
   2.282 +FromAPI(ke::HeapRoot *from)
   2.283 +{
   2.284 +    ke::Address address = reinterpret_cast<ke::Address>(from);
   2.285 +    address -= offsetof(ke::HeapRoot, obj);
   2.286 +    return reinterpret_cast<ke::HeapRoot *>(address);
   2.287 +}
   2.288 +
   2.289 +ke::HeapRoot *
   2.290 +Ke::Internals::NewHeapRoot(ke::Object **ptr)
   2.291 +{
   2.292 +    ke::Local<ke::Object> obj(ZONE(), *ptr);
   2.293 +    ke::HeapRoot *root = ke::ZONE()->globalRoots()->create(obj);
   2.294 +    if (!root)
   2.295 +        return NULL;
   2.296 +
   2.297 +    // Compute an interior pointer, so it looks like a Handle to an object.
   2.298 +    return reinterpret_cast<ke::HeapRoot *>(&root->obj);
   2.299 +}
   2.300 +
   2.301 +void
   2.302 +Ke::Internals::IncRef(ke::HeapRoot *root)
   2.303 +{
   2.304 +    ZONE()->globalRoots()->incref(FromAPI(root));
   2.305 +}
   2.306 +
   2.307 +void
   2.308 +Ke::Internals::DecRef(ke::HeapRoot *root)
   2.309 +{
   2.310 +    ZONE()->globalRoots()->decref(FromAPI(root));
   2.311 +}
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/jitcraft/GlobalRoots.cpp	Sun Jul 08 11:33:12 2012 -0700
     3.3 @@ -0,0 +1,78 @@
     3.4 +/*
     3.5 + * Copyright (C) 2004-2012 David Anderson
     3.6 + *
     3.7 + * This file is part of SourcePawn.
     3.8 + *
     3.9 + * SourcePawn is free software: you can redistribute it and/or modify it under
    3.10 + * the terms of the GNU General Public License as published by the Free
    3.11 + * Software Foundation, either version 3 of the License, or (at your option)
    3.12 + * any later version.
    3.13 + * 
    3.14 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    3.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    3.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    3.17 + *
    3.18 + * You should have received a copy of the GNU General Public License along with
    3.19 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    3.20 + */
    3.21 +#include "GlobalRoots.h"
    3.22 +#include "Zone.h"
    3.23 +
    3.24 +using namespace ke;
    3.25 +
    3.26 +GlobalRoots::GlobalRoots(Zone *zone)
    3.27 +  : zone_(zone)
    3.28 +{
    3.29 +}
    3.30 +
    3.31 +GlobalRoots::~GlobalRoots()
    3.32 +{
    3.33 +    InlineList<HeapRoot>::iterator iter = roots_.begin();
    3.34 +    while (iter != roots_.end()) {
    3.35 +        delete *iter;
    3.36 +        iter = roots_.erase(iter);
    3.37 +    }
    3.38 +}
    3.39 +
    3.40 +bool
    3.41 +GlobalRoots::initialize()
    3.42 +{
    3.43 +    return true;
    3.44 +}
    3.45 +
    3.46 +void
    3.47 +GlobalRoots::accept(VirtualObjectVisitor *visitor)
    3.48 +{
    3.49 +    for (InlineList<HeapRoot>::iterator iter = roots_.begin(); iter != roots_.end(); iter++)
    3.50 +        visitor->visit(&iter->obj);
    3.51 +}
    3.52 +
    3.53 +HeapRoot *
    3.54 +GlobalRoots::create(Handle<Object> obj)
    3.55 +{
    3.56 +    HeapRoot *root = new HeapRoot();
    3.57 +    if (!root)
    3.58 +        return NULL;
    3.59 +
    3.60 +    root->obj = obj;
    3.61 +    root->refcount = 0;
    3.62 +
    3.63 +    roots_.append(root);
    3.64 +    return root;
    3.65 +}
    3.66 +
    3.67 +void
    3.68 +GlobalRoots::incref(HeapRoot *root)
    3.69 +{
    3.70 +    root->refcount++;
    3.71 +}
    3.72 +
    3.73 +void
    3.74 +GlobalRoots::decref(HeapRoot *root)
    3.75 +{
    3.76 +    assert(root->refcount > 0);
    3.77 +    if (--root->refcount == 0) {
    3.78 +        roots_.remove(root);
    3.79 +        delete root;
    3.80 +    }
    3.81 +}
     4.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.2 +++ b/jitcraft/GlobalRoots.h	Sun Jul 08 11:33:12 2012 -0700
     4.3 @@ -0,0 +1,61 @@
     4.4 +/*
     4.5 + * Copyright (C) 2004-2012 David Anderson
     4.6 + *
     4.7 + * This file is part of SourcePawn.
     4.8 + *
     4.9 + * SourcePawn is free software: you can redistribute it and/or modify it under
    4.10 + * the terms of the GNU General Public License as published by the Free
    4.11 + * Software Foundation, either version 3 of the License, or (at your option)
    4.12 + * any later version.
    4.13 + * 
    4.14 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    4.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    4.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    4.17 + *
    4.18 + * You should have received a copy of the GNU General Public License along with
    4.19 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    4.20 + */
    4.21 +#ifndef _include_ke_global_roots_h_
    4.22 +#define _include_ke_global_roots_h_
    4.23 +
    4.24 +#include "Handles.h"
    4.25 +#include "InlineList.h"
    4.26 +#include "VirtualObjectVisitor.h"
    4.27 +
    4.28 +namespace ke {
    4.29 +
    4.30 +class Zone;
    4.31 +class Object;
    4.32 +
    4.33 +class HeapRoot : public InlineListNode<HeapRoot>
    4.34 +{
    4.35 +  public:
    4.36 +    Object *obj;
    4.37 +    intptr_t refcount;
    4.38 +};
    4.39 +
    4.40 +class GlobalRoots
    4.41 +{
    4.42 +    Zone *zone_;
    4.43 +
    4.44 +  public:
    4.45 +    GlobalRoots(Zone *zone);
    4.46 +    ~GlobalRoots();
    4.47 +
    4.48 +    bool initialize();
    4.49 +
    4.50 +    // The caller must immediately incref this.
    4.51 +    HeapRoot *create(Handle<Object> ptr);
    4.52 +
    4.53 +    void incref(HeapRoot *root);
    4.54 +    void decref(HeapRoot *root);
    4.55 +
    4.56 +    void accept(VirtualObjectVisitor *visitor);
    4.57 +
    4.58 +  private:
    4.59 +    InlineList<HeapRoot> roots_;
    4.60 +};
    4.61 +
    4.62 +}
    4.63 +
    4.64 +#endif // _include_ke_global_roots_h_
     5.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.2 +++ b/jitcraft/InlineList.h	Sun Jul 08 11:33:12 2012 -0700
     5.3 @@ -0,0 +1,129 @@
     5.4 +/*
     5.5 + * Copyright (C) 2004-2012 David Anderson
     5.6 + *
     5.7 + * This file is part of SourcePawn.
     5.8 + *
     5.9 + * SourcePawn is free software: you can redistribute it and/or modify it under
    5.10 + * the terms of the GNU General Public License as published by the Free
    5.11 + * Software Foundation, either version 3 of the License, or (at your option)
    5.12 + * any later version.
    5.13 + * 
    5.14 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    5.15 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    5.16 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    5.17 + *
    5.18 + * You should have received a copy of the GNU General Public License along with
    5.19 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
    5.20 + */
    5.21 +#ifndef _include_ke_inline_list_h_
    5.22 +#define _include_ke_inline_list_h_
    5.23 +
    5.24 +#include <stddef.h>
    5.25 +
    5.26 +namespace ke {
    5.27 +
    5.28 +template <typename T> class InlineList;
    5.29 +
    5.30 +template <typename T>
    5.31 +class InlineListNode
    5.32 +{
    5.33 +    friend class InlineList<T>;
    5.34 +
    5.35 +  public:
    5.36 +    InlineListNode()
    5.37 +      : next_(NULL),
    5.38 +        prev_(NULL)
    5.39 +    {
    5.40 +    }
    5.41 +
    5.42 +    InlineListNode(InlineListNode *next, InlineListNode *prev)
    5.43 +      : next_(next),
    5.44 +        prev_(prev)
    5.45 +    {
    5.46 +    }
    5.47 +
    5.48 +  protected:
    5.49 +    InlineListNode *next_;
    5.50 +    InlineListNode *prev_;
    5.51 +};
    5.52 +
    5.53 +template <typename T>
    5.54 +class InlineList
    5.55 +{
    5.56 +    typedef InlineListNode<T> Node;
    5.57 +
    5.58 +    Node head_;
    5.59 +
    5.60 +  public:
    5.61 +    InlineList()
    5.62 +      : head_(&head_, &head_)
    5.63 +    {
    5.64 +    }
    5.65 +
    5.66 +  public:
    5.67 +    class iterator
    5.68 +    {
    5.69 +        friend class InlineList;
    5.70 +        Node *iter_;
    5.71 +        
    5.72 +      public:
    5.73 +        iterator(Node *iter)
    5.74 +          : iter_(iter)
    5.75 +        {
    5.76 +        }
    5.77 +
    5.78 +        iterator & operator++() {
    5.79 +            iter_ = iter_->next_;
    5.80 +            return *this;
    5.81 +        }
    5.82 +        iterator operator ++(int) {
    5.83 +            iterator old(*this);
    5.84 +            iter_ = iter_->next_;
    5.85 +            return old;
    5.86 +        }
    5.87 +        T * operator *() {
    5.88 +            return static_cast<T *>(iter_);
    5.89 +        }
    5.90 +        T * operator ->() {
    5.91 +            return static_cast<T *>(iter_);
    5.92 +        }
    5.93 +        bool operator !=(const iterator &where) const {
    5.94 +            return iter_ != where.iter_;
    5.95 +        }
    5.96 +        bool operator ==(const iterator &where) const {
    5.97 +            return iter_ == where.iter_;
    5.98 +        }
    5.99 +        iterator prev() const {
   5.100 +            return iterator(iter_->prev_);
   5.101 +        }
   5.102 +        iterator next() const {
   5.103 +            return iterator(iter_->next_);
   5.104 +        }
   5.105 +    };
   5.106 +
   5.107 +    iterator begin() {
   5.108 +        return iterator(head_.next_);
   5.109 +    }
   5.110 +    iterator end() {
   5.111 +        return iterator(&head_);
   5.112 +    }
   5.113 +    void append(Node *t) {
   5.114 +        t->prev_ = head_.prev_;
   5.115 +        t->next_ = &head_;
   5.116 +        head_.prev_->next_ = t;
   5.117 +        head_.prev_ = t;
   5.118 +    }
   5.119 +    iterator erase(iterator i) {
   5.120 +        iterator next = ++i;
   5.121 +        remove(i.iter_);
   5.122 +        return next;
   5.123 +    }
   5.124 +    void remove(Node *t) {
   5.125 +        t->prev_->next_ = t->next_;
   5.126 +        t->next_->prev_ = t->prev_;
   5.127 +    }
   5.128 +};
   5.129 +
   5.130 +}
   5.131 +
   5.132 +#endif // _include_ke_inline_list_h_
     6.1 --- a/jitcraft/Zone.cpp	Sun Jul 08 01:54:08 2012 -0700
     6.2 +++ b/jitcraft/Zone.cpp	Sun Jul 08 11:33:12 2012 -0700
     6.3 @@ -19,6 +19,7 @@
     6.4  #include "Zone.h"
     6.5  #include "StringPool.h"
     6.6  #include "TypeManager.h"
     6.7 +#include "GlobalRoots.h"
     6.8  #include "AllocatorPolicies.h"
     6.9  
    6.10  using namespace ke;
    6.11 @@ -28,14 +29,17 @@
    6.12  Zone::Zone()
    6.13    : heap_(this),
    6.14      types_(NULL),
    6.15 +    symbols_(NULL),
    6.16 +    globalRoots_(NULL),
    6.17      lastLocalRoot_(NULL)
    6.18  {
    6.19  }
    6.20  
    6.21  Zone::~Zone()
    6.22  {
    6.23 +    delete types_;
    6.24      delete symbols_;
    6.25 -    delete types_;
    6.26 +    delete globalRoots_;
    6.27  }
    6.28  
    6.29  bool
    6.30 @@ -50,6 +54,10 @@
    6.31      if (!symbols_ || !symbols_->initialize())
    6.32          return false;
    6.33  
    6.34 +    globalRoots_ = new GlobalRoots(this);
    6.35 +    if (!globalRoots_ || !globalRoots_->initialize())
    6.36 +        return false;
    6.37 +
    6.38      maps_[MapKind_Meta] = heap_.metaMap();
    6.39      if ((maps_[MapKind_Type] = allocateMap(MapKind_Type, sizeof(Map))) == NULL)
    6.40          return false;
    6.41 @@ -103,6 +111,7 @@
    6.42          local = local->prev();
    6.43      }
    6.44  
    6.45 +    globalRoots_->accept(visitor);
    6.46      rootScopes_.accept(visitor);
    6.47  
    6.48      stack_.accept(visitor);
     7.1 --- a/jitcraft/Zone.h	Sun Jul 08 01:54:08 2012 -0700
     7.2 +++ b/jitcraft/Zone.h	Sun Jul 08 11:33:12 2012 -0700
     7.3 @@ -32,6 +32,7 @@
     7.4  class TypeManager;
     7.5  class String;
     7.6  class StringPool;
     7.7 +class GlobalRoots;
     7.8  
     7.9  class Zone
    7.10  {
    7.11 @@ -44,6 +45,7 @@
    7.12  
    7.13      TypeManager *types_;
    7.14      StringPool *symbols_;
    7.15 +    GlobalRoots *globalRoots_;
    7.16  
    7.17      // Root list.
    7.18      Local<Object> *lastLocalRoot_;
    7.19 @@ -91,6 +93,9 @@
    7.20      StringPool *symbols() {
    7.21          return symbols_;
    7.22      }
    7.23 +    GlobalRoots *globalRoots() {
    7.24 +        return globalRoots_;
    7.25 +    }
    7.26  
    7.27      String *makeSymbol(const char *string, size_t length);
    7.28      String *makeSymbol(const char *string);
     8.1 --- a/jitcraft/jitcraft.vcxproj	Sun Jul 08 01:54:08 2012 -0700
     8.2 +++ b/jitcraft/jitcraft.vcxproj	Sun Jul 08 11:33:12 2012 -0700
     8.3 @@ -101,6 +101,7 @@
     8.4      <ClCompile Include="Exception.cpp" />
     8.5      <ClCompile Include="FixedArray.cpp" />
     8.6      <ClCompile Include="Functions.cpp" />
     8.7 +    <ClCompile Include="GlobalRoots.cpp" />
     8.8      <ClCompile Include="Heap.cpp" />
     8.9      <ClCompile Include="Interpreter.cpp" />
    8.10      <ClCompile Include="main.cpp" />
    8.11 @@ -134,9 +135,11 @@
    8.12      <ClInclude Include="CompileContext.h" />
    8.13      <ClInclude Include="FixedArray.h" />
    8.14      <ClInclude Include="Functions.h" />
    8.15 +    <ClInclude Include="GlobalRoots.h" />
    8.16      <ClInclude Include="Handles-inl.h" />
    8.17      <ClInclude Include="HashTable.h" />
    8.18      <ClInclude Include="Heap-inl.h" />
    8.19 +    <ClInclude Include="InlineList.h" />
    8.20      <ClInclude Include="Interpreter.h" />
    8.21      <ClInclude Include="Messages.h" />
    8.22      <ClInclude Include="Modules.h" />
     9.1 --- a/jitcraft/main.cpp	Sun Jul 08 01:54:08 2012 -0700
     9.2 +++ b/jitcraft/main.cpp	Sun Jul 08 11:33:12 2012 -0700
     9.3 @@ -26,61 +26,14 @@
     9.4  #include "Interpreter.h"
     9.5  #include "Modules.h"
     9.6  #include "RootScopes.h"
     9.7 +#include "../include/keima.h"
     9.8  
     9.9  using namespace ke;
    9.10  
    9.11 -class File
    9.12 -{
    9.13 -    FILE *fp_;
    9.14 -
    9.15 -  public:
    9.16 -    File(FILE *fp)
    9.17 -      : fp_(fp)
    9.18 -    {
    9.19 -    }
    9.20 -
    9.21 -    ~File() {
    9.22 -        if (fp_)
    9.23 -            fclose(fp_);
    9.24 -    }
    9.25 -
    9.26 -    operator FILE *() {
    9.27 -        return fp_;
    9.28 -    }
    9.29 -
    9.30 -    operator bool () {
    9.31 -        return !!fp_;
    9.32 -    }
    9.33 -};
    9.34 -
    9.35 +#if 0
    9.36  static bool
    9.37  Compile(const char *stream, size_t length)
    9.38  {
    9.39 -    if (!ZONE()->initialize())
    9.40 -        return false;
    9.41 -
    9.42 -    RootScope roots(ZONE());
    9.43 -    CompileContext cc(ZONE());
    9.44 -
    9.45 -    Parser parser(ZONE(), cc, stream, length);
    9.46 -    ParseTree *tree = parser.parse();
    9.47 -    if (!tree)
    9.48 -        return false;
    9.49 -    tree->dump(stdout);
    9.50 -
    9.51 -    if (!Scope::Bind(tree))
    9.52 -        return false;
    9.53 -
    9.54 -    SemanticAnalysis semantics(ZONE(), cc, tree);
    9.55 -    if (!semantics.analyze())
    9.56 -        return false;
    9.57 -
    9.58 -    Scope::Allocate(tree);
    9.59 -
    9.60 -    BytecodeCompiler compiler(ZONE(), tree, NULL);
    9.61 -    Module *module = compiler.compile();
    9.62 -    if (!module)
    9.63 -        return false;
    9.64  
    9.65      printf("\n ------------ \n\n");
    9.66  
    9.67 @@ -106,6 +59,7 @@
    9.68  
    9.69      return true;
    9.70  }
    9.71 +#endif
    9.72  
    9.73  int main(int argc, char **argv)
    9.74  {
    9.75 @@ -114,33 +68,16 @@
    9.76          return 1;
    9.77      }
    9.78  
    9.79 -    AutoVec<char> bytes(NULL);
    9.80 -    size_t length;
    9.81 +    if (!Ke::Initialize())
    9.82 +        return 1;
    9.83      {
    9.84 -        File fp = fopen(argv[1], "rb");
    9.85 -        if (!fp) {
    9.86 -            fprintf(stderr, "Can't open file: \"%s\"\n", argv[1]);
    9.87 -            return 1;
    9.88 -        }
    9.89 -
    9.90 -        if (fseek(fp, 0, SEEK_END)) {
    9.91 -            fprintf(stderr, "Error seeking file!\n");
    9.92 +        Ke::HandleScope scope;
    9.93 +        Ke::Local<Ke::Module> module = Ke::Compile(argv[1]);
    9.94 +        if (!module)
    9.95              return 1;
    9.96 -        }
    9.97 -        long size = ftell(fp);
    9.98 -        if (size < 0) {
    9.99 -            fprintf(stderr, "Error getting file length!\n");
   9.100 -            return 1;
   9.101 -        }
   9.102 -        rewind(fp);
   9.103 -        length = size_t(size);
   9.104 -        bytes = new char[length + 1];
   9.105 -        if (fread(bytes, 1, length, fp) != length) {
   9.106 -            fprintf(stderr, "Error reading file!\n");
   9.107 -            return 1;
   9.108 -        }
   9.109 +
   9.110 +        Ke::Root<Ke::Module> root = Ke::Root<Ke::Module>::New(module);
   9.111      }
   9.112  
   9.113 -    Compile(bytes, length);
   9.114 -
   9.115 +    Ke::Shutdown();
   9.116  }