Removed jitcraft/, added AMBuild scripts for making libkeima.
authorDavid Anderson <dvander@alliedmods.net>
Tue Jul 24 23:54:14 2012 -0700 (2012-07-24)
changeset 87f8ac2633b4e3
parent 86 32ad0523b309
child 88 fc3f34f928dd
Removed jitcraft/, added AMBuild scripts for making libkeima.
configure.py
jitcraft/API.cpp
jitcraft/AST.h
jitcraft/AllocatorPolicies.h
jitcraft/Array.cpp
jitcraft/Array.h
jitcraft/Barriers.h
jitcraft/BytecodeCompiler.cpp
jitcraft/BytecodeCompiler.h
jitcraft/BytecodeEmitter.cpp
jitcraft/BytecodeEmitter.h
jitcraft/Code.h
jitcraft/CompactBuffer.h
jitcraft/CompileContext.cpp
jitcraft/CompileContext.h
jitcraft/Environments.cpp
jitcraft/Environments.h
jitcraft/Exception.cpp
jitcraft/FixedArray.cpp
jitcraft/FixedArray.h
jitcraft/Functions.cpp
jitcraft/Functions.h
jitcraft/GlobalRoots.cpp
jitcraft/GlobalRoots.h
jitcraft/Handles-inl.h
jitcraft/Handles.h
jitcraft/HashTable.h
jitcraft/Heap-inl.h
jitcraft/Heap.cpp
jitcraft/Heap.h
jitcraft/InlineList.h
jitcraft/Interpreter.cpp
jitcraft/Interpreter.h
jitcraft/Makefile.in
jitcraft/Messages.h
jitcraft/Messages.tbl
jitcraft/Modules.cpp
jitcraft/Modules.h
jitcraft/NameBinding.cpp
jitcraft/NameBinding.h
jitcraft/ObjectVisitor.h
jitcraft/Objects.h
jitcraft/Opcodes.cpp
jitcraft/Opcodes.h
jitcraft/Opcodes.tbl
jitcraft/Parser.cpp
jitcraft/Parser.h
jitcraft/Platform-Posix.cpp
jitcraft/Platform-Windows.cpp
jitcraft/Platform.h
jitcraft/PoolAllocator.cpp
jitcraft/PoolAllocator.h
jitcraft/Reference.cpp
jitcraft/Reference.h
jitcraft/RootScopes.cpp
jitcraft/RootScopes.h
jitcraft/Scanner.cpp
jitcraft/Scanner.h
jitcraft/Scopes.cpp
jitcraft/Scopes.h
jitcraft/SemanticAnalysis.cpp
jitcraft/SemanticAnalysis.h
jitcraft/Spaces-inl.h
jitcraft/Spaces.cpp
jitcraft/Spaces.h
jitcraft/Stack.cpp
jitcraft/Stack.h
jitcraft/StringPool.cpp
jitcraft/StringPool.h
jitcraft/Strings.cpp
jitcraft/Strings.h
jitcraft/Structures.cpp
jitcraft/Structures.h
jitcraft/Token.h
jitcraft/TypeManager.cpp
jitcraft/TypeManager.h
jitcraft/Types.cpp
jitcraft/Types.h
jitcraft/Utility.h
jitcraft/Vector.h
jitcraft/VirtualObjectVisitor.h
jitcraft/Zone.cpp
jitcraft/Zone.h
jitcraft/configure.in
jitcraft/jitcraft.vcxproj
jitcraft/main.cpp
src/AMBuild.library
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/configure.py	Tue Jul 24 23:54:14 2012 -0700
     1.3 @@ -0,0 +1,11 @@
     1.4 +# vim: set ts=2 sw=2 tw=99 noet:
     1.5 +import sys
     1.6 +import ambuild.runner as runner
     1.7 +
     1.8 +run = runner.Runner()
     1.9 +run.options.add_option('--enable-debug', action='store_const', const='1', dest='debug',
    1.10 +                       help='Enable debugging symbols')
    1.11 +run.options.add_option('--enable-optimize', action='store_const', const='1', dest='opt',
    1.12 +                       help='Enable optimization')
    1.13 +run.options.add_option('--arch', dest='arch', help='Architecture (x86, x64)')
    1.14 +run.Configure(sys.path[0])
     2.1 --- a/jitcraft/API.cpp	Tue Jul 24 23:53:34 2012 -0700
     2.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.3 @@ -1,483 +0,0 @@
     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 -#include "GlobalRoots.h"
    2.32 -#include "Reference.h"
    2.33 -#include "Array.h"
    2.34 -#include "Interpreter.h"
    2.35 -#include "Stack.h"
    2.36 -#include "Strings.h"
    2.37 -
    2.38 -using namespace ke;
    2.39 -
    2.40 -bool
    2.41 -Ke::Keima::Initialize()
    2.42 -{
    2.43 -    SingleThreadedZone = new Zone();
    2.44 -    if (!SingleThreadedZone || !SingleThreadedZone->initialize())
    2.45 -        return false;
    2.46 -    return true;
    2.47 -}
    2.48 -
    2.49 -void
    2.50 -Ke::Keima::Shutdown()
    2.51 -{
    2.52 -    delete SingleThreadedZone;
    2.53 -    SingleThreadedZone = NULL;
    2.54 -}
    2.55 -
    2.56 -Ke::HandleScope::HandleScope()
    2.57 -  : zone_(ke::ZONE()),
    2.58 -    position_(zone_->rootScopes().position()),
    2.59 -    prev_(*zone_->rootScopes().scope())
    2.60 -{
    2.61 -    *zone_->rootScopes().scope() = this;
    2.62 -}
    2.63 -
    2.64 -Ke::HandleScope::~HandleScope()
    2.65 -{
    2.66 -    zone_->rootScopes().unwind(position_);
    2.67 -    *zone_->rootScopes().scope() = prev_;
    2.68 -}
    2.69 -
    2.70 -ke::Object **
    2.71 -Ke::HandleScope::CreateHandle(ke::Object *obj)
    2.72 -{
    2.73 -    if (!obj)
    2.74 -        return NULL;
    2.75 -
    2.76 -    return ZONE()->rootScopes().make(obj);
    2.77 -}
    2.78 -
    2.79 -template <typename From, typename To> static inline To *
    2.80 -Open(Ke::Handle<From> from)
    2.81 -{
    2.82 -    return *reinterpret_cast<To **>(*from);
    2.83 -}
    2.84 -
    2.85 -template <typename From, typename To> static inline To *
    2.86 -Open(From *from)
    2.87 -{
    2.88 -    return *reinterpret_cast<To **>(from);
    2.89 -}
    2.90 -
    2.91 -template <typename From, typename To> static inline Ke::Local<To>
    2.92 -ToLocal(From *from)
    2.93 -{
    2.94 -    return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
    2.95 -}
    2.96 -
    2.97 -static ke::Module *
    2.98 -CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
    2.99 -{
   2.100 -    Parser parser(ZONE(), cc, stream, length);
   2.101 -    ParseTree *tree = parser.parse();
   2.102 -    if (!tree)
   2.103 -        return NULL;
   2.104 -    tree->dump(stdout);
   2.105 -
   2.106 -    if (!Scope::Bind(cc, tree))
   2.107 -        return NULL;
   2.108 -
   2.109 -    SemanticAnalysis semantics(ZONE(), cc, tree);
   2.110 -    if (!semantics.analyze())
   2.111 -        return NULL;
   2.112 -
   2.113 -    Scope::Allocate(tree);
   2.114 -
   2.115 -    BytecodeCompiler compiler(ZONE(), tree, NULL);
   2.116 -    ke::Local<Module> module(ke::ZONE(), compiler.compile());
   2.117 -    if (!module)
   2.118 -        return NULL;
   2.119 -
   2.120 -    ke::InvokeArgs args;
   2.121 -    if (!ke::ZONE()->stack().pushModuleFrame(module, args))
   2.122 -        return NULL;
   2.123 -    if (!ke::Interpret(ke::ZONE(), NULL, NULL))
   2.124 -        return NULL;
   2.125 -
   2.126 -    return module;
   2.127 -}
   2.128 -
   2.129 -Ke::Local<Ke::Module>
   2.130 -Ke::Compile(const char *path)
   2.131 -{
   2.132 -    RootScope roots(ZONE());
   2.133 -    CompileContext cc(ZONE(), path);
   2.134 -
   2.135 -    char *bytes = NULL;
   2.136 -    size_t length;
   2.137 -    {
   2.138 -        FILE *fp = fopen(path, "rb");
   2.139 -        if (!fp) {
   2.140 -            cc.reportError(SourcePosition(), Message_CantOpenFile);
   2.141 -            return Ke::Local<Ke::Module>();
   2.142 -        }
   2.143 -
   2.144 -        if (fseek(fp, 0, SEEK_END)) {
   2.145 -            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.146 -            fclose(fp);
   2.147 -            return Ke::Local<Ke::Module>();;
   2.148 -        }
   2.149 -        long size = ftell(fp);
   2.150 -        if (size < 0) {
   2.151 -            cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
   2.152 -            fclose(fp);
   2.153 -            return Ke::Local<Ke::Module>();;
   2.154 -        }
   2.155 -        rewind(fp);
   2.156 -        length = size_t(size);
   2.157 -        bytes = new char[length + 1];
   2.158 -        if (fread(bytes, 1, length, fp) != length) {
   2.159 -            cc.reportError(SourcePosition(), Message_ErrorReadingFile);
   2.160 -            fclose(fp);
   2.161 -            delete [] bytes;
   2.162 -            return Ke::Local<Ke::Module>();;
   2.163 -        }
   2.164 -        fclose(fp);
   2.165 -    }
   2.166 -
   2.167 -    ke::Local<ke::Module> module(ZONE(),  CompileFromSource(cc, path, bytes, length));
   2.168 -    delete [] bytes;
   2.169 -    if (!module)
   2.170 -        return Ke::Local<Ke::Module>();
   2.171 -
   2.172 -    ke::Local<ke::String> pathstr(ZONE(), ke::String::New(ZONE(), path, Heap::Tenure_Old));
   2.173 -    if (!pathstr)
   2.174 -        return Ke::Local<Ke::Module>();
   2.175 -
   2.176 -    module->setPath(pathstr);
   2.177 -    return ToLocal<ke::Module, Ke::Module>(module);
   2.178 -}
   2.179 -
   2.180 -void
   2.181 -Ke::Keima::InstallMessageReporter(Ke::IMessageReporter *reporter)
   2.182 -{
   2.183 -    ZONE()->installErrorReporter(reporter);
   2.184 -}
   2.185 -
   2.186 -class StackFrameIterator : public Ke::IStackFrameIterator
   2.187 -{
   2.188 -    StackIter iter_;
   2.189 -
   2.190 -  public:
   2.191 -    StackFrameIterator()
   2.192 -      : iter_(ZONE())
   2.193 -    {
   2.194 -    }
   2.195 -
   2.196 -    virtual bool done() {
   2.197 -        return iter_.done();
   2.198 -    }
   2.199 -
   2.200 -    const char *function() {
   2.201 -        return iter_.function();
   2.202 -    }
   2.203 -
   2.204 -    const char *source() {
   2.205 -        return iter_.source();
   2.206 -    }
   2.207 -
   2.208 -    unsigned lineNumber() {
   2.209 -        return iter_.lineNumber();
   2.210 -    }
   2.211 -
   2.212 -    void prev() {
   2.213 -        iter_.prev();
   2.214 -    }
   2.215 -};
   2.216 -
   2.217 -Ke::IStackFrameIterator *
   2.218 -Ke::Keima::NewStackFrameIterator()
   2.219 -{
   2.220 -    return new StackFrameIterator();
   2.221 -}
   2.222 -
   2.223 -static inline ke::HeapRoot *
   2.224 -FromAPI(ke::HeapRoot *from)
   2.225 -{
   2.226 -    ke::Address address = reinterpret_cast<ke::Address>(from);
   2.227 -    address -= offsetof(ke::HeapRoot, obj);
   2.228 -    return reinterpret_cast<ke::HeapRoot *>(address);
   2.229 -}
   2.230 -
   2.231 -ke::HeapRoot *
   2.232 -Ke::Internals::NewHeapRoot(ke::Object **ptr)
   2.233 -{
   2.234 -    ke::Local<ke::Object> obj(ZONE(), *ptr);
   2.235 -    ke::HeapRoot *root = ke::ZONE()->globalRoots()->create(obj);
   2.236 -    if (!root)
   2.237 -        return NULL;
   2.238 -
   2.239 -    // Compute an interior pointer, so it looks like a Handle to an object.
   2.240 -    return reinterpret_cast<ke::HeapRoot *>(&root->obj);
   2.241 -}
   2.242 -
   2.243 -void
   2.244 -Ke::Internals::IncRef(ke::HeapRoot *root)
   2.245 -{
   2.246 -    ZONE()->globalRoots()->incref(FromAPI(root));
   2.247 -}
   2.248 -
   2.249 -void
   2.250 -Ke::Internals::DecRef(ke::HeapRoot *root)
   2.251 -{
   2.252 -    ZONE()->globalRoots()->decref(FromAPI(root));
   2.253 -}
   2.254 -
   2.255 -bool
   2.256 -Ke::Keima::IsInCallStack(Handle<Module> argModule)
   2.257 -{
   2.258 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(argModule));
   2.259 -    return ZONE()->stack().isInCallStack(module);
   2.260 -}
   2.261 -
   2.262 -void
   2.263 -Ke::Keima::CollectGarbage()
   2.264 -{
   2.265 -    ke::ZONE()->heap().reclaim();
   2.266 -}
   2.267 -
   2.268 -unsigned
   2.269 -Ke::Module::numPublics()
   2.270 -{
   2.271 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
   2.272 -    if (!module->publics())
   2.273 -        return 0;
   2.274 -    return module->publics()->length();
   2.275 -}
   2.276 -
   2.277 -Ke::Local<Ke::Function>
   2.278 -Ke::Module::getPublic(unsigned index)
   2.279 -{
   2.280 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
   2.281 -    ke::Local<ke::Function> fun(ke::ZONE(), ke::Function::cast(module->publics()->at(index)));
   2.282 -    return ToLocal<ke::Function, Ke::Function>(fun);
   2.283 -}
   2.284 -
   2.285 -unsigned
   2.286 -Ke::Module::numNatives()
   2.287 -{
   2.288 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
   2.289 -    if (!module->natives())
   2.290 -        return 0;
   2.291 -    return module->natives()->length();
   2.292 -}
   2.293 -
   2.294 -Ke::Local<Ke::Native>
   2.295 -Ke::Module::getNative(unsigned index)
   2.296 -{
   2.297 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
   2.298 -    ke::Local<ke::Native> fun(ke::ZONE(), ke::Native::cast(module->natives()->at(index)));
   2.299 -    return ToLocal<ke::Native, Ke::Native>(fun);
   2.300 -}
   2.301 -
   2.302 -void
   2.303 -Ke::Module::setNativeIdentity(void *identity)
   2.304 -{
   2.305 -    ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
   2.306 -    module->setNativeIdentity(identity);
   2.307 -}
   2.308 -
   2.309 -unsigned
   2.310 -Ke::String::length()
   2.311 -{
   2.312 -    ke::Local<ke::String> obj(ke::ZONE(), Open<Ke::String, ke::String>(this));
   2.313 -    return obj->length();
   2.314 -}
   2.315 -
   2.316 -const char *
   2.317 -Ke::String::chars()
   2.318 -{
   2.319 -    ke::Local<ke::String> obj(ke::ZONE(), Open<Ke::String, ke::String>(this));
   2.320 -    return obj->chars();
   2.321 -}
   2.322 -
   2.323 -Ke::Local<Ke::String>
   2.324 -Ke::Function::name()
   2.325 -{
   2.326 -    ke::Local<ke::Function> fun(ke::ZONE(), Open<Ke::Function, ke::Function>(this));
   2.327 -    return ToLocal<ke::String, Ke::String>(fun->name());
   2.328 -}
   2.329 -
   2.330 -Ke::Local<Ke::String>
   2.331 -Ke::Native::name()
   2.332 -{
   2.333 -    ke::Local<ke::Native> native(ke::ZONE(), Open<Ke::Native, ke::Native>(this));
   2.334 -    return ToLocal<ke::String, Ke::String>(native->name());
   2.335 -}
   2.336 -
   2.337 -void
   2.338 -Ke::Native::bind(void *function)
   2.339 -{
   2.340 -    ke::Local<ke::Native> native(ke::ZONE(), Open<Ke::Native, ke::Native>(this));
   2.341 -    native->bind(function);
   2.342 -}
   2.343 -
   2.344 -static inline bool
   2.345 -CheckInvokeType(const Ke::Parameter &param, Type *type)
   2.346 -{
   2.347 -    switch (param.type()) {
   2.348 -      case Ke::Parameter::Array:
   2.349 -        return type->isArray() &&
   2.350 -               type->levels() == 1 &&
   2.351 -               type->contained()->isPrimitive() &&
   2.352 -               (type->contained()->primitive() != PrimitiveType_Char);
   2.353 -      case Ke::Parameter::CharArray:
   2.354 -        return type->isCharArray();
   2.355 -      case Ke::Parameter::Float:
   2.356 -        return type->isFloat();
   2.357 -      case Ke::Parameter::FloatRef:
   2.358 -        return type->isReference() && type->contained()->isFloat();
   2.359 -      case Ke::Parameter::Int:
   2.360 -        return type->isInt32();
   2.361 -      case Ke::Parameter::IntRef:
   2.362 -       return type->isReference() && type->contained()->isInt32();
   2.363 -      default:
   2.364 -        return false;
   2.365 -    }
   2.366 -}
   2.367 -
   2.368 -bool
   2.369 -Ke::Keima::CheckInvokeTypes(Ke::Handle<Ke::Function> argFun, const Ke::Parameter *params, unsigned nparams)
   2.370 -{
   2.371 -    ke::Local<ke::Function> fun(ke::ZONE(), Open<Ke::Function, ke::Function>(argFun));
   2.372 -
   2.373 -    if (fun->nargs() != nparams)
   2.374 -        return false;
   2.375 -
   2.376 -    for (unsigned i = 0; i < nparams; i++) {
   2.377 -        if (!CheckInvokeType(params[i], fun->argType(i)))
   2.378 -            return false;
   2.379 -    }
   2.380 -
   2.381 -    // Functions can only return tagged cells, for ISPE1-compatible Invoke().
   2.382 -    ke::Local<ke::Type> returnType(ke::ZONE(), fun->type()->returnType());
   2.383 -    if ((!returnType->isPrimitive() && !returnType->isVoid()) || returnType->isTraceable())
   2.384 -        return false;
   2.385 -
   2.386 -    return true;
   2.387 -}
   2.388 -
   2.389 -bool
   2.390 -Ke::Keima::Invoke(Handle<Function> argFun, const Parameter *params, unsigned nparams, int *retval)
   2.391 -{
   2.392 -    assert(CheckInvokeTypes(argFun, params, nparams));
   2.393 -
   2.394 -    ke::Local<ke::Function> fun(ke::ZONE(), Open<Ke::Function, ke::Function>(argFun));
   2.395 -
   2.396 -    if (fun->nargs() != nparams) {
   2.397 -        // :TODO: report error
   2.398 -        assert(false);
   2.399 -        return false;
   2.400 -    }
   2.401 -
   2.402 -    ke::InvokeArgs args;
   2.403 -    if (!ke::ZONE()->stack().pushInvokeFrame(fun, args))
   2.404 -        return false;
   2.405 -
   2.406 -    for (unsigned i = 0; i < nparams; i++) {
   2.407 -        ke::LocalSlot &slot = args.arg(i);
   2.408 -        switch (params[i].type()) {
   2.409 -          case Ke::Parameter::Int:
   2.410 -            slot.i32 = params[i].i32();
   2.411 -            break;
   2.412 -
   2.413 -          case Ke::Parameter::Float:
   2.414 -            slot.f = params[i].f();
   2.415 -            break;
   2.416 -
   2.417 -          case Ke::Parameter::IntRef:
   2.418 -            if (params[i].writeback()) {
   2.419 -                slot.ref = Reference::NewStack(ke::ZONE(), params[i].i32p(), Heap::Tenure_Stack);
   2.420 -            } else {
   2.421 -                LocalSlot other;
   2.422 -                other.i32 = *params[i].i32p();
   2.423 -                slot.ref = Reference::NewStack(ke::ZONE(), other, Heap::Tenure_Stack);
   2.424 -            }
   2.425 -            if (!slot.ref)
   2.426 -                return false;
   2.427 -            break;
   2.428 -
   2.429 -          case Ke::Parameter::FloatRef:
   2.430 -            if (params[i].writeback()) {
   2.431 -                slot.ref = Reference::NewStack(ke::ZONE(), params[i].fp(), Heap::Tenure_Stack);
   2.432 -            } else {
   2.433 -                LocalSlot other;
   2.434 -                other.f = *params[i].fp();
   2.435 -                slot.ref = Reference::NewStack(ke::ZONE(), other, Heap::Tenure_Stack);
   2.436 -            }
   2.437 -            if (!slot.ref)
   2.438 -                return false;
   2.439 -            break;
   2.440 -
   2.441 -          case Ke::Parameter::Array:
   2.442 -          {
   2.443 -            ke::Local<ke::ArrayMap> map(ke::ZONE(), ke::ZONE()->genericArrayMap());
   2.444 -            if (params[i].writeback()) {
   2.445 -                slot.obj = Array::NewExternal(ke::ZONE(), map, params[i].length(),
   2.446 -                                              params[i].buffer(), Heap::Tenure_Stack);
   2.447 -                if (!slot.obj)
   2.448 -                    return false;
   2.449 -            } else {
   2.450 -                Array *array = Array::New(ke::ZONE(), map, params[i].length(), Heap::Tenure_Stack);
   2.451 -                if (!slot.obj)
   2.452 -                    return false;
   2.453 -                memcpy(array->vec(), params[i].buffer(), params[i].length() * sizeof(int));
   2.454 -            }
   2.455 -            break;
   2.456 -          }
   2.457 -
   2.458 -          case Ke::Parameter::CharArray:
   2.459 -          {
   2.460 -            ke::Local<ke::ArrayMap> map(ke::ZONE(), ke::ZONE()->charArrayMap());
   2.461 -            if (params[i].writeback()) {
   2.462 -                slot.obj = Array::NewExternal(ke::ZONE(), map, params[i].length(),
   2.463 -                                              params[i].buffer(), Heap::Tenure_Stack);
   2.464 -                if (!slot.obj)
   2.465 -                    return false;
   2.466 -            } else {
   2.467 -                Array *array = Array::New(ke::ZONE(), map, params[i].length(), Heap::Tenure_Stack);
   2.468 -                if (!slot.obj)
   2.469 -                    return false;
   2.470 -                memcpy(array->vec(), params[i].buffer(), params[i].length() * sizeof(char));
   2.471 -            }
   2.472 -            break;
   2.473 -          }
   2.474 -        }
   2.475 -    }
   2.476 -
   2.477 -    LocalSlot result;
   2.478 -    if (!Interpret(ke::ZONE(), NULL, &result))
   2.479 -        return false;
   2.480 -
   2.481 -    if (fun->type()->returnType()->isVoid())
   2.482 -        result.i32 = 0;
   2.483 -
   2.484 -    *retval = result.i32;
   2.485 -    return true;
   2.486 -}
     3.1 --- a/jitcraft/AST.h	Tue Jul 24 23:53:34 2012 -0700
     3.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.3 @@ -1,873 +0,0 @@
     3.4 -/*
     3.5 - * Copyright (C) 2012 David Anderson
     3.6 - *
     3.7 - * This file is part of JITCraft.
     3.8 - *
     3.9 - * JITCraft 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 - * Foobar 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 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    3.20 - */
    3.21 -#ifndef _include_jitcraft_ast_h_
    3.22 -#define _include_jitcraft_ast_h_
    3.23 -
    3.24 -#include "PoolAllocator.h"
    3.25 -#include "Token.h"
    3.26 -#include "NameBinding.h"
    3.27 -#include "Vector.h"
    3.28 -
    3.29 -namespace ke {
    3.30 -
    3.31 -#define ASTKINDS(_)             \
    3.32 -    _(VariableDeclaration)      \
    3.33 -    _(ForStatement)             \
    3.34 -    _(ReturnStatement)          \
    3.35 -    _(IntegerLiteral)           \
    3.36 -    _(FloatLiteral)             \
    3.37 -    _(StringLiteral)            \
    3.38 -    _(BinaryExpression)         \
    3.39 -    _(BlockStatement)           \
    3.40 -    _(Assignment)               \
    3.41 -    _(NameProxy)                \
    3.42 -    _(ExpressionStatement)      \
    3.43 -    _(FunctionStatement)        \
    3.44 -    _(CallExpression)           \
    3.45 -    _(IfStatement)              \
    3.46 -    _(IndexExpression)          \
    3.47 -    _(EnumStatement)            \
    3.48 -    _(WhileStatement)           \
    3.49 -    _(BreakStatement)           \
    3.50 -    _(ContinueStatement)        \
    3.51 -    _(IncDecExpression)         \
    3.52 -    _(UnaryExpression)          \
    3.53 -    _(TernaryExpression)
    3.54 -
    3.55 -// Forward declarations.
    3.56 -#define _(name) class name;
    3.57 -ASTKINDS(_)
    3.58 -#undef _
    3.59 -
    3.60 -class AstVisitor;
    3.61 -
    3.62 -// Interface for AST nodes.
    3.63 -class AstNode : public PoolObject
    3.64 -{
    3.65 -    SourcePosition pos_;
    3.66 -
    3.67 -  public:
    3.68 -    enum Kind {
    3.69 -#       define _(name) k##name,
    3.70 -        ASTKINDS(_)
    3.71 -#       undef _
    3.72 -        AstKind_Invalid
    3.73 -    };
    3.74 -
    3.75 -    AstNode(const SourcePosition &pos)
    3.76 -      : pos_(pos)
    3.77 -    {
    3.78 -    }
    3.79 -    
    3.80 -    virtual Kind kind() const = 0;
    3.81 -
    3.82 -#define _(name)     bool is##name() { return kind() == k##name; }                   \
    3.83 -                    name *to##name() { assert(is##name()); return (name *)this; }
    3.84 -    ASTKINDS(_)
    3.85 -#undef _
    3.86 -
    3.87 -    virtual void accept(AstVisitor *visitor) = 0;
    3.88 -
    3.89 -    const SourcePosition &pos() const {
    3.90 -        return pos_;
    3.91 -    }
    3.92 -};
    3.93 -
    3.94 -class AstVisitor
    3.95 -{
    3.96 -  public:
    3.97 -#define _(name) virtual void visit(name *node) = 0;
    3.98 -    ASTKINDS(_)
    3.99 -#undef _
   3.100 -};
   3.101 -
   3.102 -class NameLocation
   3.103 -{
   3.104 -  public:
   3.105 -    enum Kind {
   3.106 -        LOCAL
   3.107 -    };
   3.108 -
   3.109 -    static NameLocation Local(VariableDeclaration *decl) {
   3.110 -        NameLocation loc;
   3.111 -        loc.kind_ = LOCAL;
   3.112 -        loc.u_.decl = decl;
   3.113 -        return loc;
   3.114 -    }
   3.115 -
   3.116 -    Kind kind() const {
   3.117 -        return kind_;
   3.118 -    }
   3.119 -
   3.120 -    VariableDeclaration *local() const {
   3.121 -        assert(kind() == LOCAL);
   3.122 -        return u_.decl;
   3.123 -    }
   3.124 -
   3.125 -  private:
   3.126 -    Kind kind_;
   3.127 -    union {
   3.128 -        VariableDeclaration *decl;
   3.129 -    } u_;
   3.130 -};
   3.131 -
   3.132 -class Statement : public AstNode
   3.133 -{
   3.134 -  public:
   3.135 -    Statement(const SourcePosition &pos)
   3.136 -      : AstNode(pos)
   3.137 -    {
   3.138 -    }
   3.139 -};
   3.140 -
   3.141 -class Expression : public AstNode
   3.142 -{
   3.143 -    ScopedRoot<Type> type_;
   3.144 -
   3.145 -  public:
   3.146 -    Expression(const SourcePosition &pos)
   3.147 -      : AstNode(pos),
   3.148 -        type_(NULL)
   3.149 -    {
   3.150 -    }
   3.151 -
   3.152 -    void setType(Type *type) {
   3.153 -        type_ = type;
   3.154 -    }
   3.155 -    Type *type() const {
   3.156 -        return type_;
   3.157 -    }
   3.158 -};
   3.159 -
   3.160 -typedef PoolList<Statement *> StatementList;
   3.161 -typedef PoolList<Expression *> ExpressionList;
   3.162 -
   3.163 -class VariableDeclaration : public Statement
   3.164 -{
   3.165 -    Variable *variable_;
   3.166 -    Expression *initialization_;
   3.167 -    ExpressionList *postDimensions_;
   3.168 -    ScopedRoot<String> tag_;
   3.169 -
   3.170 -  public:
   3.171 -    VariableDeclaration(const SourcePosition &pos, Variable *var, Handle<String> tag,
   3.172 -                        ExpressionList *postDimensions, Expression *initialization)
   3.173 -      : Statement(pos),
   3.174 -        variable_(var),
   3.175 -        initialization_(initialization),
   3.176 -        postDimensions_(postDimensions),
   3.177 -        tag_(tag)
   3.178 -    {
   3.179 -    }
   3.180 -
   3.181 -    String *tag() const {
   3.182 -        return tag_;
   3.183 -    }
   3.184 -    Kind kind() const {
   3.185 -        return kVariableDeclaration;
   3.186 -    }
   3.187 -    Variable *variable() const {
   3.188 -        return variable_;
   3.189 -    }
   3.190 -    Expression *initialization() const {
   3.191 -        return initialization_;
   3.192 -    }
   3.193 -    ExpressionList *postDimensions() const {
   3.194 -        return postDimensions_;
   3.195 -    }
   3.196 -    void accept(AstVisitor *visitor) {
   3.197 -        visitor->visit(this);
   3.198 -    }
   3.199 -};
   3.200 -
   3.201 -class Parameter : public PoolObject
   3.202 -{
   3.203 -    Variable *variable_;
   3.204 -    ScopedRoot<String> tag_;
   3.205 -    bool reference_;
   3.206 -    bool const_;
   3.207 -    ExpressionList *dimensions_;
   3.208 -
   3.209 -  public:
   3.210 -    Parameter(Variable *var, Handle<String> tag, bool reference, bool isConst, ExpressionList *dimensions)
   3.211 -      : variable_(var),
   3.212 -        tag_(tag),
   3.213 -        reference_(reference),
   3.214 -        const_(isConst),
   3.215 -        dimensions_(dimensions)
   3.216 -    {
   3.217 -    }
   3.218 -
   3.219 -    String *tag() const {
   3.220 -        return tag_;
   3.221 -    }
   3.222 -    Variable *variable() const {
   3.223 -        return variable_;
   3.224 -    }
   3.225 -    bool reference() const {
   3.226 -        return reference_;
   3.227 -    }
   3.228 -    ExpressionList *dimensions() const {
   3.229 -        return dimensions_;
   3.230 -    }
   3.231 -    bool isConst() const {
   3.232 -        return const_;
   3.233 -    }
   3.234 -};
   3.235 -
   3.236 -class NameProxy : public Expression
   3.237 -{
   3.238 -    ScopedRoot<String> name_;
   3.239 -    BoundName *binding_;
   3.240 -
   3.241 -  public:
   3.242 -    NameProxy(const SourcePosition &pos, Handle<String> name, BoundName *binding)
   3.243 -      : Expression(pos),
   3.244 -        name_(name),
   3.245 -        binding_(binding)
   3.246 -    {
   3.247 -    }
   3.248 -
   3.249 -    Kind kind() const {
   3.250 -        return kNameProxy;
   3.251 -    }
   3.252 -    String *name() const {
   3.253 -        return name_;
   3.254 -    }
   3.255 -    void accept(AstVisitor *visitor) {
   3.256 -        visitor->visit(this);
   3.257 -    }
   3.258 -    BoundName *binding() const {
   3.259 -        return binding_;
   3.260 -    }
   3.261 -    void bind(BoundName *name) {
   3.262 -        assert(!binding());
   3.263 -        binding_ = name;
   3.264 -    }
   3.265 -};
   3.266 -
   3.267 -class IntegerLiteral : public Expression
   3.268 -{
   3.269 -    int value_;
   3.270 -
   3.271 -  public:
   3.272 -    IntegerLiteral(const SourcePosition &pos, int value)
   3.273 -      : Expression(pos),
   3.274 -        value_(value)
   3.275 -    {
   3.276 -    }
   3.277 -
   3.278 -    Kind kind() const {
   3.279 -        return kIntegerLiteral;
   3.280 -    }
   3.281 -    int value() const {
   3.282 -        return value_;
   3.283 -    }
   3.284 -    void accept(AstVisitor *visitor) {
   3.285 -        visitor->visit(this);
   3.286 -    }
   3.287 -};
   3.288 -
   3.289 -class FloatLiteral : public Expression
   3.290 -{
   3.291 -    double value_;
   3.292 -
   3.293 -  public:
   3.294 -    FloatLiteral(const SourcePosition &pos, double value)
   3.295 -      : Expression(pos),
   3.296 -        value_(value)
   3.297 -    {
   3.298 -    }
   3.299 -
   3.300 -    Kind kind() const {
   3.301 -        return kFloatLiteral;
   3.302 -    }
   3.303 -    double value() const {
   3.304 -        return value_;
   3.305 -    }
   3.306 -    void accept(AstVisitor *visitor) {
   3.307 -        visitor->visit(this);
   3.308 -    }
   3.309 -};
   3.310 -
   3.311 -class StringLiteral : public Expression
   3.312 -{
   3.313 -    ScopedRoot<ByteArray> string_;
   3.314 -
   3.315 -  public:
   3.316 -    StringLiteral(const SourcePosition &pos, ByteArray *array)
   3.317 -      : Expression(pos),
   3.318 -        string_(array)
   3.319 -    {
   3.320 -    }
   3.321 -
   3.322 -    Kind kind() const {
   3.323 -        return kStringLiteral;
   3.324 -    }
   3.325 -    ByteArray *string() const {
   3.326 -        return string_;
   3.327 -    }
   3.328 -    void accept(AstVisitor *visitor) {
   3.329 -        visitor->visit(this);
   3.330 -    }
   3.331 -};
   3.332 -
   3.333 -class UnaryExpression : public Expression
   3.334 -{
   3.335 -    Expression *expression_;
   3.336 -    TokenKind token_;
   3.337 -
   3.338 -  public:
   3.339 -    UnaryExpression(const SourcePosition &pos, TokenKind token, Expression *expr)
   3.340 -      : Expression(pos),
   3.341 -        expression_(expr),
   3.342 -        token_(token)
   3.343 -    {
   3.344 -    }
   3.345 -
   3.346 -    Kind kind() const {
   3.347 -        return kUnaryExpression;
   3.348 -    }
   3.349 -    Expression *expression() const {
   3.350 -        return expression_;
   3.351 -    }
   3.352 -    TokenKind token() const {
   3.353 -        return token_;
   3.354 -    }
   3.355 -    void accept(AstVisitor *visitor) {
   3.356 -        visitor->visit(this);
   3.357 -    }
   3.358 -};
   3.359 -
   3.360 -class BinaryExpression : public Expression
   3.361 -{
   3.362 -    Expression *left_;
   3.363 -    Expression *right_;
   3.364 -    TokenKind token_;
   3.365 -
   3.366 -  public:
   3.367 -    BinaryExpression(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
   3.368 -      : Expression(pos),
   3.369 -        left_(left),
   3.370 -        right_(right),
   3.371 -        token_(token)
   3.372 -    {
   3.373 -    }
   3.374 -
   3.375 -    Kind kind() const {
   3.376 -        return kBinaryExpression;
   3.377 -    }
   3.378 -    Expression *left() const {
   3.379 -        return left_;
   3.380 -    }
   3.381 -    Expression *right() const {
   3.382 -        return right_;
   3.383 -    }
   3.384 -    TokenKind token() const {
   3.385 -        return token_;
   3.386 -    }
   3.387 -    void accept(AstVisitor *visitor) {
   3.388 -        visitor->visit(this);
   3.389 -    }
   3.390 -};
   3.391 -
   3.392 -class TernaryExpression : public Expression
   3.393 -{
   3.394 -    Expression *condition_;
   3.395 -    Expression *left_;
   3.396 -    Expression *right_;
   3.397 -
   3.398 -  public:
   3.399 -    TernaryExpression(const SourcePosition &pos, Expression *condition, Expression *left, Expression *right)
   3.400 -      : Expression(pos),
   3.401 -        condition_(condition),
   3.402 -        left_(left),
   3.403 -        right_(right)
   3.404 -    {
   3.405 -    }
   3.406 -
   3.407 -    Kind kind() const {
   3.408 -        return kTernaryExpression;
   3.409 -    }
   3.410 -    Expression *condition() const {
   3.411 -        return condition_;
   3.412 -    }
   3.413 -    Expression *left() const {
   3.414 -        return left_;
   3.415 -    }
   3.416 -    Expression *right() const {
   3.417 -        return right_;
   3.418 -    }
   3.419 -    void accept(AstVisitor *visitor) {
   3.420 -        visitor->visit(this);
   3.421 -    }
   3.422 -};
   3.423 -
   3.424 -class IndexExpression : public Expression
   3.425 -{
   3.426 -    Expression *left_;
   3.427 -    Expression *right_;
   3.428 -
   3.429 -  public:
   3.430 -    IndexExpression(const SourcePosition &pos, Expression *left, Expression *right)
   3.431 -      : Expression(pos),
   3.432 -        left_(left),
   3.433 -        right_(right)
   3.434 -    {
   3.435 -    }
   3.436 -
   3.437 -    Kind kind() const {
   3.438 -        return kIndexExpression;
   3.439 -    }
   3.440 -    Expression *left() const {
   3.441 -        return left_;
   3.442 -    }
   3.443 -    Expression *right() const {
   3.444 -        return right_;
   3.445 -    }
   3.446 -    void accept(AstVisitor *visitor) {
   3.447 -        visitor->visit(this);
   3.448 -    }
   3.449 -};
   3.450 -
   3.451 -class CallExpression : public Expression
   3.452 -{
   3.453 -    Expression *callee_;
   3.454 -    ExpressionList *arguments_;
   3.455 -
   3.456 -  public:
   3.457 -    CallExpression(const SourcePosition &pos, Expression *callee, ExpressionList *arguments)
   3.458 -      : Expression(pos),
   3.459 -        callee_(callee),
   3.460 -        arguments_(arguments)
   3.461 -    {
   3.462 -    }
   3.463 -
   3.464 -    Kind kind() const {
   3.465 -        return kCallExpression;
   3.466 -    }
   3.467 -    Expression *callee() const {
   3.468 -        return callee_;
   3.469 -    }
   3.470 -    ExpressionList *arguments() const {
   3.471 -        return arguments_;
   3.472 -    }
   3.473 -    void accept(AstVisitor *visitor) {
   3.474 -        visitor->visit(this);
   3.475 -    }
   3.476 -};
   3.477 -
   3.478 -class ForStatement : public Statement
   3.479 -{
   3.480 -    Scope *scope_;
   3.481 -    Statement *initialization_;
   3.482 -    Expression *condition_;
   3.483 -    Statement *update_;
   3.484 -    Statement *body_;
   3.485 -
   3.486 -  public:
   3.487 -    ForStatement(const SourcePosition &pos, Scope *scope, Statement *initialization,
   3.488 -                 Expression *condition, Statement *update, Statement *body)
   3.489 -      : Statement(pos),
   3.490 -        scope_(scope),
   3.491 -        initialization_(initialization),
   3.492 -        condition_(condition),
   3.493 -        update_(update),
   3.494 -        body_(body)
   3.495 -    {
   3.496 -    }
   3.497 -
   3.498 -    Kind kind() const {
   3.499 -        return kForStatement;
   3.500 -    }
   3.501 -    Statement *initialization() const {
   3.502 -        return initialization_;
   3.503 -    }
   3.504 -    Scope *scope() const {
   3.505 -        return scope_;
   3.506 -    }
   3.507 -    Expression *condition() const {
   3.508 -        return condition_;
   3.509 -    }
   3.510 -    Statement *update() const {
   3.511 -        return update_;
   3.512 -    }
   3.513 -    Statement *body() const {
   3.514 -        return body_;
   3.515 -    }
   3.516 -    void accept(AstVisitor *visitor) {
   3.517 -        visitor->visit(this);
   3.518 -    }
   3.519 -};
   3.520 -
   3.521 -class WhileStatement : public Statement
   3.522 -{
   3.523 -    TokenKind token_;
   3.524 -    Expression *condition_;
   3.525 -    Statement *body_;
   3.526 -
   3.527 -  public:
   3.528 -    WhileStatement(const SourcePosition &pos, TokenKind kind, Expression *condition, Statement *body)
   3.529 -      : Statement(pos),
   3.530 -        token_(kind),
   3.531 -        condition_(condition),
   3.532 -        body_(body)
   3.533 -    {
   3.534 -    }
   3.535 -    
   3.536 -    Kind kind() const {
   3.537 -        return kWhileStatement;
   3.538 -    }
   3.539 -    TokenKind token() const {
   3.540 -        return token_;
   3.541 -    }
   3.542 -    Expression *condition() const {
   3.543 -        return condition_;
   3.544 -    }
   3.545 -    Statement *body() const {
   3.546 -        return body_;
   3.547 -    }
   3.548 -    void accept(AstVisitor *visitor) {
   3.549 -        visitor->visit(this);
   3.550 -    }
   3.551 -};
   3.552 -
   3.553 -class ReturnStatement : public Statement
   3.554 -{
   3.555 -    Expression *expression_;
   3.556 -
   3.557 -  public:
   3.558 -    ReturnStatement(const SourcePosition &pos, Expression *expression)
   3.559 -      : Statement(pos),
   3.560 -        expression_(expression)
   3.561 -    {
   3.562 -    }
   3.563 -
   3.564 -    Kind kind() const {
   3.565 -        return kReturnStatement;
   3.566 -    }
   3.567 -    Expression *expression() const {
   3.568 -        return expression_;
   3.569 -    }
   3.570 -    void accept(AstVisitor *visitor) {
   3.571 -        visitor->visit(this);
   3.572 -    }
   3.573 -};
   3.574 -
   3.575 -class BreakStatement : public Statement
   3.576 -{
   3.577 -  public:
   3.578 -    BreakStatement(const SourcePosition &pos)
   3.579 -      : Statement(pos)
   3.580 -    {
   3.581 -    }
   3.582 -
   3.583 -    Kind kind() const {
   3.584 -        return kBreakStatement;
   3.585 -    }
   3.586 -    void accept(AstVisitor *visitor) {
   3.587 -        visitor->visit(this);
   3.588 -    }
   3.589 -};
   3.590 -
   3.591 -class ContinueStatement : public Statement
   3.592 -{
   3.593 -  public:
   3.594 -    ContinueStatement(const SourcePosition &pos)
   3.595 -      : Statement(pos)
   3.596 -    {
   3.597 -    }
   3.598 -
   3.599 -    Kind kind() const {
   3.600 -        return kContinueStatement;
   3.601 -    }
   3.602 -    void accept(AstVisitor *visitor) {
   3.603 -        visitor->visit(this);
   3.604 -    }
   3.605 -};
   3.606 -
   3.607 -class Assignment : public Expression
   3.608 -{
   3.609 -    TokenKind token_;
   3.610 -    Expression *lvalue_;
   3.611 -    Expression *expression_;
   3.612 -
   3.613 -  public:
   3.614 -    Assignment(const SourcePosition &pos, TokenKind token, Expression *left, Expression *right)
   3.615 -      : Expression(pos),
   3.616 -        token_(token),
   3.617 -        lvalue_(left),
   3.618 -        expression_(right)
   3.619 -    {
   3.620 -    }
   3.621 -
   3.622 -    Kind kind() const {
   3.623 -        return kAssignment;
   3.624 -    }
   3.625 -    TokenKind token() const {
   3.626 -        return token_;
   3.627 -    }
   3.628 -    Expression *lvalue() const {
   3.629 -        return lvalue_;
   3.630 -    }
   3.631 -    Expression *expression() const {
   3.632 -        return expression_;
   3.633 -    }
   3.634 -    void accept(AstVisitor *visitor) {
   3.635 -        visitor->visit(this);
   3.636 -    }
   3.637 -};
   3.638 -
   3.639 -class ExpressionStatement : public Statement
   3.640 -{
   3.641 -    Expression *expression_;
   3.642 -
   3.643 -  public:
   3.644 -    ExpressionStatement(Expression *expression)
   3.645 -      : Statement(expression->pos()),
   3.646 -        expression_(expression)
   3.647 -    {
   3.648 -    }
   3.649 -
   3.650 -    Kind kind() const {
   3.651 -        return kExpressionStatement;
   3.652 -    }
   3.653 -    Expression *expression() const {
   3.654 -        return expression_;
   3.655 -    }
   3.656 -    void accept(AstVisitor *visitor) {
   3.657 -        visitor->visit(this);
   3.658 -    }
   3.659 -};
   3.660 -
   3.661 -class BlockStatement : public Statement
   3.662 -{
   3.663 -    Scope *scope_;
   3.664 -    StatementList *statements_;
   3.665 -
   3.666 -  public:
   3.667 -    BlockStatement(const SourcePosition &pos, Scope *scope, StatementList *statements)
   3.668 -      : Statement(pos),
   3.669 -        scope_(scope),
   3.670 -        statements_(statements)
   3.671 -    {
   3.672 -    }
   3.673 -
   3.674 -    Kind kind() const {
   3.675 -        return kBlockStatement;
   3.676 -    }
   3.677 -    Scope *scope() const {
   3.678 -        return scope_;
   3.679 -    }
   3.680 -    StatementList *statements() const {
   3.681 -        return statements_;
   3.682 -    }
   3.683 -    void accept(AstVisitor *visitor) {
   3.684 -        visitor->visit(this);
   3.685 -    }
   3.686 -};
   3.687 -
   3.688 -typedef PoolList<Parameter *> ParameterList;
   3.689 -
   3.690 -class FunctionStatement : public Statement
   3.691 -{
   3.692 -    Scope *scope_;
   3.693 -    NamedFunction *fun_;
   3.694 -    Statement *body_;
   3.695 -    ParameterList *parameters_;
   3.696 -    bool explicitReturn_;
   3.697 -
   3.698 -  public:
   3.699 -    FunctionStatement(const SourcePosition &pos, Scope *scope, NamedFunction *fun, Statement *body,
   3.700 -                      ParameterList *parameters, bool explicitReturn)
   3.701 -      : Statement(pos),
   3.702 -        scope_(scope),
   3.703 -        fun_(fun),
   3.704 -        body_(body),
   3.705 -        parameters_(parameters),
   3.706 -        explicitReturn_(explicitReturn)
   3.707 -    {
   3.708 -    }
   3.709 -
   3.710 -    Kind kind() const {
   3.711 -        return kFunctionStatement;
   3.712 -    }
   3.713 -    Scope *scope() const {
   3.714 -        return scope_;
   3.715 -    }
   3.716 -    NamedFunction *fun() const {
   3.717 -        return fun_;
   3.718 -    }
   3.719 -    Statement *body() const {
   3.720 -        return body_;
   3.721 -    }
   3.722 -    ParameterList *parameters() const {
   3.723 -        return parameters_;
   3.724 -    }
   3.725 -    void accept(AstVisitor *visitor) {
   3.726 -        visitor->visit(this);
   3.727 -    }
   3.728 -    bool hasExplicitReturn() const {
   3.729 -        return explicitReturn_;
   3.730 -    }
   3.731 -};
   3.732 -
   3.733 -class IfStatement : public Statement
   3.734 -{
   3.735 -    Expression *condition_;
   3.736 -    Statement *ifTrue_;
   3.737 -    Statement *ifFalse_;
   3.738 -
   3.739 -  public:
   3.740 -    IfStatement(const SourcePosition &pos, Expression *condition, Statement *ifTrue)
   3.741 -      : Statement(pos),
   3.742 -        condition_(condition),
   3.743 -        ifTrue_(ifTrue),
   3.744 -        ifFalse_(NULL)
   3.745 -    {
   3.746 -    }
   3.747 -
   3.748 -    Kind kind() const {
   3.749 -        return kIfStatement;
   3.750 -    }
   3.751 -    Expression *condition() const {
   3.752 -        return condition_;
   3.753 -    }
   3.754 -    Statement *ifTrue() const {
   3.755 -        return ifTrue_;
   3.756 -    }
   3.757 -    Statement *ifFalse() const {
   3.758 -        return ifFalse_;
   3.759 -    }
   3.760 -    void setIfFalse(Statement *ifFalse) {
   3.761 -        ifFalse_ = ifFalse;
   3.762 -    }
   3.763 -    void accept(AstVisitor *visitor) {
   3.764 -        visitor->visit(this);
   3.765 -    }
   3.766 -};
   3.767 -
   3.768 -class EnumStatement : public Statement
   3.769 -{
   3.770 -    ScopedRoot<String> name_;
   3.771 -
   3.772 -  public:
   3.773 -    struct Entry {
   3.774 -        NamedConstant *name;
   3.775 -        Expression *expr;
   3.776 -
   3.777 -        Entry(NamedConstant *name, Expression *expr)
   3.778 -          : name(name),
   3.779 -            expr(expr)
   3.780 -        {
   3.781 -        }
   3.782 -    };
   3.783 -
   3.784 -    typedef PoolList<Entry> EntryList;
   3.785 -
   3.786 -  public:
   3.787 -    EnumStatement(const SourcePosition &pos, Handle<String> name, EntryList *entries)
   3.788 -      : Statement(pos),
   3.789 -        name_(name),
   3.790 -        entries_(entries)
   3.791 -    {
   3.792 -    }
   3.793 -
   3.794 -    Kind kind() const {
   3.795 -        return kEnumStatement;
   3.796 -    }
   3.797 -    String *name() const {
   3.798 -        return name_;
   3.799 -    }
   3.800 -    EntryList *entries() const {
   3.801 -        return entries_;
   3.802 -    }
   3.803 -    void accept(AstVisitor *visitor) {
   3.804 -        visitor->visit(this);
   3.805 -    }
   3.806 -
   3.807 -  private:
   3.808 -    EntryList *entries_;
   3.809 -};
   3.810 -
   3.811 -class IncDecExpression : public Expression
   3.812 -{
   3.813 -    TokenKind token_;
   3.814 -    Expression *expression_;
   3.815 -    bool postfix_;
   3.816 -
   3.817 -  public:
   3.818 -    IncDecExpression(const SourcePosition &pos, TokenKind token, Expression *expression, bool postfix)
   3.819 -      : Expression(pos),
   3.820 -        token_(token),
   3.821 -        expression_(expression),
   3.822 -        postfix_(postfix)
   3.823 -    {
   3.824 -    }
   3.825 -
   3.826 -    Kind kind() const {
   3.827 -        return kIncDecExpression;
   3.828 -    }
   3.829 -    TokenKind token() const {
   3.830 -        return token_;
   3.831 -    }
   3.832 -    Expression *expression() const {
   3.833 -        return expression_;
   3.834 -    }
   3.835 -    bool postfix() const {
   3.836 -        return postfix_;
   3.837 -    }
   3.838 -    void accept(AstVisitor *visitor) {
   3.839 -        visitor->visit(this);
   3.840 -    }
   3.841 -};
   3.842 -
   3.843 -class Scope;
   3.844 -
   3.845 -typedef PoolList<NameProxy *> NameProxyList;
   3.846 -
   3.847 -class ParseTree : public PoolObject
   3.848 -{
   3.849 -    StatementList *statements_;
   3.850 -    Scope *scope_;
   3.851 -    NameProxyList *unbound_;
   3.852 -
   3.853 -  public:
   3.854 -    ParseTree(Scope *scope, StatementList *statements, NameProxyList *unbound)
   3.855 -      : statements_(statements),
   3.856 -        scope_(scope),
   3.857 -        unbound_(unbound)
   3.858 -    {
   3.859 -    }
   3.860 -
   3.861 -    void dump(FILE *fp);
   3.862 -
   3.863 -    StatementList *statements() const {
   3.864 -        return statements_;
   3.865 -    }
   3.866 -    Scope *scope() const {
   3.867 -        return scope_;
   3.868 -    }
   3.869 -    NameProxyList *unbound() const {
   3.870 -        return unbound_;
   3.871 -    }
   3.872 -};
   3.873 -
   3.874 -}
   3.875 -
   3.876 -#endif // _include_jitcraft_ast_h_
     4.1 --- a/jitcraft/AllocatorPolicies.h	Tue Jul 24 23:53:34 2012 -0700
     4.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     4.3 @@ -1,45 +0,0 @@
     4.4 -/*
     4.5 - * Copyright (C) 2012 David Anderson
     4.6 - *
     4.7 - * This file is part of JITCraft.
     4.8 - *
     4.9 - * JITCraft 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 - * Foobar 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 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    4.20 - */
    4.21 -#ifndef _include_jc_allocators_h_
    4.22 -#define _include_jc_allocators_h_
    4.23 -
    4.24 -#include <stdlib.h>
    4.25 -
    4.26 -namespace ke {
    4.27 -
    4.28 -class ZoneAllocatorPolicy
    4.29 -{
    4.30 -  protected:
    4.31 -    void reportOutOfMemory();
    4.32 -    void reportAllocationOverflow();
    4.33 -
    4.34 -  public:
    4.35 -    void free(void *memory) {
    4.36 -        ::free(memory);
    4.37 -    }
    4.38 -    void *malloc(size_t bytes) {
    4.39 -        void *ptr = ::malloc(bytes);
    4.40 -        if (!ptr)
    4.41 -            reportOutOfMemory();
    4.42 -        return ptr;
    4.43 -    }
    4.44 -};
    4.45 -
    4.46 -}
    4.47 -
    4.48 -#endif // _include_jc_allocators_h_
     5.1 --- a/jitcraft/Array.cpp	Tue Jul 24 23:53:34 2012 -0700
     5.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     5.3 @@ -1,77 +0,0 @@
     5.4 -/*
     5.5 - * Copyright (C) 2012 David Anderson
     5.6 - *
     5.7 - * This file is part of JITCraft.
     5.8 - *
     5.9 - * JITCraft 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 - * Foobar 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 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    5.20 - */
    5.21 -#include "Array.h"
    5.22 -#include "Heap.h"
    5.23 -#include "Zone.h"
    5.24 -#include "Heap-inl.h"
    5.25 -
    5.26 -using namespace ke;
    5.27 -
    5.28 -ArrayMap *
    5.29 -ArrayMap::New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained)
    5.30 -{
    5.31 -    Local<Map> obj(zone, zone->allocateMap(MapKind_Array, sizeof(ArrayMap), MapKind_MetaArray));
    5.32 -    if (!obj)
    5.33 -        return NULL;
    5.34 -
    5.35 -    Local<ArrayMap> map(zone, ArrayMap::cast(obj));
    5.36 -    map->type_ = type;
    5.37 -    map->contained_ = contained;
    5.38 -    return map;
    5.39 -}
    5.40 -
    5.41 -static inline size_t
    5.42 -SizeFor(Type *type, unsigned elements)
    5.43 -{
    5.44 -    if (type->levels() > 1)
    5.45 -        return sizeof(Array) + elements * sizeof(ke::Object *);
    5.46 -    if (type->contained()->isInt32())
    5.47 -        return sizeof(Array) + elements * sizeof(int);
    5.48 -    if (type->contained()->primitive() == PrimitiveType_Char)
    5.49 -        return sizeof(Array) + elements * sizeof(char);
    5.50 -    assert(type->contained()->isFloat());
    5.51 -    return elements * sizeof(float);
    5.52 -}
    5.53 -
    5.54 -Array *
    5.55 -Array::New(Zone *zone, Handle<ArrayMap> map, uint32 elements, Heap::Tenure tenure)
    5.56 -{
    5.57 -    size_t elementBytes = SizeFor(map->type(), elements);
    5.58 -    size_t bytes = sizeof(Array) + elementBytes;
    5.59 -    Local<Array> array(zone, Array::cast(zone->allocate(map, bytes, tenure)));
    5.60 -    if (!array)
    5.61 -        return NULL;
    5.62 -
    5.63 -    array->nelements_ = elements;
    5.64 -    array->elements_ = (Array *)array + 1;
    5.65 -    memset(array->elements_, 0, elementBytes);
    5.66 -    return array;
    5.67 -}
    5.68 -
    5.69 -Array *
    5.70 -Array::NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements, void *buffer,
    5.71 -                   Heap::Tenure tenure)
    5.72 -{
    5.73 -    Local<Array> array(zone, Array::cast(zone->allocate(map, sizeof(Array), tenure)));
    5.74 -    if (!array)
    5.75 -        return NULL;
    5.76 -
    5.77 -    array->nelements_ = nelements;
    5.78 -    array->elements_ = buffer;
    5.79 -    return array;
    5.80 -}
     6.1 --- a/jitcraft/Array.h	Tue Jul 24 23:53:34 2012 -0700
     6.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     6.3 @@ -1,204 +0,0 @@
     6.4 -/*
     6.5 - * Copyright (C) 2012 David Anderson
     6.6 - *
     6.7 - * This file is part of JITCraft.
     6.8 - *
     6.9 - * JITCraft is free software: you can redistribute it and/or modify it under
    6.10 - * the terms of the GNU General Public License as published by the Free
    6.11 - * Software Foundation, either version 3 of the License, or (at your option)
    6.12 - * any later version.
    6.13 - * 
    6.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    6.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    6.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    6.17 - *
    6.18 - * You should have received a copy of the GNU General Public License along with
    6.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    6.20 - */
    6.21 -#ifndef _include_jitcraft_array_h_
    6.22 -#define _include_jitcraft_array_h_
    6.23 -
    6.24 -#include "Heap.h"
    6.25 -#include "Handles.h"
    6.26 -#include "Types.h"
    6.27 -
    6.28 -namespace ke {
    6.29 -
    6.30 -class ArrayMap;
    6.31 -
    6.32 -class Array : public Object
    6.33 -{
    6.34 -    friend class ArrayMap;
    6.35 -
    6.36 -    uint32 nelements_;
    6.37 -    void *elements_;
    6.38 -
    6.39 -  public:
    6.40 -    static Array *New(Zone *zone, Handle<ArrayMap> map, uint32 elements,
    6.41 -                      Heap::Tenure = Heap::Tenure_Default);
    6.42 -    static Array *NewExternal(Zone *zone, Handle<ArrayMap> map, uint32 nelements,
    6.43 -                              void *elements, Heap::Tenure = Heap::Tenure_Default);
    6.44 -
    6.45 -    uint32 nelements() {
    6.46 -        return nelements_;
    6.47 -    }
    6.48 -    void *vec() {
    6.49 -        return elements_;
    6.50 -    }
    6.51 -
    6.52 -    inline int *int32Vec();
    6.53 -    inline float *floatVec();
    6.54 -    inline Object **objVec();
    6.55 -    inline char *chars();
    6.56 -
    6.57 -    inline Type *type();
    6.58 -    inline size_t elementSize();
    6.59 -
    6.60 -    int readInt32(size_t index) {
    6.61 -        assert(index < nelements());
    6.62 -        return int32Vec()[index];
    6.63 -    }
    6.64 -    void writeInt32(size_t index, int i) {
    6.65 -        assert(index < nelements());
    6.66 -        int32Vec()[index] = i;
    6.67 -    }
    6.68 -    char readChar(size_t index) {
    6.69 -        assert(index < nelements());
    6.70 -        return chars()[index];
    6.71 -    }
    6.72 -    void writeChar(size_t index, char c) {
    6.73 -        assert(index < nelements());
    6.74 -        chars()[index] = c;
    6.75 -    }
    6.76 -    float readFloat(size_t index) {
    6.77 -        assert(index < nelements());
    6.78 -        return floatVec()[index];
    6.79 -    }
    6.80 -    void writeFloat(size_t index, float f) {
    6.81 -        assert(index < nelements());
    6.82 -        floatVec()[index] = f;
    6.83 -    }
    6.84 -    inline void *slotPtr(size_t index);
    6.85 -    Object *readObject(size_t index) {
    6.86 -        assert(index < nelements());
    6.87 -        return objVec()[index];
    6.88 -    }
    6.89 -    void writeObject(Zone *zone, size_t index, Object *ptr) {
    6.90 -        assert(index < nelements());
    6.91 -        write(zone, &objVec()[index], ptr);
    6.92 -    }
    6.93 -
    6.94 -    bool isExternal() {
    6.95 -        // Inline arrays always have their elements pointing at the next slot.
    6.96 -        Address buffer = reinterpret_cast<Address>(elements_);
    6.97 -        return buffer != reinterpret_cast<Address>(this + 1);
    6.98 -    }
    6.99 -
   6.100 -    static inline size_t SizeOf(Array *array) {
   6.101 -        if (array->isExternal())
   6.102 -            return sizeof(Array);
   6.103 -        return sizeof(Array) + array->nelements() * array->elementSize();
   6.104 -    }
   6.105 -
   6.106 -    static Array *cast(Object *obj) {
   6.107 -        assert(!obj || obj->is(MapKind_Array));
   6.108 -        return reinterpret_cast<Array *>(obj);
   6.109 -    }
   6.110 -};
   6.111 -
   6.112 -class ArrayMap : public Map
   6.113 -{
   6.114 -    Barriered<Type> type_;
   6.115 -    Barriered<ArrayMap> contained_;
   6.116 -
   6.117 -  public:
   6.118 -    static ArrayMap *New(Zone *zone, Handle<Type> type, Handle<ArrayMap> contained);
   6.119 -
   6.120 -    Type *type() {
   6.121 -        return type_;
   6.122 -    }
   6.123 -    ArrayMap *contained() {
   6.124 -        return contained_;
   6.125 -    }
   6.126 -
   6.127 -    // GC Descriptor.
   6.128 -    static inline size_t offsetOfType() {
   6.129 -        return offsetof(ArrayMap, type_);
   6.130 -    }
   6.131 -    static inline size_t offsetOfContained() {
   6.132 -        return offsetof(ArrayMap, contained_);
   6.133 -    }
   6.134 -    // End GC Descriptor.
   6.135 -    
   6.136 -    static ArrayMap *cast(Object *obj) {
   6.137 -        assert(!obj || obj->is(MapKind_MetaArray));
   6.138 -        return reinterpret_cast<ArrayMap *>(obj);
   6.139 -    }
   6.140 -};
   6.141 -
   6.142 -inline int *
   6.143 -Array::int32Vec()
   6.144 -{
   6.145 -    assert(type()->levels() == 1);
   6.146 -    assert(type()->contained()->isInt32());
   6.147 -    return reinterpret_cast<int *>(vec());
   6.148 -}
   6.149 -
   6.150 -inline float *
   6.151 -Array::floatVec()
   6.152 -{
   6.153 -    assert(type()->levels() == 1);
   6.154 -    assert(type()->contained()->isFloat());
   6.155 -    return reinterpret_cast<float *>(vec());
   6.156 -}
   6.157 -
   6.158 -inline Object **
   6.159 -Array::objVec()
   6.160 -{
   6.161 -    assert(type()->levels() > 1);
   6.162 -    return reinterpret_cast<Object **>(vec());
   6.163 -}
   6.164 -
   6.165 -inline void *
   6.166 -Array::slotPtr(size_t index)
   6.167 -{
   6.168 -    assert(type()->contained()->primitive() == PrimitiveType_Int32 ||
   6.169 -           type()->contained()->primitive() == PrimitiveType_Float);
   6.170 -    assert(index < nelements());
   6.171 -    return reinterpret_cast<int *>(vec()) + index;
   6.172 -}
   6.173 -
   6.174 -inline char *
   6.175 -Array::chars()
   6.176 -{
   6.177 -    assert(type()->levels() == 1);
   6.178 -    assert(type()->contained()->primitive() == PrimitiveType_Char);
   6.179 -    return reinterpret_cast<char *>(vec());
   6.180 -}
   6.181 -
   6.182 -inline Type *
   6.183 -Array::type()
   6.184 -{
   6.185 -    return ArrayMap::cast(map())->type();
   6.186 -}
   6.187 -
   6.188 -inline size_t
   6.189 -Array::elementSize()
   6.190 -{
   6.191 -    assert(type()->isArray());
   6.192 -    if (type()->contained()->isArray())
   6.193 -        return sizeof(Object *);
   6.194 -    switch (type()->contained()->primitive()) {
   6.195 -      case PrimitiveType_Float:
   6.196 -        return sizeof(float);
   6.197 -      case PrimitiveType_Int32:
   6.198 -        return sizeof(int);
   6.199 -      default:
   6.200 -        assert(type()->contained()->primitive() == PrimitiveType_Char);
   6.201 -        return sizeof(char);
   6.202 -    }
   6.203 -}
   6.204 -
   6.205 -}
   6.206 -
   6.207 -#endif // _include_jitcraft_array_h_
     7.1 --- a/jitcraft/Barriers.h	Tue Jul 24 23:53:34 2012 -0700
     7.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     7.3 @@ -1,93 +0,0 @@
     7.4 -/*
     7.5 - * Copyright (C) 2012 David Anderson
     7.6 - *
     7.7 - * This file is part of JITCraft.
     7.8 - *
     7.9 - * JITCraft is free software: you can redistribute it and/or modify it under
    7.10 - * the terms of the GNU General Public License as published by the Free
    7.11 - * Software Foundation, either version 3 of the License, or (at your option)
    7.12 - * any later version.
    7.13 - * 
    7.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    7.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    7.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    7.17 - *
    7.18 - * You should have received a copy of the GNU General Public License along with
    7.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    7.20 - */
    7.21 -#ifndef _include_jitcraft_barriers_h_
    7.22 -#define _include_jitcraft_barriers_h_
    7.23 -
    7.24 -namespace ke {
    7.25 -
    7.26 -class Object;
    7.27 -
    7.28 -// Used to store unbarriered heap locations.
    7.29 -template <typename T>
    7.30 -class Unbarriered
    7.31 -{
    7.32 -    T *obj_;
    7.33 -
    7.34 -  public:
    7.35 -    Unbarriered()
    7.36 -      : obj_(NULL)
    7.37 -    {
    7.38 -    }
    7.39 -
    7.40 -    T *operator ->() const {
    7.41 -        return operator *();
    7.42 -    }
    7.43 -    T *operator *() const {
    7.44 -        return static_cast<T *>(obj_);
    7.45 -    }
    7.46 -    Unbarriered &operator =(T *obj) {
    7.47 -        obj_ = obj;
    7.48 -        return *this;
    7.49 -    }
    7.50 -    Object **address() {
    7.51 -        return reinterpret_cast<Object **>(&obj_);
    7.52 -    }
    7.53 -    operator bool () const {
    7.54 -        return !!obj_;
    7.55 -    }
    7.56 -    operator T*() const {
    7.57 -        return static_cast<T *>(obj_);
    7.58 -    }
    7.59 -};
    7.60 -
    7.61 -// Used to store unbarriered heap locations.
    7.62 -template <typename T>
    7.63 -class Barriered
    7.64 -{
    7.65 -    T *obj_;
    7.66 -
    7.67 -  public:
    7.68 -    Barriered()
    7.69 -      : obj_(NULL)
    7.70 -    {
    7.71 -    }
    7.72 -
    7.73 -    T *operator ->() const {
    7.74 -        return operator *();
    7.75 -    }
    7.76 -    T *operator *() const {
    7.77 -        return static_cast<T *>(obj_);
    7.78 -    }
    7.79 -    Barriered &operator =(T *obj) {
    7.80 -        obj_ = obj;
    7.81 -        return *this;
    7.82 -    }
    7.83 -    Object **addr() {
    7.84 -        return reinterpret_cast<Object **>(&obj_);
    7.85 -    }
    7.86 -    operator bool () const {
    7.87 -        return !!obj_;
    7.88 -    }
    7.89 -    operator T*() const {
    7.90 -        return static_cast<T *>(obj_);
    7.91 -    }
    7.92 -};
    7.93 -
    7.94 -}
    7.95 -
    7.96 -#endif // _include_jitcraft_barriers_h_
     8.1 --- a/jitcraft/BytecodeCompiler.cpp	Tue Jul 24 23:53:34 2012 -0700
     8.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.3 @@ -1,1096 +0,0 @@
     8.4 -/* vim: set ts=4 sw=4 tw=99 et:
     8.5 - *
     8.6 - * Copyright (C) 2012 David Anderson
     8.7 - *
     8.8 - * This file is part of JITCraft.
     8.9 - *
    8.10 - * JITCraft is free software: you can redistribute it and/or modify it under
    8.11 - * the terms of the GNU General Public License as published by the Free
    8.12 - * Software Foundation, either version 3 of the License, or (at your option)
    8.13 - * any later version.
    8.14 - * 
    8.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    8.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    8.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    8.18 - *
    8.19 - * You should have received a copy of the GNU General Public License along with
    8.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    8.21 - */
    8.22 -#include "BytecodeCompiler.h"
    8.23 -#include "Scopes.h"
    8.24 -#include "Modules.h"
    8.25 -#include "Types.h"
    8.26 -#include "Array.h"
    8.27 -#include "Strings.h"
    8.28 -#include "Zone.h"
    8.29 -#include "Environments.h"
    8.30 -#include "Heap-inl.h"
    8.31 -
    8.32 -using namespace ke;
    8.33 -
    8.34 -typedef BytecodeEmitter::Label Label;
    8.35 -
    8.36 -#define __ emitter_.
    8.37 -
    8.38 -BytecodeCompiler::BytecodeCompiler(Zone *zone, ParseTree *tree, ModuleData *module)
    8.39 -  : zone_(zone),
    8.40 -    tree_(tree),
    8.41 -    emitter_(zone->pool()),
    8.42 -    moduleData_(module),
    8.43 -    locals_(NULL),
    8.44 -    scope_(NULL),
    8.45 -    loop_(NULL)
    8.46 -{
    8.47 -}
    8.48 -
    8.49 -static inline TokenKind
    8.50 -ToCompare(Expression *expr)
    8.51 -{
    8.52 -    if (expr->isBinaryExpression()) {
    8.53 -        BinaryExpression *b = expr->toBinaryExpression();
    8.54 -        if (b->token() >= TOK_EQUALS && b->token() <= TOK_OR)
    8.55 -            return b->token();
    8.56 -    } else if (expr->isUnaryExpression()) {
    8.57 -        UnaryExpression *u = expr->toUnaryExpression();
    8.58 -        if (u->token() == TOK_NOT)
    8.59 -            return TOK_NOT;
    8.60 -    }
    8.61 -    return TOK_EOF;
    8.62 -}
    8.63 -
    8.64 -static inline Opcode
    8.65 -CompareTokenToJump(TokenKind kind)
    8.66 -{
    8.67 -    switch (kind) {
    8.68 -      case TOK_EQUALS:
    8.69 -        return OP_JEQ;
    8.70 -      case TOK_NOTEQUALS:
    8.71 -        return OP_JNE;
    8.72 -      case TOK_GT:
    8.73 -        return OP_JG;
    8.74 -      case TOK_GE:
    8.75 -        return OP_JGE;
    8.76 -      case TOK_LT:
    8.77 -        return OP_JL;
    8.78 -      default:
    8.79 -        assert(kind == TOK_LE);
    8.80 -        return OP_JLE;
    8.81 -    }
    8.82 -}
    8.83 -
    8.84 -static inline Opcode
    8.85 -TokenToOpcode(TokenKind kind)
    8.86 -{
    8.87 -    switch (kind) {
    8.88 -      case TOK_PLUS:
    8.89 -        return OP_ADD;
    8.90 -      case TOK_MINUS:
    8.91 -        return OP_SUB;
    8.92 -      case TOK_STAR:
    8.93 -        return OP_MUL;
    8.94 -      case TOK_SLASH:
    8.95 -        return OP_DIV;
    8.96 -      case TOK_PERCENT:
    8.97 -        return OP_MOD;
    8.98 -      case TOK_SHR:
    8.99 -        return OP_SHR;
   8.100 -      case TOK_USHR:
   8.101 -        return OP_USHR;
   8.102 -      case TOK_SHL:
   8.103 -        return OP_SHL;
   8.104 -      case TOK_BITAND:
   8.105 -        return OP_BITAND;
   8.106 -      case TOK_BITOR:
   8.107 -        return OP_BITOR;
   8.108 -      case TOK_GT:
   8.109 -          return OP_GT;
   8.110 -      case TOK_GE:
   8.111 -          return OP_GE;
   8.112 -      case TOK_LT:
   8.113 -          return OP_LT;
   8.114 -      case TOK_LE:
   8.115 -          return OP_LE;
   8.116 -      case TOK_EQUALS:
   8.117 -          return OP_EQ;
   8.118 -      case TOK_NOTEQUALS:
   8.119 -          return OP_NE;
   8.120 -      default:
   8.121 -        assert(kind == TOK_BITXOR);
   8.122 -        return OP_BITXOR;
   8.123 -    }
   8.124 -}
   8.125 -
   8.126 -void
   8.127 -BytecodeCompiler::recordLifoSlot(Scope *scope)
   8.128 -{
   8.129 -    if (!scope)
   8.130 -        return;
   8.131 -
   8.132 -    if (Variable *var = scope->lifoSlot()) {
   8.133 -        locals_->set(zone_, var->slot(), var->type());
   8.134 -        __ savelifo(var->slot());
   8.135 -    }
   8.136 -}
   8.137 -
   8.138 -void
   8.139 -BytecodeCompiler::unwindTo(Scope *scope)
   8.140 -{
   8.141 -    // Note: we only need to unwind to the outermost scope's LIFO slot.
   8.142 -    Variable *var = NULL;
   8.143 -    for (Scope *current = scope_; current != scope; current = current->enclosing()) {
   8.144 -        if (Variable *slot = current->lifoSlot())
   8.145 -            var = slot;
   8.146 -    }
   8.147 -
   8.148 -    if (var)
   8.149 -        __ unwindlifo(var->slot());
   8.150 -}
   8.151 -
   8.152 -void
   8.153 -BytecodeCompiler::visit(NameProxy *name)
   8.154 -{
   8.155 -    switch (name->binding()->kind()) {
   8.156 -      case BoundName::VARIABLE:
   8.157 -      {
   8.158 -        Variable *var = name->binding()->toVariable();
   8.159 -
   8.160 -        if (var->location() == Variable::STACK) {
   8.161 -            __ getlocal(var);
   8.162 -            assert(!name->type()->isReference());
   8.163 -        } else if (var->location() == Variable::ENVIRONMENT) {
   8.164 -            getEnvSlot(var);
   8.165 -        } else {
   8.166 -            assert(var->location() == Variable::PARAMETER);
   8.167 -            __ getarg(var);
   8.168 -
   8.169 -            // If this argument is actually a reference, dereference it now.
   8.170 -            if (var->type()->isReference())
   8.171 -                __ getref(var->type()->contained()->primitive());
   8.172 -        }
   8.173 -        break;
   8.174 -      }
   8.175 -
   8.176 -      case BoundName::FUNCTION:
   8.177 -      {
   8.178 -        NamedFunction *fun = name->binding()->toNamedFunction();
   8.179 -        __ module();
   8.180 -        __ getmodule_fn(fun->slot());
   8.181 -        break;
   8.182 -      }
   8.183 -
   8.184 -      default:
   8.185 -      {
   8.186 -        NamedConstant *constant = name->binding()->toNamedConstant();
   8.187 -        __ int_(constant->value().toInt());
   8.188 -        break;
   8.189 -      }
   8.190 -    }
   8.191 -}
   8.192 -
   8.193 -void
   8.194 -BytecodeCompiler::visit(ExpressionStatement *node)
   8.195 -{
   8.196 -    // Expressions leave their value on the top of the stack, so we make sure
   8.197 -    // to balance the stack if they're used as a statement.
   8.198 -    node->expression()->accept(this);
   8.199 -    if (!node->expression()->type()->isVoid())
   8.200 -        __ pop();
   8.201 -}
   8.202 -
   8.203 -void
   8.204 -BytecodeCompiler::visit(Assignment *node)
   8.205 -{
   8.206 -    // The first step is three sub-steps:
   8.207 -    //
   8.208 -    //   (1) Bind the left-hand side.
   8.209 -    //   -- If a cumulative operation (+=, etc):
   8.210 -    //   (2) Save a copy of the binding on the stack.
   8.211 -    //   (3) Dereference the binding to get a value.
   8.212 -    //
   8.213 -    if (node->lvalue()->isNameProxy()) {
   8.214 -        NameProxy *proxy = node->lvalue()->toNameProxy();
   8.215 -        Variable *var = proxy->binding()->toVariable();
   8.216 -
   8.217 -        // Bind.
   8.218 -        if (var->type()->isReference() || var->type()->isArray())
   8.219 -            __ get(var);
   8.220 -
   8.221 -        // Get the value if needed.
   8.222 -        if (node->token() != TOK_ASSIGN) {
   8.223 -            // += etc is not allowed on arrays.
   8.224 -            assert(!var->type()->isArray());
   8.225 -
   8.226 -            if (var->type()->isReference()) {
   8.227 -                __ dup();
   8.228 -                __ getref(var->type()->contained()->primitive());
   8.229 -            } else {
   8.230 -                __ get(var);
   8.231 -            }
   8.232 -        }
   8.233 -    } else {
   8.234 -        IndexExpression *index = node->lvalue()->toIndexExpression();
   8.235 -        __ note_position(index->pos());
   8.236 -
   8.237 -        // Note: Eventually, watch out for a whole here. An expression like:
   8.238 -        //
   8.239 -        //   (a[4] = (5, a = []))
   8.240 -        //
   8.241 -        // Could shrink array, so we need to either bind a[i] to a Reference,
   8.242 -        // or keep the bounds check near the set. This is just a semantic
   8.243 -        // decision.
   8.244 -        index->left()->accept(this);
   8.245 -        index->right()->accept(this);
   8.246 -
   8.247 -        if (node->token() != TOK_ASSIGN) {
   8.248 -            __ dup2();
   8.249 -            __ bounds();
   8.250 -            if (node->type()->isArray())
   8.251 -                __ getarray_o();
   8.252 -            else
   8.253 -                __ getarray(node->type()->primitive());
   8.254 -        }
   8.255 -    }
   8.256 -
   8.257 -    if (node->token() == TOK_ASSIGN) {
   8.258 -        node->expression()->accept(this);
   8.259 -    } else {
   8.260 -        visitForALU(node->type(), node->expression());
   8.261 -
   8.262 -        TokenKind alu = TokenKind(int(node->token()) - (TOK_ASSIGN_ADD - TOK_PLUS));
   8.263 -        __ note_position(node->pos());
   8.264 -        __ binary(TokenToOpcode(alu));
   8.265 -    }
   8.266 -
   8.267 -    // Emit the store.
   8.268 -    if (node->expression()->type()->isArray()) {
   8.269 -        // Unlike references, which can only be computed from a NamePRoxy,
   8.270 -        // arrays can be computed from multiple lvalue types.
   8.271 -        __ note_position(node->pos());
   8.272 -        __ arraycopy();
   8.273 -    } else if (node->lvalue()->isNameProxy()) {
   8.274 -        NameProxy *proxy = node->lvalue()->toNameProxy();
   8.275 -        Variable *var = proxy->binding()->toVariable();
   8.276 -
   8.277 -        if (var->type()->isReference())
   8.278 -            __ setref(var->type()->contained()->primitive());
   8.279 -        else
   8.280 -            __ set(var);
   8.281 -    } else {
   8.282 -        IndexExpression *index = node->lvalue()->toIndexExpression();
   8.283 -        // :TODO: get rid of the BOUNDS instruction, embed it in g/setarray*?
   8.284 -        // We can't emit it here because the stack is slightly out of position.
   8.285 -        // __ bounds();
   8.286 -        __ setarray(index->left()->type()->contained()->primitive());
   8.287 -    }
   8.288 -}
   8.289 -
   8.290 -void
   8.291 -BytecodeCompiler::visit(IncDecExpression *node)
   8.292 -{
   8.293 -    // In the postfix case, the logic looks like:
   8.294 -    //      (1) Bind       -> REF
   8.295 -    //      (2) Dup        -> REF REF
   8.296 -    //      (3) Fetch      -> REF VAL
   8.297 -    //      (4) Swap       -> VAL REF
   8.298 -    //      (5) Pick       -> VAL REF VAL
   8.299 -    //      (6) Add        -> VAL REF VAL+1
   8.300 -    //      (7) Store      -> VAL VAL+1
   8.301 -    //      (8) Drop       -> VAL
   8.302 -    //
   8.303 -    // In the prefix case, the logic looks like:
   8.304 -    //      (1) Bind       -> REF
   8.305 -    //      (2) Dup        -> REF REF
   8.306 -    //      (3) Fetch      -> REF VAL
   8.307 -    //      --
   8.308 -    //      --
   8.309 -    //      (6) Add        -> REF VAL+1
   8.310 -    //      (7) Store      -> VAL+1
   8.311 -    //      --
   8.312 -    //
   8.313 -    // This is squirrely enough such that we don't bother sharing too much
   8.314 -    // with the above.
   8.315 -    // 
   8.316 -    // Note: We simulate a "Pick" operation with a dup2+pop.
   8.317 -
   8.318 -    // This is steps (1) to (5).
   8.319 -    Expression *expr = node->expression();
   8.320 -    if (expr->isNameProxy()) {
   8.321 -        NameProxy *proxy = expr->toNameProxy();
   8.322 -        Variable *var = proxy->binding()->toVariable();
   8.323 -
   8.324 -        // Bind.
   8.325 -        if (var->type()->isReference() || var->type()->isArray())
   8.326 -            __ get(var);
   8.327 -
   8.328 -        // Dup and fetch.
   8.329 -        if (var->type()->isReference()) {
   8.330 -            __ dup();
   8.331 -            __ getref(node->type()->primitive());
   8.332 -            if (node->postfix()) {
   8.333 -                __ swap();
   8.334 -                __ pick2();
   8.335 -            }
   8.336 -        } else {
   8.337 -            assert(!var->type()->isArray());
   8.338 -            __ get(var);
   8.339 -            if (node->postfix())
   8.340 -                __ dup();
   8.341 -        }
   8.342 -    } else {
   8.343 -        IndexExpression *index = expr->toIndexExpression();
   8.344 -        __ note_position(index->pos());
   8.345 -
   8.346 -        index->left()->accept(this);
   8.347 -        index->right()->accept(this);
   8.348 -
   8.349 -        assert(!node->type()->isArray());
   8.350 -        __ bounds();
   8.351 -        __ dup2();
   8.352 -        __ getarray(node->type()->primitive());
   8.353 -
   8.354 -        if (node->postfix()) {
   8.355 -            // The stack looks like this now:
   8.356 -            // ARRAY INDEX VALUE
   8.357 -            //
   8.358 -            // So we must use a PICK operation to rotate the stack into position.
   8.359 -            __ roll3();         // INDEX VALUE ARRAY
   8.360 -            __ roll3();         // VALUE ARRAY INDEX
   8.361 -            __ pick3();         // VALUE ARRAY INDEX VALUE
   8.362 -        }
   8.363 -    }
   8.364 -
   8.365 -    // Perform step (6).
   8.366 -    if (node->type()->isFloat()) {
   8.367 -        __ float_(1.0);
   8.368 -    } else {
   8.369 -        assert(node->type()->isInt32());
   8.370 -        __ int_(1);
   8.371 -    }
   8.372 -
   8.373 -    __ note_position(node->pos());
   8.374 -    if (node->token() == TOK_INCREMENT)
   8.375 -        __ binary(OP_ADD);
   8.376 -    else
   8.377 -        __ binary(OP_SUB);
   8.378 -
   8.379 -    // Perform step (7).
   8.380 -    if (expr->isNameProxy()) {
   8.381 -        NameProxy *proxy = expr->toNameProxy();
   8.382 -        Variable *var = proxy->binding()->toVariable();
   8.383 -
   8.384 -        if (var->type()->isReference())
   8.385 -            __ setref(node->type()->primitive());
   8.386 -        else
   8.387 -            __ set(var);
   8.388 -    } else {
   8.389 -        __ setarray(node->type()->primitive());
   8.390 -    }
   8.391 -
   8.392 -    // Perform step (8).
   8.393 -    if (node->postfix())
   8.394 -        __ pop();
   8.395 -}
   8.396 -
   8.397 -void
   8.398 -BytecodeCompiler::visitForALU(Type *needed, Expression *node)
   8.399 -{
   8.400 -    node->accept(this);
   8.401 -    if (needed->isFloat() && !node->type()->isFloat())
   8.402 -        __ cvt_i2f();
   8.403 -    else
   8.404 -        assert(needed->primitive() == node->type()->primitive());
   8.405 -}
   8.406 -
   8.407 -static inline Type *
   8.408 -GetCoercionType(TokenKind tok, Type *left, Type *right)
   8.409 -{
   8.410 -    if (left->isFloat())
   8.411 -        return left;
   8.412 -    return right;
   8.413 -}
   8.414 -
   8.415 -void
   8.416 -BytecodeCompiler::visit(UnaryExpression *node)
   8.417 -{
   8.418 -    switch (node->token()) {
   8.419 -      case TOK_MINUS:
   8.420 -      {
   8.421 -        Local<Type> type(zone_, node->expression()->type());
   8.422 -        node->expression()->accept(this);
   8.423 -        
   8.424 -        if (node->type()->isFloat())
   8.425 -            __ neg_f();
   8.426 -        else
   8.427 -            __ neg();
   8.428 -        break;
   8.429 -      }
   8.430 -
   8.431 -      case TOK_NOT:
   8.432 -      {
   8.433 -        Local<Type> type(zone_, node->expression()->type());
   8.434 -        node->expression()->accept(this);
   8.435 -        
   8.436 -        if (node->type()->isFloat())
   8.437 -            __ not_f();
   8.438 -        else
   8.439 -            __ not_();
   8.440 -        break;
   8.441 -      }
   8.442 -
   8.443 -      default:
   8.444 -        assert(node->token() == TOK_TILDE);
   8.445 -        node->expression()->accept(this);
   8.446 -        __ bitnot();
   8.447 -        break;
   8.448 -    }
   8.449 -}
   8.450 -
   8.451 -void
   8.452 -BytecodeCompiler::visit(BinaryExpression *node)
   8.453 -{
   8.454 -    if (node->token() == TOK_AND || node->token() == TOK_OR) {
   8.455 -        Label success, failure, done;
   8.456 -        visitForTest(node, &success, &failure, &success);
   8.457 -        __ bind(&success);
   8.458 -        __ int_(1);
   8.459 -        __ drop(1);         // Otherwise, the stack depth will be +1 too much.
   8.460 -        __ jump(&done);
   8.461 -        __ bind(&failure);
   8.462 -        __ int_(0);
   8.463 -        __ bind(&done);
   8.464 -        return;
   8.465 -    }
   8.466 -
   8.467 -    Local<Type> leftType(zone_, node->left()->type());
   8.468 -    Local<Type> rightType(zone_, node->right()->type());
   8.469 -    Local<Type> coerce(zone_, GetCoercionType(node->token(), leftType, rightType));
   8.470 -
   8.471 -    visitForALU(coerce, node->left());
   8.472 -    visitForALU(coerce, node->right());
   8.473 -
   8.474 -    Opcode op = TokenToOpcode(node->token());
   8.475 -    if (node->type()->isFloat())
   8.476 -        op = (Opcode)(int(op) + (OP_ADD_F - OP_ADD));
   8.477 -
   8.478 -    __ note_position(node->pos());
   8.479 -    __ binary(op);
   8.480 -}
   8.481 -
   8.482 -void
   8.483 -BytecodeCompiler::visit(IndexExpression *node)
   8.484 -{
   8.485 -    node->left()->accept(this);
   8.486 -    node->right()->accept(this);
   8.487 -    __ note_position(node->pos());
   8.488 -    __ bounds();
   8.489 -
   8.490 -    if (node->type()->isArray())
   8.491 -        __ getarray_o();
   8.492 -    else
   8.493 -        __ getarray(node->type()->primitive());
   8.494 -}
   8.495 -
   8.496 -void
   8.497 -BytecodeCompiler::visit(ReturnStatement *node)
   8.498 -{
   8.499 -    if (node->expression()) {
   8.500 -        node->expression()->accept(this);
   8.501 -        __ return_();
   8.502 -    } else {
   8.503 -        __ returnvoid();
   8.504 -    }
   8.505 -}
   8.506 -
   8.507 -void
   8.508 -BytecodeCompiler::visitForTest(Expression *expression,
   8.509 -                               Label *trueBranch,
   8.510 -                               Label *falseBranch,
   8.511 -                               Label *fallthrough)
   8.512 -{
   8.513 -    TokenKind token = ToCompare(expression);
   8.514 -    if (token == TOK_EOF || token == TOK_NOT) {
   8.515 -        if (token == TOK_EOF)
   8.516 -            expression->accept(this);
   8.517 -        else
   8.518 -            expression->toUnaryExpression()->expression()->accept(this);
   8.519 -        
   8.520 -        bool jumpOnTrue = (fallthrough == falseBranch) ^ (token == TOK_NOT);
   8.521 -
   8.522 -        Opcode op = jumpOnTrue ? OP_JT : OP_JF;
   8.523 -        if (expression->type()->isFloat())
   8.524 -            op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
   8.525 -
   8.526 -        if (fallthrough == falseBranch)
   8.527 -            __ j(op, trueBranch);
   8.528 -        else
   8.529 -            __ j(op, falseBranch); 
   8.530 -        return;
   8.531 -    }
   8.532 -
   8.533 -    BinaryExpression *binary = expression->toBinaryExpression();
   8.534 -
   8.535 -    if (token == TOK_AND || token == TOK_OR) {
   8.536 -        Label next;
   8.537 -        if (token == TOK_AND)
   8.538 -            visitForTest(binary->left(), &next, falseBranch, &next);
   8.539 -        else
   8.540 -            visitForTest(binary->left(), trueBranch, &next, &next);
   8.541 -        __ bind(&next);
   8.542 -        visitForTest(binary->right(), trueBranch, falseBranch, fallthrough);
   8.543 -        return;
   8.544 -    }
   8.545 -
   8.546 -    Opcode op = CompareTokenToJump(token);
   8.547 -    if (fallthrough == trueBranch)
   8.548 -        op = Invert(op);
   8.549 -
   8.550 -    Local<Type> leftType(zone_, binary->left()->type());
   8.551 -    Local<Type> rightType(zone_, binary->right()->type());
   8.552 -    Local<Type> coerce(zone_, GetCoercionType(binary->token(), leftType, rightType));
   8.553 -
   8.554 -    visitForALU(coerce, binary->left());
   8.555 -    visitForALU(coerce, binary->right());
   8.556 -    if (coerce->isFloat())
   8.557 -        op = (Opcode)(int(op) + (OP_JL_F - OP_JL));
   8.558 -
   8.559 -    if (fallthrough == trueBranch)
   8.560 -        __ j(op, falseBranch);
   8.561 -    else
   8.562 -        __ j(op, trueBranch);
   8.563 -}
   8.564 -
   8.565 -void
   8.566 -BytecodeCompiler::visit(ForStatement *node)
   8.567 -{
   8.568 -    AutoEnterScope forScope(this, node->scope());
   8.569 -
   8.570 -    recordLifoSlot(node->scope());
   8.571 -
   8.572 -    Label join, update;
   8.573 -    LoopScope loop(scope_, &join, &update, &loop_);
   8.574 -
   8.575 -    if (node->initialization())
   8.576 -        node->initialization()->accept(this);
   8.577 -
   8.578 -    Label header, test;
   8.579 -    if (node->condition())
   8.580 -        __ jump(&test);
   8.581 -
   8.582 -    __ bind(&header);
   8.583 -    node->body()->accept(this);
   8.584 -
   8.585 -    __ bind(&update);
   8.586 -    if (node->update())
   8.587 -        node->update()->accept(this);
   8.588 -
   8.589 -    if (node->condition()) {
   8.590 -        __ bind(&test);
   8.591 -        visitForTest(node->condition(), &header, &join, &join);
   8.592 -    } else {
   8.593 -        __ jump(&header);
   8.594 -    }
   8.595 -
   8.596 -    __ bind(&join);
   8.597 -
   8.598 -    if (node->scope())
   8.599 -        unwindTo(node->scope()->enclosing());
   8.600 -    assert(__ stackDepth() == 0);
   8.601 -}
   8.602 -
   8.603 -void
   8.604 -BytecodeCompiler::visit(WhileStatement *node)
   8.605 -{
   8.606 -    Label header, join;
   8.607 -
   8.608 -    __ bind(&header);
   8.609 -
   8.610 -    LoopScope loop(scope_, &join, &header, &loop_);
   8.611 -
   8.612 -    if (node->token() == TOK_WHILE) {
   8.613 -        Label body;
   8.614 -
   8.615 -        visitForTest(node->condition(), &body, &join, &body);
   8.616 -        __ bind(&body);
   8.617 -        node->body()->accept(this);
   8.618 -        __ jump(&header);
   8.619 -    } else {
   8.620 -        node->body()->accept(this);
   8.621 -        visitForTest(node->condition(), &header, &join, &join);
   8.622 -    }
   8.623 -
   8.624 -    __ bind(&join);
   8.625 -}
   8.626 -
   8.627 -void
   8.628 -BytecodeCompiler::visit(BreakStatement *node)
   8.629 -{
   8.630 -    unwindTo(loop_->scope());
   8.631 -    __ jump(loop_->break_());
   8.632 -}
   8.633 -
   8.634 -void
   8.635 -BytecodeCompiler::visit(ContinueStatement *node)
   8.636 -{
   8.637 -    unwindTo(loop_->scope());
   8.638 -    __ jump(loop_->continue_());
   8.639 -}
   8.640 -
   8.641 -void
   8.642 -BytecodeCompiler::visit(BlockStatement *node)
   8.643 -{
   8.644 -    AutoEnterScope blockScope(this, node->scope());
   8.645 -
   8.646 -    recordLifoSlot(node->scope());
   8.647 -
   8.648 -    for (size_t i = 0; i < node->statements()->length(); i++) {
   8.649 -        Statement *statement = node->statements()->at(i);
   8.650 -        statement->accept(this);
   8.651 -        assert(__ stackDepth() == 0);
   8.652 -    }
   8.653 -
   8.654 -    // We don't bother emitting an "unwind" instruction for function scopes,
   8.655 -    // since this is taken care of by the calling convention.
   8.656 -    if (node->scope() && node->scope()->enclosing()->kind() != Scope::FUNCTION)
   8.657 -        unwindTo(node->scope()->enclosing());
   8.658 -}
   8.659 -
   8.660 -void
   8.661 -BytecodeCompiler::visit(IntegerLiteral *node)
   8.662 -{
   8.663 -    __ int_(node->value());
   8.664 -}
   8.665 -
   8.666 -void
   8.667 -BytecodeCompiler::visit(FloatLiteral *node)
   8.668 -{
   8.669 -    __ float_((float)node->value());
   8.670 -}
   8.671 -
   8.672 -static inline ArrayMap *
   8.673 -BuildArrayMap(Zone *zone, Handle<Type> type)
   8.674 -{
   8.675 -    Local<ArrayMap> contained(zone);
   8.676 -    if (type->levels() > 1) {
   8.677 -        Local<Type> containedType(zone, type->contained());
   8.678 -        contained = BuildArrayMap(zone, containedType);
   8.679 -        if (!contained)
   8.680 -            return NULL;
   8.681 -    }
   8.682 -
   8.683 -    return ArrayMap::New(zone, type, contained);
   8.684 -}
   8.685 -
   8.686 -void
   8.687 -BytecodeCompiler::visit(StringLiteral *node)
   8.688 -{
   8.689 -    Local<Type> type(zone_, node->type());
   8.690 -    Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
   8.691 -    if (!map)
   8.692 -        return;
   8.693 -
   8.694 -    Local<Array> array(zone_, Array::New(zone_, map, node->string()->length(), Heap::Tenure_Old));
   8.695 -    if (!array)
   8.696 -        return;
   8.697 -
   8.698 -    assert(array->nelements() >= node->string()->length());
   8.699 -    memcpy(array->chars(), node->string()->raw(), node->string()->length() * sizeof(char));
   8.700 -
   8.701 -    __ note_position(node->pos());
   8.702 -    __ object(array);
   8.703 -}
   8.704 -
   8.705 -void
   8.706 -BytecodeCompiler::getEnvSlot(Variable *var)
   8.707 -{
   8.708 -    assert(var->scope()->kind() == Scope::GLOBAL);
   8.709 -    __ getglobal(var);
   8.710 -}
   8.711 -
   8.712 -void
   8.713 -BytecodeCompiler::setEnvSlot(Variable *var)
   8.714 -{
   8.715 -    assert(var->scope()->kind() == Scope::GLOBAL);
   8.716 -    __ setglobal(var);
   8.717 -}
   8.718 -
   8.719 -void
   8.720 -BytecodeCompiler::visit(VariableDeclaration *node)
   8.721 -{
   8.722 -    Variable *var = node->variable();
   8.723 -    
   8.724 -    Local<Type> type(zone_, var->type());
   8.725 -    if (type->isArray()) {
   8.726 -        Local<ArrayMap> map(zone_, BuildArrayMap(zone_, type));
   8.727 -        __ note_position(node->pos());
   8.728 -        if (var->scope()->kind() == Scope::GLOBAL)
   8.729 -            __ newarray(map, Heap::Tenure_Old);
   8.730 -        else if (var->needsHeapAllocation())
   8.731 -            __ newarray(map, Heap::Tenure_Default);
   8.732 -        else
   8.733 -            __ newarray(map, Heap::Tenure_Stack);
   8.734 -
   8.735 -        if (node->initialization()) {
   8.736 -            node->initialization()->accept(this);
   8.737 -            __ note_position(node->pos());
   8.738 -            __ arraycopy();
   8.739 -        }
   8.740 -    } else {
   8.741 -        if (node->initialization()) {
   8.742 -            node->initialization()->accept(this);
   8.743 -        } else {
   8.744 -            if (!node->postDimensions())
   8.745 -                __ int_(0);
   8.746 -        }
   8.747 -    }
   8.748 -
   8.749 -    if (var->location() == Variable::STACK) {
   8.750 -        __ setlocal(var);
   8.751 -        locals_->set(zone_, var->slot(), var->type());
   8.752 -    } else {
   8.753 -        assert(var->location() == Variable::ENVIRONMENT);
   8.754 -        setEnvSlot(var);
   8.755 -    }
   8.756 -
   8.757 -    __ pop();
   8.758 -}
   8.759 -
   8.760 -void
   8.761 -BytecodeCompiler::visit(CallExpression *node)
   8.762 -{
   8.763 -    Local<Type> funType(zone_, node->callee()->type());
   8.764 -
   8.765 -    // Sniff out natives, which have a specific opcode and are guaranteed to
   8.766 -    // be called via name proxy.
   8.767 -    NamedFunction *native = NULL;
   8.768 -    if (funType->isNative()) {
   8.769 -        native = node->callee()->toNameProxy()->binding()->toNamedFunction();
   8.770 -    }
   8.771 -
   8.772 -    for (size_t i = node->arguments()->length() - 1; i < node->arguments()->length(); i--) {
   8.773 -        Expression *arg = node->arguments()->at(i);
   8.774 -
   8.775 -        // We need to compute a reference if the parameter was in the form:
   8.776 -        //  f(&a)
   8.777 -        // Note this form does not allow: f({})
   8.778 -        // 
   8.779 -        // We also need to compute references for all variadic native
   8.780 -        // arguments, but arrays and references are already in the
   8.781 -        // appropriate form.
   8.782 -        Local<Type> given(zone_, arg->type());
   8.783 -        bool mustPushReference = false;
   8.784 -        if (i >= funType->parameters()->length()) {
   8.785 -            assert(funType->isNative() && funType->isNativeVariadic());
   8.786 -            mustPushReference = !given->isArray() && !given->isReference();
   8.787 -        } else if (funType->parameterAt(i)->isReference()) {
   8.788 -            mustPushReference = !given->isReference();
   8.789 -        }
   8.790 -
   8.791 -        // If a native is passed to a native, it must only be one level deep.
   8.792 -        assert(!funType->isNative() || !given->isArray() || given->levels() == 1);
   8.793 -
   8.794 -        if (mustPushReference) {
   8.795 -            if (arg->isNameProxy()) {
   8.796 -                // :TODO: test with functions and globals
   8.797 -                // Compute a reference to the name.
   8.798 -                Variable *var = arg->toNameProxy()->binding()->toVariable();
   8.799 -                __ note_position(node->pos());
   8.800 -                __ newref(var);
   8.801 -            } else if (arg->isIndexExpression()) {
   8.802 -                IndexExpression *expr = arg->toIndexExpression();
   8.803 -                expr->left()->accept(this);
   8.804 -                expr->right()->accept(this);
   8.805 -                __ note_position(expr->pos());
   8.806 -                __ bounds();
   8.807 -                __ arrayref_lifo();
   8.808 -            } else {
   8.809 -                // We don't know how to, or can't, build a direct reference to
   8.810 -                // this type. Make an indirect one, by taking the top of the
   8.811 -                // stack and boxing it up.
   8.812 -                arg->accept(this);
   8.813 -                __ note_position(node->pos());
   8.814 -                __ slotref_lifo();
   8.815 -            }
   8.816 -        } else {
   8.817 -            arg->accept(this);
   8.818 -        }
   8.819 -    }
   8.820 -
   8.821 -    __ note_position(node->pos());
   8.822 -    if (native) {
   8.823 -        __ callnative(native->slot(), node->arguments()->length());
   8.824 -        __ drop(node->arguments()->length());
   8.825 -    } else {
   8.826 -        node->callee()->accept(this);
   8.827 -        __ call(funType);
   8.828 -        __ drop(node->arguments()->length() + 1);
   8.829 -    }
   8.830 -}
   8.831 -
   8.832 -void
   8.833 -BytecodeCompiler::visit(TernaryExpression *node)
   8.834 -{
   8.835 -    Label success, failure, join;
   8.836 -
   8.837 -    visitForTest(node->condition(), &success, &failure, &success);
   8.838 -    __ bind(&success);
   8.839 -    node->left()->accept(this);
   8.840 -    __ drop(1);
   8.841 -    __ jump(&join);
   8.842 -    __ bind(&failure);
   8.843 -    node->right()->accept(this);
   8.844 -    __ bind(&join);
   8.845 -}
   8.846 -
   8.847 -void
   8.848 -BytecodeCompiler::visit(IfStatement *node)
   8.849 -{
   8.850 -    Label join;
   8.851 -    if (!node->ifFalse()) {
   8.852 -        Label success;
   8.853 -
   8.854 -        visitForTest(node->condition(), &success, &join, &success);
   8.855 -        __ bind(&success);
   8.856 -        node->ifTrue()->accept(this);
   8.857 -    } else {
   8.858 -        Label success, next;
   8.859 -
   8.860 -        visitForTest(node->condition(), &success, &next, &success);
   8.861 -        __ bind(&success);
   8.862 -        node->ifTrue()->accept(this);
   8.863 -        __ jump(&join);
   8.864 -        __ bind(&next);
   8.865 -        node->ifFalse()->accept(this);
   8.866 -    }
   8.867 -
   8.868 -    __ bind(&join);
   8.869 -}
   8.870 -
   8.871 -void
   8.872 -BytecodeCompiler::visit(FunctionStatement *node)
   8.873 -{
   8.874 -    if (node->fun()->isNative()) {
   8.875 -        assert(!moduleData_->natives->at(node->fun()->slot()));
   8.876 -
   8.877 -        Local<Type> type(zone_, node->fun()->type());
   8.878 -        Local<String> name(zone_, node->fun()->name());
   8.879 -        Local<Native> native(zone_, Native::New(zone_, type, name));
   8.880 -        if (!native)
   8.881 -            return;
   8.882 -
   8.883 -        moduleData_->natives->set(zone_, node->fun()->slot(), native);
   8.884 -        return;
   8.885 -    }
   8.886 -
   8.887 -    // If the function has no body, then it's just a declaration.
   8.888 -    if (!node->body()) {
   8.889 -        assert(node->fun()->isForward() || node->fun()->isPublic());
   8.890 -        return;
   8.891 -    }
   8.892 -
   8.893 -    BytecodeCompiler child(zone_, tree_, moduleData_);
   8.894 -    Local<Function> fun(zone_, child.compileFunction(moduleData_, node));
   8.895 -    if (!fun)
   8.896 -        return;
   8.897 -    
   8.898 -    assert(!moduleData_->module->getFunction(node->fun()->slot()));
   8.899 -    moduleData_->module->setFunction(zone_, node->fun()->slot(), fun);
   8.900 -}
   8.901 -
   8.902 -void
   8.903 -BytecodeCompiler::visit(EnumStatement *node)
   8.904 -{
   8.905 -    // :TODO: eventually, we'll export these.
   8.906 -}
   8.907 -
   8.908 -Code *
   8.909 -BytecodeCompiler::compileCode(Scope *scope, unsigned lineno)
   8.910 -{
   8.911 -    // STOP doubles as RETURNVOID.
   8.912 -    __ stop();
   8.913 -
   8.914 -    if (__ oom() || zone_->hasPendingException())
   8.915 -        return NULL;
   8.916 -
   8.917 -    Local<ByteArray> bytes(zone_, ByteArray::New(zone_, __ length() * sizeof(bytecode), Heap::Tenure_Old));
   8.918 -    if (!bytes)
   8.919 -        return NULL;
   8.920 -    memcpy(bytes->raw(), __ buffer(), __ length());
   8.921 -
   8.922 -    for (size_t i = 0; i < scope->maxContainedLocals(); i++)
   8.923 -        assert(locals_->at(i));
   8.924 -
   8.925 -    Local<FixedArray> objects(zone_, FixedArray::New(zone_, __ objects()->length(), Heap::Tenure_Old));
   8.926 -    if (!objects)
   8.927 -        return NULL;
   8.928 -
   8.929 -    for (size_t i = 0; i < __ objects()->length(); i++)
   8.930 -        objects->set(zone_, i, *(__ objects()->at(i)));
   8.931 -
   8.932 -    Local<ByteArray> safepoints(zone_);
   8.933 -
   8.934 -    // If any stack slots hold gc pointers at potential failure points in the
   8.935 -    // bytecode, record them now. We do this by building a list of tuples;
   8.936 -    // each tuple contains the pc offset, and a bitset containing which stack
   8.937 -    // slots must be scanned by the gc.
   8.938 -    if (__ oopRecords()->length()) {
   8.939 -        size_t bytesPerSafepoint = Code::BytesPerSafepoint(__ maxStackDepth());
   8.940 -        size_t gcmapSize = bytesPerSafepoint * __ oopRecords()->length();
   8.941 -        safepoints = ByteArray::New(zone_, gcmapSize, Heap::Tenure_Old);
   8.942 -        if (!safepoints)
   8.943 -            return NULL;
   8.944 -
   8.945 -        Address cursor = safepoints->raw();
   8.946 -        for (size_t i = 0; i < __ oopRecords()->length(); i++) {
   8.947 -            OopRecord *record = __ oopRecords()->at(i);
   8.948 -            assert(record->depth <= __ maxStackDepth());
   8.949 -
   8.950 -            *reinterpret_cast<unsigned *>(cursor) = record->offset;
   8.951 -
   8.952 -            unsigned char *bits = reinterpret_cast<unsigned char *>(cursor + sizeof(unsigned));
   8.953 -            for (unsigned i = 0; i < record->depth; i++)
   8.954 -                bits[i / 8] |= (1 << (i % 8));
   8.955 -
   8.956 -            cursor += bytesPerSafepoint;
   8.957 -        }
   8.958 -
   8.959 -        assert(cursor == safepoints->raw() + gcmapSize);
   8.960 -    }
   8.961 -
   8.962 -    Local<ByteArray> sourcemap(zone_);
   8.963 -    if (__ sourcemapLength()) {
   8.964 -        sourcemap = ByteArray::New(zone_, __ sourcemapLength(), Heap::Tenure_Old);
   8.965 -        if (!sourcemap)
   8.966 -            return NULL;
   8.967 -
   8.968 -        memcpy(sourcemap->raw(), __ sourcemap(), __ sourcemapLength());
   8.969 -    }
   8.970 -
   8.971 -    Local<Code> code(zone_);
   8.972 -
   8.973 -    code = Code::New(zone_,
   8.974 -                     bytes,
   8.975 -                     locals_,
   8.976 -                     objects,
   8.977 -                     __ maxStackDepth(),
   8.978 -                     moduleData_->module,
   8.979 -                     safepoints,
   8.980 -                     sourcemap,
   8.981 -                     lineno);
   8.982 -    return code;
   8.983 -}
   8.984 -
   8.985 -Function *
   8.986 -BytecodeCompiler::compileFunction(ModuleData *module, FunctionStatement *node)
   8.987 -{
   8.988 -    // Note: No need to record a life slot here, since it's part of the Frame.
   8.989 -    AutoEnterScope functionScope(this, node->scope());
   8.990 -
   8.991 -    // Set the initial line, because line mappings are deltas.
   8.992 -    __ setFirstLine(node->pos().line);
   8.993 -    locals_ = FixedArray::New(zone_, node->scope()->maxContainedLocals(), Heap::Tenure_Old);
   8.994 -
   8.995 -    node->body()->accept(this);
   8.996 -
   8.997 -    unsigned nargs = node->scope()->numArguments();
   8.998 -    Local<FixedArray> args(zone_, FixedArray::New(zone_, nargs, Heap::Tenure_Old));
   8.999 -    if (!args)
  8.1000 -        return NULL;
  8.1001 -
  8.1002 -    for (size_t i = 0; i < node->scope()->numArguments(); i++)
  8.1003 -        args->set(zone_, i, node->scope()->getArgument(i)->type());
  8.1004 -
  8.1005 -
  8.1006 -    Local<Code> code(zone_, compileCode(node->scope(), node->pos().line));
  8.1007 -    if (!code)
  8.1008 -        return NULL;
  8.1009 -
  8.1010 -    Local<Type> type(zone_, node->fun()->type());
  8.1011 -    Local<String> name(zone_, node->fun()->name());
  8.1012 -    Local<Function> fun(zone_, Function::New(zone_, code, type, name, node->pos()));
  8.1013 -    if (!fun)
  8.1014 -        return NULL;
  8.1015 -
  8.1016 -    // If this function had a forward, export it as a named public.
  8.1017 -    if (node->fun()->isPublic()) {
  8.1018 -        assert(node->fun()->isPublic());
  8.1019 -        ScopedRoot<Function> root(fun);
  8.1020 -        if (!root)
  8.1021 -            return NULL;
  8.1022 -        if (!moduleData_->publics.append(root))
  8.1023 -            return NULL;
  8.1024 -    }
  8.1025 -
  8.1026 -    Disassemble(code, stdout);
  8.1027 -    
  8.1028 -    return fun;
  8.1029 -}
  8.1030 -
  8.1031 -Module *
  8.1032 -BytecodeCompiler::compile()
  8.1033 -{
  8.1034 -    AutoEnterScope scope(this, tree_->scope());
  8.1035 -
  8.1036 -    ModuleData moduleData;
  8.1037 -
  8.1038 -    moduleData_ = &moduleData;
  8.1039 -    moduleData_->module = Module::New(zone_, tree_->scope()->numFunctions());
  8.1040 -
  8.1041 -    if (!moduleData_)
  8.1042 -        return NULL;
  8.1043 -    
  8.1044 -    moduleData_->natives = FixedArray::New(zone_, tree_->scope()->numNatives(), Heap::Tenure_Old);
  8.1045 -    if (!moduleData_->natives)
  8.1046 -        return NULL;
  8.1047 -
  8.1048 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  8.1049 -        Statement *statement = tree_->statements()->at(i);
  8.1050 -        statement->accept(this);
  8.1051 -    }
  8.1052 -
  8.1053 -    if (zone_->hasPendingException())
  8.1054 -        return NULL;
  8.1055 -
  8.1056 -#ifndef NDEBUG
  8.1057 -    for (size_t i = 0; i < tree_->scope()->numFunctions(); i++)
  8.1058 -        assert(moduleData_->module->getFunction(i));
  8.1059 -    for (size_t i = 0; i < tree_->scope()->numNatives(); i++)
  8.1060 -        assert(moduleData_->natives->at(i));
  8.1061 -#endif
  8.1062 -
  8.1063 -    if (moduleData_->publics.length()) {
  8.1064 -        Local<Function> fun(zone_);
  8.1065 -        Local<FixedArray> list(zone_, FixedArray::New(zone_, moduleData_->publics.length(),
  8.1066 -                               Heap::Tenure_Old));
  8.1067 -        if (!list)
  8.1068 -            return NULL;
  8.1069 -
  8.1070 -        for (size_t i = 0; i < moduleData_->publics.length(); i++)
  8.1071 -            list->set(zone_, i, moduleData_->publics[i]);
  8.1072 -
  8.1073 -        moduleData_->module->setPublics(list);
  8.1074 -    }
  8.1075 -
  8.1076 -    moduleData_->module->setNatives(moduleData_->natives);
  8.1077 -
  8.1078 -    if (scope_->numEnvironmentVars()) {
  8.1079 -        Local<EnvironmentMap> globalMap(zone_, scope_->createEnvironmentMap(zone_));
  8.1080 -        if (!globalMap)
  8.1081 -            return NULL;
  8.1082 -
  8.1083 -        Local<Environment> environment(zone_, Environment::New(zone_, globalMap));
  8.1084 -        if (!environment)
  8.1085 -            return NULL;
  8.1086 -
  8.1087 -        moduleData_->module->setEnvironment(environment);
  8.1088 -    }
  8.1089 -
  8.1090 -    Local<Code> code(zone_, compileCode(tree_->scope(), 1));
  8.1091 -    if (!code)
  8.1092 -        return NULL;
  8.1093 -
  8.1094 -    Disassemble(code, stdout);
  8.1095 -
  8.1096 -    moduleData_->module->setCode(code);
  8.1097 -
  8.1098 -    return moduleData_->module;
  8.1099 -}
     9.1 --- a/jitcraft/BytecodeCompiler.h	Tue Jul 24 23:53:34 2012 -0700
     9.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     9.3 @@ -1,149 +0,0 @@
     9.4 -/* vim: set ts=4 sw=4 tw=99 et:
     9.5 - *
     9.6 - * Copyright (C) 2012 David Anderson
     9.7 - *
     9.8 - * This file is part of JITCraft.
     9.9 - *
    9.10 - * JITCraft is free software: you can redistribute it and/or modify it under
    9.11 - * the terms of the GNU General Public License as published by the Free
    9.12 - * Software Foundation, either version 3 of the License, or (at your option)
    9.13 - * any later version.
    9.14 - * 
    9.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    9.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    9.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    9.18 - *
    9.19 - * You should have received a copy of the GNU General Public License along with
    9.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    9.21 - */
    9.22 -#ifndef _include_bytecode_compiler_h_
    9.23 -#define _include_bytecode_compiler_h_
    9.24 -
    9.25 -#include "AST.h"
    9.26 -#include "BytecodeEmitter.h"
    9.27 -#include "Functions.h"
    9.28 -
    9.29 -namespace ke {
    9.30 -
    9.31 -class Module;
    9.32 -
    9.33 -struct ModuleData
    9.34 -{
    9.35 -    ScopedRoot<Module> module;
    9.36 -    PoolList<ScopedRoot<Function> > publics;
    9.37 -    ScopedRoot<FixedArray> natives;
    9.38 -};
    9.39 -
    9.40 -class BytecodeCompiler : public AstVisitor
    9.41 -{
    9.42 -    Zone *zone_;
    9.43 -    ParseTree *tree_;
    9.44 -    BytecodeEmitter emitter_;
    9.45 -    ScopedRoot<FixedArray> locals_;
    9.46 -    Scope *scope_;
    9.47 -    ModuleData *moduleData_;
    9.48 -
    9.49 -    class LoopScope
    9.50 -    {
    9.51 -        Scope *scope_;
    9.52 -        BytecodeEmitter::Label *bk_;
    9.53 -        BytecodeEmitter::Label *ct_;
    9.54 -        LoopScope **prevp_;
    9.55 -        LoopScope *prev_;
    9.56 -
    9.57 -      public:
    9.58 -        LoopScope(Scope *scope, BytecodeEmitter::Label *bk, BytecodeEmitter::Label *ct,
    9.59 -                  LoopScope **prevp)
    9.60 -          : scope_(scope),
    9.61 -            bk_(bk),
    9.62 -            ct_(ct),
    9.63 -            prevp_(prevp),
    9.64 -            prev_(*prevp)
    9.65 -        {
    9.66 -            *prevp_ = this;
    9.67 -        }
    9.68 -
    9.69 -        ~LoopScope()
    9.70 -        {
    9.71 -            *prevp_ = prev_;
    9.72 -        }
    9.73 -
    9.74 -        BytecodeEmitter::Label *break_() {
    9.75 -            return bk_;
    9.76 -        }
    9.77 -        BytecodeEmitter::Label *continue_() {
    9.78 -            return ct_;
    9.79 -        }
    9.80 -        Scope *scope() {
    9.81 -            return scope_;
    9.82 -        }
    9.83 -    };
    9.84 -
    9.85 -    LoopScope *loop_;
    9.86 -
    9.87 -  public:
    9.88 -    class AutoEnterScope
    9.89 -    {
    9.90 -        BytecodeCompiler *bc_;
    9.91 -        Scope *saved_;
    9.92 -
    9.93 -      public:
    9.94 -        AutoEnterScope(BytecodeCompiler *bc, Scope *scope)
    9.95 -          : bc_(bc),
    9.96 -            saved_(bc->scope_)
    9.97 -        {
    9.98 -            if (scope)
    9.99 -                bc->scope_ = scope;
   9.100 -        }
   9.101 -        ~AutoEnterScope() {
   9.102 -            bc_->scope_ = saved_;
   9.103 -        }
   9.104 -    };
   9.105 -
   9.106 -  private:
   9.107 -    void recordLifoSlot(Scope *scope);
   9.108 -    void unwindTo(Scope *scope);
   9.109 -    void visitForTest(Expression *expression,
   9.110 -                      BytecodeEmitter::Label *trueBranch,
   9.111 -                      BytecodeEmitter::Label *falseBranch,
   9.112 -                      BytecodeEmitter::Label *fallthrough);
   9.113 -    Code *compileCode(Scope *scope, unsigned lineno);
   9.114 -    Function *compileFunction(ModuleData *module, FunctionStatement *fun);
   9.115 -    void visitForALU(Type *needed, Expression *node);
   9.116 -
   9.117 -    void getEnvSlot(Variable *var);
   9.118 -    void setEnvSlot(Variable *var);
   9.119 -
   9.120 -  public:
   9.121 -    BytecodeCompiler(Zone *zone, ParseTree *tree, ModuleData *module);
   9.122 -
   9.123 -    Module *compile();
   9.124 -
   9.125 -  public:
   9.126 -    void visit(NameProxy *name);
   9.127 -    void visit(Assignment *node);
   9.128 -    void visit(BinaryExpression *node);
   9.129 -    void visit(ReturnStatement *node);
   9.130 -    void visit(ForStatement *node);
   9.131 -    void visit(BlockStatement *node);
   9.132 -    void visit(VariableDeclaration *node);
   9.133 -    void visit(IntegerLiteral *node);
   9.134 -    void visit(FloatLiteral *node);
   9.135 -    void visit(StringLiteral *node);
   9.136 -    void visit(ExpressionStatement *node);
   9.137 -    void visit(FunctionStatement *node);
   9.138 -    void visit(CallExpression *node);
   9.139 -    void visit(IfStatement *node);
   9.140 -    void visit(IndexExpression *node);
   9.141 -    void visit(EnumStatement *node);
   9.142 -    void visit(WhileStatement *node);
   9.143 -    void visit(BreakStatement *node);
   9.144 -    void visit(ContinueStatement *node);
   9.145 -    void visit(IncDecExpression *node);
   9.146 -    void visit(UnaryExpression *node);
   9.147 -    void visit(TernaryExpression *node);
   9.148 -};
   9.149 -
   9.150 -}
   9.151 -
   9.152 -#endif // _include_bytecode_generator_h_
    10.1 --- a/jitcraft/BytecodeEmitter.cpp	Tue Jul 24 23:53:34 2012 -0700
    10.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.3 @@ -1,114 +0,0 @@
    10.4 -/* vim: set ts=4 sw=4 tw=99 et:
    10.5 - *
    10.6 - * Copyright (C) 2012 David Anderson
    10.7 - *
    10.8 - * This file is part of JITCraft.
    10.9 - *
   10.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   10.11 - * the terms of the GNU General Public License as published by the Free
   10.12 - * Software Foundation, either version 3 of the License, or (at your option)
   10.13 - * any later version.
   10.14 - * 
   10.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   10.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   10.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   10.18 - *
   10.19 - * You should have received a copy of the GNU General Public License along with
   10.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   10.21 - */
   10.22 -#include <stdlib.h>
   10.23 -#include "BytecodeEmitter.h"
   10.24 -#include "Utility.h"
   10.25 -#include "Types.h"
   10.26 -#include "Zone.h"
   10.27 -
   10.28 -using namespace ke;
   10.29 -
   10.30 -BytecodeEmitter::BytecodeEmitter(PoolAllocator &pool)
   10.31 -  : pool_(pool),
   10.32 -    buffer_(inline_buffer_),
   10.33 -    buffer_pos_(buffer_),
   10.34 -    buffer_end_(buffer_pos_ + ARRAY_LENGTH(inline_buffer_)),
   10.35 -    oom_(false),
   10.36 -    maxStackDepth_(0)
   10.37 -{
   10.38 -    lastCodePosition_ = 0;
   10.39 -    firstLine_ = 1;
   10.40 -}
   10.41 -
   10.42 -bool
   10.43 -BytecodeEmitter::growBuffer(size_t nbytes)
   10.44 -{
   10.45 -    if (oom_) {
   10.46 -        buffer_pos_ = buffer_;
   10.47 -        return false;
   10.48 -    }
   10.49 -
   10.50 -    size_t newSize = size_t((buffer_end_ - buffer_) * 2);
   10.51 -    if (newSize >= MAX_LENGTH) {
   10.52 -        oom_ = true;
   10.53 -        buffer_pos_ = buffer_;
   10.54 -        ZONE()->reportOutOfMemory();
   10.55 -        return false;
   10.56 -    }
   10.57 -
   10.58 -    bytecode *newBuffer;
   10.59 -    if (buffer_ == inline_buffer_)
   10.60 -        newBuffer = (bytecode *)malloc(nbytes);
   10.61 -    else
   10.62 -        newBuffer = (bytecode *)realloc(buffer_, newSize);
   10.63 -
   10.64 -    // If we can't allocate a buffer, reset the buffer to the start and set
   10.65 -    // a flag to indicate out-of-memory.
   10.66 -    if (!newBuffer) {
   10.67 -        oom_ = true;
   10.68 -        buffer_pos_ = buffer_;
   10.69 -        ZONE()->reportOutOfMemory();
   10.70 -        return false;
   10.71 -    }
   10.72 -
   10.73 -    buffer_pos_ = newBuffer + size_t(buffer_pos_ - buffer_);
   10.74 -    buffer_ = newBuffer;
   10.75 -    buffer_end_ = buffer_ + newSize;
   10.76 -    return true;
   10.77 -}
   10.78 -
   10.79 -void
   10.80 -BytecodeEmitter::recordOops()
   10.81 -{
   10.82 -    OopRecord *record = new (pool_) OopRecord(oopMap_.length(), position());
   10.83 -
   10.84 -    record->slots = (bool *)pool_.allocate(record->depth);
   10.85 -    if (!record->slots) {
   10.86 -        oom_ = true;
   10.87 -        return;
   10.88 -    }
   10.89 -
   10.90 -    bool hadOops = false;
   10.91 -    for (size_t i = 0; i < oopMap_.length(); i++) {
   10.92 -        bool bit = oopMap_[i];
   10.93 -        record->slots[i] = bit;
   10.94 -        hadOops |= bit;
   10.95 -    }
   10.96 -
   10.97 -    if (!hadOops)
   10.98 -        return;
   10.99 -
  10.100 -    oom_ &= oopRecords_.append(record);
  10.101 -}
  10.102 -
  10.103 -void
  10.104 -BytecodeEmitter::note_position(const SourcePosition &pos)
  10.105 -{
  10.106 -    assert(pos.line > 0);
  10.107 -    assert(unsigned(pos.line) >= firstLine_);
  10.108 -
  10.109 -    unsigned lineDelta = unsigned(pos.line) - firstLine_;
  10.110 -    unsigned pcDelta = unsigned(position()) - lastCodePosition_;
  10.111 -
  10.112 -    sourcemap_.writeUint32(pcDelta);
  10.113 -    sourcemap_.writeUint32(lineDelta);
  10.114 -    sourcemap_.writeUint32(pos.col);
  10.115 -
  10.116 -    lastCodePosition_ = unsigned(position());
  10.117 -}
    11.1 --- a/jitcraft/BytecodeEmitter.h	Tue Jul 24 23:53:34 2012 -0700
    11.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.3 @@ -1,626 +0,0 @@
    11.4 -/* vim: set ts=4 sw=4 tw=99 et:
    11.5 - *
    11.6 - * Copyright (C) 2012 David Anderson
    11.7 - *
    11.8 - * This file is part of JITCraft.
    11.9 - *
   11.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   11.11 - * the terms of the GNU General Public License as published by the Free
   11.12 - * Software Foundation, either version 3 of the License, or (at your option)
   11.13 - * any later version.
   11.14 - * 
   11.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   11.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   11.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   11.18 - *
   11.19 - * You should have received a copy of the GNU General Public License along with
   11.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   11.21 - */
   11.22 -#ifndef _include_bytecode_emitter_h_
   11.23 -#define _include_bytecode_emitter_h_
   11.24 -
   11.25 -#include <assert.h>
   11.26 -#include <limits.h>
   11.27 -#include "Opcodes.h"
   11.28 -#include "NameBinding.h"
   11.29 -#include "Handles.h"
   11.30 -#include "CompactBuffer.h"
   11.31 -
   11.32 -namespace ke {
   11.33 -
   11.34 -class Type;
   11.35 -class Map;
   11.36 -
   11.37 -typedef PoolList<ScopedRoot<Object>> ObjectList;
   11.38 -
   11.39 -struct OopRecord : public PoolObject
   11.40 -{
   11.41 -    unsigned depth;
   11.42 -    unsigned offset;
   11.43 -    bool *slots;
   11.44 -
   11.45 -    OopRecord(unsigned length, unsigned offset)
   11.46 -      : depth(length),
   11.47 -        offset(offset),
   11.48 -        slots(NULL)
   11.49 -    {
   11.50 -    }
   11.51 -};
   11.52 -
   11.53 -class BytecodeEmitter
   11.54 -{
   11.55 -  private:
   11.56 -    PoolAllocator &pool_;
   11.57 -
   11.58 -    bytecode *buffer_;
   11.59 -    bytecode *buffer_pos_;
   11.60 -    bytecode *buffer_end_;
   11.61 -    bytecode inline_buffer_[512];
   11.62 -    bool oom_;
   11.63 -    unsigned maxStackDepth_;
   11.64 -    ObjectList objects_;
   11.65 -    PoolList<bool> oopMap_;
   11.66 -    PoolList<OopRecord *> oopRecords_;
   11.67 -    CompactBufferWriter sourcemap_;
   11.68 -    unsigned lastCodePosition_;
   11.69 -    unsigned firstLine_;
   11.70 -
   11.71 -  private:
   11.72 -    // The maximum size of a code object must be such that the distance between
   11.73 -    // two instructions fits into a signed, 31-bit integer. This ensures that
   11.74 -    // all code-bounded buffers (like the number of object literals or
   11.75 -    // safepoints) does not need to be bounds checked. It also means we can add
   11.76 -    // any two offsets and be guaranteed that they don't overflow.
   11.77 -    static const size_t MAX_LENGTH = INT_MAX / 2;
   11.78 -
   11.79 -  private:
   11.80 -    bool growBuffer(size_t bytes);
   11.81 -
   11.82 -    // Checking the return value is not necessary, since the inline buffer is
   11.83 -    // used as a ballast.
   11.84 -    bool ensure(size_t bytes) {
   11.85 -        if (buffer_pos_ + bytes > buffer_end_)
   11.86 -            return growBuffer(bytes);
   11.87 -        return true;
   11.88 -    }
   11.89 -
   11.90 -    void writeUint8(unsigned value) {
   11.91 -        assert(value <= UCHAR_MAX);
   11.92 -        *buffer_pos_++ = value;
   11.93 -    }
   11.94 -    void writeFloat(float value) {
   11.95 -        *(float *)buffer_pos_ = value;
   11.96 -        buffer_pos_ += sizeof(float);
   11.97 -    }
   11.98 -    void writeInt32(int value) {
   11.99 -        *(int *)buffer_pos_ = value;
  11.100 -        buffer_pos_ += sizeof(int);
  11.101 -    }
  11.102 -    void writeUint32(unsigned value) {
  11.103 -        *(unsigned *)buffer_pos_ = value;
  11.104 -        buffer_pos_ += sizeof(unsigned);
  11.105 -    }
  11.106 -    void writeOp(Opcode op) {
  11.107 -        if (oom_)
  11.108 -            return;
  11.109 -
  11.110 -        writeUint8(op);
  11.111 -        for (int i = 0; i < OpcodeInfo[op].nuses; i++)
  11.112 -            oopMap_.pop();
  11.113 -        for (int i = 0; i < OpcodeInfo[op].ndefs; i++)
  11.114 -            oopMap_.append(false);
  11.115 -        if (oopMap_.length() > maxStackDepth_)
  11.116 -            maxStackDepth_ = oopMap_.length();
  11.117 -    }
  11.118 -    void writeObject(Object *obj) {
  11.119 -        writeUint32(objects_.length());
  11.120 -        ScopedRoot<Object> root(obj);
  11.121 -        if (!objects_.append(root))
  11.122 -            oom_ = true;
  11.123 -    }
  11.124 -
  11.125 -    int position() const {
  11.126 -        assert(buffer_pos_ - buffer_ < INT_MAX / 2);
  11.127 -        return int(buffer_pos_ - buffer_);
  11.128 -    }
  11.129 -
  11.130 -  public:
  11.131 -    BytecodeEmitter(PoolAllocator &pool);
  11.132 -
  11.133 -    bytecode *buffer() const {
  11.134 -        return buffer_;
  11.135 -    }
  11.136 -    unsigned length() const {
  11.137 -        return unsigned(buffer_pos_ - buffer_);
  11.138 -    }
  11.139 -    bool oom() const {
  11.140 -        return oom_ || sourcemap_.oom();
  11.141 -    }
  11.142 -    unsigned stackDepth() const {
  11.143 -        return oopMap_.length();
  11.144 -    }
  11.145 -    unsigned maxStackDepth() const {
  11.146 -        return maxStackDepth_;
  11.147 -    }
  11.148 -    const ObjectList *objects() const {
  11.149 -        return &objects_;
  11.150 -    }
  11.151 -    PoolList<OopRecord *> *oopRecords() {
  11.152 -        return &oopRecords_;
  11.153 -    }
  11.154 -
  11.155 -    void drop(unsigned amt) {
  11.156 -        assert(amt <= stackDepth());
  11.157 -        for (unsigned i = 0; i < amt; i++)
  11.158 -            oopMap_.pop();
  11.159 -    }
  11.160 -
  11.161 -    void note_position(const SourcePosition &pos);
  11.162 -    uint8 *sourcemap() const {
  11.163 -        return sourcemap_.buffer();
  11.164 -    }
  11.165 -    size_t sourcemapLength() const {
  11.166 -        return sourcemap_.length();
  11.167 -    }
  11.168 -    void setFirstLine(unsigned line) {
  11.169 -        assert(!sourcemap_.length());
  11.170 -        firstLine_ = line;
  11.171 -    }
  11.172 -
  11.173 -  public:
  11.174 -    // A label represents a local control-flow target in the bytecode. A label
  11.175 -    // may be in three states:
  11.176 -    //
  11.177 -    // (1) Empty - the label is not used yet.
  11.178 -    // (2) Pending - the label has incoming jumps, but the actual location of
  11.179 -    //               is not yet known. The list of jumps is threaded through
  11.180 -    //               the four bytes reserved for each emitted jump target. In
  11.181 -    //               this case, the offset field is the location of the most
  11.182 -    //               recently emitted incoming jump.
  11.183 -    // (3) Bound   - the label's position has been pinned.
  11.184 -    //
  11.185 -    // A jump can be emitted to a label in any state. Binding a label
  11.186 -    // immediately backpatches all pending incoming jumps. A label must be
  11.187 -    // bound if it is used.
  11.188 -    class Label
  11.189 -    {
  11.190 -        int offset_ : 31;
  11.191 -        bool bound_ : 1;
  11.192 -
  11.193 -        void setOffset(int offset) {
  11.194 -            offset_ = offset;
  11.195 -            assert(offset_ == offset);
  11.196 -        }
  11.197 -
  11.198 -      public:
  11.199 -        static const int INVALID_OFFSET = -1;
  11.200 -
  11.201 -      public:
  11.202 -        Label()
  11.203 -          : offset_(INVALID_OFFSET),
  11.204 -            bound_(false)
  11.205 -        {
  11.206 -        }
  11.207 -        ~Label()
  11.208 -        {
  11.209 -            assert(bound_ || offset_ == INVALID_OFFSET);
  11.210 -        }
  11.211 -        
  11.212 -        bool bound() const {
  11.213 -            return bound_;
  11.214 -        }
  11.215 -        int offset() const {
  11.216 -            return offset_;
  11.217 -        }
  11.218 -        void bind(int offset) {
  11.219 -            assert(!bound_);
  11.220 -            setOffset(offset);
  11.221 -            bound_ = true;
  11.222 -        }
  11.223 -        int link(int offset) {
  11.224 -            assert(!bound_);
  11.225 -            int old = offset_;
  11.226 -            setOffset(offset);
  11.227 -            return old;
  11.228 -        }
  11.229 -    };
  11.230 -
  11.231 -  private:
  11.232 -    int patchJumpAt(int at, int to) {
  11.233 -        assert(at >= 0 && at < position());
  11.234 -        int old = *(int *)(buffer_ + at + 1);
  11.235 -        *(int *)(buffer_ + at + 1) = (to - at);
  11.236 -        return old;
  11.237 -    }
  11.238 -
  11.239 -    void singleByteOp(Opcode op) {
  11.240 -        assert(OpcodeInfo[op].length == 1);
  11.241 -        ensure(OpcodeInfo[op].length);
  11.242 -        writeOp(op);
  11.243 -    }
  11.244 -
  11.245 -    // Mark a stack slot as having an object pointer.
  11.246 -    void markOop(unsigned depth, bool oop = true) {
  11.247 -        if (oom_)
  11.248 -            return;
  11.249 -        oopMap_[oopMap_.length() - depth] = oop;
  11.250 -    }
  11.251 -    bool getOop(unsigned depth) {
  11.252 -        if (oom_)
  11.253 -            return false;
  11.254 -        return oopMap_[oopMap_.length() - depth];
  11.255 -    }
  11.256 -
  11.257 -    // Mark the current bytecode position as either re-entrant (meaning, it
  11.258 -    // can leave the interpreter or call to another function), or causing GC.
  11.259 -    // This will record which stack slots have objects and associate that
  11.260 -    // information with the current pc.
  11.261 -    void recordOops();
  11.262 -
  11.263 -  public:
  11.264 -    void int_(int value) {
  11.265 -        ensure(OP_INT);
  11.266 -        writeOp(OP_INT);
  11.267 -        writeInt32(value);
  11.268 -    }
  11.269 -    void return_() {
  11.270 -        ensure(OP_RETURN);
  11.271 -        writeOp(OP_RETURN);
  11.272 -    }
  11.273 -    void getlocal(Variable *var) {
  11.274 -        ensure(OP_GETLOCAL_LENGTH);
  11.275 -        writeOp(OP_GETLOCAL);
  11.276 -        writeUint32(var->slot());
  11.277 -
  11.278 -        if (var->type()->isTraceable())
  11.279 -            markOop(1);
  11.280 -    }
  11.281 -    void setlocal(Variable *var) {
  11.282 -        ensure(OP_SETLOCAL_LENGTH);
  11.283 -        writeOp(OP_SETLOCAL);
  11.284 -        writeUint32(var->slot());
  11.285 -
  11.286 -        if (var->type()->isTraceable())
  11.287 -            markOop(1);
  11.288 -    }
  11.289 -    void getarg(Variable *var) {
  11.290 -        ensure(OP_GETARG_LENGTH);
  11.291 -        writeOp(OP_GETARG);
  11.292 -        writeUint32(var->slot());
  11.293 -
  11.294 -        if (var->type()->isTraceable())
  11.295 -            markOop(1);
  11.296 -    }
  11.297 -    void setarg(Variable *var) {
  11.298 -        ensure(OP_SETARG_LENGTH);
  11.299 -        writeOp(OP_SETARG);
  11.300 -        writeUint32(var->slot());
  11.301 -
  11.302 -        if (var->type()->isTraceable())
  11.303 -            markOop(1);
  11.304 -    }
  11.305 -
  11.306 -    void j(Opcode op, Label *label) {
  11.307 -        // Since jumps can skip around the stream, do not try to do anything
  11.308 -        // in a potentially truncated state.
  11.309 -        if (oom())
  11.310 -            return;
  11.311 -
  11.312 -        assert(op >= OP_JL && op <= OP_JUMP);
  11.313 -        ensure(OP_JUMP_LENGTH);
  11.314 -
  11.315 -        if (label->bound()) {
  11.316 -            // We can immediately emit this jump.
  11.317 -            int distance = label->offset() - position();
  11.318 -            writeOp(op);
  11.319 -            writeInt32(distance);
  11.320 -        } else {
  11.321 -            // We can't emit this jump yet. Add a placeholder.
  11.322 -            int old = label->link(position());
  11.323 -            writeOp(op);
  11.324 -            writeInt32(old);
  11.325 -        }
  11.326 -    }
  11.327 -    void bind(Label *label) {
  11.328 -        if (oom())
  11.329 -            return;
  11.330 -
  11.331 -        assert(!label->bound());
  11.332 -
  11.333 -        int offset = label->offset();
  11.334 -        while (offset != Label::INVALID_OFFSET)
  11.335 -            offset = patchJumpAt(offset, position());
  11.336 -
  11.337 -        label->bind(position());
  11.338 -    }
  11.339 -    void jump(Label *label) {
  11.340 -        j(OP_JUMP, label);
  11.341 -    }
  11.342 -
  11.343 -    void binary(Opcode op) {
  11.344 -        singleByteOp(op);
  11.345 -    }
  11.346 -
  11.347 -    void pop() {
  11.348 -        singleByteOp(OP_POP);
  11.349 -    }
  11.350 -    void stop() {
  11.351 -        singleByteOp(OP_STOP);
  11.352 -    }
  11.353 -    void call(Handle<Type> fun) {
  11.354 -        recordOops();
  11.355 -        ensure(OP_CALL_LENGTH);
  11.356 -        writeOp(OP_CALL);
  11.357 -
  11.358 -        if (fun->returnType()->isVoid())
  11.359 -            drop(1);
  11.360 -        else if (fun->returnType()->isTraceable())
  11.361 -            markOop(1);
  11.362 -    }
  11.363 -    void callnative(unsigned index, unsigned argc) {
  11.364 -        recordOops();
  11.365 -        ensure(OP_CALLNATIVE_LENGTH);
  11.366 -        writeOp(OP_CALLNATIVE);
  11.367 -        writeUint32(index);
  11.368 -        writeUint32(argc);
  11.369 -    }
  11.370 -
  11.371 -    void getarray(PrimitiveType type) {
  11.372 -        switch (type) {
  11.373 -          case PrimitiveType_Float:
  11.374 -            singleByteOp(OP_GETARRAY_F);
  11.375 -            break;
  11.376 -          case PrimitiveType_Int32:
  11.377 -            singleByteOp(OP_GETARRAY_I);
  11.378 -            break;
  11.379 -          default:
  11.380 -            assert(type == PrimitiveType_Char);
  11.381 -            singleByteOp(OP_GETARRAY_C);
  11.382 -            break;
  11.383 -        }
  11.384 -    }
  11.385 -    void setarray(PrimitiveType type) {
  11.386 -        switch (type) {
  11.387 -          case PrimitiveType_Float:
  11.388 -            singleByteOp(OP_SETARRAY_F);
  11.389 -            break;
  11.390 -          case PrimitiveType_Int32:
  11.391 -            singleByteOp(OP_SETARRAY_I);
  11.392 -            break;
  11.393 -          default:
  11.394 -            assert(type == PrimitiveType_Char);
  11.395 -            singleByteOp(OP_SETARRAY_C);
  11.396 -            break;
  11.397 -        }
  11.398 -    }
  11.399 -
  11.400 -    void getglobal(Variable *var) {
  11.401 -        ensure(OP_GETGLOBAL_F_LENGTH);
  11.402 -        if (var->type()->isPrimitive()) {
  11.403 -            switch (var->type()->primitive()) {
  11.404 -              case PrimitiveType_Float:
  11.405 -                writeOp(OP_GETGLOBAL_F);
  11.406 -                break;
  11.407 -              default:
  11.408 -                assert(var->type()->primitive() == PrimitiveType_Int32);
  11.409 -                writeOp(OP_GETGLOBAL_I);
  11.410 -                break;
  11.411 -            }
  11.412 -        } else {
  11.413 -            writeOp(OP_GETGLOBAL_O);
  11.414 -            markOop(1);
  11.415 -        }
  11.416 -        writeUint32(var->slot());
  11.417 -    }
  11.418 -    void setglobal(Variable *var) {
  11.419 -        ensure(OP_SETGLOBAL_F_LENGTH);
  11.420 -        if (var->type()->isPrimitive()) {
  11.421 -            switch (var->type()->primitive()) {
  11.422 -              case PrimitiveType_Float:
  11.423 -                writeOp(OP_SETGLOBAL_F);
  11.424 -                break;
  11.425 -              default:
  11.426 -                assert(var->type()->primitive() == PrimitiveType_Int32);
  11.427 -                writeOp(OP_SETGLOBAL_I);
  11.428 -                break;
  11.429 -            }
  11.430 -        } else {
  11.431 -            writeOp(OP_SETGLOBAL_O);
  11.432 -        }
  11.433 -        writeUint32(var->slot());
  11.434 -    }
  11.435 -
  11.436 -    void getarray_o() {
  11.437 -        singleByteOp(OP_GETARRAY_O);
  11.438 -        markOop(1);
  11.439 -    }
  11.440 -    void bounds() {
  11.441 -        singleByteOp(OP_BOUNDS);
  11.442 -        markOop(2);
  11.443 -    }
  11.444 -    void float_(float value) {
  11.445 -        ensure(OP_FLOAT_LENGTH);
  11.446 -        writeOp(OP_FLOAT);
  11.447 -        writeFloat(value);
  11.448 -    }
  11.449 -    void cvt_i2f() {
  11.450 -        singleByteOp(OP_CVT_I2F);
  11.451 -    }
  11.452 -    void newarray(Handle<Map> map, Heap::Tenure tenure) {
  11.453 -        recordOops();
  11.454 -        ensure(OP_NEWARRAY_LENGTH);
  11.455 -        writeOp(OP_NEWARRAY);
  11.456 -        writeUint8(tenure);
  11.457 -        writeObject(map);
  11.458 -        markOop(1);
  11.459 -    }
  11.460 -    void savelifo(unsigned slot) {
  11.461 -        ensure(OP_SAVELIFO_LENGTH);
  11.462 -        writeOp(OP_SAVELIFO);
  11.463 -        writeUint32(slot);
  11.464 -    }
  11.465 -    void unwindlifo(unsigned slot) {
  11.466 -        ensure(OP_UNWINDLIFO_LENGTH);
  11.467 -        writeOp(OP_UNWINDLIFO);
  11.468 -        writeUint32(slot);
  11.469 -    }
  11.470 -    void newref(Variable *var) {
  11.471 -        recordOops();
  11.472 -        if (var->location() == Variable::STACK) {
  11.473 -            ensure(OP_VARREF_LIFO_LENGTH);
  11.474 -            writeOp(OP_VARREF_LIFO);
  11.475 -        } else {
  11.476 -            assert(var->location() == Variable::PARAMETER);
  11.477 -            ensure(OP_ARGREF_LIFO_LENGTH);
  11.478 -            writeOp(OP_ARGREF_LIFO);
  11.479 -        }
  11.480 -        writeUint32(var->slot());
  11.481 -        markOop(1);
  11.482 -    }
  11.483 -
  11.484 -    void slotref_lifo() {
  11.485 -        recordOops();
  11.486 -        singleByteOp(OP_SLOTREF_LIFO);
  11.487 -        markOop(1);
  11.488 -    }
  11.489 -    void arrayref_lifo() {
  11.490 -        recordOops();
  11.491 -        singleByteOp(OP_ARRAYREF_LIFO);
  11.492 -        markOop(1);
  11.493 -    }
  11.494 -    void getref(PrimitiveType type) {
  11.495 -        if (type == PrimitiveType_Int32) {
  11.496 -            singleByteOp(OP_GETREF_I);
  11.497 -        } else {
  11.498 -            assert(type == PrimitiveType_Float);
  11.499 -            singleByteOp(OP_GETREF_F);
  11.500 -        }
  11.501 -    }
  11.502 -    void setref(PrimitiveType type) {
  11.503 -        if (type == PrimitiveType_Int32) {
  11.504 -            singleByteOp(OP_SETREF_I);
  11.505 -        } else {
  11.506 -            assert(type == PrimitiveType_Float);
  11.507 -            singleByteOp(OP_SETREF_F);
  11.508 -        }
  11.509 -    }
  11.510 -    void object(Handle<Object> obj) {
  11.511 -        ensure(OP_OBJECT_LENGTH);
  11.512 -        writeOp(OP_OBJECT);
  11.513 -        writeObject(obj);
  11.514 -        markOop(1);
  11.515 -    }
  11.516 -    void arraycopy() {
  11.517 -        singleByteOp(OP_ARRAYCOPY);
  11.518 -        markOop(1);
  11.519 -    }
  11.520 -
  11.521 -    void dup() {
  11.522 -        bool oop = getOop(1);
  11.523 -        singleByteOp(OP_DUP);
  11.524 -        markOop(1, oop);
  11.525 -    }
  11.526 -    void dup2() {
  11.527 -        bool oop2 = getOop(2);
  11.528 -        bool oop1 = getOop(1);
  11.529 -
  11.530 -        singleByteOp(OP_DUP2);
  11.531 -
  11.532 -        markOop(2, oop2);
  11.533 -        markOop(1, oop1);
  11.534 -    }
  11.535 -    void swap() {
  11.536 -        bool oop2 = getOop(2);
  11.537 -        bool oop1 = getOop(1);
  11.538 -
  11.539 -        singleByteOp(OP_SWAP);
  11.540 -
  11.541 -        markOop(2, oop1);
  11.542 -        markOop(1, oop2);
  11.543 -    }
  11.544 -    void roll3() {
  11.545 -        bool oop3 = getOop(3);
  11.546 -        bool oop2 = getOop(2);
  11.547 -        bool oop1 = getOop(1);
  11.548 -
  11.549 -        singleByteOp(OP_ROLL3);
  11.550 -
  11.551 -        markOop(3, oop2);
  11.552 -        markOop(2, oop1);
  11.553 -        markOop(1, oop3);
  11.554 -    }
  11.555 -    void pick2() {
  11.556 -        bool oop2 = getOop(2);
  11.557 -        bool oop1 = getOop(1);
  11.558 -
  11.559 -        singleByteOp(OP_PICK2);
  11.560 -
  11.561 -        markOop(3, oop2);
  11.562 -        markOop(2, oop1);
  11.563 -        markOop(1, oop2);
  11.564 -    }
  11.565 -    void pick3() {
  11.566 -        bool oop3 = getOop(3);
  11.567 -        bool oop2 = getOop(2);
  11.568 -        bool oop1 = getOop(1);
  11.569 -
  11.570 -        singleByteOp(OP_PICK3);
  11.571 -
  11.572 -        markOop(4, oop3);
  11.573 -        markOop(3, oop2);
  11.574 -        markOop(2, oop1);
  11.575 -        markOop(1, oop3);
  11.576 -    }
  11.577 -
  11.578 -    void returnvoid() {
  11.579 -        singleByteOp(OP_RETURNVOID);
  11.580 -    }
  11.581 -    void module() {
  11.582 -        singleByteOp(OP_MODULE);
  11.583 -        markOop(1);
  11.584 -    }
  11.585 -    void getmodule_fn(unsigned index) {
  11.586 -        ensure(OP_GETMODULE_FN_LENGTH);
  11.587 -        writeOp(OP_GETMODULE_FN);
  11.588 -        writeUint32(index);
  11.589 -        markOop(1);
  11.590 -    }
  11.591 -    void bitnot() {
  11.592 -        singleByteOp(OP_BITNOT);
  11.593 -    }
  11.594 -    void not_() {
  11.595 -        singleByteOp(OP_NOT);
  11.596 -    }
  11.597 -    void not_f() {
  11.598 -        singleByteOp(OP_NOT_F);
  11.599 -    }
  11.600 -    void neg() {
  11.601 -        singleByteOp(OP_NEG);
  11.602 -    }
  11.603 -    void neg_f() {
  11.604 -        singleByteOp(OP_NEG_F);
  11.605 -    }
  11.606 -
  11.607 -    // Helpers.
  11.608 -    void get(Variable *var) {
  11.609 -        if (var->location() == Variable::STACK) {
  11.610 -            getlocal(var);
  11.611 -        } else {
  11.612 -            assert(var->location() == Variable::PARAMETER);
  11.613 -            getarg(var);
  11.614 -        }
  11.615 -    }
  11.616 -    void set(Variable *var) {
  11.617 -        assert(!var->type()->isReference());
  11.618 -        if (var->location() == Variable::STACK) {
  11.619 -            setlocal(var);
  11.620 -        } else {
  11.621 -            assert(var->location() == Variable::PARAMETER);
  11.622 -            setarg(var);
  11.623 -        }
  11.624 -    }
  11.625 -};
  11.626 -
  11.627 -}
  11.628 -
  11.629 -#endif // _include_bytecode_emitter_h_
    12.1 --- a/jitcraft/Code.h	Tue Jul 24 23:53:34 2012 -0700
    12.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    12.3 @@ -1,127 +0,0 @@
    12.4 -/* vim: set ts=4 sw=4 tw=99 et:
    12.5 - *
    12.6 - * Copyright (C) 2012 David Anderson
    12.7 - *
    12.8 - * This file is part of JITCraft.
    12.9 - *
   12.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   12.11 - * the terms of the GNU General Public License as published by the Free
   12.12 - * Software Foundation, either version 3 of the License, or (at your option)
   12.13 - * any later version.
   12.14 - * 
   12.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   12.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   12.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   12.18 - *
   12.19 - * You should have received a copy of the GNU General Public License along with
   12.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   12.21 - */
   12.22 -#ifndef _include_jc_code_h_
   12.23 -#define _include_jc_code_h_
   12.24 -
   12.25 -#include "Opcodes.h"
   12.26 -#include "Barriers.h"
   12.27 -#include "Heap.h"
   12.28 -#include "Types.h"
   12.29 -#include "FixedArray.h"
   12.30 -#include "Token.h"
   12.31 -
   12.32 -namespace ke {
   12.33 -
   12.34 -class Module;
   12.35 -class Type;
   12.36 -
   12.37 -// A code object contains the bytecode compiled from a function (or global
   12.38 -// script), as well as all information needed to interpret or JIT-compile
   12.39 -// the bytecode.
   12.40 -class Code : public Object
   12.41 -{
   12.42 -    Barriered<Module> module_;
   12.43 -    Barriered<ByteArray> bytecode_;
   12.44 -    Barriered<FixedArray> locals_;
   12.45 -    Barriered<FixedArray> objects_;
   12.46 -    Barriered<ByteArray> safepoints_;
   12.47 -    Barriered<ByteArray> sourcemap_;
   12.48 -    unsigned maxStackDepth_;
   12.49 -    unsigned lineNumber_;
   12.50 -
   12.51 -  public:
   12.52 -    static inline size_t BytesPerSafepoint(size_t stackDepth) {
   12.53 -        return (Align(stackDepth, 8) / 8) + sizeof(unsigned);
   12.54 -    }
   12.55 -
   12.56 -  public:
   12.57 -    static Code *New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
   12.58 -                     Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module,
   12.59 -                     Handle<ByteArray> safepoints, Handle<ByteArray> sourcemap,
   12.60 -                     unsigned lineNumber);
   12.61 -
   12.62 -    Module *module() {
   12.63 -        return module_;
   12.64 -    }
   12.65 -    bytecode *start() {
   12.66 -        return bytecode_->raw();
   12.67 -    }
   12.68 -    unsigned length() {
   12.69 -        return bytecode_->length();
   12.70 -    }
   12.71 -    Type *localType(size_t index) {
   12.72 -        return Type::cast(locals_->at(index));
   12.73 -    }
   12.74 -    unsigned nlocals() {
   12.75 -        return locals_ ? locals_->length() : 0;
   12.76 -    }
   12.77 -    unsigned maxStackDepth() {
   12.78 -        return maxStackDepth_;
   12.79 -    }
   12.80 -    Map *map(size_t index) {
   12.81 -        return Map::cast(objects_->at(index));
   12.82 -    }
   12.83 -    Object *object(size_t index) {
   12.84 -        return objects_->at(index);
   12.85 -    }
   12.86 -    ByteArray *safepoints() {
   12.87 -        return safepoints_;
   12.88 -    }
   12.89 -    uint8 *safepointAt(unsigned pcOffset);
   12.90 -
   12.91 -    unsigned pcToOffset(bytecode *pc) {
   12.92 -        assert(pc >= start() && pc < start() + length());
   12.93 -        return pc - start();
   12.94 -    }
   12.95 -
   12.96 -    SourcePosition pcToSource(unsigned pc);
   12.97 -    unsigned lineNumber() {
   12.98 -        return lineNumber_;
   12.99 -    }
  12.100 -
  12.101 -    // GC Descriptor.
  12.102 -    static inline size_t offsetOfModule() {
  12.103 -        return offsetof(Code, module_);
  12.104 -    }
  12.105 -    static inline size_t offsetOfBytecode() {
  12.106 -        return offsetof(Code, bytecode_);
  12.107 -    }
  12.108 -    static inline size_t offsetOfLocals() {
  12.109 -        return offsetof(Code, locals_);
  12.110 -    }
  12.111 -    static inline size_t offsetOfObjects() {
  12.112 -        return offsetof(Code, objects_);
  12.113 -    }
  12.114 -    static inline size_t offsetOfSafepoints() {
  12.115 -        return offsetof(Code, safepoints_);
  12.116 -    }
  12.117 -    static inline size_t offsetOfSourceMap() {
  12.118 -        return offsetof(Code, sourcemap_);
  12.119 -    }
  12.120 -    // End GC Descriptor.
  12.121 -
  12.122 -    static Code *cast(Object *obj) {
  12.123 -        assert(!obj || obj->is(MapKind_Code));
  12.124 -        return reinterpret_cast<Code *>(obj);
  12.125 -    }
  12.126 -};
  12.127 -
  12.128 -}
  12.129 -
  12.130 -#endif // _include_jc_code_h_
    13.1 --- a/jitcraft/CompactBuffer.h	Tue Jul 24 23:53:34 2012 -0700
    13.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    13.3 @@ -1,100 +0,0 @@
    13.4 -/* vim: set ts=4 sw=4 tw=99 et:
    13.5 - *
    13.6 - * Copyright (C) 2012 David Anderson
    13.7 - *
    13.8 - * This file is part of JITCraft.
    13.9 - *
   13.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   13.11 - * the terms of the GNU General Public License as published by the Free
   13.12 - * Software Foundation, either version 3 of the License, or (at your option)
   13.13 - * any later version.
   13.14 - * 
   13.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   13.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   13.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   13.18 - *
   13.19 - * You should have received a copy of the GNU General Public License along with
   13.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   13.21 - */
   13.22 -#ifndef _include_jc_compact_buffer_h_
   13.23 -#define _include_jc_compact_buffer_h_
   13.24 -
   13.25 -#include "AllocatorPolicies.h"
   13.26 -#include "Utility.h"
   13.27 -#include "Vector.h"
   13.28 -
   13.29 -namespace ke {
   13.30 -
   13.31 -class CompactBufferReader
   13.32 -{
   13.33 -    const uint8 *pos_;
   13.34 -    const uint8 *end_;
   13.35 -
   13.36 -  public:
   13.37 -    CompactBufferReader(const uint8 *start, const uint8 *end)
   13.38 -      : pos_(start),
   13.39 -        end_(end)
   13.40 -    {
   13.41 -    }
   13.42 -
   13.43 -    uint8 readUint8() {
   13.44 -        assert(pos_ < end_);
   13.45 -        return *pos_++;
   13.46 -    }
   13.47 -
   13.48 -    uint32 readUint32() {
   13.49 -        uint32 value = 0;
   13.50 -        uint32 shift = 0;
   13.51 -
   13.52 -        uint8 byte;
   13.53 -        do {
   13.54 -            byte = readUint8();
   13.55 -            value |= (byte >> 1) << shift;
   13.56 -            shift += 7;
   13.57 -        } while (byte & 1);
   13.58 -
   13.59 -        assert(shift < 32);
   13.60 -        return value;
   13.61 -    }
   13.62 -
   13.63 -    bool done() const {
   13.64 -        return pos_ == end_;
   13.65 -    }
   13.66 -};
   13.67 -
   13.68 -class CompactBufferWriter
   13.69 -{
   13.70 -    Vector<uint8, ZoneAllocatorPolicy> buffer_;
   13.71 -    bool enoughMemory_;
   13.72 -
   13.73 -  public:
   13.74 -    CompactBufferWriter()
   13.75 -      : enoughMemory_(true)
   13.76 -    {
   13.77 -    }
   13.78 -
   13.79 -    void writeUint8(unsigned value) {
   13.80 -        enoughMemory_ &= buffer_.append(value);
   13.81 -    }
   13.82 -    void writeUint32(unsigned value) {
   13.83 -        do {
   13.84 -            writeUint8(((value & 0x7F) << 1) | (value > 0x7F));
   13.85 -            value >>= 7;
   13.86 -        } while (value);
   13.87 -    }
   13.88 -
   13.89 -    uint8 *buffer() const {
   13.90 -        return buffer_.buffer();
   13.91 -    }
   13.92 -    size_t length() const {
   13.93 -        return buffer_.length();
   13.94 -    }
   13.95 -
   13.96 -    bool oom() const {
   13.97 -        return !enoughMemory_;
   13.98 -    }
   13.99 -};
  13.100 -
  13.101 -}
  13.102 -
  13.103 -#endif // _include_jc_compact_buffer_h_
    14.1 --- a/jitcraft/CompileContext.cpp	Tue Jul 24 23:53:34 2012 -0700
    14.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    14.3 @@ -1,56 +0,0 @@
    14.4 -/*
    14.5 - * Copyright (C) 2012 David Anderson
    14.6 - *
    14.7 - * This file is part of JITCraft.
    14.8 - *
    14.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   14.10 - * the terms of the GNU General Public License as published by the Free
   14.11 - * Software Foundation, either version 3 of the License, or (at your option)
   14.12 - * any later version.
   14.13 - * 
   14.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   14.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   14.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   14.17 - *
   14.18 - * You should have received a copy of the GNU General Public License along with
   14.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   14.20 - */
   14.21 -#include <stdio.h>
   14.22 -#include "Scanner.h"
   14.23 -#include "CompileContext.h"
   14.24 -#include "Zone.h"
   14.25 -
   14.26 -using namespace ke;
   14.27 -
   14.28 -CompileContext::CompileContext(Zone *zone, const char *file)
   14.29 -  : zone_(zone),
   14.30 -    failures_(0),
   14.31 -    file_(file)
   14.32 -{
   14.33 -}
   14.34 -
   14.35 -CompileContext::~CompileContext()
   14.36 -{
   14.37 -    if (failures_)
   14.38 -        zone_->endCompilationErrors();
   14.39 -}
   14.40 -
   14.41 -void
   14.42 -CompileContext::reportErrorVa(const SourcePosition &pos, Message msg, va_list ap)
   14.43 -{
   14.44 -    if (!failures_)
   14.45 -        zone_->beginCompilationErrors(file_);
   14.46 -
   14.47 -    zone_->reportCompilationError(msg, pos.line, pos.col, ap);
   14.48 -
   14.49 -    failures_++;
   14.50 -}
   14.51 -
   14.52 -void
   14.53 -CompileContext::reportError(const SourcePosition &pos, Message msg, ...)
   14.54 -{
   14.55 -    va_list ap;
   14.56 -    va_start(ap, msg);
   14.57 -    reportErrorVa(pos, msg, ap);
   14.58 -    va_end(ap);
   14.59 -}
    15.1 --- a/jitcraft/CompileContext.h	Tue Jul 24 23:53:34 2012 -0700
    15.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    15.3 @@ -1,49 +0,0 @@
    15.4 -/*
    15.5 - * Copyright (C) 2012 David Anderson
    15.6 - *
    15.7 - * This file is part of JITCraft.
    15.8 - *
    15.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   15.10 - * the terms of the GNU General Public License as published by the Free
   15.11 - * Software Foundation, either version 3 of the License, or (at your option)
   15.12 - * any later version.
   15.13 - * 
   15.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   15.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   15.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   15.17 - *
   15.18 - * You should have received a copy of the GNU General Public License along with
   15.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   15.20 - */
   15.21 -#ifndef _include_jitcraft_compile_context_h_
   15.22 -#define _include_jitcraft_compile_context_h_
   15.23 -
   15.24 -#include <stdarg.h>
   15.25 -#include "Messages.h"
   15.26 -
   15.27 -namespace ke {
   15.28 -
   15.29 -class Zone;
   15.30 -struct SourcePosition;
   15.31 -
   15.32 -class CompileContext
   15.33 -{
   15.34 -    Zone *zone_;
   15.35 -    unsigned failures_;
   15.36 -    const char *file_;
   15.37 -
   15.38 -  public:
   15.39 -    CompileContext(Zone *zone, const char *file);
   15.40 -    ~CompileContext();
   15.41 -
   15.42 -    void reportErrorVa(const SourcePosition &pos, Message msg, va_list ap);
   15.43 -    void reportError(const SourcePosition &pos, Message msg, ...);
   15.44 -
   15.45 -    unsigned failures() const {
   15.46 -        return failures_;
   15.47 -    }
   15.48 -};
   15.49 -
   15.50 -}
   15.51 -
   15.52 -#endif // _include_jitcraft_compile_context_h_
    16.1 --- a/jitcraft/Environments.cpp	Tue Jul 24 23:53:34 2012 -0700
    16.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    16.3 @@ -1,97 +0,0 @@
    16.4 -/*
    16.5 - * Copyright (C) 2012 David Anderson
    16.6 - *
    16.7 - * This file is part of JITCraft.
    16.8 - *
    16.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   16.10 - * the terms of the GNU General Public License as published by the Free
   16.11 - * Software Foundation, either version 3 of the License, or (at your option)
   16.12 - * any later version.
   16.13 - * 
   16.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   16.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   16.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   16.17 - *
   16.18 - * You should have received a copy of the GNU General Public License along with
   16.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   16.20 - */
   16.21 -#include "Utility.h"
   16.22 -#include "Environments.h"
   16.23 -#include "Structures.h"
   16.24 -#include "FixedArray.h"
   16.25 -#include "Zone.h"
   16.26 -#include "NameBinding.h"
   16.27 -
   16.28 -using namespace ke;
   16.29 -
   16.30 -EnvironmentSlotDescriptorArray *
   16.31 -EnvironmentSlotDescriptorArray::New(Zone *zone, unsigned nslots)
   16.32 -{
   16.33 -    size_t bytesNeeded = sizeof(EnvironmentSlotDescriptorArray) +
   16.34 -                         sizeof(EnvironmentSlotDescriptor) * nslots;
   16.35 -
   16.36 -    Local<EnvironmentSlotDescriptorArray> array(zone);
   16.37 -    Local<Map> map(zone, zone->getMap(MapKind_EnvironmentSlotDescriptorArray));
   16.38 -
   16.39 -    array = EnvironmentSlotDescriptorArray::cast(zone->allocate(map, bytesNeeded, Heap::Tenure_Old));
   16.40 -    if (!array)
   16.41 -        return NULL;
   16.42 -
   16.43 -    // We zero the array for safety, since we could GC or fail before initialization.
   16.44 -    array->length_ = nslots;
   16.45 -    memset(array->slots(), 0, sizeof(EnvironmentSlotDescriptor) * nslots);
   16.46 -    return array;
   16.47 -}
   16.48 -
   16.49 -Environment *
   16.50 -Environment::New(Zone *zone, Handle<EnvironmentMap> map, Heap::Tenure tenure)
   16.51 -{
   16.52 -    size_t bytesNeeded = sizeof(Environment) + map->structureSize();
   16.53 -    Local<Environment> env(zone, Environment::cast(zone->allocate(map, bytesNeeded, tenure)));
   16.54 -    if (!env)
   16.55 -        return NULL;
   16.56 -
   16.57 -    // Initialize when called from C++, to make sure object slots are NULL.
   16.58 -    memset((Object *)env + 1, 0, map->structureSize());
   16.59 -    return env;
   16.60 -}
   16.61 -
   16.62 -EnvironmentMap *
   16.63 -EnvironmentMap::New(Zone *zone, unsigned nvars, Variable **vars)
   16.64 -{
   16.65 -    StructureBufferBuilder structure;
   16.66 -
   16.67 -    Local<EnvironmentSlotDescriptorArray> slots(zone);
   16.68 -    slots = EnvironmentSlotDescriptorArray::New(zone, nvars);
   16.69 -    if (!slots)
   16.70 -        return NULL;
   16.71 -
   16.72 -    // Build the descriptor table, mapping each slot to an offset and type.
   16.73 -    Local<Type> type(zone);
   16.74 -    for (unsigned i = 0; i < nvars; i++) {
   16.75 -        assert(vars[i]->slot() == i);
   16.76 -        type = vars[i]->type();
   16.77 -
   16.78 -        EnvironmentSlotDescriptor &desc = slots->slots()[i];
   16.79 -        if (!structure.add(type, &desc.offset))
   16.80 -            return NULL;
   16.81 -
   16.82 -        desc.type = type;
   16.83 -    }
   16.84 -
   16.85 -    // Allocate the actual map now.
   16.86 -    size_t bytesNeeded = sizeof(EnvironmentMap) + structure.traceableOffsetCount() * sizeof(unsigned);
   16.87 -    Local<EnvironmentMap> map(zone);
   16.88 -    
   16.89 -    map = EnvironmentMap::cast(zone->allocateMap(MapKind_Environment, bytesNeeded, MapKind_MetaEnvironment));
   16.90 -    if (!map)
   16.91 -        return NULL;
   16.92 -    
   16.93 -    // Fill in the map fields, and copy the traceable offsets structure.
   16.94 -    map->structureSize_ = structure.structureSize();
   16.95 -    map->traceOffsetCount_ = structure.traceableOffsetCount();
   16.96 -    map->slots_ = slots;
   16.97 -    memcpy(const_cast<unsigned *>(map->traceOffsets()), structure.offsets(), sizeof(unsigned) * structure.traceableOffsetCount());
   16.98 -
   16.99 -    return map;
  16.100 -}
    17.1 --- a/jitcraft/Environments.h	Tue Jul 24 23:53:34 2012 -0700
    17.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    17.3 @@ -1,168 +0,0 @@
    17.4 -/*
    17.5 - * Copyright (C) 2012 David Anderson
    17.6 - *
    17.7 - * This file is part of JITCraft.
    17.8 - *
    17.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   17.10 - * the terms of the GNU General Public License as published by the Free
   17.11 - * Software Foundation, either version 3 of the License, or (at your option)
   17.12 - * any later version.
   17.13 - * 
   17.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   17.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   17.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   17.17 - *
   17.18 - * You should have received a copy of the GNU General Public License along with
   17.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   17.20 - */
   17.21 -#ifndef _include_ke_environment_h_
   17.22 -#define _include_ke_environment_h_
   17.23 -
   17.24 -#include "Objects.h"
   17.25 -#include "Handles.h"
   17.26 -#include "Heap.h"
   17.27 -#include "FixedArray.h"
   17.28 -
   17.29 -namespace ke {
   17.30 -
   17.31 -class EnvironmentMap;
   17.32 -class Variable;
   17.33 -class ByteArray;
   17.34 -class Type;
   17.35 -
   17.36 -// An environment represents the lexical environment of a code or function
   17.37 -// object. It used for variables which may be accessed outside a function's
   17.38 -// normal activation (i.e., upvars).
   17.39 -//
   17.40 -// A module uses an Environment to store its global variables.
   17.41 -class Environment : public Object
   17.42 -{
   17.43 -    template <typename T>
   17.44 -    inline T *pointerToSlot(unsigned slot);
   17.45 -
   17.46 -  public:
   17.47 -    static Environment *New(Zone *zone, Handle<EnvironmentMap> map, Heap::Tenure tenure = Heap::Tenure_Default);
   17.48 -
   17.49 -    inline EnvironmentMap *map();
   17.50 -    inline size_t size();
   17.51 -
   17.52 -    float getFloat(unsigned slot) {
   17.53 -        return *pointerToSlot<float>(slot);
   17.54 -    }
   17.55 -    int getInt32(unsigned slot) {
   17.56 -        return *pointerToSlot<int>(slot);
   17.57 -    }
   17.58 -    Object *getObject(unsigned slot) {
   17.59 -        return *pointerToSlot<Object *>(slot);
   17.60 -    }
   17.61 -    void setFloat(unsigned slot, float f) {
   17.62 -        *pointerToSlot<float>(slot) = f;
   17.63 -    }
   17.64 -    void setInt32(unsigned slot, int i) {
   17.65 -        *pointerToSlot<int>(slot) = i;
   17.66 -    }
   17.67 -    void setObject(unsigned slot, Object *obj) {
   17.68 -        // :TODO: write barrier
   17.69 -        *pointerToSlot<Object *>(slot) = obj;
   17.70 -    }
   17.71 -
   17.72 -    static inline size_t offsetOfSlotOffset(unsigned offset) {
   17.73 -        return sizeof(Environment) + offset;
   17.74 -    }
   17.75 -
   17.76 -    static inline Environment *cast(Object *obj) {
   17.77 -        assert(!obj || obj->is(MapKind_Environment));
   17.78 -        return reinterpret_cast<Environment *>(obj);
   17.79 -    }
   17.80 -};
   17.81 -
   17.82 -struct EnvironmentSlotDescriptor
   17.83 -{
   17.84 -    Barriered<Type> type;
   17.85 -    unsigned offset;
   17.86 -};
   17.87 -
   17.88 -class EnvironmentSlotDescriptorArray : public Object
   17.89 -{
   17.90 -    unsigned length_;
   17.91 -
   17.92 -  public:
   17.93 -    static EnvironmentSlotDescriptorArray *New(Zone *zone, unsigned length);
   17.94 -
   17.95 -    EnvironmentSlotDescriptor *slots() {
   17.96 -        return reinterpret_cast<EnvironmentSlotDescriptor *>(this + 1);
   17.97 -    }
   17.98 -    EnvironmentSlotDescriptor &at(unsigned slot) {
   17.99 -        assert(slot < length_);
  17.100 -        return slots()[slot];
  17.101 -    }
  17.102 -    unsigned length() {
  17.103 -        return length_;
  17.104 -    }
  17.105 -    unsigned size() {
  17.106 -        return Align(sizeof(*this) + length() * sizeof(EnvironmentSlotDescriptorArray),
  17.107 -                     kObjectAlignment);
  17.108 -    }
  17.109 -
  17.110 -    static inline EnvironmentSlotDescriptorArray *cast(Object *obj) {
  17.111 -        assert(!obj || obj->is(MapKind_EnvironmentSlotDescriptorArray));
  17.112 -        return reinterpret_cast<EnvironmentSlotDescriptorArray *>(obj);
  17.113 -    }
  17.114 -};
  17.115 -
  17.116 -class EnvironmentMap : public Map
  17.117 -{
  17.118 -    unsigned structureSize_;
  17.119 -    unsigned traceOffsetCount_;
  17.120 -    Barriered<EnvironmentSlotDescriptorArray> slots_;
  17.121 -
  17.122 -  public:
  17.123 -    static EnvironmentMap *New(Zone *zone, unsigned nvars, Variable **vars);
  17.124 -
  17.125 -    unsigned structureSize() {
  17.126 -        return structureSize_;
  17.127 -    }
  17.128 -    unsigned traceOffsetCount() {
  17.129 -        return traceOffsetCount_;
  17.130 -    }
  17.131 -    const unsigned *traceOffsets() {
  17.132 -        return reinterpret_cast<unsigned *>(this + 1);
  17.133 -    }
  17.134 -    size_t size() {
  17.135 -        return Align(sizeof(EnvironmentMap) + sizeof(unsigned) * traceOffsetCount(), kObjectAlignment);
  17.136 -    }
  17.137 -    EnvironmentSlotDescriptor &slotDescriptor(unsigned slot) {
  17.138 -        return slots_->at(slot);
  17.139 -    }
  17.140 -
  17.141 -    static inline size_t offsetOfSlots() {
  17.142 -        return offsetof(EnvironmentMap, slots_);
  17.143 -    }
  17.144 -
  17.145 -    static inline EnvironmentMap *cast(Object *obj) {
  17.146 -        assert(!obj || obj->is(MapKind_MetaEnvironment));
  17.147 -        return reinterpret_cast<EnvironmentMap *>(obj);
  17.148 -    }
  17.149 -};
  17.150 -
  17.151 -size_t
  17.152 -Environment::size()
  17.153 -{
  17.154 -    return Align(sizeof(Environment) + map()->structureSize(), kObjectAlignment);
  17.155 -}
  17.156 -
  17.157 -EnvironmentMap *
  17.158 -Environment::map()
  17.159 -{
  17.160 -    return EnvironmentMap::cast(Object::map());
  17.161 -}
  17.162 -
  17.163 -template <typename T> T *
  17.164 -Environment::pointerToSlot(unsigned slot)
  17.165 -{
  17.166 -    return reinterpret_cast<T *>(reinterpret_cast<char *>(this + 1) + map()->slotDescriptor(slot).offset);
  17.167 -}
  17.168 -
  17.169 -}
  17.170 -
  17.171 -#endif // _include_ke_environment_h_
    18.1 --- a/jitcraft/Exception.cpp	Tue Jul 24 23:53:34 2012 -0700
    18.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    18.3 @@ -1,31 +0,0 @@
    18.4 -
    18.5 -/*
    18.6 - * Copyright (C) 2012 David Anderson
    18.7 - *
    18.8 - * This file is part of JITCraft.
    18.9 - *
   18.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   18.11 - * the terms of the GNU General Public License as published by the Free
   18.12 - * Software Foundation, either version 3 of the License, or (at your option)
   18.13 - * any later version.
   18.14 - * 
   18.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   18.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   18.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   18.18 - *
   18.19 - * You should have received a copy of the GNU General Public License along with
   18.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   18.21 - */
   18.22 -#include "Utility.h"
   18.23 -#include "Messages.h"
   18.24 -
   18.25 -using namespace ke;
   18.26 -
   18.27 -const MessageInfo ke::Messages[] =
   18.28 -{
   18.29 -#define MSG(Name, Type, String) \
   18.30 -    { MessageType_##Type, String },
   18.31 -# include "Messages.tbl"
   18.32 -#undef MSG
   18.33 -    { MessageType_SyntaxError, NULL }
   18.34 -};
    19.1 --- a/jitcraft/FixedArray.cpp	Tue Jul 24 23:53:34 2012 -0700
    19.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    19.3 @@ -1,76 +0,0 @@
    19.4 -/*
    19.5 - * Copyright (C) 2012 David Anderson
    19.6 - *
    19.7 - * This file is part of JITCraft.
    19.8 - *
    19.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   19.10 - * the terms of the GNU General Public License as published by the Free
   19.11 - * Software Foundation, either version 3 of the License, or (at your option)
   19.12 - * any later version.
   19.13 - * 
   19.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   19.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   19.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   19.17 - *
   19.18 - * You should have received a copy of the GNU General Public License along with
   19.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   19.20 - */
   19.21 -#include <limits.h>
   19.22 -#include "FixedArray.h"
   19.23 -#include "Zone.h"
   19.24 -#include "Heap-inl.h"
   19.25 -
   19.26 -using namespace ke;
   19.27 -
   19.28 -static const unsigned kMaxFixedArrayLength = ((INT_MAX - sizeof(FixedArray)) / sizeof(ke::Object *));
   19.29 -
   19.30 -FixedArray *
   19.31 -FixedArray::New(Zone *zone, unsigned length, Heap::Tenure tenure)
   19.32 -{
   19.33 -    if (length >= kMaxFixedArrayLength) {
   19.34 -        zone->reportError(Message_ArrayTooBig);
   19.35 -        return NULL;
   19.36 -    }
   19.37 -
   19.38 -    Local<FixedArray> array(zone, FixedArray::cast(zone->allocate(MapKind_FixedArray, SizeFor(length), tenure)));
   19.39 -    if (!array)
   19.40 -        return NULL;
   19.41 -
   19.42 -    array->length_ = length;
   19.43 -    memset(array->vec(), 0, length * sizeof(Object *));
   19.44 -    return array;
   19.45 -}
   19.46 -
   19.47 -ByteArray *
   19.48 -ByteArray::New(Zone *zone, unsigned length, Heap::Tenure tenure)
   19.49 -{
   19.50 -    if (length >= kMaxFixedArrayLength) {
   19.51 -        zone->reportError(Message_ArrayTooBig);
   19.52 -        return NULL;
   19.53 -    }
   19.54 -
   19.55 -    Local<ByteArray> array(zone, ByteArray::cast(zone->allocate(MapKind_ByteArray, SizeFor(length), tenure)));
   19.56 -    if (!array)
   19.57 -        return NULL;
   19.58 -
   19.59 -    array->length_ = length;
   19.60 -    memset(array->raw(), 0, length);
   19.61 -    return array;
   19.62 -}
   19.63 -
   19.64 -ByteArray *
   19.65 -ByteArray::New(Zone *zone, Handle<Map> map, unsigned length, Heap::Tenure tenure)
   19.66 -{
   19.67 -    if (length >= kMaxFixedArrayLength) {
   19.68 -        zone->reportError(Message_ArrayTooBig);
   19.69 -        return NULL;
   19.70 -    }
   19.71 -
   19.72 -    Local<ByteArray> array(zone, ByteArray::cast(zone->allocate(map, SizeFor(length), tenure)));
   19.73 -    if (!array)
   19.74 -        return NULL;
   19.75 -
   19.76 -    array->length_ = length;
   19.77 -    memset(array->raw(), 0, length);
   19.78 -    return array;
   19.79 -}
    20.1 --- a/jitcraft/FixedArray.h	Tue Jul 24 23:53:34 2012 -0700
    20.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    20.3 @@ -1,89 +0,0 @@
    20.4 -/* vim: set ts=4 sw=4 tw=99 et
    20.5 - *
    20.6 - * Copyright (C) 2012 David Anderson
    20.7 - *
    20.8 - * This file is part of JITCraft.
    20.9 - *
   20.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   20.11 - * the terms of the GNU General Public License as published by the Free
   20.12 - * Software Foundation, either version 3 of the License, or (at your option)
   20.13 - * any later version.
   20.14 - * 
   20.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   20.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   20.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   20.18 - *
   20.19 - * You should have received a copy of the GNU General Public License along with
   20.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   20.21 - */
   20.22 -#ifndef _include_jitcraft_fixedarray_h_
   20.23 -#define _include_jitcraft_fixedarray_h_
   20.24 -
   20.25 -#include "Heap.h"
   20.26 -
   20.27 -namespace ke {
   20.28 -
   20.29 -// A fixed-length array that contains Object * slots.
   20.30 -class FixedArray : public Object
   20.31 -{
   20.32 -    uint32 length_;
   20.33 -
   20.34 -  private:
   20.35 -    Object **vec() {
   20.36 -        return reinterpret_cast<Object **>(this + 1);
   20.37 -    }
   20.38 -
   20.39 -  public:
   20.40 -    static FixedArray *New(Zone *zone, unsigned length, Heap::Tenure tenure);
   20.41 -
   20.42 -    unsigned length() {
   20.43 -        return length_;
   20.44 -    }
   20.45 -    Object *at(size_t i) {
   20.46 -        assert(i < length());
   20.47 -        return vec()[i];
   20.48 -    }
   20.49 -    void set(Zone *zone, size_t i, Object *obj) {
   20.50 -        assert(i < length());
   20.51 -        write(zone, &vec()[i], obj);
   20.52 -    }
   20.53 -
   20.54 -    static size_t SizeFor(unsigned length) {
   20.55 -        return sizeof(FixedArray) + sizeof(Object *) * length;
   20.56 -    }
   20.57 -
   20.58 -    static inline FixedArray *cast(Object *obj) {
   20.59 -        assert(!obj || obj->is(MapKind_FixedArray));
   20.60 -        return reinterpret_cast<FixedArray *>(obj);
   20.61 -    }
   20.62 -};
   20.63 -
   20.64 -// A fixed-length array containing raw bytes.
   20.65 -class ByteArray : public Object
   20.66 -{
   20.67 -    uint32 length_;
   20.68 -
   20.69 -  public:
   20.70 -    static ByteArray *New(Zone *zone, unsigned length, Heap::Tenure tenure = Heap::Tenure_Default);
   20.71 -    static ByteArray *New(Zone *zone, Handle<Map> map, unsigned length, Heap::Tenure tenure = Heap::Tenure_Default);
   20.72 -
   20.73 -    unsigned length() {
   20.74 -        return length_;
   20.75 -    }
   20.76 -    Address raw() {
   20.77 -        return reinterpret_cast<uint8 *>(this + 1);
   20.78 -    }
   20.79 -
   20.80 -    static size_t SizeFor(unsigned length) {
   20.81 -        return Align(sizeof(ByteArray) + sizeof(uint8) * length, kObjectAlignment);
   20.82 -    }
   20.83 -
   20.84 -    static inline ByteArray *cast(Object *obj) {
   20.85 -        assert(!obj || obj->is(MapKind_ByteArray));
   20.86 -        return reinterpret_cast<ByteArray *>(obj);
   20.87 -    }
   20.88 -};
   20.89 -
   20.90 -}
   20.91 -
   20.92 -#endif // _include_jitcraft_fixedarray_h_
    21.1 --- a/jitcraft/Functions.cpp	Tue Jul 24 23:53:34 2012 -0700
    21.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    21.3 @@ -1,51 +0,0 @@
    21.4 -/*
    21.5 - * Copyright (C) 2012 David Anderson
    21.6 - *
    21.7 - * This file is part of JITCraft.
    21.8 - *
    21.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   21.10 - * the terms of the GNU General Public License as published by the Free
   21.11 - * Software Foundation, either version 3 of the License, or (at your option)
   21.12 - * any later version.
   21.13 - * 
   21.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   21.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   21.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   21.17 - *
   21.18 - * You should have received a copy of the GNU General Public License along with
   21.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   21.20 - */
   21.21 -#include "Functions.h"
   21.22 -#include "Modules.h"
   21.23 -#include "Zone.h"
   21.24 -#include "Heap-inl.h"
   21.25 -
   21.26 -using namespace ke;
   21.27 -
   21.28 -Function *
   21.29 -Function::New(Zone *zone, Handle<Code> code, Handle<Type> type, Handle<String> name,
   21.30 -              const SourcePosition &pos)
   21.31 -{
   21.32 -    Function *fun = Function::cast(zone->allocate(MapKind_Function, sizeof(Function), Heap::Tenure_Old));
   21.33 -    if (!fun)
   21.34 -        return NULL;
   21.35 -
   21.36 -    fun->code_ = code;
   21.37 -    fun->pos_ = pos;
   21.38 -    fun->type_ = type;
   21.39 -    fun->name_ = name;
   21.40 -    return fun;
   21.41 -}
   21.42 -
   21.43 -Native *
   21.44 -Native::New(Zone *zone, Handle<Type> type, Handle<String> name)
   21.45 -{
   21.46 -    Native *fun = Native::cast(zone->allocate(MapKind_Native, sizeof(Native), Heap::Tenure_Old));
   21.47 -    if (!fun)
   21.48 -        return NULL;
   21.49 -
   21.50 -    fun->type_ = type;
   21.51 -    fun->name_ = name;
   21.52 -    fun->function_ = NULL;
   21.53 -    return fun;
   21.54 -}
    22.1 --- a/jitcraft/Functions.h	Tue Jul 24 23:53:34 2012 -0700
    22.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    22.3 @@ -1,122 +0,0 @@
    22.4 -/*
    22.5 - * Copyright (C) 2012 David Anderson
    22.6 - *
    22.7 - * This file is part of JITCraft.
    22.8 - *
    22.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   22.10 - * the terms of the GNU General Public License as published by the Free
   22.11 - * Software Foundation, either version 3 of the License, or (at your option)
   22.12 - * any later version.
   22.13 - * 
   22.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   22.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   22.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   22.17 - *
   22.18 - * You should have received a copy of the GNU General Public License along with
   22.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   22.20 - */
   22.21 -#ifndef _include_jitcraft_function_h_
   22.22 -#define _include_jitcraft_function_h_
   22.23 -
   22.24 -#include "Heap.h"
   22.25 -#include "Barriers.h"
   22.26 -#include "Token.h"
   22.27 -#include "Types.h"
   22.28 -
   22.29 -namespace ke {
   22.30 -
   22.31 -class Code;
   22.32 -class Module;
   22.33 -class Type;
   22.34 -class String;
   22.35 -
   22.36 -class Function : public Object
   22.37 -{
   22.38 -    Barriered<Code> code_;
   22.39 -    Barriered<Type> type_;
   22.40 -    Barriered<String> name_;
   22.41 -    SourcePosition pos_;
   22.42 -
   22.43 - public:
   22.44 -    static Function *New(Zone *zone, Handle<Code> code, Handle<Type> type, Handle<String> name,
   22.45 -                         const SourcePosition &pos);
   22.46 -
   22.47 -    Code *code() const {
   22.48 -        return code_;
   22.49 -    }
   22.50 -    Type *type() const {
   22.51 -        return type_;
   22.52 -    }
   22.53 -    String *name() const {
   22.54 -        return name_;
   22.55 -    }
   22.56 -    const SourcePosition &pos() {
   22.57 -        return pos_;
   22.58 -    }
   22.59 -    unsigned nargs() {
   22.60 -        return type()->parameters()->length();
   22.61 -    }
   22.62 -    Type *argType(size_t index) {
   22.63 -        return type()->parameterAt(index);
   22.64 -    }
   22.65 -
   22.66 -    // Begin GC Descriptor.
   22.67 -    static inline size_t offsetOfCode() {
   22.68 -        return offsetof(Function, code_);
   22.69 -    }
   22.70 -    static inline size_t offsetOfType() {
   22.71 -        return offsetof(Function, type_);
   22.72 -    }
   22.73 -    static inline size_t offsetOfName() {
   22.74 -        return offsetof(Function, name_);
   22.75 -    }
   22.76 -    // End GC Descriptor.
   22.77 -
   22.78 -    static inline Function *cast(Object *obj) {
   22.79 -        assert(!obj || obj->is(MapKind_Function));
   22.80 -        return reinterpret_cast<Function *>(obj);
   22.81 -    }
   22.82 -};
   22.83 -
   22.84 -// A Native is a function with a very specialized calling convention, intended
   22.85 -// for earlier ISourcePawnEngine API compatibility.
   22.86 -class Native : public Object
   22.87 -{
   22.88 -    Barriered<Type> type_;
   22.89 -    Barriered<String> name_;
   22.90 -    void *function_;
   22.91 -
   22.92 -  public:
   22.93 -    static Native *New(Zone *zone, Handle<Type> type, Handle<String> name);
   22.94 -
   22.95 -    void *function() {
   22.96 -        return function_;
   22.97 -    }
   22.98 -    Type *type() {
   22.99 -        return type_;
  22.100 -    }
  22.101 -    String *name() {
  22.102 -        return name_;
  22.103 -    }
  22.104 -    void bind(void *function) {
  22.105 -        function_ = function;
  22.106 -    }
  22.107 -
  22.108 -    // Begin GC Descriptor.
  22.109 -    static inline size_t offsetOfType() {
  22.110 -        return offsetof(Native, type_);
  22.111 -    }
  22.112 -    static inline size_t offsetOfName() {
  22.113 -        return offsetof(Native, name_);
  22.114 -    }
  22.115 -    // End GC Descriptor.
  22.116 -
  22.117 -    static inline Native *cast(Object *obj) {
  22.118 -        assert(!obj || obj->is(MapKind_Native));
  22.119 -        return reinterpret_cast<Native *>(obj);
  22.120 -    }
  22.121 -};
  22.122 -
  22.123 -}
  22.124 -
  22.125 -#endif // _include_jitcraft_function_h_
    23.1 --- a/jitcraft/GlobalRoots.cpp	Tue Jul 24 23:53:34 2012 -0700
    23.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    23.3 @@ -1,81 +0,0 @@
    23.4 -/*
    23.5 - * Copyright (C) 2004-2012 David Anderson
    23.6 - *
    23.7 - * This file is part of SourcePawn.
    23.8 - *
    23.9 - * SourcePawn is free software: you can redistribute it and/or modify it under
   23.10 - * the terms of the GNU General Public License as published by the Free
   23.11 - * Software Foundation, either version 3 of the License, or (at your option)
   23.12 - * any later version.
   23.13 - * 
   23.14 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   23.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   23.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   23.17 - *
   23.18 - * You should have received a copy of the GNU General Public License along with
   23.19 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   23.20 - */
   23.21 -#include "GlobalRoots.h"
   23.22 -#include "Zone.h"
   23.23 -
   23.24 -using namespace ke;
   23.25 -
   23.26 -GlobalRoots::GlobalRoots(Zone *zone)
   23.27 -  : zone_(zone)
   23.28 -{
   23.29 -}
   23.30 -
   23.31 -GlobalRoots::~GlobalRoots()
   23.32 -{
   23.33 -    InlineList<HeapRoot>::iterator iter = roots_.begin();
   23.34 -    while (iter != roots_.end()) {
   23.35 -		HeapRoot *root = *iter;
   23.36 -        iter = roots_.erase(iter);
   23.37 -		delete root;
   23.38 -    }
   23.39 -}
   23.40 -
   23.41 -bool
   23.42 -GlobalRoots::initialize()
   23.43 -{
   23.44 -    return true;
   23.45 -}
   23.46 -
   23.47 -void
   23.48 -GlobalRoots::accept(VirtualObjectVisitor *visitor)
   23.49 -{
   23.50 -    for (InlineList<HeapRoot>::iterator iter = roots_.begin(); iter != roots_.end(); iter++)
   23.51 -        visitor->visit(&iter->obj);
   23.52 -}
   23.53 -
   23.54 -HeapRoot *
   23.55 -GlobalRoots::create(Handle<Object> obj)
   23.56 -{
   23.57 -    HeapRoot *root = new HeapRoot();
   23.58 -    if (!root) {
   23.59 -        ZONE()->reportOutOfMemory();
   23.60 -        return NULL;
   23.61 -    }
   23.62 -
   23.63 -    root->obj = obj;
   23.64 -    root->refcount = 1;
   23.65 -
   23.66 -    roots_.append(root);
   23.67 -    return root;
   23.68 -}
   23.69 -
   23.70 -void
   23.71 -GlobalRoots::incref(HeapRoot *root)
   23.72 -{
   23.73 -    root->refcount++;
   23.74 -}
   23.75 -
   23.76 -void
   23.77 -GlobalRoots::decref(HeapRoot *root)
   23.78 -{
   23.79 -    assert(root->refcount > 0);
   23.80 -    if (--root->refcount == 0) {
   23.81 -        roots_.remove(root);
   23.82 -        delete root;
   23.83 -    }
   23.84 -}
    24.1 --- a/jitcraft/GlobalRoots.h	Tue Jul 24 23:53:34 2012 -0700
    24.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    24.3 @@ -1,61 +0,0 @@
    24.4 -/*
    24.5 - * Copyright (C) 2004-2012 David Anderson
    24.6 - *
    24.7 - * This file is part of SourcePawn.
    24.8 - *
    24.9 - * SourcePawn is free software: you can redistribute it and/or modify it under
   24.10 - * the terms of the GNU General Public License as published by the Free
   24.11 - * Software Foundation, either version 3 of the License, or (at your option)
   24.12 - * any later version.
   24.13 - * 
   24.14 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   24.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   24.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   24.17 - *
   24.18 - * You should have received a copy of the GNU General Public License along with
   24.19 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   24.20 - */
   24.21 -#ifndef _include_ke_global_roots_h_
   24.22 -#define _include_ke_global_roots_h_
   24.23 -
   24.24 -#include "Handles.h"
   24.25 -#include "InlineList.h"
   24.26 -#include "VirtualObjectVisitor.h"
   24.27 -
   24.28 -namespace ke {
   24.29 -
   24.30 -class Zone;
   24.31 -class Object;
   24.32 -
   24.33 -class HeapRoot : public InlineListNode<HeapRoot>
   24.34 -{
   24.35 -  public:
   24.36 -    Object *obj;
   24.37 -    intptr_t refcount;
   24.38 -};
   24.39 -
   24.40 -class GlobalRoots
   24.41 -{
   24.42 -    Zone *zone_;
   24.43 -
   24.44 -  public:
   24.45 -    GlobalRoots(Zone *zone);
   24.46 -    ~GlobalRoots();
   24.47 -
   24.48 -    bool initialize();
   24.49 -
   24.50 -    // The caller must immediately incref this.
   24.51 -    HeapRoot *create(Handle<Object> ptr);
   24.52 -
   24.53 -    void incref(HeapRoot *root);
   24.54 -    void decref(HeapRoot *root);
   24.55 -
   24.56 -    void accept(VirtualObjectVisitor *visitor);
   24.57 -
   24.58 -  private:
   24.59 -    InlineList<HeapRoot> roots_;
   24.60 -};
   24.61 -
   24.62 -}
   24.63 -
   24.64 -#endif // _include_ke_global_roots_h_
    25.1 --- a/jitcraft/Handles-inl.h	Tue Jul 24 23:53:34 2012 -0700
    25.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    25.3 @@ -1,62 +0,0 @@
    25.4 -/*
    25.5 - * Copyright (C) 2012 David Anderson
    25.6 - *
    25.7 - * This file is part of JITCraft.
    25.8 - *
    25.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   25.10 - * the terms of the GNU General Public License as published by the Free
   25.11 - * Software Foundation, either version 3 of the License, or (at your option)
   25.12 - * any later version.
   25.13 - * 
   25.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   25.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   25.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   25.17 - *
   25.18 - * You should have received a copy of the GNU General Public License along with
   25.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   25.20 - */
   25.21 -#ifndef _include_jitcraft_rooting_inl_h_
   25.22 -#define _include_jitcraft_rooting_inl_h_
   25.23 -
   25.24 -#include "Heap.h"
   25.25 -
   25.26 -namespace ke {
   25.27 -
   25.28 -template <typename T>
   25.29 -Local<T>::Local(Environment *env)
   25.30 -  : zone_(env->zone()), thing_(NULL)
   25.31 -{
   25.32 -    prev_ = zone_->registerThingLocal(toRaw());
   25.33 -}
   25.34 -
   25.35 -template <typename T>
   25.36 -Local<T>::Local(Environment *env, T *thing)
   25.37 -  : zone_(env->zone()), thing_(thing)
   25.38 -{
   25.39 -    prev_ = zone_->registerThingLocal(toRaw());
   25.40 -}
   25.41 -
   25.42 -template <typename T>
   25.43 -Local<T>::Local(Zone *zone)
   25.44 -  : zone_(zone), thing_(NULL)
   25.45 -{
   25.46 -    prev_ = zone_->registerThingLocal(toRaw());
   25.47 -}
   25.48 -
   25.49 -template <typename T>
   25.50 -Local<T>::Local(Zone *zone, T *thing)
   25.51 -  : zone_(zone), thing_(thing)
   25.52 -{
   25.53 -    prev_ = zone_->registerThingLocal(toRaw());
   25.54 -}
   25.55 -
   25.56 -
   25.57 -template <typename T>
   25.58 -Local<T>::~Local()
   25.59 -{
   25.60 -    zone_->deregisterThingLocal(toRaw(), prev_);
   25.61 -}
   25.62 -
   25.63 -}
   25.64 -
   25.65 -#endif // _include_jitcraft_rooting_inl_h_
    26.1 --- a/jitcraft/Handles.h	Tue Jul 24 23:53:34 2012 -0700
    26.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    26.3 @@ -1,204 +0,0 @@
    26.4 -/* vim: set ts=4 sw=4 tw=99 et:
    26.5 - *
    26.6 - * Copyright (C) 2012 David Anderson
    26.7 - *
    26.8 - * This file is part of JITCraft.
    26.9 - *
   26.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   26.11 - * the terms of the GNU General Public License as published by the Free
   26.12 - * Software Foundation, either version 3 of the License, or (at your option)
   26.13 - * any later version.
   26.14 - * 
   26.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   26.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   26.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   26.18 - *
   26.19 - * You should have received a copy of the GNU General Public License along with
   26.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   26.21 - */
   26.22 -#ifndef _include_jitcraft_rooting_h_
   26.23 -#define _include_jitcraft_rooting_h_
   26.24 -
   26.25 -#include <stdlib.h>
   26.26 -
   26.27 -namespace ke {
   26.28 -
   26.29 -class Zone;
   26.30 -class Object;
   26.31 -
   26.32 -template <typename T> class Local;
   26.33 -template <typename T> class ScopedRoot;
   26.34 -
   26.35 -/*
   26.36 - * Internal handles work differently from API handles. An API handle is a
   26.37 - * root, whereas as an internal handle points to a rooted location. This
   26.38 - * subtle difference makes handles easy for embedders, but somewhat
   26.39 - * cumbersome internally.
   26.40 - */
   26.41 -template <typename T>
   26.42 -class Handle
   26.43 -{
   26.44 -    T * const *thingp_;
   26.45 -
   26.46 -  public:
   26.47 -    Handle(const Handle &other) {
   26.48 -        thingp_ = other.address();
   26.49 -    }
   26.50 -    template <typename S> Handle(const Handle<S> &handle) {
   26.51 -        typeCheck<S>();
   26.52 -        thingp_ = reinterpret_cast<T * const *>(handle.address());
   26.53 -    }
   26.54 -    template <typename S> inline Handle(const Local<S> &local);
   26.55 -    template <typename S> inline Handle(const ScopedRoot<S> &root);
   26.56 -
   26.57 -  public:
   26.58 -    T *operator ->() {
   26.59 -        return *thingp_;
   26.60 -    }
   26.61 -    T *operator *() {
   26.62 -        return *thingp_;
   26.63 -    }
   26.64 -    operator T *() { return *thingp_; }
   26.65 -    operator bool() const {
   26.66 -        return thingp_ && *thingp_;
   26.67 -    }
   26.68 -    T * const *address() const {
   26.69 -        return thingp_;
   26.70 -    }
   26.71 -
   26.72 -  private:
   26.73 -    template <typename S>
   26.74 -    void typeCheck() {
   26.75 -#ifndef NDEBUG
   26.76 -        T *v1 = NULL;
   26.77 -        S *v2 = NULL;
   26.78 -        v1 = v2;
   26.79 -        (void)v1;
   26.80 -#endif
   26.81 -    }
   26.82 -};
   26.83 -
   26.84 -template <typename T>
   26.85 -class Local
   26.86 -{
   26.87 -    friend class Zone;
   26.88 -
   26.89 -    Zone *zone_;
   26.90 -    T *thing_;
   26.91 -    Local<Object> *prev_;
   26.92 -
   26.93 -    Local<Object> *prev() {
   26.94 -        return prev_;
   26.95 -    }
   26.96 -    Local<Object> *toRaw() {
   26.97 -        return reinterpret_cast<Local<Object>*>(this);
   26.98 -    }
   26.99 -
  26.100 -  public:
  26.101 -    // These are implemented in Zone.h.
  26.102 -    inline explicit Local(Zone *zone, T *thing = NULL);
  26.103 -    inline ~Local();
  26.104 -
  26.105 -    const Local &operator =(T *thing) {
  26.106 -        thing_ = thing;
  26.107 -        return *this;
  26.108 -    }
  26.109 -    T *operator ->() const {
  26.110 -        return operator *();
  26.111 -    }
  26.112 -    T *operator *() const {
  26.113 -        return thing_;
  26.114 -    }
  26.115 -    operator bool () const {
  26.116 -        return !!thing_;
  26.117 -    }
  26.118 -    bool operator !=(const Local &other) {
  26.119 -        return thing_ != other.thing_;
  26.120 -    }
  26.121 -
  26.122 -    Object **address() {
  26.123 -        return (Object **)&thing_;
  26.124 -    }
  26.125 -    Object * const *address() const {
  26.126 -        return (Object * const *)&thing_;
  26.127 -    }
  26.128 -    T **ref() {
  26.129 -        return &thing_;
  26.130 -    }
  26.131 -    operator T *() {
  26.132 -        return thing_;
  26.133 -    }
  26.134 -
  26.135 -  private:
  26.136 -    // Disallow heap allocation.
  26.137 -    void *operator new(size_t size);
  26.138 -    void *operator new[](size_t size);
  26.139 -
  26.140 -    // Disallow copy construction.
  26.141 -    Local(const Local<T> &other);
  26.142 -    Local &operator =(const Local &other);
  26.143 -};
  26.144 -
  26.145 -// A ScopedRoot is a special kind of handle for storing references on the
  26.146 -// heap in bulk.
  26.147 -template <typename T>
  26.148 -class ScopedRoot
  26.149 -{
  26.150 -    T **thingp_;
  26.151 -
  26.152 -  private:
  26.153 -    // This is implemented in Zone.h.
  26.154 -    inline T **make(T *other);
  26.155 -
  26.156 -    void assign(T *other) {
  26.157 -        *thingp_ = other;
  26.158 -    }
  26.159 -
  26.160 -  public:
  26.161 -    ScopedRoot();
  26.162 -
  26.163 -    // This is implemented in Zone.h.
  26.164 -    inline ScopedRoot(T *thing);
  26.165 -
  26.166 -    ScopedRoot &operator =(const ScopedRoot<T> &other) {
  26.167 -        assign(*other);
  26.168 -        return *this;
  26.169 -    }
  26.170 -    ScopedRoot &operator =(T *other) {
  26.171 -        assign(other);
  26.172 -        return *this;
  26.173 -    }
  26.174 -    T *operator ->() const {
  26.175 -        return operator *();
  26.176 -    }
  26.177 -    T *operator *() const {
  26.178 -        return *thingp_;
  26.179 -    }
  26.180 -    operator T *() const {
  26.181 -        return *thingp_;
  26.182 -    }
  26.183 -    operator bool () const {
  26.184 -        return !!*thingp_;
  26.185 -    }
  26.186 -    T **address() const {
  26.187 -        return thingp_;
  26.188 -    }
  26.189 -};
  26.190 -
  26.191 -template <typename T> template <typename S> inline
  26.192 -Handle<T>::Handle(const Local<S> &local)
  26.193 -{
  26.194 -    typeCheck<S>();
  26.195 -    thingp_ = reinterpret_cast<T * const *>(local.address());
  26.196 -}
  26.197 -
  26.198 -template <typename T> template <typename S> inline
  26.199 -Handle<T>::Handle(const ScopedRoot<S> &root)
  26.200 -{
  26.201 -    typeCheck<S>();
  26.202 -    thingp_ = reinterpret_cast<T * const *>(root.address());
  26.203 -}
  26.204 -
  26.205 -}
  26.206 -
  26.207 -#endif // _include_jitcraft_rooting_h_
    27.1 --- a/jitcraft/HashTable.h	Tue Jul 24 23:53:34 2012 -0700
    27.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    27.3 @@ -1,424 +0,0 @@
    27.4 -/*
    27.5 - * Copyright (C) 2012 David Anderson
    27.6 - *
    27.7 - * This file is part of JITCraft.
    27.8 - *
    27.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   27.10 - * the terms of the GNU General Public License as published by the Free
   27.11 - * Software Foundation, either version 3 of the License, or (at your option)
   27.12 - * any later version.
   27.13 - * 
   27.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   27.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   27.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   27.17 - *
   27.18 - * You should have received a copy of the GNU General Public License along with
   27.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   27.20 - */
   27.21 -#ifndef _INCLUDE_KEIMA_HASHTABLE_H_
   27.22 -#define _INCLUDE_KEIMA_HASHTABLE_H_
   27.23 -
   27.24 -#include <new>
   27.25 -#include <limits.h>
   27.26 -#include "Utility.h"
   27.27 -
   27.28 -namespace ke {
   27.29 -
   27.30 -template <typename T>
   27.31 -class HashTableEntry
   27.32 -{
   27.33 -    uint32 hash_;
   27.34 -    T t_;
   27.35 -
   27.36 -  public:
   27.37 -    static const uint32 kFreeHash = 0;
   27.38 -    static const uint32 kRemovedHash = 1;
   27.39 -
   27.40 -  public:
   27.41 -    void setHash(uint32 hash) {
   27.42 -        hash_ = hash;
   27.43 -    }
   27.44 -    uint32 hash() const {
   27.45 -        return hash_;
   27.46 -    }
   27.47 -    void setRemoved() {
   27.48 -        hash_ = kRemovedHash;
   27.49 -        t_ = T();
   27.50 -    }
   27.51 -    void construct() {
   27.52 -        hash_ = kFreeHash;
   27.53 -        new (&t_) T();
   27.54 -    }
   27.55 -    void destruct() {
   27.56 -        t_.~T();
   27.57 -    }
   27.58 -    bool removed() const {
   27.59 -        return hash_ == kRemovedHash;
   27.60 -    }
   27.61 -    bool free() const {
   27.62 -        return hash_ == kFreeHash;
   27.63 -    }
   27.64 -    bool isLive() const {
   27.65 -        return hash_ > kRemovedHash;
   27.66 -    }
   27.67 -    T &payload() {
   27.68 -        return t_;
   27.69 -    }
   27.70 -    bool sameHash(uint32 hash) const {
   27.71 -        return hash_ == hash;
   27.72 -    }
   27.73 -};
   27.74 -
   27.75 -template <typename HashPolicy, typename AllocPolicy>
   27.76 -class HashTable : public AllocPolicy
   27.77 -{
   27.78 -    friend class iterator;
   27.79 -
   27.80 -    typedef typename HashPolicy::Payload Payload;
   27.81 -    typedef HashTableEntry<Payload> Entry;
   27.82 -
   27.83 -    uint32 capacity_;
   27.84 -    uint32 nelements_;
   27.85 -    uint32 ndeleted_;
   27.86 -    Entry *table_;
   27.87 -    uint32 minCapacity_;
   27.88 -
   27.89 -  private:
   27.90 -    static const uint32 kMinCapacity = 16;
   27.91 -    static const uint32 kMaxCapacity = INT_MAX / sizeof(Entry);
   27.92 -
   27.93 -    template <typename Key>
   27.94 -    uint32 computeHash(const Key &key) {
   27.95 -        // Multiply by golden ratio.
   27.96 -        uint32 hash = HashPolicy::hash(key) * 0x9E3779B9;
   27.97 -        if (hash == Entry::kFreeHash || hash == Entry::kRemovedHash)
   27.98 -            hash += 2;
   27.99 -        return hash;
  27.100 -    }
  27.101 -
  27.102 -    Entry *createTable(uint32 capacity) {
  27.103 -        assert(capacity <= kMaxCapacity);
  27.104 -
  27.105 -        Entry *table = (Entry *)this->malloc(capacity * sizeof(Entry));
  27.106 -        if (!table)
  27.107 -            return NULL;
  27.108 -
  27.109 -        for (size_t i = 0; i < capacity; i++)
  27.110 -            table[i].construct();
  27.111 -
  27.112 -        return table;
  27.113 -    }
  27.114 -
  27.115 -  public:
  27.116 -    class Result
  27.117 -    {
  27.118 -        friend class HashTable;
  27.119 -
  27.120 -        Entry *entry_;
  27.121 -
  27.122 -        Entry &entry() {
  27.123 -            return *entry_;
  27.124 -        }
  27.125 -
  27.126 -      public:
  27.127 -        Result(Entry *entry)
  27.128 -          : entry_(entry)
  27.129 -        { }
  27.130 -
  27.131 -        Payload * operator ->() {
  27.132 -            return entry_->payload();
  27.133 -        }
  27.134 -        Payload & operator *() {
  27.135 -            return entry_->payload();
  27.136 -        }
  27.137 -
  27.138 -        bool found() const {
  27.139 -            return entry_->isLive();
  27.140 -        }
  27.141 -    };
  27.142 -
  27.143 -    class Insert : public Result
  27.144 -    {
  27.145 -        uint32 hash_;
  27.146 -
  27.147 -      public:
  27.148 -        Insert(Entry *entry, uint32 hash)
  27.149 -          : Result(entry),
  27.150 -            hash_(hash)
  27.151 -        {
  27.152 -        }
  27.153 -
  27.154 -        uint32 hash() const {
  27.155 -            return hash_;
  27.156 -        }
  27.157 -    };
  27.158 -
  27.159 -  private:
  27.160 -    class Probulator {
  27.161 -        uint32 hash_;
  27.162 -        uint32 capacity_;
  27.163 -
  27.164 -      public:
  27.165 -        Probulator(uint32 hash, uint32 capacity)
  27.166 -          : hash_(hash),
  27.167 -            capacity_(capacity)
  27.168 -        {
  27.169 -            assert(IsPowerOfTwo(capacity_)); 
  27.170 -        }
  27.171 -
  27.172 -        uint32 entry() const {
  27.173 -            return hash_ & (capacity_ - 1);
  27.174 -        }
  27.175 -        uint32 next() {
  27.176 -            hash_++;
  27.177 -            return entry();
  27.178 -        }
  27.179 -    };
  27.180 -
  27.181 -    bool underloaded() const {
  27.182 -        // Check if the table is underloaded: < 25% entries used.
  27.183 -        return (capacity_ > kMinCapacity) && (nelements_ + ndeleted_ < capacity_ / 4);
  27.184 -    }
  27.185 -    bool overloaded() const {
  27.186 -        // Grow if the table is overloaded: > 75% entries used.
  27.187 -        return (nelements_ + ndeleted_) > ((capacity_ / 2) + (capacity_ / 4));
  27.188 -    }
  27.189 -
  27.190 -    bool shrink() {
  27.191 -        if ((capacity_ >> 1) < minCapacity_)
  27.192 -            return true;
  27.193 -        return changeCapacity(capacity_ >> 1);
  27.194 -    }
  27.195 -    
  27.196 -    bool grow() {
  27.197 -        assert(IsPowerOfTwo(kMaxCapacity));
  27.198 -        if (capacity_ >= kMaxCapacity) {
  27.199 -            this->reportAllocationOverflow();
  27.200 -            return false;
  27.201 -        }
  27.202 -        return changeCapacity(capacity_ << 1);
  27.203 -    }
  27.204 -
  27.205 -    bool changeCapacity(uint32 newCapacity) {
  27.206 -        assert(newCapacity <= kMaxCapacity);
  27.207 -
  27.208 -        Entry *newTable = createTable(newCapacity);
  27.209 -        if (!newTable)
  27.210 -            return false;
  27.211 -
  27.212 -        Entry *oldTable = table_;
  27.213 -        uint32 oldCapacity = capacity_;
  27.214 -
  27.215 -        table_ = newTable;
  27.216 -        capacity_ = newCapacity;
  27.217 -        ndeleted_ = 0;
  27.218 -
  27.219 -        for (uint32 i = 0; i < oldCapacity; i++) {
  27.220 -            Entry &oldEntry = oldTable[i];
  27.221 -            if (oldEntry.isLive()) {
  27.222 -                Insert p = insertUnique(oldEntry.hash());
  27.223 -                p.entry().setHash(p.hash());
  27.224 -                p.entry().payload() = oldEntry.payload();
  27.225 -            }
  27.226 -            oldEntry.destruct();
  27.227 -        }
  27.228 -        this->free(oldTable);
  27.229 -
  27.230 -        return true;
  27.231 -    }
  27.232 -
  27.233 -    // For use when the key is known to be unique.
  27.234 -    Insert insertUnique(uint32 hash) {
  27.235 -        Probulator probulator(hash, capacity_);
  27.236 -
  27.237 -        Entry *e = &table_[probulator.entry()];
  27.238 -        for (;;) {
  27.239 -            if (e->free() || e->removed())
  27.240 -                break;
  27.241 -            e = &table_[probulator.next()];
  27.242 -        }
  27.243 -
  27.244 -        return Insert(e, hash);
  27.245 -    }
  27.246 -
  27.247 -    template <typename Key>
  27.248 -    Result lookup(const Key &key) {
  27.249 -        uint32 hash = computeHash(key);
  27.250 -        Probulator probulator(hash, capacity_);
  27.251 -
  27.252 -        Entry *e = &table_[probulator.entry()];
  27.253 -        for (;;) {
  27.254 -            if (e->free())
  27.255 -                break;
  27.256 -            if (e->isLive() &&
  27.257 -                e->sameHash(hash) &&
  27.258 -                HashPolicy::matches(key, e->payload()))
  27.259 -            {
  27.260 -                return Result(e);
  27.261 -            }
  27.262 -            e = &table_[probulator.next()];
  27.263 -        }
  27.264 -
  27.265 -        return Result(e);
  27.266 -    }
  27.267 -
  27.268 -    template <typename Key>
  27.269 -    Insert lookupForAdd(const Key &key) {
  27.270 -        uint32 hash = computeHash(key);
  27.271 -        Probulator probulator(hash, capacity_);
  27.272 -
  27.273 -        Entry *e = &table_[probulator.entry()];
  27.274 -        for (;;) {
  27.275 -            if (!e->isLive())
  27.276 -                break;
  27.277 -            if (e->sameHash(hash) && HashPolicy::matches(key, e->payload()))
  27.278 -                break;
  27.279 -            e = &table_[probulator.next()];
  27.280 -        }
  27.281 -
  27.282 -        return Insert(e, hash);
  27.283 -    }
  27.284 -
  27.285 -    bool add(Insert &i) {
  27.286 -        assert(!i.found());
  27.287 -
  27.288 -        // If the entry is deleted, just re-use the slot.
  27.289 -        if (i.entry().removed()) {
  27.290 -            ndeleted_--;
  27.291 -            return true;
  27.292 -        }
  27.293 -
  27.294 -        // Otherwise, see if we're at max capacity.
  27.295 -        if (nelements_ == kMaxCapacity) {
  27.296 -            this->reportAllocationOverflow();
  27.297 -            return false;
  27.298 -        }
  27.299 -
  27.300 -        // Check if the table is over or underloaded. The table is always at
  27.301 -        // least 25% free, so this check is enough to guarantee one free slot.
  27.302 -        // (Without one free slot, insertion search could infinite loop.)
  27.303 -        uint32 oldCapacity = capacity_;
  27.304 -        if (!checkDensity())
  27.305 -            return false;
  27.306 -
  27.307 -        // If the table changed size, we need to find a new insertion point.
  27.308 -        // Note that a removed entry is impossible: either we caught it above,
  27.309 -        // or we just resized and no entries are removed.
  27.310 -        if (capacity_ != oldCapacity)
  27.311 -            i = insertUnique(i.hash());
  27.312 -
  27.313 -        i.entry().setHash(i.hash());
  27.314 -        nelements_++;
  27.315 -
  27.316 -        return true;
  27.317 -    }
  27.318 -
  27.319 -    void remove(Entry &e) {
  27.320 -        assert(e.isLive());
  27.321 -        e.setRemoved();
  27.322 -        ndeleted_++;
  27.323 -        nelements_--;
  27.324 -    }
  27.325 -
  27.326 -  public:
  27.327 -    HashTable(AllocPolicy ap)
  27.328 -      : AllocPolicy(ap),
  27.329 -        capacity_(0),
  27.330 -        nelements_(0),
  27.331 -        ndeleted_(0),
  27.332 -        table_(NULL),
  27.333 -        minCapacity_(kMinCapacity)
  27.334 -    {
  27.335 -    }
  27.336 -
  27.337 -    ~HashTable()
  27.338 -    {
  27.339 -        for (uint32 i = 0; i < capacity_; i++)
  27.340 -            table_[i].destruct();
  27.341 -        this->free(table_);
  27.342 -    }
  27.343 -
  27.344 -    bool init(uint32 capacity = 0) {
  27.345 -        if (capacity < kMinCapacity)
  27.346 -            capacity = kMinCapacity;
  27.347 -        else if (capacity > kMaxCapacity)
  27.348 -            capacity = kMaxCapacity;
  27.349 -
  27.350 -        minCapacity_ = capacity;
  27.351 -
  27.352 -        assert(IsPowerOfTwo(capacity));
  27.353 -        capacity_ = capacity;
  27.354 -
  27.355 -        table_ = createTable(capacity_);
  27.356 -        if (!table_)
  27.357 -            return false;
  27.358 -
  27.359 -        return true;
  27.360 -    }
  27.361 -
  27.362 -    template <typename Key>
  27.363 -    Result find(const Key &key) {
  27.364 -        return lookup(key);
  27.365 -    }
  27.366 -
  27.367 -    template <typename Key>
  27.368 -    Insert findForAdd(const Key &key) {
  27.369 -        return lookupForAdd(key);
  27.370 -    }
  27.371 -
  27.372 -    bool add(Insert &i, const Payload &payload) {
  27.373 -        if (!add(i))
  27.374 -            return false;
  27.375 -        *i = payload;
  27.376 -        return true;
  27.377 -    }
  27.378 -
  27.379 -    bool checkDensity() {
  27.380 -        if (underloaded())
  27.381 -            return shrink(); 
  27.382 -        if (overloaded())
  27.383 -            return grow();
  27.384 -        return true;
  27.385 -    }
  27.386 -
  27.387 -  public:
  27.388 -    class iterator
  27.389 -    {
  27.390 -        HashTable *table_;
  27.391 -        Entry *i_;
  27.392 -        Entry *end_;
  27.393 -
  27.394 -      public:
  27.395 -        iterator(HashTable *table)
  27.396 -          : table_(table),
  27.397 -            i_(table->table_),
  27.398 -            end_(table->table_ + table->capacity_)
  27.399 -        {
  27.400 -            while (i_ < end_ && !i_->isLive())
  27.401 -                i_++;
  27.402 -        }
  27.403 -
  27.404 -        bool empty() const {
  27.405 -            return i_ == end_;
  27.406 -        }
  27.407 -
  27.408 -        void erase() {
  27.409 -            assert(!empty());
  27.410 -            table_->remove(*i_);
  27.411 -        }
  27.412 -
  27.413 -        const Payload &operator *() const {
  27.414 -            return i_->payload();
  27.415 -        }
  27.416 -
  27.417 -        void next() {
  27.418 -            do {
  27.419 -                i_++;
  27.420 -            } while (i_ < end_ && !i_->isLive());
  27.421 -        }
  27.422 -    };
  27.423 -};
  27.424 -
  27.425 -}
  27.426 -
  27.427 -#endif // _INCLUDE_KEIMA_HASHTABLE_H_
    28.1 --- a/jitcraft/Heap-inl.h	Tue Jul 24 23:53:34 2012 -0700
    28.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    28.3 @@ -1,118 +0,0 @@
    28.4 -/* vim: set ts=4 sw=4 tw=99 et:
    28.5 - *
    28.6 - * Copyright (C) 2012 David Anderson
    28.7 - *
    28.8 - * This file is part of JITCraft.
    28.9 - *
   28.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   28.11 - * the terms of the GNU General Public License as published by the Free
   28.12 - * Software Foundation, either version 3 of the License, or (at your option)
   28.13 - * any later version.
   28.14 - * 
   28.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   28.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   28.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   28.18 - *
   28.19 - * You should have received a copy of the GNU General Public License along with
   28.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   28.21 - */
   28.22 -#ifndef _include_jitcraft_heap_inl_h_
   28.23 -#define _include_jitcraft_heap_inl_h_
   28.24 -
   28.25 -#include "Heap.h"
   28.26 -#include "Spaces-inl.h"
   28.27 -
   28.28 -namespace ke {
   28.29 -
   28.30 -static inline Object *
   28.31 -InitAddressIntoObject(Address address, Map *map)
   28.32 -{
   28.33 -    uintptr_t untagged = reinterpret_cast<uintptr_t>(address);
   28.34 -    assert(IsAligned(untagged, kObjectAlignment));
   28.35 -
   28.36 -    Object *obj = reinterpret_cast<Object *>(address);
   28.37 -    obj->init(map);
   28.38 -    return obj;
   28.39 -}
   28.40 -
   28.41 -inline Address
   28.42 -Heap::newObject(size_t bytes, Tenure age)
   28.43 -{
   28.44 -    if (bytes >= HeapChunk::kLargeObjectThreshold)
   28.45 -        return newLargeObject(bytes);
   28.46 -
   28.47 -    if (age == Tenure_Stack) {
   28.48 -        if (Address addr = newStackObject(bytes))
   28.49 -            return addr;
   28.50 -    }
   28.51 -
   28.52 -#if 0
   28.53 -    if (age == Tenure_Default) {
   28.54 -        if (Address addr = newSpace_.allocate(bytes))
   28.55 -            return addr;
   28.56 -
   28.57 -        scavenge();
   28.58 -        if (Address addr = newSpace_.allocate(bytes))
   28.59 -            return addr;
   28.60 -    }
   28.61 -#endif
   28.62 -
   28.63 -    // Try an old-space allocation.
   28.64 -    if (Address addr = newOldObject(bytes))
   28.65 -        return addr;
   28.66 -
   28.67 -    // Uh-oh - perform a last-ditch collection.
   28.68 -    reclaim();
   28.69 -
   28.70 -    return newOldObject(bytes);
   28.71 -}
   28.72 -
   28.73 -inline Object *
   28.74 -Heap::allocate(Handle<Map> map, size_t bytes, Tenure age)
   28.75 -{
   28.76 -    size_t actualBytes = Align(bytes, kObjectAlignment);
   28.77 -
   28.78 -    // All objects must be at least two words.
   28.79 -    assert(actualBytes >= sizeof(Object *) * 2);
   28.80 -
   28.81 -    Address address = newObject(actualBytes, age);
   28.82 -    if (!address) {
   28.83 -        reportOutOfMemory();
   28.84 -        return NULL;
   28.85 -    }
   28.86 -    return InitAddressIntoObject(address, map);
   28.87 -}
   28.88 -
   28.89 -inline Address
   28.90 -Heap::newStackObject(size_t bytes)
   28.91 -{
   28.92 -    return lifoSpace_.allocate(bytes);
   28.93 -}
   28.94 -
   28.95 -inline Address
   28.96 -Heap::newOldObject(size_t bytes)
   28.97 -{
   28.98 -    return oldSpace_.allocate(bytes);
   28.99 -}
  28.100 -
  28.101 -inline Address
  28.102 -Heap::newLargeObject(size_t bytes)
  28.103 -{
  28.104 -    if (Address address = largeSpace_.allocate(bytes))
  28.105 -        return address;
  28.106 -
  28.107 -    reclaim();
  28.108 -
  28.109 -    return largeSpace_.allocate(bytes);
  28.110 -}
  28.111 -
  28.112 -inline void
  28.113 -Object::write(Zone *zone, Object **ptr, Object *obj)
  28.114 -{
  28.115 -    *ptr = obj;
  28.116 -}
  28.117 -
  28.118 -}
  28.119 -
  28.120 -#endif // _include_jitcraft_heap_inl_h_
  28.121 -
    29.1 --- a/jitcraft/Heap.cpp	Tue Jul 24 23:53:34 2012 -0700
    29.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    29.3 @@ -1,372 +0,0 @@
    29.4 -/* vim: set ts=4 sw=4 tw=99 et:
    29.5 - *
    29.6 - * Copyright (C) 2012 David Anderson
    29.7 - *
    29.8 - * This file is part of JITCraft.
    29.9 - *
   29.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   29.11 - * the terms of the GNU General Public License as published by the Free
   29.12 - * Software Foundation, either version 3 of the License, or (at your option)
   29.13 - * any later version.
   29.14 - * 
   29.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   29.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   29.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   29.18 - *
   29.19 - * You should have received a copy of the GNU General Public License along with
   29.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   29.21 - */
   29.22 -#include "Heap.h"
   29.23 -#include "Heap-inl.h"
   29.24 -#include "Spaces-inl.h"
   29.25 -#include "VirtualObjectVisitor.h"
   29.26 -#include "ObjectVisitor.h"
   29.27 -#include "Zone.h"
   29.28 -#include "StringPool.h"
   29.29 -
   29.30 -using namespace ke;
   29.31 -
   29.32 -static const size_t kMarkStackSize = 256 * kKB;
   29.33 -
   29.34 -Heap::Heap(Zone *zone)
   29.35 -  : zone_(zone),
   29.36 -    markStack_(NULL),
   29.37 -    oldSpace_(zone),
   29.38 -    mapSpace_(zone)
   29.39 -{
   29.40 -}
   29.41 -
   29.42 -bool
   29.43 -Heap::initialize()
   29.44 -{
   29.45 -    if (!lifoSpace_.initialize())
   29.46 -        return false;
   29.47 -    if (!oldSpace_.initialize())
   29.48 -        return false;
   29.49 -    if (!mapSpace_.initialize())
   29.50 -        return false;
   29.51 -    if (!largeSpace_.initialize())
   29.52 -        return false;
   29.53 -
   29.54 -    markStack_ = malloc(kMarkStackSize);
   29.55 -    if (!markStack_)
   29.56 -        return false;
   29.57 -
   29.58 -    if ((metaMap_ = allocateMap(MapKind_Meta, sizeof(Map))) == NULL)
   29.59 -        return false;
   29.60 -    metaMap_->init(metaMap_);
   29.61 -
   29.62 -    return true;
   29.63 -}
   29.64 -
   29.65 -Heap::~Heap()
   29.66 -{
   29.67 -    free(markStack_);
   29.68 -}
   29.69 -
   29.70 -Map *
   29.71 -Heap::allocateMap(MapKind kind, size_t bytes)
   29.72 -{
   29.73 -    size_t actualBytes = Align(bytes, kObjectAlignment);
   29.74 -
   29.75 -    Address addr = mapSpace_.allocate(actualBytes);
   29.76 -    if (!addr) {
   29.77 -        reportOutOfMemory();
   29.78 -        return NULL;
   29.79 -    }
   29.80 -
   29.81 -    // Note that we use a NULL type initially, and reinterpret-cast to get
   29.82 -    // the Type pointer, so we can allocate the self-referencing meta type.
   29.83 -    Object *obj = InitAddressIntoObject(addr, NULL);
   29.84 -    Map *map = reinterpret_cast<Map *>(obj);
   29.85 -    map->setKind(kind);
   29.86 -    return map;
   29.87 -}
   29.88 -
   29.89 -// To avoid marking recursively, we use a worklist to manage the marking
   29.90 -// process. Algorithm:
   29.91 -//
   29.92 -// (1) While the mark stack is not empty:
   29.93 -//  (a) Remove object |o| from the mark stack.
   29.94 -//  (b) For each reference |p| in object |o|,
   29.95 -//   (i)  Mark |p| as Black.
   29.96 -//   (ii) Push |p| onto the mark stack.
   29.97 -//   (iv) If the mark stack overflowde, mark |p| as Grey.
   29.98 -//
   29.99 -// We run this algorithm after pushing every root object onto the mark stack.
  29.100 -// After all roots have been processed, it may be that the mark stack
  29.101 -// overflowed. In this case, we use the following algorithm:
  29.102 -//
  29.103 -//  (1) while the mark stack has overflowed:
  29.104 -//   (a) Search the heap for grey objects, adding as many as possible to the
  29.105 -//       mark stack.
  29.106 -//   (b) Run the mark-stack-emptying algorithm above.
  29.107 -//
  29.108 -// This algorithm is guaranteed to terminate, because even if there are more
  29.109 -// grey objects than mark stack capacity, we eventually all objects will
  29.110 -// become grey, and grey objects are not re-pushed onto the mark stack. Thus,
  29.111 -// eventually, all objects will become black.
  29.112 -//
  29.113 -namespace ke {
  29.114 -class MarkStack
  29.115 -{
  29.116 -    Object **base_;
  29.117 -    Object **top_;
  29.118 -    Object **end_;
  29.119 -    bool overflowed_;
  29.120 -
  29.121 -  public:
  29.122 -    MarkStack(Object **base, Object **end)
  29.123 -      : base_(base),
  29.124 -        top_(base),
  29.125 -        end_(end),
  29.126 -        overflowed_(false)
  29.127 -    {
  29.128 -    }
  29.129 -
  29.130 -    void pushBlack(Object *ptr) {
  29.131 -        assert(HeapChunk::IsBlack(HeapChunk::GetMarkBit(ptr)));
  29.132 -        if (top_ >= end_) {
  29.133 -            MarkBit bit = HeapChunk::GetMarkBit(ptr);
  29.134 -            HeapChunk::BlackToGrey(bit);
  29.135 -            overflowed_ = true;
  29.136 -            return;
  29.137 -        }
  29.138 -        *top_++ = ptr;
  29.139 -    }
  29.140 -
  29.141 -    Object *pop() {
  29.142 -        assert(!empty());
  29.143 -        return *--top_;
  29.144 -    }
  29.145 -    bool overflowed() const {
  29.146 -        return overflowed_;
  29.147 -    }
  29.148 -    bool empty() const {
  29.149 -        return base_ == top_;
  29.150 -    }
  29.151 -    void reset() {
  29.152 -        assert(empty());
  29.153 -        overflowed_ = true;
  29.154 -    }
  29.155 -};
  29.156 -} // namespace ke
  29.157 -
  29.158 -// Iterates over an object's body, pushing its referenced objects onto the
  29.159 -// mark stack.
  29.160 -class MarkingVisitor : public ObjectVisitor<VirtualObjectVisitor>
  29.161 -{
  29.162 -    MarkStack &stack_;
  29.163 -
  29.164 -  public:
  29.165 -    MarkingVisitor(MarkStack &stack)
  29.166 -      : stack_(stack)
  29.167 -    {
  29.168 -    }
  29.169 -
  29.170 -    void visit(Object **ptr) {
  29.171 -        if (!*ptr)
  29.172 -            return;
  29.173 -
  29.174 -        Object *obj = *ptr;
  29.175 -
  29.176 -        // If the object is grey, we'll find it later when searching the heap.
  29.177 -        // If the object is black, it's already been scsanned.
  29.178 -        MarkBit bit = HeapChunk::GetMarkBit(obj);
  29.179 -        if (HeapChunk::IsBlackOrGrey(bit))
  29.180 -            return;
  29.181 -
  29.182 -        // Place the object in the stack and optimistically mark it black. If
  29.183 -        // the stack overflows, it'll become grey instead.
  29.184 -        HeapChunk::WhiteToBlack(bit);
  29.185 -        stack_.pushBlack(obj);
  29.186 -    }
  29.187 -};
  29.188 -
  29.189 -static void
  29.190 -ProcessMarkStack(MarkStack &stack)
  29.191 -{
  29.192 -    MarkingVisitor visitor(stack);
  29.193 -
  29.194 -    while (!stack.empty()) {
  29.195 -        Object *obj = stack.pop();
  29.196 -        assert(HeapChunk::IsBlack(HeapChunk::GetMarkBit(obj)));
  29.197 -
  29.198 -        visitor.iterate(obj);
  29.199 -    }
  29.200 -}
  29.201 -
  29.202 -class RootMarkingVisitor : public VirtualObjectVisitor
  29.203 -{
  29.204 -    MarkStack &stack_;
  29.205 -    MarkingVisitor visitor_;
  29.206 -
  29.207 -  public:
  29.208 -    RootMarkingVisitor(MarkStack &stack)
  29.209 -      : stack_(stack),
  29.210 -        visitor_(stack)
  29.211 -    {
  29.212 -    }
  29.213 -
  29.214 -    void visit(Object **ptr) {
  29.215 -        // Flush the stack after every new root. Note that the root gets pushed
  29.216 -        // as black; that's okay. If the mark stack overflows, its children are
  29.217 -        // guaranteed to be at least grey.
  29.218 -        visitor_.visit(ptr);
  29.219 -        ProcessMarkStack(stack_);
  29.220 -    }
  29.221 -};
  29.222 -
  29.223 -typedef ChunkObjectIteratorBase<ObjectSizeEvaluator> ChunkObjectIterator;
  29.224 -
  29.225 -static inline bool
  29.226 -EnqueueGreyObject(MarkStack &stack, Object *obj)
  29.227 -{
  29.228 -    assert(!stack.overflowed());
  29.229 -    MarkBit bit = HeapChunk::GetMarkBit(obj);
  29.230 -    if (HeapChunk::IsGrey(bit)) {
  29.231 -        HeapChunk::GreyToBlack(bit);
  29.232 -        stack.pushBlack(obj);
  29.233 -        return !stack.overflowed();
  29.234 -    }
  29.235 -    return true;
  29.236 -}
  29.237 -
  29.238 -static void
  29.239 -EnqueueGreyObjectsInChunks(MarkStack &stack, ChunkObjectIterator iter)
  29.240 -{
  29.241 -    for (Object *obj = iter.next(); obj; obj = iter.next()) {
  29.242 -        if (!EnqueueGreyObject(stack, obj))
  29.243 -            return;
  29.244 -    }
  29.245 -}
  29.246 -
  29.247 -static void
  29.248 -EnqueueGreyObjectsInLargeChunks(MarkStack &stack, HeapChunk *first)
  29.249 -{
  29.250 -    for (HeapChunk *chunk = first; chunk; chunk = chunk->next()) {
  29.251 -        Object *obj = reinterpret_cast<Object *>(chunk->first());
  29.252 -        if (!EnqueueGreyObject(stack, obj))
  29.253 -            return;
  29.254 -    }
  29.255 -}
  29.256 -
  29.257 -void
  29.258 -Heap::findGreyObjects(MarkStack &stack)
  29.259 -{
  29.260 -    EnqueueGreyObjectsInChunks(stack, lifoSpace_.begin(ObjectSizeEvaluator()));
  29.261 -    if (stack.overflowed())
  29.262 -        return;
  29.263 -
  29.264 -    EnqueueGreyObjectsInChunks(stack, mapSpace_.begin(ObjectSizeEvaluator()));
  29.265 -    if (stack.overflowed())
  29.266 -        return;
  29.267 -    
  29.268 -    EnqueueGreyObjectsInChunks(stack, oldSpace_.begin(ObjectSizeEvaluator()));
  29.269 -    if (stack.overflowed())
  29.270 -        return;
  29.271 -
  29.272 -    EnqueueGreyObjectsInLargeChunks(stack, largeSpace_.first());
  29.273 -    if (stack.overflowed())
  29.274 -        return;
  29.275 -}
  29.276 -
  29.277 -void
  29.278 -Heap::mark()
  29.279 -{
  29.280 -    Object **qbase = reinterpret_cast<Object **>(markStack_);
  29.281 -    Object **qend = qbase + (kMarkStackSize / sizeof(Object *));
  29.282 -    MarkStack stack(qbase, qend);
  29.283 -    RootMarkingVisitor visitor(stack);
  29.284 -
  29.285 -    // Attempt to mark all objects reachable from the root set.
  29.286 -    zone_->accept(&visitor);
  29.287 -    assert(stack.empty());
  29.288 -
  29.289 -    // If the stack overflowed, we need to look through the entire heap for
  29.290 -    // grey objects to rescan. We keep doing this until there are no grey
  29.291 -    // objects left.
  29.292 -    while (stack.overflowed()) {
  29.293 -        stack.reset();
  29.294 -        findGreyObjects(stack);
  29.295 -        ProcessMarkStack(stack);
  29.296 -    }
  29.297 -}
  29.298 -
  29.299 -// Use the mark bits to scan for live objects, and mark the regions in
  29.300 -// between them as free.
  29.301 -static void
  29.302 -SweepOldSpaceChunk(OldSpace *space, HeapChunk *chunk)
  29.303 -{
  29.304 -    uint32 *markbits = chunk->markBits();
  29.305 -    uint32 *markbitsEnd = markbits + HeapChunk::kMarkWords;
  29.306 -    Address freeStart = chunk->first();
  29.307 -
  29.308 -    // Scoot up to the first usable markword. Since memory is reserved for
  29.309 -    // mark bits, not all addresses are allocatable, so quite a few of the
  29.310 -    // initial mark bits are wasted. (1KB of mark bytes on x86.)
  29.311 -    markbits = HeapChunk::GetMarkBit(reinterpret_cast<Object *>(chunk->first())).word();
  29.312 -
  29.313 -    uint32 bits = *markbits;
  29.314 -    for (;;) {
  29.315 -        while (bits) {
  29.316 -            uint32 bit = FindRightmostBit(bits);
  29.317 -            Address object = HeapChunk::FromMarkBit(chunk, markbits, bit);
  29.318 -
  29.319 -            assert(object >= freeStart);
  29.320 -            if (freeStart != object)
  29.321 -                space->markRegionFree(freeStart, object - freeStart);
  29.322 -
  29.323 -            Object *obj = reinterpret_cast<Object *>(object);
  29.324 -            freeStart = object + SizeOfObject(obj, obj->map());
  29.325 -
  29.326 -            // Since black is 10, we never need to clear the next bit.
  29.327 -            bits &= ~(1 << bit);
  29.328 -        }
  29.329 -        markbits++;
  29.330 -        bits = *markbits;
  29.331 -        if (markbits >= markbitsEnd)
  29.332 -            break;
  29.333 -    }
  29.334 -
  29.335 -    if (freeStart == chunk->base())
  29.336 -        chunk->setEmpty();
  29.337 -    else if (freeStart != chunk->end())
  29.338 -        space->markRegionFree(freeStart, chunk->end() - freeStart);
  29.339 -}
  29.340 -
  29.341 -static void
  29.342 -SweepOldSpace(OldSpace *space)
  29.343 -{
  29.344 -    space->resetFreeList();
  29.345 -    for (HeapChunk *chunk = space->first(); chunk; chunk = chunk->next()) {
  29.346 -        SweepOldSpaceChunk(space, chunk);
  29.347 -        chunk->resetMarkBits();
  29.348 -    }
  29.349 -    space->freeUnusedPages();
  29.350 -}
  29.351 -
  29.352 -void
  29.353 -Heap::sweep()
  29.354 -{
  29.355 -    // Before destroying mark bits, sweep weak roots.
  29.356 -    zone_->symbols()->sweep();
  29.357 -
  29.358 -    // Note: we don't bother sweeping the LIFO space.
  29.359 -    SweepOldSpace(&mapSpace_);
  29.360 -    SweepOldSpace(&oldSpace_);
  29.361 -    largeSpace_.sweep();
  29.362 -}
  29.363 -
  29.364 -void
  29.365 -Heap::reclaim()
  29.366 -{
  29.367 -    mark();
  29.368 -    sweep();
  29.369 -}
  29.370 -
  29.371 -void
  29.372 -Heap::reportOutOfMemory()
  29.373 -{
  29.374 -    zone_->reportOutOfMemory();
  29.375 -}
    30.1 --- a/jitcraft/Heap.h	Tue Jul 24 23:53:34 2012 -0700
    30.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    30.3 @@ -1,143 +0,0 @@
    30.4 -/* vim: set ts=4 sw=4 tw=99 et:
    30.5 - *
    30.6 - * Copyright (C) 2012 David Anderson
    30.7 - *
    30.8 - * This file is part of JITCraft.
    30.9 - *
   30.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   30.11 - * the terms of the GNU General Public License as published by the Free
   30.12 - * Software Foundation, either version 3 of the License, or (at your option)
   30.13 - * any later version.
   30.14 - * 
   30.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   30.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   30.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   30.18 - *
   30.19 - * You should have received a copy of the GNU General Public License along with
   30.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   30.21 - */
   30.22 -#ifndef _include_jitcraft_heap_h_
   30.23 -#define _include_jitcraft_heap_h_
   30.24 -
   30.25 -#include "Utility.h"
   30.26 -#include "Spaces.h"
   30.27 -#include "Barriers.h"
   30.28 -#include "Objects.h"
   30.29 -#include "Handles.h"
   30.30 -
   30.31 -namespace ke {
   30.32 -
   30.33 -class Zone;
   30.34 -class MarkStack;
   30.35 -
   30.36 -// Heap-allocated objects go here. Heaps are thread-local. The heap contains
   30.37 -// four spaces:
   30.38 -//
   30.39 -//    LIFO Space:  Used for objects that may be stack-allocated.
   30.40 -//    Old Space:   Used for objects that are expected to be long-lived, or that
   30.41 -//                 survive one collection.
   30.42 -//    Large Space: Used for objects that are so large they should never be
   30.43 -//                 moved between spaces.
   30.44 -//
   30.45 -// ALLOCATING AN OBJECT DOES NOT ZERO ITS MEMORY.
   30.46 -// ALLOCATING AN OBJECT DOES NOT ZERO ITS MEMORY!
   30.47 -//
   30.48 -// ---------------------------------------------------------------------------
   30.49 -//
   30.50 -// The following is a high-level overview of how garbage collection works in
   30.51 -// Keima. Detailed notes are present in Heap.cpp.
   30.52 -//
   30.53 -// THE TRI-COLOR INVARIANT: Via an object's mark bits, we maintain the
   30.54 -//   property that an object that has been fully marked may never reference a
   30.55 -//   dead object. Objects exist in three states during collection: unmarked
   30.56 -//   (white), scheduled for marking (grey), and fully marked (black).
   30.57 -//
   30.58 -//   When initiating collection, all objects are white. Objects in the root
   30.59 -//   set are made grey. The marking process takes grey objects and marks that
   30.60 -//   each child object is live: if the child is white, it becomes grey. Once
   30.61 -//   all children are grey or black, the parent grey object can become black,
   30.62 -//   as it has been fully traversed.
   30.63 -//
   30.64 -//   The result of this process is that when there are no more grey objects,
   30.65 -//   then we are guaranteed that all black objects are live, and all white
   30.66 -//   objects are dead.
   30.67 -//
   30.68 -// MAJOR COLLECTIONS are performed periodically, when either a given memory
   30.69 -//   threshold has been reached, or when requested by the host application.
   30.70 -//   They are also performed if no memory can be allocated.
   30.71 -//
   30.72 -//   Major collections are extremely slow; they require full heap traversal,
   30.73 -//   which can take more than a second on very large heaps. However, they
   30.74 -//   have the greatest chance at reclaiming all syntactically dead objects.
   30.75 -//
   30.76 -// SWEEPING is performed after major collections. The free space in between
   30.77 -//   live objects is added to a free list. Tenured allocations are then
   30.78 -//   performed in the free space, if possible.
   30.79 -//
   30.80 -class Heap
   30.81 -{
   30.82 -    Zone *zone_;
   30.83 -    HeapStack lifoSpace_;
   30.84 -    OldSpace mapSpace_;
   30.85 -    OldSpace oldSpace_;
   30.86 -    LargeObjectSpace largeSpace_;
   30.87 -
   30.88 -    Map *metaMap_;
   30.89 -
   30.90 -    // This is a big hunk o' memory used for marking iteratively. Eventually,
   30.91 -    // this will be replaced by the inactive semispace in the nursery.
   30.92 -    void *markStack_;
   30.93 -
   30.94 -  public:
   30.95 -    enum Tenure {
   30.96 -        // Default, objects go into the nursery.
   30.97 -        Tenure_Default,
   30.98 -        
   30.99 -        // If objects are proven to not escape the stack, they can go into
  30.100 -        // a LIFO arena. Allocation on the LIFO arena is not guaranteed to
  30.101 -        // succeed; thus, objects may still be allocated in other arenas.
  30.102 -        Tenure_Stack,
  30.103 -
  30.104 -        // Objects that should not go into the nursery (i.e. are expected
  30.105 -        // to be long-living) go here.
  30.106 -        Tenure_Old
  30.107 -    };
  30.108 -
  30.109 -  private:
  30.110 -    inline Address newLargeObject(size_t bytes);
  30.111 -    inline Address newOldObject(size_t bytes);
  30.112 -    inline Address newStackObject(size_t bytes);
  30.113 -    inline Address newObject(size_t bytes, Tenure pretenure);
  30.114 -
  30.115 -  private:
  30.116 -    void findGreyObjects(MarkStack &stack);
  30.117 -    void mark();
  30.118 -    void sweep();
  30.119 -
  30.120 -    void reportOutOfMemory();
  30.121 -
  30.122 -  public:
  30.123 -    Heap(Zone *zone);
  30.124 -    ~Heap();
  30.125 -    bool initialize();
  30.126 -
  30.127 -    inline Object *allocate(Handle<Map> map, size_t byes, Tenure pretenure);
  30.128 -    Map *allocateMap(MapKind kind, size_t bytes);
  30.129 -
  30.130 -    Map *metaMap() {
  30.131 -        return metaMap_;
  30.132 -    }
  30.133 -    inline Address lifoPosition() const {
  30.134 -        return lifoSpace_.position();
  30.135 -    }
  30.136 -    inline void unwindLifo(Address to) {
  30.137 -        lifoSpace_.unwind(to);
  30.138 -    }
  30.139 -
  30.140 -    // Perform a full garbage collection.
  30.141 -    void reclaim();
  30.142 -};
  30.143 -
  30.144 -}
  30.145 -
  30.146 -#endif //_include_jitcraft_heap_h_
    31.1 --- a/jitcraft/InlineList.h	Tue Jul 24 23:53:34 2012 -0700
    31.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    31.3 @@ -1,129 +0,0 @@
    31.4 -/*
    31.5 - * Copyright (C) 2004-2012 David Anderson
    31.6 - *
    31.7 - * This file is part of SourcePawn.
    31.8 - *
    31.9 - * SourcePawn is free software: you can redistribute it and/or modify it under
   31.10 - * the terms of the GNU General Public License as published by the Free
   31.11 - * Software Foundation, either version 3 of the License, or (at your option)
   31.12 - * any later version.
   31.13 - * 
   31.14 - * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
   31.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   31.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   31.17 - *
   31.18 - * You should have received a copy of the GNU General Public License along with
   31.19 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
   31.20 - */
   31.21 -#ifndef _include_ke_inline_list_h_
   31.22 -#define _include_ke_inline_list_h_
   31.23 -
   31.24 -#include <stddef.h>
   31.25 -
   31.26 -namespace ke {
   31.27 -
   31.28 -template <typename T> class InlineList;
   31.29 -
   31.30 -template <typename T>
   31.31 -class InlineListNode
   31.32 -{
   31.33 -    friend class InlineList<T>;
   31.34 -
   31.35 -  public:
   31.36 -    InlineListNode()
   31.37 -      : next_(NULL),
   31.38 -        prev_(NULL)
   31.39 -    {
   31.40 -    }
   31.41 -
   31.42 -    InlineListNode(InlineListNode *next, InlineListNode *prev)
   31.43 -      : next_(next),
   31.44 -        prev_(prev)
   31.45 -    {
   31.46 -    }
   31.47 -
   31.48 -  protected:
   31.49 -    InlineListNode *next_;
   31.50 -    InlineListNode *prev_;
   31.51 -};
   31.52 -
   31.53 -template <typename T>
   31.54 -class InlineList
   31.55 -{
   31.56 -    typedef InlineListNode<T> Node;
   31.57 -
   31.58 -    Node head_;
   31.59 -
   31.60 -  public:
   31.61 -    InlineList()
   31.62 -      : head_(&head_, &head_)
   31.63 -    {
   31.64 -    }
   31.65 -
   31.66 -  public:
   31.67 -    class iterator
   31.68 -    {
   31.69 -        friend class InlineList;
   31.70 -        Node *iter_;
   31.71 -        
   31.72 -      public:
   31.73 -        iterator(Node *iter)
   31.74 -          : iter_(iter)
   31.75 -        {
   31.76 -        }
   31.77 -
   31.78 -        iterator & operator++() {
   31.79 -            iter_ = iter_->next_;
   31.80 -            return *this;
   31.81 -        }
   31.82 -        iterator operator ++(int) {
   31.83 -            iterator old(*this);
   31.84 -            iter_ = iter_->next_;
   31.85 -            return old;
   31.86 -        }
   31.87 -        T * operator *() {
   31.88 -            return static_cast<T *>(iter_);
   31.89 -        }
   31.90 -        T * operator ->() {
   31.91 -            return static_cast<T *>(iter_);
   31.92 -        }
   31.93 -        bool operator !=(const iterator &where) const {
   31.94 -            return iter_ != where.iter_;
   31.95 -        }
   31.96 -        bool operator ==(const iterator &where) const {
   31.97 -            return iter_ == where.iter_;
   31.98 -        }
   31.99 -        iterator prev() const {
  31.100 -            return iterator(iter_->prev_);
  31.101 -        }
  31.102 -        iterator next() const {
  31.103 -            return iterator(iter_->next_);
  31.104 -        }
  31.105 -    };
  31.106 -
  31.107 -    iterator begin() {
  31.108 -        return iterator(head_.next_);
  31.109 -    }
  31.110 -    iterator end() {
  31.111 -        return iterator(&head_);
  31.112 -    }
  31.113 -    void append(Node *t) {
  31.114 -        t->prev_ = head_.prev_;
  31.115 -        t->next_ = &head_;
  31.116 -        head_.prev_->next_ = t;
  31.117 -        head_.prev_ = t;
  31.118 -    }
  31.119 -    iterator erase(iterator i) {
  31.120 -        iterator next = ++i;
  31.121 -        remove(i.iter_);
  31.122 -        return next;
  31.123 -    }
  31.124 -    void remove(Node *t) {
  31.125 -        t->prev_->next_ = t->next_;
  31.126 -        t->next_->prev_ = t->prev_;
  31.127 -    }
  31.128 -};
  31.129 -
  31.130 -}
  31.131 -
  31.132 -#endif // _include_ke_inline_list_h_
    32.1 --- a/jitcraft/Interpreter.cpp	Tue Jul 24 23:53:34 2012 -0700
    32.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    32.3 @@ -1,937 +0,0 @@
    32.4 -/* vim: set ts=4 sw=4 tw=99 et:
    32.5 - *
    32.6 - * Copyright (C) 2012 David Anderson
    32.7 - *
    32.8 - * This file is part of JITCraft.
    32.9 - *
   32.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   32.11 - * the terms of the GNU General Public License as published by the Free
   32.12 - * Software Foundation, either version 3 of the License, or (at your option)
   32.13 - * any later version.
   32.14 - * 
   32.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   32.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   32.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   32.18 - *
   32.19 - * You should have received a copy of the GNU General Public License along with
   32.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   32.21 - */
   32.22 -#include "Interpreter.h"
   32.23 -#include "Modules.h"
   32.24 -#include "Zone.h"
   32.25 -#include "Types.h"
   32.26 -#include "Array.h"
   32.27 -#include "Reference.h"
   32.28 -#include "Strings.h"
   32.29 -#include "Environments.h"
   32.30 -#include "Heap-inl.h"
   32.31 -
   32.32 -using namespace ke;
   32.33 -
   32.34 -#define PUSH_I32(top, value)    \
   32.35 -    do {                        \
   32.36 -        top.sp->i32 = value;    \
   32.37 -        top.sp++;               \
   32.38 -   } while (0)
   32.39 -
   32.40 -#define PUSH_F(top, value)      \
   32.41 -    do {                        \
   32.42 -        top.sp->f = value;      \
   32.43 -        top.sp++;               \
   32.44 -   } while (0)
   32.45 -
   32.46 -static inline int
   32.47 -POP_I32(Top &top)
   32.48 -{
   32.49 -    int value = top.sp[-1].i32;
   32.50 -    top.sp--;
   32.51 -    return value;
   32.52 -}
   32.53 -
   32.54 -static inline float
   32.55 -POP_F(Top &top)
   32.56 -{
   32.57 -    float value = top.sp[-1].f;
   32.58 -    top.sp--;
   32.59 -    return value;
   32.60 -}
   32.61 -
   32.62 -// Pawn's original semantics specify some kind of floor operation, so
   32.63 -// (8 / -3 == -3) and (-8 / 3 == -1). The SourcePawn 1 compiler (spcomp) uses
   32.64 -// the upstream algorithm when constant folding. However the SourcePawn 1 JIT
   32.65 -// does not. My guess is that Borja freaked out seeing the 13-instruction x86
   32.66 -// sequence necessary to get this functionality (I vaguely recall a thread
   32.67 -// where we discussed this with Mark Peter? But the ITB forums are gone...),
   32.68 -// and we just decided to break the damn thing. So SP1 was inconsistent, but
   32.69 -// we are not. And for completeness, we assert that the C compiler does the
   32.70 -// right thing, since C89 leaves it unspecified.
   32.71 -STATIC_ASSERT(8 / -3 == -2);
   32.72 -STATIC_ASSERT(-8 / 3 == -2);
   32.73 -
   32.74 -static inline bool
   32.75 -PushNewRef(Zone *zone, Top &top, void *location, Heap::Tenure tenure)
   32.76 -{
   32.77 -    Reference *ref = Reference::NewStack(zone, location, tenure);
   32.78 -    if (!ref)
   32.79 -        return false;
   32.80 -    top.sp->ref = ref;
   32.81 -    top.sp++;
   32.82 -    return true;
   32.83 -}
   32.84 -
   32.85 -// Generate an array with completely static sizes.
   32.86 -static Array *
   32.87 -GenerateArray(Zone *zone, Handle<ArrayMap> map, Heap::Tenure tenure)
   32.88 -{
   32.89 -    assert(map->type()->elements() != -1);
   32.90 -
   32.91 -    Local<Array> array(zone, Array::New(zone, map, map->type()->elements(), tenure));
   32.92 -    if (!array)
   32.93 -        return NULL;
   32.94 -
   32.95 -    if (map->type()->levels() == 1)
   32.96 -        return array;
   32.97 -
   32.98 -    Local<ArrayMap> contained(zone, map->contained());
   32.99 -    Local<Array> sub(zone);
  32.100 -    for (unsigned i = 0; i < unsigned(map->type()->elements()); i++) {
  32.101 -        sub = GenerateArray(zone, contained, tenure);
  32.102 -        if (!sub)
  32.103 -            return NULL;
  32.104 -        array->writeObject(zone, i, sub);
  32.105 -    }
  32.106 -
  32.107 -    return array;
  32.108 -}
  32.109 -
  32.110 -static bool
  32.111 -CopyArray(Zone *zone, Array *source, Array *dest)
  32.112 -{
  32.113 -    assert(source->type()->levels() == 1);
  32.114 -    assert(dest->type()->levels() == 1);
  32.115 -    assert(source->type()->contained()->primitive() ==
  32.116 -           dest->type()->contained()->primitive());
  32.117 -    assert(source->nelements() >= dest->nelements());
  32.118 -    assert(dest->elementSize() == source->elementSize());
  32.119 -
  32.120 -    memcpy(source->vec(), dest->vec(), dest->nelements() * dest->elementSize());
  32.121 -    return true;
  32.122 -}
  32.123 -
  32.124 -static bool
  32.125 -InvokeNative(Zone *zone, Handle<Native> native, void *identity, LocalSlot *args, unsigned argc,
  32.126 -             int *result)
  32.127 -{
  32.128 -    NativeArgs guard;
  32.129 -
  32.130 -    if (!zone->stack().pushNativeFrame(native, guard, argc + 1))
  32.131 -        return false;
  32.132 -
  32.133 -    intptr_t *cells = guard.args();
  32.134 -
  32.135 -    // params[0] == argc, in ISPE
  32.136 -    cells[0] = argc;
  32.137 -
  32.138 -    // Pass the formal arguments.
  32.139 -    Local<Type> type(zone, native->type());
  32.140 -    Local<Type> param(zone);
  32.141 -    for (unsigned i = 0; i < type->parameters()->length(); i++) {
  32.142 -        param = type->parameterAt(i);
  32.143 -        
  32.144 -        // For floats, we rely on the aliasing of |i32| and |f|.
  32.145 -        LocalSlot &arg = args[-int(i) - 1];
  32.146 -        if (param->isInt32() || param->isFloat()) {
  32.147 -            cells[i + 1] = arg.i32;
  32.148 -        } else if (param->isReference()) {
  32.149 -            cells[i + 1] = reinterpret_cast<intptr_t>(arg.ref->location());
  32.150 -        } else {
  32.151 -            assert(param->isArray());
  32.152 -            cells[i + 1] = reinterpret_cast<intptr_t>(arg.array->vec());
  32.153 -        }
  32.154 -    }
  32.155 -
  32.156 -    // For variadic arguments, the compiler left either arrays or references.
  32.157 -    for (unsigned i = type->parameters()->length(); i < argc; i++) {
  32.158 -        LocalSlot &arg = args[-int(i) - 1];
  32.159 -
  32.160 -        if (arg.obj->is(MapKind_Reference)) {
  32.161 -            cells[i + 1] = reinterpret_cast<intptr_t>(arg.ref->location());
  32.162 -        } else {
  32.163 -            assert(arg.obj->is(MapKind_Array));
  32.164 -            cells[i + 1] = reinterpret_cast<intptr_t>(arg.array->vec());
  32.165 -        }
  32.166 -    }
  32.167 -
  32.168 -    typedef intptr_t (*INVOKE)(void *, intptr_t *);
  32.169 -    INVOKE invoke = (INVOKE)native->function();
  32.170 -    *result = invoke(identity, cells);
  32.171 -
  32.172 -    return !zone->hasPendingException();
  32.173 -}
  32.174 -
  32.175 -bool
  32.176 -ke::Interpret(Zone *zone, Frame *entryFrame, LocalSlot *result)
  32.177 -{
  32.178 -    Top &top = *zone->stack().top();
  32.179 -    if (!entryFrame)
  32.180 -        entryFrame = top.fp;
  32.181 -
  32.182 -    LocalSlot *locals = entryFrame->locals();
  32.183 -
  32.184 -    for (;;) {
  32.185 -        Opcode op = Opcode(*top.pc);
  32.186 -        switch (op) {
  32.187 -
  32.188 -case OP_NOP:
  32.189 -    break;
  32.190 -
  32.191 -case OP_INT:
  32.192 -    PUSH_I32(top, READ_INT32(top.pc));
  32.193 -    break;
  32.194 -
  32.195 -case OP_FLOAT:
  32.196 -    PUSH_F(top, READ_FLOAT(top.pc));
  32.197 -    break;
  32.198 -
  32.199 -case OP_RETURN:
  32.200 -case OP_RETURNVOID:
  32.201 -case OP_STOP:
  32.202 -{
  32.203 -    if (op == OP_RETURN)
  32.204 -        *result = *--top.sp;
  32.205 -
  32.206 -    if (top.fp == entryFrame)
  32.207 -        goto done;
  32.208 -
  32.209 -    // This must not GC.
  32.210 -    zone->stack().popInlineFrame();
  32.211 -    locals = top.fp->locals();
  32.212 -
  32.213 -    if (op == OP_RETURN)
  32.214 -        *top.sp++ = *result;
  32.215 -
  32.216 -    top.pc += OpcodeInfo[*top.pc].length;
  32.217 -    continue;
  32.218 -}
  32.219 -
  32.220 -case OP_POP:
  32.221 -{
  32.222 -    top.sp--;
  32.223 -    break;
  32.224 -}
  32.225 -
  32.226 -#define RELATIONAL_JUMP(op)                 \
  32.227 -    {                                       \
  32.228 -        int right = POP_I32(top);           \
  32.229 -        int left = POP_I32(top);            \
  32.230 -        if (left op right) {                \
  32.231 -            top.pc += READ_INT32(top.pc);   \
  32.232 -            continue;                       \
  32.233 -        }                                   \
  32.234 -    }
  32.235 -
  32.236 -case OP_JL:
  32.237 -    RELATIONAL_JUMP(<);
  32.238 -    break;
  32.239 -
  32.240 -case OP_JLE:
  32.241 -    RELATIONAL_JUMP(<=);
  32.242 -    break;
  32.243 -
  32.244 -case OP_JG:
  32.245 -    RELATIONAL_JUMP(>);
  32.246 -    break;
  32.247 -
  32.248 -case OP_JGE:
  32.249 -    RELATIONAL_JUMP(>=);
  32.250 -    break;
  32.251 -
  32.252 -case OP_JEQ:
  32.253 -    RELATIONAL_JUMP(==);
  32.254 -    break;
  32.255 -
  32.256 -case OP_JNE:
  32.257 -    RELATIONAL_JUMP(!=);
  32.258 -    break;
  32.259 -
  32.260 -#undef RELATIONAL_JUMP
  32.261 -
  32.262 -case OP_JT:
  32.263 -{
  32.264 -    int value = POP_I32(top);
  32.265 -    if (value) {
  32.266 -        top.pc += READ_INT32(top.pc);
  32.267 -        continue;
  32.268 -    }
  32.269 -    break;
  32.270 -}
  32.271 -
  32.272 -case OP_JF:
  32.273 -{
  32.274 -    int value = POP_I32(top);
  32.275 -    if (!value) {
  32.276 -        top.pc += READ_INT32(top.pc);
  32.277 -        continue;
  32.278 -    }
  32.279 -    break;
  32.280 -}
  32.281 -
  32.282 -#define RELATIONAL_JUMP_F(op)               \
  32.283 -    {                                       \
  32.284 -        float right = POP_F(top);           \
  32.285 -        float left = POP_F(top);            \
  32.286 -        if (left op right) {                \
  32.287 -            top.pc += READ_INT32(top.pc);   \
  32.288 -            continue;                       \
  32.289 -        }                                   \
  32.290 -    }
  32.291 -
  32.292 -case OP_JL_F:
  32.293 -    RELATIONAL_JUMP_F(<);
  32.294 -    break;
  32.295 -
  32.296 -case OP_JLE_F:
  32.297 -    RELATIONAL_JUMP_F(<=);
  32.298 -    break;
  32.299 -
  32.300 -case OP_JG_F:
  32.301 -    RELATIONAL_JUMP_F(>);
  32.302 -    break;
  32.303 -
  32.304 -case OP_JGE_F:
  32.305 -    RELATIONAL_JUMP_F(>=);
  32.306 -    break;
  32.307 -
  32.308 -case OP_JEQ_F:
  32.309 -    RELATIONAL_JUMP_F(==);
  32.310 -    break;
  32.311 -
  32.312 -case OP_JNE_F:
  32.313 -    RELATIONAL_JUMP_F(!=);
  32.314 -    break;
  32.315 -
  32.316 -case OP_JT_F:
  32.317 -{
  32.318 -    float value = POP_F(top);
  32.319 -    if (value) {
  32.320 -        top.pc += READ_INT32(top.pc);
  32.321 -        continue;
  32.322 -    }
  32.323 -    break;
  32.324 -}
  32.325 -
  32.326 -case OP_JF_F:
  32.327 -{
  32.328 -    float value = POP_F(top);
  32.329 -    if (!value) {
  32.330 -        top.pc += READ_INT32(top.pc);
  32.331 -        continue;
  32.332 -    }
  32.333 -    break;
  32.334 -}
  32.335 -
  32.336 -case OP_JUMP:
  32.337 -    top.pc += READ_INT32(top.pc);
  32.338 -    continue;
  32.339 -
  32.340 -case OP_GETLOCAL:
  32.341 -{
  32.342 -    int slot = READ_INT32(top.pc);
  32.343 -    *top.sp++ = locals[slot];
  32.344 -    break;
  32.345 -}
  32.346 -
  32.347 -case OP_SETLOCAL:
  32.348 -{
  32.349 -    int slot = READ_INT32(top.pc);
  32.350 -    locals[slot] = top.sp[-1];
  32.351 -    break;
  32.352 -}
  32.353 -
  32.354 -case OP_ADD:
  32.355 -{
  32.356 -    top.sp[-2].i32 = top.sp[-2].i32 + top.sp[-1].i32;
  32.357 -    top.sp--;
  32.358 -    break;
  32.359 -}
  32.360 -
  32.361 -case OP_SUB:
  32.362 -{
  32.363 -    top.sp[-2].i32 = top.sp[-2].i32 - top.sp[-1].i32;
  32.364 -    top.sp--;
  32.365 -    break;
  32.366 -}
  32.367 -
  32.368 -case OP_MUL:
  32.369 -{
  32.370 -    top.sp[-2].i32 = top.sp[-2].i32 * top.sp[-1].i32;
  32.371 -    top.sp--;
  32.372 -    break;
  32.373 -}
  32.374 -
  32.375 -case OP_DIV:
  32.376 -{
  32.377 -    if (top.sp[-1].i32 == 0) {
  32.378 -        zone->reportError(Message_IntegerDivideByZero);
  32.379 -        goto error;
  32.380 -    }
  32.381 -    top.sp[-2].i32 = top.sp[-2].i32 / top.sp[-1].i32;
  32.382 -    top.sp--;
  32.383 -    break;
  32.384 -}
  32.385 -
  32.386 -case OP_MOD:
  32.387 -{
  32.388 -    if (top.sp[-1].i32 == 0) {
  32.389 -        zone->reportError(Message_IntegerDivideByZero);
  32.390 -        goto error;
  32.391 -    }
  32.392 -    top.sp[-2].i32 = top.sp[-2].i32 % top.sp[-1].i32;
  32.393 -    top.sp--;
  32.394 -    break;
  32.395 -}
  32.396 -
  32.397 -case OP_LT:
  32.398 -{
  32.399 -    top.sp[-2].i32 = top.sp[-2].i32 < top.sp[-1].i32;
  32.400 -    top.sp--;
  32.401 -    break;
  32.402 -}
  32.403 -
  32.404 -case OP_LE:
  32.405 -{
  32.406 -    top.sp[-2].i32 = top.sp[-2].i32 <= top.sp[-1].i32;
  32.407 -    top.sp--;
  32.408 -    break;
  32.409 -}
  32.410 -
  32.411 -case OP_GT:
  32.412 -{
  32.413 -    top.sp[-2].i32 = top.sp[-2].i32 > top.sp[-1].i32;
  32.414 -    top.sp--;
  32.415 -    break;
  32.416 -}
  32.417 -
  32.418 -case OP_GE:
  32.419 -{
  32.420 -    top.sp[-2].i32 = top.sp[-2].i32 >= top.sp[-1].i32;
  32.421 -    top.sp--;
  32.422 -    break;
  32.423 -}
  32.424 -
  32.425 -case OP_EQ:
  32.426 -{
  32.427 -    top.sp[-2].i32 = (top.sp[-2].i32 == top.sp[-1].i32);
  32.428 -    top.sp--;
  32.429 -    break;
  32.430 -}
  32.431 -
  32.432 -case OP_NE:
  32.433 -{
  32.434 -    top.sp[-2].i32 = (top.sp[-2].i32 != top.sp[-1].i32);
  32.435 -    top.sp--;
  32.436 -    break;
  32.437 -}
  32.438 -
  32.439 -case OP_ADD_F:
  32.440 -{
  32.441 -    top.sp[-2].f = top.sp[-2].f + top.sp[-1].f;
  32.442 -    top.sp--;
  32.443 -    break;
  32.444 -}
  32.445 -
  32.446 -case OP_SUB_F:
  32.447 -{
  32.448 -    top.sp[-2].f = top.sp[-2].f - top.sp[-1].f;
  32.449 -    top.sp--;
  32.450 -    break;
  32.451 -}
  32.452 -
  32.453 -case OP_MUL_F:
  32.454 -{
  32.455 -    top.sp[-2].f = top.sp[-2].f * top.sp[-1].f;
  32.456 -    top.sp--;
  32.457 -    break;
  32.458 -}
  32.459 -
  32.460 -case OP_DIV_F:
  32.461 -{
  32.462 -    top.sp[-2].f = top.sp[-2].f / top.sp[-1].f;
  32.463 -    top.sp--;
  32.464 -    break;
  32.465 -}
  32.466 -
  32.467 -case OP_LT_F:
  32.468 -{
  32.469 -    top.sp[-2].f = top.sp[-2].f < top.sp[-1].f;
  32.470 -    top.sp--;
  32.471 -    break;
  32.472 -}
  32.473 -
  32.474 -case OP_LE_F:
  32.475 -{
  32.476 -    top.sp[-2].f = top.sp[-2].f <= top.sp[-1].f;
  32.477 -    top.sp--;
  32.478 -    break;
  32.479 -}
  32.480 -
  32.481 -case OP_GT_F:
  32.482 -{
  32.483 -    top.sp[-2].f = top.sp[-2].f > top.sp[-1].f;
  32.484 -    top.sp--;
  32.485 -    break;
  32.486 -}
  32.487 -
  32.488 -case OP_GE_F:
  32.489 -{
  32.490 -    top.sp[-2].f = top.sp[-2].f >= top.sp[-1].f;
  32.491 -    top.sp--;
  32.492 -    break;
  32.493 -}
  32.494 -
  32.495 -case OP_EQ_F:
  32.496 -{
  32.497 -    top.sp[-2].i32 = (top.sp[-2].f == top.sp[-1].f);
  32.498 -    top.sp--;
  32.499 -    break;
  32.500 -}
  32.501 -
  32.502 -case OP_NE_F:
  32.503 -{
  32.504 -    top.sp[-2].i32 = (top.sp[-2].f != top.sp[-1].f);
  32.505 -    top.sp--;
  32.506 -    break;
  32.507 -}
  32.508 -
  32.509 -case OP_SHL:
  32.510 -{
  32.511 -    top.sp[-2].i32 = top.sp[-2].i32 << top.sp[-1].i32;
  32.512 -    top.sp--;
  32.513 -    break;
  32.514 -}
  32.515 -
  32.516 -case OP_SHR:
  32.517 -{
  32.518 -    top.sp[-2].i32 = top.sp[-2].i32 >> top.sp[-1].i32;
  32.519 -    top.sp--;
  32.520 -    break;
  32.521 -}
  32.522 -
  32.523 -case OP_USHR:
  32.524 -{
  32.525 -    top.sp[-2].i32 = unsigned(top.sp[-2].i32) << unsigned(top.sp[-1].i32);
  32.526 -    top.sp--;
  32.527 -    break;
  32.528 -}
  32.529 -
  32.530 -case OP_BITAND:
  32.531 -{
  32.532 -    top.sp[-2].i32 = top.sp[-2].i32 & top.sp[-1].i32;
  32.533 -    top.sp--;
  32.534 -    break;
  32.535 -}
  32.536 -
  32.537 -case OP_BITOR:
  32.538 -{
  32.539 -    top.sp[-2].i32 = top.sp[-2].i32 | top.sp[-1].i32;
  32.540 -    top.sp--;
  32.541 -    break;
  32.542 -}
  32.543 -
  32.544 -case OP_BITXOR:
  32.545 -{
  32.546 -    top.sp[-2].i32 = top.sp[-2].i32 ^ top.sp[-1].i32;
  32.547 -    top.sp--;
  32.548 -    break;
  32.549 -}
  32.550 -
  32.551 -case OP_BITNOT:
  32.552 -{
  32.553 -    top.sp[-1].i32 = ~top.sp[-1].i32;
  32.554 -    break;
  32.555 -}
  32.556 -
  32.557 -case OP_NOT:
  32.558 -{
  32.559 -    top.sp[-1].i32 = top.sp[-1].i32 ? 0 : 1;
  32.560 -    break;
  32.561 -}
  32.562 -
  32.563 -case OP_NOT_F:
  32.564 -{
  32.565 -    top.sp[-1].i32 = top.sp[-1].f ? 0 : 1;
  32.566 -    break;
  32.567 -}
  32.568 -
  32.569 -case OP_NEG:
  32.570 -{
  32.571 -    top.sp[-1].i32 = -top.sp[-1].i32;
  32.572 -    break;
  32.573 -}
  32.574 -
  32.575 -case OP_NEG_F:
  32.576 -{
  32.577 -    top.sp[-1].f = -top.sp[-1].f;
  32.578 -    break;
  32.579 -}
  32.580 -
  32.581 -case OP_CALL:
  32.582 -{
  32.583 -    Local<Function> newFun(zone, top.sp[-1].fun);
  32.584 -    top.sp--;
  32.585 -
  32.586 -    if (!zone->stack().pushInlineFrame(newFun))
  32.587 -        goto error;
  32.588 -
  32.589 -    locals = top.fp->locals();
  32.590 -    continue;
  32.591 -}
  32.592 -
  32.593 -case OP_GETARG:
  32.594 -{
  32.595 -    unsigned slot = READ_UINT32(top.pc);
  32.596 -    *top.sp++ = top.fp->arg(slot);
  32.597 -    break;
  32.598 -}
  32.599 -
  32.600 -case OP_SETARG:
  32.601 -{
  32.602 -    unsigned slot = READ_UINT32(top.pc);
  32.603 -    top.fp->arg(slot) = *--top.sp;
  32.604 -    break;
  32.605 -}
  32.606 -
  32.607 -case OP_BOUNDS:
  32.608 -{
  32.609 -    Array *array = top.sp[-2].array;
  32.610 -    int index = top.sp[-1].i32;
  32.611 -    if (index < 0 || unsigned(index) >= array->nelements()) {
  32.612 -        zone->reportError(Message_ArrayIndexOutOfBounds, index, array->nelements());
  32.613 -        goto error;
  32.614 -    }
  32.615 -    break;
  32.616 -}
  32.617 -
  32.618 -case OP_GETARRAY_I:
  32.619 -{
  32.620 -    Array *array = top.sp[-2].array;
  32.621 -    int index = top.sp[-1].i32;
  32.622 -    top.sp[-2].i32 = array->readInt32(index);
  32.623 -    top.sp--;
  32.624 -    break;
  32.625 -}
  32.626 -
  32.627 -case OP_GETARRAY_F:
  32.628 -{
  32.629 -    Array *array = top.sp[-2].array;
  32.630 -    int index = top.sp[-1].i32;
  32.631 -    top.sp[-2].f = array->readFloat(index);
  32.632 -    top.sp--;
  32.633 -    break;
  32.634 -}
  32.635 -
  32.636 -case OP_GETARRAY_C:
  32.637 -{
  32.638 -    Array *array = top.sp[-2].array;
  32.639 -    int index = top.sp[-1].i32;
  32.640 -    top.sp[-2].i32 = array->readChar(index);
  32.641 -    top.sp--;
  32.642 -    break;
  32.643 -}
  32.644 -
  32.645 -case OP_SETARRAY_I:
  32.646 -{
  32.647 -    Array *array = top.sp[-3].array;
  32.648 -    int index = top.sp[-2].i32;
  32.649 -    array->writeInt32(index, top.sp[-1].i32);
  32.650 -    top.sp[-3] = top.sp[-1];
  32.651 -    top.sp -= 2;
  32.652 -    break;
  32.653 -}
  32.654 -
  32.655 -case OP_SETARRAY_F:
  32.656 -{
  32.657 -    Array *array = top.sp[-3].array;
  32.658 -    int index = top.sp[-2].i32;
  32.659 -    array->writeFloat(index, top.sp[-1].f);
  32.660 -    top.sp[-3] = top.sp[-1];
  32.661 -    top.sp -= 2;
  32.662 -    break;
  32.663 -}
  32.664 -
  32.665 -case OP_SETARRAY_C:
  32.666 -{
  32.667 -    Array *array = top.sp[-3].array;
  32.668 -    int index = top.sp[-2].i32;
  32.669 -    array->writeChar(index, top.sp[-1].i32);
  32.670 -    top.sp[-3] = top.sp[-1];
  32.671 -    top.sp -= 2;
  32.672 -    break;
  32.673 -}
  32.674 -
  32.675 -case OP_GETARRAY_O:
  32.676 -{
  32.677 -    Array *array = top.sp[-2].array;
  32.678 -    int index = top.sp[-1].i32;
  32.679 -    top.sp[-2].array = Array::cast(array->readObject(index));
  32.680 -    top.sp--;
  32.681 -    break;
  32.682 -}
  32.683 -
  32.684 -case OP_CVT_I2F:
  32.685 -{
  32.686 -    int ival = POP_I32(top);
  32.687 -    float fval = (float)ival;
  32.688 -    PUSH_F(top, fval);
  32.689 -    break;
  32.690 -}
  32.691 -
  32.692 -case OP_NEWARRAY:
  32.693 -{
  32.694 -    Heap::Tenure tenure = (Heap::Tenure)top.pc[1];
  32.695 -    Local<ArrayMap> map(zone, ArrayMap::cast(top.fp->code()->map(READ_UINT32(top.pc + 1))));
  32.696 -    Array *array = GenerateArray(zone, map, tenure);
  32.697 -    if (!array)
  32.698 -        goto error;
  32.699 -    top.sp->obj = array;
  32.700 -    top.sp++;
  32.701 -    break;
  32.702 -}
  32.703 -
  32.704 -case OP_SAVELIFO:
  32.705 -{
  32.706 -    unsigned slot = READ_UINT32(top.pc);
  32.707 -    locals[slot].address = zone->heap().lifoPosition();
  32.708 -    break;
  32.709 -}
  32.710 -
  32.711 -case OP_UNWINDLIFO:
  32.712 -{
  32.713 -    unsigned slot = READ_UINT32(top.pc);
  32.714 -    zone->heap().unwindLifo(locals[slot].address);
  32.715 -    break;
  32.716 -}
  32.717 -
  32.718 -case OP_VARREF_LIFO:
  32.719 -{
  32.720 -    unsigned slot = READ_UINT32(top.pc);
  32.721 -    if (!PushNewRef(zone, top, &locals[slot], Heap::Tenure_Stack))
  32.722 -        goto error;
  32.723 -    break;
  32.724 -}
  32.725 -
  32.726 -case OP_ARGREF_LIFO:
  32.727 -{
  32.728 -    unsigned slot = READ_UINT32(top.pc);
  32.729 -    if (!PushNewRef(zone, top, &top.fp->arg(slot), Heap::Tenure_Stack))
  32.730 -        goto error;
  32.731 -    break;
  32.732 -}
  32.733 -
  32.734 -case OP_ARRAYREF_LIFO:
  32.735 -{
  32.736 -    Local<Array> array(zone, top.sp[-2].array);
  32.737 -    Local<Reference> ref(zone, Reference::NewArray(zone, array, top.sp[-1].i32, Heap::Tenure_Stack));
  32.738 -    if (!ref)
  32.739 -        goto error;
  32.740 -    top.sp[-2].ref = ref;
  32.741 -    top.sp--;
  32.742 -    break;
  32.743 -}
  32.744 -
  32.745 -case OP_SLOTREF_LIFO:
  32.746 -{
  32.747 -    Reference *ref = Reference::NewStack(zone, top.sp[-1], Heap::Tenure_Stack);
  32.748 -    if (!ref)
  32.749 -        goto error;
  32.750 -    top.sp[-1].ref = ref;
  32.751 -    break;
  32.752 -}
  32.753 -
  32.754 -case OP_GETREF_I:
  32.755 -{
  32.756 -    top.sp[-1].i32 = top.sp[-1].ref->getInt();
  32.757 -    break;
  32.758 -}
  32.759 -
  32.760 -case OP_SETREF_I:
  32.761 -{
  32.762 -    top.sp[-2].ref->setInt(top.sp[-1].i32);
  32.763 -    top.sp[-2].i32 = top.sp[-1].i32;
  32.764 -    top.sp--;
  32.765 -    break;
  32.766 -}
  32.767 -
  32.768 -case OP_GETREF_F:
  32.769 -{
  32.770 -    top.sp[-1].f = top.sp[-1].ref->getFloat();
  32.771 -    break;
  32.772 -}
  32.773 -
  32.774 -case OP_SETREF_F:
  32.775 -{
  32.776 -    top.sp[-2].ref->setFloat(top.sp[-1].f);
  32.777 -    top.sp[-2].f = top.sp[-1].f;
  32.778 -    break;
  32.779 -}
  32.780 -
  32.781 -case OP_OBJECT:
  32.782 -{
  32.783 -    top.sp->obj = top.fp->code()->object(READ_UINT32(top.pc));
  32.784 -    top.sp++;
  32.785 -    break;
  32.786 -}
  32.787 -
  32.788 -case OP_ARRAYCOPY:
  32.789 -{
  32.790 -    // Note for this assignment opcode, we return the left-hand side, not the
  32.791 -    // right, since in this case the result of the expression could be different.
  32.792 -    if (!CopyArray(zone, top.sp[-2].array, top.sp[-1].array))
  32.793 -        goto error;
  32.794 -    top.sp--;
  32.795 -    break;
  32.796 -}
  32.797 -
  32.798 -case OP_DUP:
  32.799 -{
  32.800 -    top.sp++;
  32.801 -    top.sp[-1] = top.sp[-2];
  32.802 -    break;
  32.803 -}
  32.804 -
  32.805 -case OP_DUP2:
  32.806 -{
  32.807 -    top.sp += 2;
  32.808 -    top.sp[-2] = top.sp[-4];
  32.809 -    top.sp[-1] = top.sp[-3];
  32.810 -    break;
  32.811 -}
  32.812 -
  32.813 -case OP_SWAP:
  32.814 -{
  32.815 -    LocalSlot slot = top.sp[-2];
  32.816 -    top.sp[-2] = top.sp[-1];
  32.817 -    top.sp[-1] = slot;
  32.818 -    break;
  32.819 -}
  32.820 -
  32.821 -case OP_ROLL3:
  32.822 -{
  32.823 -    LocalSlot slot = top.sp[-3];
  32.824 -    top.sp[-3] = top.sp[-2];
  32.825 -    top.sp[-2] = top.sp[-1];
  32.826 -    top.sp[-1] = slot;
  32.827 -    break;
  32.828 -}
  32.829 -
  32.830 -case OP_PICK2:
  32.831 -{
  32.832 -    top.sp++;
  32.833 -    top.sp[-1] = top.sp[-3];
  32.834 -    break;
  32.835 -}
  32.836 -
  32.837 -case OP_PICK3:
  32.838 -{
  32.839 -    top.sp++;
  32.840 -    top.sp[-1] = top.sp[-4];
  32.841 -    break;
  32.842 -}
  32.843 -
  32.844 -case OP_CALLNATIVE:
  32.845 -{
  32.846 -    unsigned index = READ_UINT32(top.pc);
  32.847 -    unsigned argc = READ_UINT32(top.pc + 4);
  32.848 -
  32.849 -    Local<Native> native(zone, Native::cast(top.fp->code()->module()->natives()->at(index)));
  32.850 -    if (!native->function()) {
  32.851 -        zone->reportError(Message_NativeNotBound, native->name()->chars());
  32.852 -        goto error;
  32.853 -    }
  32.854 -
  32.855 -    int result;
  32.856 -    void *nativeIdentity = top.fp->code()->module()->nativeIdentity();
  32.857 -    if (!InvokeNative(zone, native, nativeIdentity, top.sp, argc, &result))
  32.858 -        goto error;
  32.859 -
  32.860 -    top.sp -= argc;
  32.861 -    PUSH_I32(top, result);
  32.862 -    break;
  32.863 -}
  32.864 -
  32.865 -case OP_MODULE:
  32.866 -{
  32.867 -    top.sp++;
  32.868 -    top.sp[-1].module = top.fp->code()->module();
  32.869 -    break;
  32.870 -}
  32.871 -
  32.872 -case OP_GETMODULE_FN:
  32.873 -{
  32.874 -    top.sp[-1].fun = top.sp[-1].module->getFunction(READ_UINT32(top.pc));
  32.875 -    break;
  32.876 -}
  32.877 -
  32.878 -case OP_GETGLOBAL_I:
  32.879 -{
  32.880 -    unsigned slot = READ_UINT32(top.pc);
  32.881 -    top.sp++;
  32.882 -    top.sp[-1].i32 = top.fp->code()->module()->environment()->getInt32(slot);
  32.883 -    break;
  32.884 -}
  32.885 -
  32.886 -case OP_GETGLOBAL_F:
  32.887 -{
  32.888 -    unsigned slot = READ_UINT32(top.pc);
  32.889 -    top.sp++;
  32.890 -    top.sp[-1].f = top.fp->code()->module()->environment()->getFloat(slot);
  32.891 -    break;
  32.892 -}
  32.893 -
  32.894 -case OP_GETGLOBAL_O:
  32.895 -{
  32.896 -    unsigned slot = READ_UINT32(top.pc);
  32.897 -    top.sp++;
  32.898 -    top.sp[-1].obj = top.fp->code()->module()->environment()->getObject(slot);
  32.899 -    break;
  32.900 -}
  32.901 -
  32.902 -case OP_SETGLOBAL_I:
  32.903 -{
  32.904 -    unsigned slot = READ_UINT32(top.pc);
  32.905 -    top.fp->code()->module()->environment()->setInt32(slot, top.sp[-1].i32);
  32.906 -    break;
  32.907 -}
  32.908 -
  32.909 -case OP_SETGLOBAL_F:
  32.910 -{
  32.911 -    unsigned slot = READ_UINT32(top.pc);
  32.912 -    top.fp->code()->module()->environment()->setFloat(slot, top.sp[-1].f);
  32.913 -    break;
  32.914 -}
  32.915 -
  32.916 -case OP_SETGLOBAL_O:
  32.917 -{
  32.918 -    unsigned slot = READ_UINT32(top.pc);
  32.919 -    top.fp->code()->module()->environment()->setObject(slot, top.sp[-1].obj);
  32.920 -    break;
  32.921 -}
  32.922 -
  32.923 -default:
  32.924 -    assert(false);
  32.925 -    return false;
  32.926 -
  32.927 -        }
  32.928 -
  32.929 -        top.pc += OpcodeInfo[op].length;
  32.930 -    }
  32.931 -
  32.932 -done:
  32.933 -    return true;
  32.934 -
  32.935 -error:
  32.936 -    // Unwind frames until we can continue.
  32.937 -    while (top.fp != entryFrame)
  32.938 -        zone->stack().popInlineFrame();
  32.939 -    return false;
  32.940 -}
    33.1 --- a/jitcraft/Interpreter.h	Tue Jul 24 23:53:34 2012 -0700
    33.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    33.3 @@ -1,29 +0,0 @@
    33.4 -/*
    33.5 - * Copyright (C) 2012 David Anderson
    33.6 - *
    33.7 - * This file is part of JITCraft.
    33.8 - *
    33.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   33.10 - * the terms of the GNU General Public License as published by the Free
   33.11 - * Software Foundation, either version 3 of the License, or (at your option)
   33.12 - * any later version.
   33.13 - * 
   33.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   33.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   33.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   33.17 - *
   33.18 - * You should have received a copy of the GNU General Public License along with
   33.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   33.20 - */
   33.21 -#ifndef _include_jc_interpreter_h_
   33.22 -#define _include_jc_interpreter_h_
   33.23 -
   33.24 -#include "Stack.h"
   33.25 -
   33.26 -namespace ke {
   33.27 -
   33.28 -bool Interpret(Zone *zone, Frame *frame, LocalSlot *result);
   33.29 -
   33.30 -}
   33.31 -
   33.32 -#endif // _include_jc_interpreter_h_
    34.1 --- a/jitcraft/Makefile.in	Tue Jul 24 23:53:34 2012 -0700
    34.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    34.3 @@ -1,96 +0,0 @@
    34.4 -#vim: set ft=make: 
    34.5 -
    34.6 -CXX=@CXX@
    34.7 -CXXFLAGS=@CXXFLAGS@
    34.8 -srcdir=@srcdir@
    34.9 -VPATH=${srcdir}
   34.10 -TOOLS=${srcdir}/../build
   34.11 -CXXVENDOR=@CXXVENDOR@
   34.12 -PLATFORM="@PLATFORM@"
   34.13 -NULL =
   34.14 -
   34.15 -INCLUDES += 
   34.16 -CXXFLAGS += $(INCLUDES)
   34.17 -BASECXXFLAGS = -Wall -Werror -Wno-null-arithmetic -Wno-invalid-offsetof -g3 -O0
   34.18 -
   34.19 -CPPSRCS = \
   34.20 -	Array.cpp                  \
   34.21 -	BytecodeCompiler.cpp       \
   34.22 -	BytecodeEmitter.cpp	   \
   34.23 -	CompileContext.cpp         \
   34.24 -        Exception.cpp              \
   34.25 -        FixedArray.cpp             \
   34.26 -        Functions.cpp              \
   34.27 -	Heap.cpp                   \
   34.28 -        Interpreter.cpp            \
   34.29 -	Modules.cpp                \
   34.30 -	NameBinding.cpp            \
   34.31 -	Parser.cpp                 \
   34.32 -	Opcodes.cpp                \
   34.33 -	PoolAllocator.cpp          \
   34.34 -	Reference.cpp              \
   34.35 -	RootScopes.cpp             \
   34.36 -	Scanner.cpp                \
   34.37 -	Scopes.cpp                 \
   34.38 -	SemanticAnalysis.cpp       \
   34.39 -	Spaces.cpp                 \
   34.40 -	Stack.cpp                  \
   34.41 -	TypeManager.cpp            \
   34.42 -	Types.cpp                  \
   34.43 -	Zone.cpp                   \
   34.44 -	main.cpp                   \
   34.45 -	$(NULL)
   34.46 -
   34.47 -ifeq ("darwin", $(PLATFORM))
   34.48 -CPPSRCS += \
   34.49 -	Platform-Posix.cpp         \
   34.50 -	$(NULL)
   34.51 -endif
   34.52 -ifeq ("linux", $(PLATFORM))
   34.53 -CPPSRCS += \
   34.54 -	Platform-Posix.cpp         \
   34.55 -	$(NULL)
   34.56 -endif
   34.57 -
   34.58 -default: all
   34.59 -
   34.60 -OBJECTS := $(CPPSRCS:%.cpp=%.o)
   34.61 -
   34.62 -ifeq ($(CXXVENDOR), microsoft)
   34.63 -
   34.64 -CXXFLAGS += /DWIN32 /D_WINDOWS
   34.65 -
   34.66 -%.o: %.cpp
   34.67 -	$(CXX) $(CXXFLAGS) /Fo$@ /c /TP /nologo $<
   34.68 -else
   34.69 -
   34.70 -%.o: %.cpp
   34.71 -	$(CXX) $(BASECXXFLAGS) $(CXXFLAGS) -c -o $@ -Wp,-MD,.deps/$(patsubst %.o,%.d,$@) $<
   34.72 -
   34.73 -endif
   34.74 -
   34.75 -#$(CXX) $(BASECXXFLAGS) $(CXXFLAGS) -c -o $@ -Wp,-MD,.deps/$(basename $(@F)).pp $<
   34.76 -
   34.77 -DEPEND_FILES := $(strip $(wildcard .deps/*.d))
   34.78 -
   34.79 -ifneq (,$(DEPEND_FILES))
   34.80 -DEPEND_RESULTS = $(shell $(TOOLS)/mddepend.pl - $(DEPEND_FILES))
   34.81 -$(eval $(DEPEND_RESULTS))
   34.82 -endif
   34.83 -
   34.84 -all: foobar
   34.85 -
   34.86 -foobar: libfoobar.a main.o
   34.87 -	$(CXX) main.o libfoobar.a -lpthread -o foobar
   34.88 -
   34.89 -libfoobar.a: $(OBJECTS)
   34.90 -	$(AR) -crs libfoobar.a $(OBJECTS)
   34.91 -
   34.92 -FORCE:
   34.93 -
   34.94 -clean:
   34.95 -	rm -f .deps/*.d
   34.96 -	rm -f *.o
   34.97 -	rm -f libfoobar.a
   34.98 -	rm -f foobar
   34.99 -
    35.1 --- a/jitcraft/Messages.h	Tue Jul 24 23:53:34 2012 -0700
    35.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    35.3 @@ -1,48 +0,0 @@
    35.4 -/*
    35.5 - * Copyright (C) 2012 David Anderson
    35.6 - *
    35.7 - * This file is part of JITCraft.
    35.8 - *
    35.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   35.10 - * the terms of the GNU General Public License as published by the Free
   35.11 - * Software Foundation, either version 3 of the License, or (at your option)
   35.12 - * any later version.
   35.13 - * 
   35.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   35.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   35.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   35.17 - *
   35.18 - * You should have received a copy of the GNU General Public License along with
   35.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   35.20 - */
   35.21 -#ifndef _include_jitcraft_messages_h_
   35.22 -#define _include_jitcraft_messages_h_
   35.23 -
   35.24 -namespace ke {
   35.25 -
   35.26 -enum MessageType
   35.27 -{
   35.28 -    MessageType_SyntaxError,
   35.29 -    MessageType_TypeError,
   35.30 -    MessageType_SystemError
   35.31 -};
   35.32 -
   35.33 -enum Message
   35.34 -{
   35.35 -#define MSG(Name, Type, String)     Message_##Name,
   35.36 -# include "Messages.tbl"
   35.37 -#undef MSG
   35.38 -    MessageType_Total
   35.39 -};
   35.40 -
   35.41 -struct MessageInfo
   35.42 -{
   35.43 -    MessageType type;
   35.44 -    const char *format;
   35.45 -};
   35.46 -
   35.47 -extern const MessageInfo Messages[];
   35.48 -
   35.49 -}
   35.50 -
   35.51 -#endif // _include_jitcraft_messages_h_
    36.1 --- a/jitcraft/Messages.tbl	Tue Jul 24 23:53:34 2012 -0700
    36.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    36.3 @@ -1,62 +0,0 @@
    36.4 -MSG(UnterminatedComment,            SyntaxError,            "unterminated comment")
    36.5 -MSG(UnexpectedCharacter,            SyntaxError,            "unexpected character '%c' (code %02X)")
    36.6 -MSG(UnterminatedString,             SyntaxError,            "unterminated string")
    36.7 -MSG(UnknownEscapeCode,              SyntaxError,            "unknown escape code '%c'")
    36.8 -MSG(ExpectedDigitForFloat,          SyntaxError,            "expected digit in float literal, got '%c'")
    36.9 -MSG(WrongToken,                     SyntaxError,            "expected token '%s', got '%s'")
   36.10 -MSG(ExpectedExpression,             SyntaxError,            "expected expression, got '%s'")
   36.11 -MSG(RedeclaredName,                 SyntaxError,            "name '%s' was redeclared (previous at line %d, col %d)")
   36.12 -MSG(ExpectedLValue,                 SyntaxError,            "impossible assignment, expected l-value")
   36.13 -MSG(MaximumArrayDepth,              SyntaxError,            "maximum array dimension depth exceeded")
   36.14 -MSG(ArrayInitializerDepth,          SyntaxError,            "array declaration and initializer have different dimension counts")
   36.15 -MSG(BadArraySize,                   SyntaxError,            "array size must be positive")
   36.16 -MSG(ArraySizeTooBig,                SyntaxError,            "array size is too big")
   36.17 -MSG(EnumFieldNotConstant,           SyntaxError,            "enum fields must be constant integers")
   36.18 -MSG(BreakOutsideLoop,               SyntaxError,            "break occurs outside any loop")
   36.19 -MSG(ContinueOutsideLoop,            SyntaxError,            "continue occurs outside any loop")
   36.20 -MSG(InvalidEnumName,                SyntaxError,            "invalid enumeration name")
   36.21 -MSG(IndexMustBeInteger,             SyntaxError,            "array index must be integer")
   36.22 -MSG(IndexBaseMustBeArray,           SyntaxError,            "cannot index into non-array")
   36.23 -MSG(ArrayIsNotBoolean,              SyntaxError,            "cannot convert an array to boolean")
   36.24 -MSG(CalleeNotFunction,              SyntaxError,            "callee is not a function")
   36.25 -MSG(ArgumentCountMismatch,          SyntaxError,            "argument counts do not match")
   36.26 -MSG(CannotAssignArrayToScalar,      SyntaxError,            "cannot coerce an array to a scalar")
   36.27 -MSG(UnsupportedType,                SyntaxError,            "unsupported type")
   36.28 -MSG(TagMismatch,                    SyntaxError,            "tag mismatch (expected '%s', got '%s')")
   36.29 -MSG(ArrayDimensionsMismatch,        SyntaxError,            "number of array dimensions does not match")
   36.30 -MSG(ExpectedArray,                  SyntaxError,            "expected array")
   36.31 -MSG(ArrayDimensionSizeMismatch,     SyntaxError,            "array dimension sizes do not match (level %d)")
   36.32 -MSG(ArrayDimensionNotInteger,       SyntaxError,            "array dimension size must be an integer expression")
   36.33 -MSG(ArrayNotSupported,              SyntaxError,            "array declaration not yet supported")
   36.34 -MSG(ArrayInitializerUnknown,        SyntaxError,            "array initialized size is not known")
   36.35 -MSG(DynamicArrayHasInitializer,     SyntaxError,            "dynamic arrays cannot have initializers")
   36.36 -MSG(ArraySizeNotSpecified,          SyntaxError,            "array size was not specified")
   36.37 -MSG(ArraySizeCannotBeDetermined,    SyntaxError,            "array size cannot be determined from initializer")
   36.38 -MSG(ArrayAssignmentTooBig,          SyntaxError,            "destination array is too small")
   36.39 -MSG(CannotDeclareStringCell,        SyntaxError,            "cannot declare a String cell")
   36.40 -MSG(BinaryTypeError,                SyntaxError,            "operator '%s' does not support types '%s' and '%s'")
   36.41 -MSG(ArraySizeNotKnown,              SyntaxError,            "array size is not known")
   36.42 -MSG(UnaryTypeError,                 SyntaxError,            "operator '%s' does not support type '%s'")
   36.43 -MSG(CantOpenFile,                   SyntaxError,            "cannot open file")
   36.44 -MSG(ErrorSeekingFile,               SyntaxError,            "error seeking file")
   36.45 -MSG(ErrorReadingFile,               SyntaxError,            "error reading file")
   36.46 -MSG(ExpectedGlobal,                 SyntaxError,            "expected global variable or function")
   36.47 -MSG(ForwardNotImplemented,          SyntaxError,            "forward '%s' not implemented")
   36.48 -MSG(ForwardDeclareMismatches,       SyntaxError,            "declaration does not match original forward signature")
   36.49 -MSG(ArrayCantBeReference,           SyntaxError,            "a parameter cannot be both an array and a reference")
   36.50 -MSG(ArraySizeMustBeConstant,        SyntaxError,            "array size must be a constant integer")
   36.51 -MSG(ReferenceIsConstant,            SyntaxError,            "cannot assign to a constant lvalue")
   36.52 -MSG(MultiArrayInNative,             SyntaxError,            "multidimensional arrays cannot be passed to natives")
   36.53 -MSG(InvalidVarArgs,                 SyntaxError,            "varargs cannot be const or ref")
   36.54 -MSG(VarArgsOutsideNative,           SyntaxError,            "variadic arguments can only be specified on natives")
   36.55 -MSG(ArrayTooBig,                    TypeError,              "array size is too large")
   36.56 -MSG(IntegerDivideByZero,            TypeError,              "integer divide by zero")
   36.57 -MSG(ArrayIndexOutOfBounds,          TypeError,              "array index %d is out of bounds [0, %d)")
   36.58 -MSG(NativeNotBound,                 TypeError,              "attempted to call unbound native \"%s\"")
   36.59 -MSG(AllocationOverflow,             SystemError,            "allocation request overflowed")
   36.60 -MSG(TooMuchRecursion,               SystemError,            "stack overflow: too much recursion")
   36.61 -MSG(MissingReturnValue,             SyntaxError,            "tagged function must return a value")
   36.62 -MSG(NotAllPathsReturnValue,         SyntaxError,            "not all paths through function return a value")
   36.63 -MSG(UsedVoidReturn,                 SyntaxError,            "return value expected, but function does not return a value")
   36.64 -MSG(FunctionDoesNotReturnValue,     SyntaxError,            "cannot use the result of a function with no return value")
   36.65 -MSG(IdentifierNotFound,             SyntaxError,            "identifier '%s' could not be found")
   36.66 \ No newline at end of file
    37.1 --- a/jitcraft/Modules.cpp	Tue Jul 24 23:53:34 2012 -0700
    37.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    37.3 @@ -1,43 +0,0 @@
    37.4 -/*
    37.5 - * Copyright (C) 2012 David Anderson
    37.6 - *
    37.7 - * This file is part of JITCraft.
    37.8 - *
    37.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   37.10 - * the terms of the GNU General Public License as published by the Free
   37.11 - * Software Foundation, either version 3 of the License, or (at your option)
   37.12 - * any later version.
   37.13 - * 
   37.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   37.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   37.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   37.17 - *
   37.18 - * You should have received a copy of the GNU General Public License along with
   37.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   37.20 - */
   37.21 -#include "Modules.h"
   37.22 -#include "Zone.h"
   37.23 -#include "Heap.h"
   37.24 -#include "Heap-inl.h"
   37.25 -
   37.26 -using namespace ke;
   37.27 -
   37.28 -Module *
   37.29 -Module::New(Zone *zone, unsigned nfunctions)
   37.30 -{
   37.31 -    Local<Module> module(zone, Module::cast(zone->allocate(MapKind_Module, sizeof(Module), Heap::Tenure_Old)));
   37.32 -    if (!module)
   37.33 -        return NULL;
   37.34 -
   37.35 -    Local<FixedArray> functions(zone, FixedArray::New(zone, nfunctions, Heap::Tenure_Old));
   37.36 -    if (!functions)
   37.37 -        return NULL;
   37.38 -
   37.39 -    module->functions_ = functions;
   37.40 -    module->file_ = NULL;
   37.41 -    module->publics_ = NULL;
   37.42 -    module->natives_ = NULL;
   37.43 -    module->environment_ = NULL;
   37.44 -    module->nativeIdentity_ = NULL;
   37.45 -    return module;
   37.46 -}
    38.1 --- a/jitcraft/Modules.h	Tue Jul 24 23:53:34 2012 -0700
    38.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    38.3 @@ -1,119 +0,0 @@
    38.4 -/*
    38.5 - * Copyright (C) 2012 David Anderson
    38.6 - *
    38.7 - * This file is part of JITCraft.
    38.8 - *
    38.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   38.10 - * the terms of the GNU General Public License as published by the Free
   38.11 - * Software Foundation, either version 3 of the License, or (at your option)
   38.12 - * any later version.
   38.13 - * 
   38.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   38.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   38.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   38.17 - *
   38.18 - * You should have received a copy of the GNU General Public License along with
   38.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   38.20 - */
   38.21 -#ifndef _include_jc_module_h_
   38.22 -#define _include_jc_module_h_
   38.23 -
   38.24 -#include "Heap.h"
   38.25 -#include "Code.h"
   38.26 -#include "Functions.h"
   38.27 -
   38.28 -namespace ke {
   38.29 -
   38.30 -class Environment;
   38.31 -
   38.32 -class Module : public Object
   38.33 -{
   38.34 -    Barriered<FixedArray> functions_;
   38.35 -    Barriered<FixedArray> publics_;
   38.36 -    Barriered<FixedArray> natives_;
   38.37 -    Barriered<String> file_;
   38.38 -    Barriered<Environment> environment_;
   38.39 -    Barriered<Code> code_;
   38.40 -    void *nativeIdentity_;
   38.41 -
   38.42 -  public:
   38.43 -    static Module *New(Zone *zone, unsigned nfunctions);
   38.44 -
   38.45 -    Function *getFunction(size_t i) {
   38.46 -        return Function::cast(functions_->at(i));
   38.47 -    }
   38.48 -    void setFunction(Zone *zone, size_t i, Function *fun) {
   38.49 -        assert(!functions_->at(i));
   38.50 -        assert(fun);
   38.51 -        functions_->set(zone, i, fun);
   38.52 -    }
   38.53 -
   38.54 -    FixedArray *publics() {
   38.55 -        return publics_;
   38.56 -    }
   38.57 -    FixedArray *natives() {
   38.58 -        return natives_;
   38.59 -    }
   38.60 -    String *file() {
   38.61 -        return file_;
   38.62 -    }
   38.63 -    Environment *environment() {
   38.64 -        return environment_;
   38.65 -    }
   38.66 -    Code *code() {
   38.67 -        return code_;
   38.68 -    }
   38.69 -
   38.70 -    void setPublics(Handle<FixedArray> publics) {
   38.71 -        publics_ = publics;
   38.72 -    }
   38.73 -    void setNatives(Handle<FixedArray> natives) {
   38.74 -        natives_ = natives;
   38.75 -    }
   38.76 -    void setPath(Handle<String> path) {
   38.77 -        file_ = path;
   38.78 -    }
   38.79 -    void setEnvironment(Handle<Environment> environment) {
   38.80 -        environment_ = environment;
   38.81 -    }
   38.82 -    void setCode(Handle<Code> code) {
   38.83 -        code_ = code;
   38.84 -    }
   38.85 -
   38.86 -    void *nativeIdentity() {
   38.87 -        return nativeIdentity_;
   38.88 -    }
   38.89 -    void setNativeIdentity(void *identity) {
   38.90 -        nativeIdentity_ = identity;
   38.91 -    }
   38.92 -
   38.93 -    // Begin GC Descriptor.
   38.94 -    static inline size_t offsetOfFunctions() {
   38.95 -        return offsetof(Module, functions_);
   38.96 -    }
   38.97 -    static inline size_t offsetOfPublics() {
   38.98 -        return offsetof(Module, publics_);
   38.99 -    }
  38.100 -    static inline size_t offsetOfNatives() {
  38.101 -        return offsetof(Module, natives_);
  38.102 -    }
  38.103 -    static inline size_t offsetOfFile() {
  38.104 -        return offsetof(Module, file_);
  38.105 -    }
  38.106 -    static inline size_t offsetOfEnvironment() {
  38.107 -        return offsetof(Module, environment_);
  38.108 -    }
  38.109 -    static inline size_t offsetOfCode() {
  38.110 -        return offsetof(Module, code_);
  38.111 -    }
  38.112 -    // End GC Descriptor.
  38.113 -
  38.114 -    static inline Module *cast(Object *obj) {
  38.115 -        assert(!obj || obj->is(MapKind_Module));
  38.116 -        return reinterpret_cast<Module *>(obj);
  38.117 -    }
  38.118 -};
  38.119 -
  38.120 -}
  38.121 -
  38.122 -#endif // _include_jc_module_h_
    39.1 --- a/jitcraft/NameBinding.cpp	Tue Jul 24 23:53:34 2012 -0700
    39.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    39.3 @@ -1,51 +0,0 @@
    39.4 -/*
    39.5 - * Copyright (C) 2012 David Anderson
    39.6 - *
    39.7 - * This file is part of JITCraft.
    39.8 - *
    39.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   39.10 - * the terms of the GNU General Public License as published by the Free
   39.11 - * Software Foundation, either version 3 of the License, or (at your option)
   39.12 - * any later version.
   39.13 - * 
   39.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   39.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   39.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   39.17 - *
   39.18 - * You should have received a copy of the GNU General Public License along with
   39.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   39.20 - */
   39.21 -#include "NameBinding.h"
   39.22 -#include "Strings.h"
   39.23 -#include "Zone.h"
   39.24 -#include "Scopes.h"
   39.25 -
   39.26 -using namespace ke;
   39.27 -
   39.28 -BoundName::BoundName(Scope *scope, Handle<String> name, const SourcePosition &pos)
   39.29 -  : scope_(scope),
   39.30 -    name_(name),
   39.31 -    type_(NULL),
   39.32 -    pos_(pos)
   39.33 -{
   39.34 -}
   39.35 -
   39.36 -NamedFunction::NamedFunction(Scope *scope, Handle<String> name, const SourcePosition &pos,
   39.37 -                             TokenKind token)
   39.38 -  : BoundName(scope, name, pos),
   39.39 -    token_(token),
   39.40 -    isVariadicNative_(false)
   39.41 -{
   39.42 -}
   39.43 -
   39.44 -Variable::Variable(Scope *scope, Handle<String> name, const SourcePosition &pos)
   39.45 -  : BoundName(scope, name, pos),
   39.46 -    location_(UNALLOCATED)
   39.47 -{
   39.48 -}
   39.49 -
   39.50 -bool
   39.51 -Variable::needsHeapAllocation()
   39.52 -{
   39.53 -    return scope()->kind() == Scope::GLOBAL;
   39.54 -}
    40.1 --- a/jitcraft/NameBinding.h	Tue Jul 24 23:53:34 2012 -0700
    40.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    40.3 @@ -1,211 +0,0 @@
    40.4 -/*
    40.5 - * Copyright (C) 2012 David Anderson
    40.6 - *
    40.7 - * This file is part of JITCraft.
    40.8 - *
    40.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   40.10 - * the terms of the GNU General Public License as published by the Free
   40.11 - * Software Foundation, either version 3 of the License, or (at your option)
   40.12 - * any later version.
   40.13 - * 
   40.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   40.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   40.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   40.17 - *
   40.18 - * You should have received a copy of the GNU General Public License along with
   40.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   40.20 - */
   40.21 -#ifndef _include_name_binding_h_
   40.22 -#define _include_name_binding_h_
   40.23 -
   40.24 -#include "PoolAllocator.h"
   40.25 -#include "Types.h"
   40.26 -#include "Scanner.h"
   40.27 -
   40.28 -namespace ke {
   40.29 -
   40.30 -class Variable;
   40.31 -class NamedFunction;
   40.32 -class Scope;
   40.33 -class Type;
   40.34 -class NamedEnum;
   40.35 -class NamedConstant;
   40.36 -class String;
   40.37 -
   40.38 -class BoundName : public PoolObject
   40.39 -{
   40.40 -    Scope *scope_;
   40.41 -    ScopedRoot<String> name_;
   40.42 -    ScopedRoot<Type> type_;
   40.43 -
   40.44 -  protected:
   40.45 -    SourcePosition pos_;
   40.46 -
   40.47 -  public:
   40.48 -    enum Kind {
   40.49 -      VARIABLE,
   40.50 -      FUNCTION,
   40.51 -      ENUM,
   40.52 -      CONSTANT
   40.53 -    };
   40.54 -
   40.55 -    BoundName(Scope *scope, Handle<String> name, const SourcePosition &pos);
   40.56 -
   40.57 -    virtual Kind kind() const = 0;
   40.58 -
   40.59 -    String *name() const {
   40.60 -        return name_;
   40.61 -    }
   40.62 -    Scope *scope() const {
   40.63 -        return scope_;
   40.64 -    }
   40.65 -    Variable *toVariable() {
   40.66 -        assert(kind() == VARIABLE);
   40.67 -        return reinterpret_cast<Variable *>(this);
   40.68 -    }
   40.69 -    NamedFunction *toNamedFunction() {
   40.70 -        assert(kind() == FUNCTION);
   40.71 -        return reinterpret_cast<NamedFunction *>(this);
   40.72 -    }
   40.73 -    NamedConstant *toNamedConstant() {
   40.74 -        assert(kind() == CONSTANT);
   40.75 -        return reinterpret_cast<NamedConstant *>(this);
   40.76 -    }
   40.77 -    Type *type() const {
   40.78 -        return type_;
   40.79 -    }
   40.80 -    void setType(Handle<Type> type) {
   40.81 -        type_ = type;
   40.82 -    }
   40.83 -    const SourcePosition &pos() {
   40.84 -        return pos_;
   40.85 -    }
   40.86 -};
   40.87 -
   40.88 -class NamedFunction : public BoundName
   40.89 -{
   40.90 -    unsigned slot_;
   40.91 -    TokenKind token_;
   40.92 -    ScopedRoot<Type> forwardType_;
   40.93 -    bool isVariadicNative_;
   40.94 -
   40.95 -  public:
   40.96 -    NamedFunction(Scope *scope, Handle<String> name, const SourcePosition &pos, TokenKind token);
   40.97 -
   40.98 -    Kind kind() const {
   40.99 -        return FUNCTION;
  40.100 -    }
  40.101 -    void allocate(unsigned slot) {
  40.102 -        slot_ = slot;
  40.103 -    }
  40.104 -    bool isForward() const {
  40.105 -        return token_ == TOK_FORWARD;
  40.106 -    }
  40.107 -    bool isPublic() const {
  40.108 -        return token_ == TOK_PUBLIC;
  40.109 -    }
  40.110 -    bool isNative() const {
  40.111 -        return token_ == TOK_NATIVE;
  40.112 -    }
  40.113 -    void setForwardType(Handle<Type> type) {
  40.114 -        forwardType_ = type;
  40.115 -    }
  40.116 -    Type *forwardType() {
  40.117 -        return forwardType_;
  40.118 -    }
  40.119 -    void setImplemented(const SourcePosition &at) {
  40.120 -        token_ = TOK_PUBLIC;
  40.121 -        pos_ = at;
  40.122 -    }
  40.123 -    void markNativeVariadic() {
  40.124 -        assert(token_ == TOK_NATIVE);
  40.125 -        isVariadicNative_ = true;
  40.126 -    }
  40.127 -    bool isNativeVariadic() {
  40.128 -        assert(token_ == TOK_NATIVE);
  40.129 -        return isVariadicNative_;
  40.130 -    }
  40.131 -    unsigned slot() const {
  40.132 -        return slot_;
  40.133 -    }
  40.134 -};
  40.135 -
  40.136 -class NamedEnum : public BoundName
  40.137 -{
  40.138 -  public:
  40.139 -    NamedEnum(Scope *scope, Handle<String> name, const SourcePosition &pos)
  40.140 -      : BoundName(scope, name, pos)
  40.141 -    {
  40.142 -    }
  40.143 -
  40.144 -    Kind kind() const {
  40.145 -        return ENUM;
  40.146 -    }
  40.147 -};
  40.148 -
  40.149 -class NamedConstant : public BoundName
  40.150 -{
  40.151 -    BoxedPrimitive value_;
  40.152 -    Type *type_;
  40.153 -
  40.154 -  public:
  40.155 -    NamedConstant(Scope *scope, Handle<String> name, const SourcePosition &pos)
  40.156 -      : BoundName(scope, name, pos),
  40.157 -        type_(NULL)
  40.158 -    {
  40.159 -    }
  40.160 -
  40.161 -    Kind kind() const {
  40.162 -        return CONSTANT;
  40.163 -    }
  40.164 -    void set(Type *type, const BoxedPrimitive &value) {
  40.165 -        value_ = value;
  40.166 -        type_ = type;
  40.167 -    }
  40.168 -    Type *type() const {
  40.169 -        return type_;
  40.170 -    }
  40.171 -    BoxedPrimitive value() const {
  40.172 -        return value_;
  40.173 -    }
  40.174 -};
  40.175 -
  40.176 -class Variable : public BoundName
  40.177 -{
  40.178 -  public:
  40.179 -    enum Location {
  40.180 -        UNALLOCATED,
  40.181 -        STACK,
  40.182 -        PARAMETER,
  40.183 -        ENVIRONMENT
  40.184 -    };
  40.185 -
  40.186 -    Variable(Scope *scope, Handle<String> name, const SourcePosition &pos);
  40.187 -
  40.188 -    Kind kind() const {
  40.189 -        return VARIABLE;
  40.190 -    }
  40.191 -    bool unallocated() const {
  40.192 -        return location() == UNALLOCATED;
  40.193 -    }
  40.194 -    void allocate(Location location, unsigned slot) {
  40.195 -        location_ = location;
  40.196 -        slot_ = slot;
  40.197 -    }
  40.198 -    Location location() const {
  40.199 -        return location_;
  40.200 -    }
  40.201 -    unsigned slot() const {
  40.202 -        assert(!unallocated());
  40.203 -        return slot_;
  40.204 -    }
  40.205 -    bool needsHeapAllocation();
  40.206 -
  40.207 -  private:
  40.208 -    Location location_;
  40.209 -    unsigned slot_;
  40.210 -};
  40.211 -
  40.212 -}
  40.213 -
  40.214 -#endif // _include_name_binding_h_
    41.1 --- a/jitcraft/ObjectVisitor.h	Tue Jul 24 23:53:34 2012 -0700
    41.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    41.3 @@ -1,269 +0,0 @@
    41.4 -/* vim: set ts=4 sw=4 tw=99 et:
    41.5 - *
    41.6 - * Copyright (C) 2012 David Anderson
    41.7 - *
    41.8 - * This file is part of JITCraft.
    41.9 - *
   41.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   41.11 - * the terms of the GNU General Public License as published by the Free
   41.12 - * Software Foundation, either version 3 of the License, or (at your option)
   41.13 - * any later version.
   41.14 - * 
   41.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   41.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   41.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   41.18 - *
   41.19 - * You should have received a copy of the GNU General Public License along with
   41.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   41.21 - */
   41.22 -#ifndef _include_jc_object_visitor_h_
   41.23 -#define _include_jc_object_visitor_h_
   41.24 -
   41.25 -#include "Objects.h"
   41.26 -#include "Types.h"
   41.27 -#include "FixedArray.h"
   41.28 -#include "Code.h"
   41.29 -#include "Reference.h"
   41.30 -#include "Modules.h"
   41.31 -#include "Functions.h"
   41.32 -#include "Array.h"
   41.33 -#include "Strings.h"
   41.34 -#include "Environments.h"
   41.35 -
   41.36 -namespace ke {
   41.37 -
   41.38 -// An ObjectVisitor is used for traversing object references in the heap. Since
   41.39 -// this pattern must be lightning fast, we avoid virtual dispatch by forcing
   41.40 -// visitors to compose themselves with the visiting logic.
   41.41 -template <typename T>
   41.42 -class ObjectVisitor : public T
   41.43 -{
   41.44 -  private:
   41.45 -    void visitField(Object *obj, size_t offset) {
   41.46 -        this->visit(reinterpret_cast<Object **>(Address(obj) + offset));
   41.47 -    }
   41.48 -
   41.49 -    size_t iterateType(Object *obj) {
   41.50 -        visitField(obj, Type::offsetOfContained());
   41.51 -        visitField(obj, Type::offsetOfReturnType());
   41.52 -        visitField(obj, Type::offsetOfParameters());
   41.53 -        visitField(obj, Type::offsetOfTag());
   41.54 -        return sizeof(Type);
   41.55 -    }
   41.56 -
   41.57 -    size_t iterateFixedArray(FixedArray *array) {
   41.58 -        unsigned length = array->length();
   41.59 -        Object **ptr = reinterpret_cast<Object **>(array + 1);
   41.60 -        for (unsigned i = 0; i < length; i++)
   41.61 -            this->visit(ptr + i);
   41.62 -        return FixedArray::SizeFor(length);
   41.63 -    }
   41.64 -
   41.65 -    size_t iterateByteArray(ByteArray *array) {
   41.66 -        return ByteArray::SizeFor(array->length());
   41.67 -    }
   41.68 -
   41.69 -    size_t iterateCode(Object *obj) {
   41.70 -        visitField(obj, Code::offsetOfModule());
   41.71 -        visitField(obj, Code::offsetOfBytecode());
   41.72 -        visitField(obj, Code::offsetOfLocals());
   41.73 -        visitField(obj, Code::offsetOfObjects());
   41.74 -        visitField(obj, Code::offsetOfSafepoints());
   41.75 -        visitField(obj, Code::offsetOfSourceMap());
   41.76 -        return sizeof(Code);
   41.77 -    }
   41.78 -
   41.79 -    size_t iterateReference(Object *obj) {
   41.80 -        visitField(obj, Reference::offsetOfBase());
   41.81 -        return sizeof(Reference);
   41.82 -    }
   41.83 -
   41.84 -    size_t iterateModule(Object *obj) {
   41.85 -        visitField(obj, Module::offsetOfFunctions());
   41.86 -        visitField(obj, Module::offsetOfPublics());
   41.87 -        visitField(obj, Module::offsetOfNatives());
   41.88 -        visitField(obj, Module::offsetOfFile());
   41.89 -        visitField(obj, Module::offsetOfEnvironment());
   41.90 -        visitField(obj, Module::offsetOfCode());
   41.91 -        return sizeof(Module);
   41.92 -    }
   41.93 -
   41.94 -    size_t iterateFunction(Object *obj) {
   41.95 -        visitField(obj, Function::offsetOfCode());
   41.96 -        visitField(obj, Function::offsetOfType());
   41.97 -        visitField(obj, Function::offsetOfName());
   41.98 -        return sizeof(Function);
   41.99 -    }
  41.100 -
  41.101 -    size_t iterateNative(Object *obj) {
  41.102 -        visitField(obj, Native::offsetOfType());
  41.103 -        visitField(obj, Native::offsetOfName());
  41.104 -        return sizeof(Native);
  41.105 -    }
  41.106 -
  41.107 -    size_t iterateString(Object *obj) {
  41.108 -        return String::SizeFor(String::cast(obj)->length());
  41.109 -    }
  41.110 -
  41.111 -    size_t iterateArray(Array *array, ArrayMap *map) {
  41.112 -        assert(map->type()->isArray());
  41.113 -        if (map->contained()) {
  41.114 -            unsigned length = array->nelements();
  41.115 -            Object **vec = array->objVec();
  41.116 -            for (unsigned i = 0; i < length; i++)
  41.117 -                this->visit(vec + i);
  41.118 -        }
  41.119 -        return Array::SizeOf(array);
  41.120 -    }
  41.121 -
  41.122 -    size_t iterateArrayMap(ArrayMap *map) {
  41.123 -        visitField(map, ArrayMap::offsetOfType());
  41.124 -        visitField(map, ArrayMap::offsetOfContained());
  41.125 -        return sizeof(ArrayMap);
  41.126 -    }
  41.127 -
  41.128 -    size_t iterateEnvironmentSlotDescriptorArray(EnvironmentSlotDescriptorArray *env) {
  41.129 -        unsigned length = env->length();
  41.130 -        EnvironmentSlotDescriptor *desc = env->slots();
  41.131 -        for (unsigned i = 0; i < length; i++)
  41.132 -            this->visit(desc->type.addr());
  41.133 -        return env->size();
  41.134 -    }
  41.135 -
  41.136 -    size_t iterateEnvironmentMap(EnvironmentMap *map) {
  41.137 -        visitField(map, EnvironmentMap::offsetOfSlots());
  41.138 -        return map->size();
  41.139 -    }
  41.140 -
  41.141 -    size_t iterateEnvironment(Environment *env) {
  41.142 -        EnvironmentMap *map = env->map();
  41.143 -        const unsigned *offsets = map->traceOffsets();
  41.144 -        unsigned noffsets = map->traceOffsetCount();
  41.145 -        for (unsigned i = 0; i < noffsets; i++)
  41.146 -            visitField(env, Environment::offsetOfSlotOffset(offsets[i]));
  41.147 -        return env->size();
  41.148 -    }
  41.149 -
  41.150 -  public:
  41.151 -    size_t iterate(Object *obj) {
  41.152 -        visitField(obj, Object::offsetOfMap());
  41.153 -        return iterate(obj, obj->map());
  41.154 -    }
  41.155 -
  41.156 -    size_t iterate(Object *obj, Map *map) {
  41.157 -        switch (map->kind()) {
  41.158 -          case MapKind_Type:
  41.159 -            return iterateType(obj);
  41.160 -
  41.161 -          case MapKind_FixedArray:
  41.162 -            return iterateFixedArray(FixedArray::cast(obj));
  41.163 -
  41.164 -          case MapKind_ByteArray:
  41.165 -            return iterateByteArray(ByteArray::cast(obj));
  41.166 -
  41.167 -          case MapKind_Code:
  41.168 -            return iterateCode(obj);
  41.169 -
  41.170 -          case MapKind_Reference:
  41.171 -            return iterateReference(obj);
  41.172 -
  41.173 -          case MapKind_Module:
  41.174 -            return iterateModule(obj);
  41.175 -
  41.176 -          case MapKind_Function:
  41.177 -            return iterateFunction(obj);
  41.178 -
  41.179 -          case MapKind_String:
  41.180 -            return iterateString(obj);
  41.181 -
  41.182 -          case MapKind_Array:
  41.183 -            return Align(iterateArray(Array::cast(obj), ArrayMap::cast(map)), kObjectAlignment);
  41.184 -
  41.185 -          case MapKind_EnvironmentSlotDescriptorArray:
  41.186 -            return iterateEnvironmentSlotDescriptorArray(EnvironmentSlotDescriptorArray::cast(obj));
  41.187 -
  41.188 -          case MapKind_Environment:
  41.189 -            return iterateEnvironment(Environment::cast(obj));
  41.190 -
  41.191 -          case MapKind_Native:
  41.192 -            return iterateNative(obj);
  41.193 -
  41.194 -          case MapKind_MetaArray:
  41.195 -            return iterateArrayMap(ArrayMap::cast(obj));
  41.196 -
  41.197 -          case MapKind_MetaEnvironment:
  41.198 -            return iterateEnvironmentMap(EnvironmentMap::cast(obj));
  41.199 -
  41.200 -          default:
  41.201 -            assert(map->kind() == MapKind_Meta);
  41.202 -            return sizeof(Map);
  41.203 -        }
  41.204 -    }
  41.205 -};
  41.206 -
  41.207 -static inline size_t
  41.208 -SizeOfObject(Object *obj, Map *map)
  41.209 -{
  41.210 -    switch (map->kind()) {
  41.211 -      case MapKind_Type:
  41.212 -        return sizeof(Type);
  41.213 -
  41.214 -      case MapKind_FixedArray:
  41.215 -        return FixedArray::SizeFor(FixedArray::cast(obj)->length());
  41.216 -
  41.217 -      case MapKind_ByteArray:
  41.218 -        return ByteArray::SizeFor(ByteArray::cast(obj)->length());
  41.219 -
  41.220 -      case MapKind_Code:
  41.221 -        return sizeof(Code);
  41.222 -
  41.223 -      case MapKind_Reference:
  41.224 -        return sizeof(Reference);
  41.225 -
  41.226 -      case MapKind_Module:
  41.227 -        return sizeof(Module);
  41.228 -
  41.229 -      case MapKind_Function:
  41.230 -        return sizeof(Function);
  41.231 -
  41.232 -      case MapKind_String:
  41.233 -        return String::SizeFor(String::cast(obj)->length());
  41.234 -
  41.235 -      case MapKind_Native:
  41.236 -        return sizeof(Native);
  41.237 -
  41.238 -      case MapKind_Array:
  41.239 -        return Align(Array::SizeOf(Array::cast(obj)), kObjectAlignment);
  41.240 -
  41.241 -      case MapKind_EnvironmentSlotDescriptorArray:
  41.242 -        return EnvironmentSlotDescriptorArray::cast(obj)->size();
  41.243 -
  41.244 -      case MapKind_Environment:
  41.245 -        return Environment::cast(obj)->size();
  41.246 -
  41.247 -      case MapKind_MetaArray:
  41.248 -        return sizeof(ArrayMap);
  41.249 -
  41.250 -      case MapKind_MetaEnvironment:
  41.251 -        return EnvironmentMap::cast(obj)->size();
  41.252 -
  41.253 -      case MapKind_FreeRegion:
  41.254 -        return *reinterpret_cast<size_t *>(reinterpret_cast<Address>(obj + 1));
  41.255 -
  41.256 -      default:
  41.257 -        assert(map->kind() == MapKind_Meta);
  41.258 -        return sizeof(Map);
  41.259 -    }
  41.260 -}
  41.261 -
  41.262 -class ObjectSizeEvaluator
  41.263 -{
  41.264 -  public:
  41.265 -    size_t operator()(Object *obj, Map *map) {
  41.266 -        return SizeOfObject(obj, map);
  41.267 -    }
  41.268 -};
  41.269 -
  41.270 -}
  41.271 -
  41.272 -#endif // _include_jc_object_visitor_h_
    42.1 --- a/jitcraft/Objects.h	Tue Jul 24 23:53:34 2012 -0700
    42.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    42.3 @@ -1,119 +0,0 @@
    42.4 -/* vim: set ts=4 sw=4 tw=99 et:
    42.5 - *
    42.6 - * Copyright (C) 2012 David Anderson
    42.7 - *
    42.8 - * This file is part of JITCraft.
    42.9 - *
   42.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   42.11 - * the terms of the GNU General Public License as published by the Free
   42.12 - * Software Foundation, either version 3 of the License, or (at your option)
   42.13 - * any later version.
   42.14 - * 
   42.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   42.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   42.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   42.18 - *
   42.19 - * You should have received a copy of the GNU General Public License along with
   42.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   42.21 - */
   42.22 -#ifndef _include_jitcraft_objects_h_
   42.23 -#define _include_jitcraft_objects_h_
   42.24 -
   42.25 -#include "Utility.h"
   42.26 -#include "Spaces.h"
   42.27 -#include "Barriers.h"
   42.28 -
   42.29 -namespace ke {
   42.30 -
   42.31 -class Zone;
   42.32 -
   42.33 -// Garbage-collection objects require a header to describe their layout. This
   42.34 -// header is called a "map". The different kinds of maps are enumerated below.
   42.35 -class Map;
   42.36 -
   42.37 -enum MapKind
   42.38 -{
   42.39 -    // Represents Type objects.
   42.40 -    MapKind_Type,
   42.41 -
   42.42 -    // Represents basic data structures. When adding to this, don't forget
   42.43 -    // to update Zone::initialize(), or you'll get a NULL crash trying to
   42.44 -    // allocate, since these maps are cached.
   42.45 -    MapKind_FixedArray,
   42.46 -    MapKind_ByteArray,
   42.47 -    MapKind_Code,
   42.48 -    MapKind_Reference,
   42.49 -    MapKind_Module,
   42.50 -    MapKind_Function,
   42.51 -    MapKind_String,
   42.52 -    MapKind_Native,
   42.53 -    MapKind_FreeRegion,     // Special map denoting freed space.
   42.54 -    MapKind_EnvironmentSlotDescriptorArray,
   42.55 -    MapKind_Environment,
   42.56 -
   42.57 -    // Used to represent Arrays. This does not have a canonical map.
   42.58 -    MapKind_Array,
   42.59 -
   42.60 -    // These represent special Map subclasses that require special tracing.
   42.61 -    MapKinds_Special,
   42.62 -    MapKind_Meta,               // (default map class)
   42.63 -    MapKind_MetaArray,          // ArrayMap instances
   42.64 -    MapKind_MetaEnvironment,    // EnvironmentMap instances
   42.65 -    MapKinds_EndSpecial,
   42.66 -
   42.67 -    MapKinds_Total
   42.68 -};
   42.69 -
   42.70 -// All garbage collected objects must inherit from GCObject. Note that using
   42.71 -// virtual functions is illegal, as the |map| field would be displaced.
   42.72 -class Object
   42.73 -{
   42.74 -    Barriered<Map> map_;
   42.75 -
   42.76 -  public:
   42.77 -    void init(Map *map) {
   42.78 -        map_ = map;
   42.79 -    }
   42.80 -
   42.81 -    Map *map() {
   42.82 -        return map_;
   42.83 -    }
   42.84 -    inline bool is(MapKind map);
   42.85 -
   42.86 -    inline void write(Zone *zone, Object **ptr, Object *value);
   42.87 -
   42.88 -    static inline size_t offsetOfMap() {
   42.89 -        return offsetof(Object, map_);
   42.90 -    }
   42.91 -};
   42.92 -
   42.93 -// Maps describe the layout of GCObjects. Every GCObject requires a map.
   42.94 -class Map : public Object
   42.95 -{
   42.96 -    MapKind kind_;
   42.97 -
   42.98 -  public:
   42.99 -    void setKind(MapKind kind) {
  42.100 -        kind_ = kind;
  42.101 -    }
  42.102 -    MapKind kind() {
  42.103 -        return kind_;
  42.104 -    }
  42.105 -
  42.106 -    static inline Map *cast(Object *obj) {
  42.107 -        // Note that ArrayMap is a map, but a special one: since it is non-
  42.108 -        assert(obj->map()->kind() > MapKinds_Special &&
  42.109 -               obj->map()->kind() < MapKinds_EndSpecial);
  42.110 -        return reinterpret_cast<Map *>(obj);
  42.111 -    }
  42.112 -};
  42.113 -
  42.114 -inline bool
  42.115 -Object::is(MapKind kind)
  42.116 -{
  42.117 -    return map()->kind() == kind;
  42.118 -}
  42.119 -
  42.120 -}
  42.121 -
  42.122 -#endif //_include_jitcraft_objects_h_
    43.1 --- a/jitcraft/Opcodes.cpp	Tue Jul 24 23:53:34 2012 -0700
    43.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    43.3 @@ -1,311 +0,0 @@
    43.4 -/* vim: set ts=4 sw=4 tw=99 et:
    43.5 - *
    43.6 - * Copyright (C) 2012 David Anderson
    43.7 - *
    43.8 - * This file is part of JITCraft.
    43.9 - *
   43.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   43.11 - * the terms of the GNU General Public License as published by the Free
   43.12 - * Software Foundation, either version 3 of the License, or (at your option)
   43.13 - * any later version.
   43.14 - * 
   43.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   43.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   43.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   43.18 - *
   43.19 - * You should have received a copy of the GNU General Public License along with
   43.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   43.21 - */
   43.22 -#include <stdlib.h>
   43.23 -#include "Opcodes.h"
   43.24 -#include "Utility.h"
   43.25 -#include "Code.h"
   43.26 -#include "Zone.h"
   43.27 -#include "Array.h"
   43.28 -#include "Strings.h"
   43.29 -#include "CompactBuffer.h"
   43.30 -#include "Heap-inl.h"
   43.31 -
   43.32 -using namespace ke;
   43.33 -
   43.34 -OpInfo ke::OpcodeInfo[] =
   43.35 -{
   43.36 -#define OPDEF(name, number, text, length, uses, defs) \
   43.37 -    {text, length, uses, defs},
   43.38 -#include "Opcodes.tbl"
   43.39 -#undef OPDEF
   43.40 -};
   43.41 -
   43.42 -Code *
   43.43 -Code::New(Zone *zone, Handle<ByteArray> bytecode, Handle<FixedArray> locals,
   43.44 -          Handle<FixedArray> objects, unsigned maxStackDepth, Handle<Module> module,
   43.45 -	      Handle<ByteArray> safepoints, Handle<ByteArray> sourcemap,
   43.46 -          unsigned lineNumber)
   43.47 -{
   43.48 -    Local<Code> code(zone, Code::cast(zone->allocate(MapKind_Code, sizeof(Code), Heap::Tenure_Old)));
   43.49 -    if (!code)
   43.50 -        return NULL;
   43.51 -
   43.52 -    code->bytecode_ = bytecode;
   43.53 -    code->locals_ = locals;
   43.54 -    code->objects_ = objects;
   43.55 -    code->maxStackDepth_ = maxStackDepth;
   43.56 -    code->module_ = module;
   43.57 -    code->safepoints_ = safepoints;
   43.58 -    code->sourcemap_ = sourcemap;
   43.59 -    code->lineNumber_ = lineNumber;
   43.60 -    return code;
   43.61 -}
   43.62 -
   43.63 -static int
   43.64 -CompareSafepoints(const void *a, const void *b)
   43.65 -{
   43.66 -    const unsigned *sa = reinterpret_cast<const unsigned *>(a);
   43.67 -    const unsigned *sb = reinterpret_cast<const unsigned *>(b);
   43.68 -    if (*sa > *sb)
   43.69 -        return 1;
   43.70 -    if (*sa == *sb)
   43.71 -        return 0;
   43.72 -    return -1;
   43.73 -}
   43.74 -
   43.75 -uint8 *
   43.76 -Code::safepointAt(unsigned pcOffset)
   43.77 -{
   43.78 -    // Only specific opcodes may have safepoints. Asking for a safepoint at
   43.79 -    // any other position indicates a failure to mark that position as a
   43.80 -    // safepoint, which is a bug.
   43.81 -    Opcode op = Opcode(*(start() + pcOffset));
   43.82 -    assert(op == OP_CALL || op == OP_NEWARRAY || op == OP_VARREF_LIFO ||
   43.83 -           op == OP_ARGREF_LIFO || op == OP_SLOTREF_LIFO || op == OP_ARRAYREF_LIFO ||
   43.84 -           op == OP_ARRAYCOPY);
   43.85 -
   43.86 -    if (!safepoints_)
   43.87 -        return NULL;
   43.88 -
   43.89 -    size_t bytesPerSafepoint = BytesPerSafepoint(maxStackDepth());
   43.90 -    assert(!(safepoints_->length() % bytesPerSafepoint));
   43.91 -
   43.92 -    size_t count = safepoints_->length() / bytesPerSafepoint;
   43.93 -
   43.94 -    void *result = bsearch(&pcOffset,
   43.95 -                           safepoints_->raw(),
   43.96 -                           count,
   43.97 -                           bytesPerSafepoint,
   43.98 -                           CompareSafepoints);
   43.99 -
  43.100 -    if (!result)
  43.101 -        return NULL;
  43.102 -
  43.103 -    assert(*reinterpret_cast<unsigned *>(result) == pcOffset);
  43.104 -
  43.105 -    return Address(result) + sizeof(unsigned);
  43.106 -}
  43.107 -
  43.108 -SourcePosition
  43.109 -Code::pcToSource(unsigned pc)
  43.110 -{
  43.111 -    assert(pc < bytecode_->length());
  43.112 -
  43.113 -    CompactBufferReader reader(sourcemap_->raw(), sourcemap_->raw() + sourcemap_->length());
  43.114 -
  43.115 -    unsigned line = 1;
  43.116 -    unsigned col = 0;
  43.117 -    unsigned curPc = 0;
  43.118 -    while (!reader.done()) {
  43.119 -        curPc += reader.readUint32();
  43.120 -        if (curPc > pc)
  43.121 -            break;
  43.122 -
  43.123 -        line = reader.readUint32();
  43.124 -        col = reader.readUint32();
  43.125 -    }
  43.126 -
  43.127 -    return SourcePosition(lineNumber_ + line, col);
  43.128 -}
  43.129 -
  43.130 -// All jumps must be the same length.
  43.131 -STATIC_ASSERT(OP_JL_LENGTH == OP_JUMP_LENGTH);
  43.132 -STATIC_ASSERT(OP_JLE_LENGTH == OP_JUMP_LENGTH);
  43.133 -STATIC_ASSERT(OP_JG_LENGTH == OP_JUMP_LENGTH);
  43.134 -STATIC_ASSERT(OP_JGE_LENGTH == OP_JUMP_LENGTH);
  43.135 -STATIC_ASSERT(OP_JEQ_LENGTH == OP_JUMP_LENGTH);
  43.136 -STATIC_ASSERT(OP_JNE_LENGTH == OP_JUMP_LENGTH);
  43.137 -STATIC_ASSERT(OP_JT_LENGTH == OP_JUMP_LENGTH);
  43.138 -STATIC_ASSERT(OP_JF_LENGTH == OP_JUMP_LENGTH);
  43.139 -
  43.140 -void
  43.141 -ke::Disassemble(Code *code, FILE *fp)
  43.142 -{
  43.143 -    bytecode *pc = code->start();
  43.144 -    for (;;) {
  43.145 -        Opcode op = Opcode(*pc);
  43.146 -
  43.147 -        fprintf(fp, "%-4d %s ", int(pc - code->start()), OpcodeInfo[op].name);
  43.148 -
  43.149 -        switch (op) {
  43.150 -          case OP_NOP:
  43.151 -          case OP_RETURN:
  43.152 -          case OP_RETURNVOID:
  43.153 -          case OP_ADD:
  43.154 -          case OP_SUB:
  43.155 -          case OP_MUL:
  43.156 -          case OP_DIV:
  43.157 -          case OP_ADD_F:
  43.158 -          case OP_SUB_F:
  43.159 -          case OP_MUL_F:
  43.160 -          case OP_DIV_F:
  43.161 -          case OP_CVT_I2F:
  43.162 -          case OP_POP:
  43.163 -          case OP_GETARRAY_I:
  43.164 -          case OP_SETARRAY_I:
  43.165 -          case OP_GETARRAY_F:
  43.166 -          case OP_SETARRAY_F:
  43.167 -          case OP_GETARRAY_C:
  43.168 -          case OP_SETARRAY_C:
  43.169 -          case OP_GETARRAY_O:
  43.170 -          case OP_BOUNDS:
  43.171 -          case OP_SHL:
  43.172 -          case OP_SHR:
  43.173 -          case OP_USHR:
  43.174 -          case OP_BITAND:
  43.175 -          case OP_BITOR:
  43.176 -          case OP_BITXOR:
  43.177 -          case OP_GETREF_I:
  43.178 -          case OP_SETREF_I:
  43.179 -          case OP_GETREF_F:
  43.180 -          case OP_SETREF_F:
  43.181 -          case OP_SLOTREF_LIFO:
  43.182 -          case OP_ARRAYREF_LIFO:
  43.183 -          case OP_ARRAYCOPY:
  43.184 -          case OP_DUP:
  43.185 -          case OP_DUP2:
  43.186 -          case OP_SWAP:
  43.187 -          case OP_ROLL3:
  43.188 -          case OP_PICK2:
  43.189 -          case OP_PICK3:
  43.190 -          case OP_CALL:
  43.191 -          case OP_MODULE:
  43.192 -          case OP_LT:
  43.193 -          case OP_LE:
  43.194 -          case OP_GE:
  43.195 -          case OP_GT:
  43.196 -          case OP_EQ:
  43.197 -          case OP_NE:
  43.198 -          case OP_LT_F:
  43.199 -          case OP_LE_F:
  43.200 -          case OP_GE_F:
  43.201 -          case OP_GT_F:
  43.202 -          case OP_EQ_F:
  43.203 -          case OP_NE_F:
  43.204 -          case OP_BITNOT:
  43.205 -          case OP_NOT:
  43.206 -          case OP_NOT_F:
  43.207 -          case OP_NEG:
  43.208 -          case OP_NEG_F:
  43.209 -          case OP_MOD:
  43.210 -            break;
  43.211 -
  43.212 -          case OP_STOP:
  43.213 -            fprintf(fp, "\n");
  43.214 -            break;
  43.215 -
  43.216 -          case OP_INT:
  43.217 -            fprintf(fp, "%d", READ_INT32(pc));
  43.218 -            break;
  43.219 -
  43.220 -          case OP_FLOAT:
  43.221 -            fprintf(fp, "%f", READ_FLOAT(pc));
  43.222 -            break;
  43.223 -
  43.224 -          case OP_JL:
  43.225 -          case OP_JLE:
  43.226 -          case OP_JG:
  43.227 -          case OP_JGE:
  43.228 -          case OP_JEQ:
  43.229 -          case OP_JNE:
  43.230 -          case OP_JT:
  43.231 -          case OP_JF:
  43.232 -          case OP_JL_F:
  43.233 -          case OP_JLE_F:
  43.234 -          case OP_JG_F:
  43.235 -          case OP_JGE_F:
  43.236 -          case OP_JEQ_F:
  43.237 -          case OP_JNE_F:
  43.238 -          case OP_JT_F:
  43.239 -          case OP_JF_F:
  43.240 -          case OP_JUMP:
  43.241 -            fprintf(fp, "%u (%+d)", unsigned((pc + READ_INT32(pc)) - code->start()), READ_INT32(pc));
  43.242 -            break;
  43.243 -
  43.244 -          case OP_NEWARRAY:
  43.245 -          {
  43.246 -            Heap::Tenure tenure = (Heap::Tenure)pc[1];
  43.247 -            ArrayMap *map = ArrayMap::cast(code->map(READ_UINT32(pc + 1)));
  43.248 -            fprintf(fp, "%s:", map->type()->innermost()->tag()
  43.249 -                               ? map->type()->innermost()->tag()->chars()
  43.250 -                               : "_");
  43.251 -            for (; map; map = map->contained()) {
  43.252 -                Type *type = map->type();
  43.253 -                fprintf(fp, "[%d]", type->elements());
  43.254 -            }
  43.255 -            if (tenure == Heap::Tenure_Stack)
  43.256 -                fprintf(fp, " ; lifo");
  43.257 -            else if (tenure == Heap::Tenure_Old)
  43.258 -                fprintf(fp, " ; pretenured");
  43.259 -            break;
  43.260 -          }
  43.261 -
  43.262 -          case OP_GETLOCAL:
  43.263 -          case OP_SETLOCAL:
  43.264 -          case OP_GETARG:
  43.265 -          case OP_SETARG:
  43.266 -          case OP_SAVELIFO:
  43.267 -          case OP_UNWINDLIFO:
  43.268 -          case OP_VARREF_LIFO:
  43.269 -          case OP_ARGREF_LIFO:
  43.270 -          case OP_OBJECT:
  43.271 -          case OP_GETMODULE_FN:
  43.272 -          case OP_GETGLOBAL_I:
  43.273 -          case OP_GETGLOBAL_F:
  43.274 -          case OP_GETGLOBAL_O:
  43.275 -          case OP_SETGLOBAL_I:
  43.276 -          case OP_SETGLOBAL_F:
  43.277 -          case OP_SETGLOBAL_O:
  43.278 -            fprintf(fp, "%u", READ_UINT32(pc));
  43.279 -            break;
  43.280 -
  43.281 -          case OP_CALLNATIVE:
  43.282 -            fprintf(fp, "%u %u", READ_UINT32(pc), READ_UINT32(pc + 4));
  43.283 -            break;
  43.284 -
  43.285 -          default:
  43.286 -            // Unknown opcode!
  43.287 -            assert(false);
  43.288 -            return;
  43.289 -        }
  43.290 -
  43.291 -        if (op == OP_STOP)
  43.292 -            break;
  43.293 -
  43.294 -        fprintf(fp, "\n");
  43.295 -        pc += OpcodeInfo[op].length;
  43.296 -        assert(pc < code->start() + code->length());
  43.297 -    }
  43.298 -
  43.299 -    fprintf(fp, "\nSafepoints:\n");
  43.300 -    ByteArray *safepoints = code->safepoints();
  43.301 -    if (safepoints) {
  43.302 -        size_t nsafepoints = safepoints->length() / Code::BytesPerSafepoint(code->maxStackDepth());
  43.303 -        for (size_t i = 0; i < nsafepoints; i++) {
  43.304 -            Address address = safepoints->raw() + Code::BytesPerSafepoint(code->maxStackDepth()) * i;
  43.305 -            fprintf(fp, "%4d: ", *reinterpret_cast<unsigned *>(address));
  43.306 -            unsigned char *bits = (unsigned char *)(address + sizeof(unsigned));
  43.307 -            for (unsigned j = 0; j < code->maxStackDepth(); j++) {
  43.308 -                if (bits[j / 8] & (1 << (j % 8)))
  43.309 -                    fprintf(fp, "%d ", j);
  43.310 -            }
  43.311 -            fprintf(fp, "\n");
  43.312 -        }
  43.313 -    }
  43.314 -}
    44.1 --- a/jitcraft/Opcodes.h	Tue Jul 24 23:53:34 2012 -0700
    44.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    44.3 @@ -1,94 +0,0 @@
    44.4 -/*
    44.5 - * Copyright (C) 2012 David Anderson
    44.6 - *
    44.7 - * This file is part of JITCraft.
    44.8 - *
    44.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   44.10 - * the terms of the GNU General Public License as published by the Free
   44.11 - * Software Foundation, either version 3 of the License, or (at your option)
   44.12 - * any later version.
   44.13 - * 
   44.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   44.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   44.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   44.17 - *
   44.18 - * You should have received a copy of the GNU General Public License along with
   44.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   44.20 - */
   44.21 -#ifndef _include_opcodes_h_
   44.22 -#define _include_opcodes_h_
   44.23 -
   44.24 -#include <assert.h>
   44.25 -#include <stdio.h>
   44.26 -
   44.27 -namespace ke {
   44.28 -
   44.29 -enum Opcode
   44.30 -{
   44.31 -#define OPDEF(name, number, text, length, uses, defs)   \
   44.32 -    name = number,
   44.33 -#include "Opcodes.tbl"
   44.34 -#undef OPDEF
   44.35 -    OPCODES_TOTAL
   44.36 -};
   44.37 -
   44.38 -#define OPDEF(name, number, text, length, uses, defs)   \
   44.39 -static const unsigned name##_LENGTH = length;
   44.40 -#include "Opcodes.tbl"
   44.41 -#undef OPDEF
   44.42 -
   44.43 -struct OpInfo
   44.44 -{
   44.45 -    const char *name;
   44.46 -    int length;
   44.47 -    int nuses;
   44.48 -    int ndefs;
   44.49 -};
   44.50 -
   44.51 -typedef unsigned char bytecode;
   44.52 -
   44.53 -extern OpInfo OpcodeInfo[];
   44.54 -
   44.55 -static inline Opcode
   44.56 -Invert(Opcode op)
   44.57 -{
   44.58 -    switch (op) {
   44.59 -      case OP_JEQ:
   44.60 -        return OP_JNE;
   44.61 -      case OP_JNE:
   44.62 -        return OP_JEQ;
   44.63 -      case OP_JG:
   44.64 -        return OP_JLE;
   44.65 -      case OP_JGE:
   44.66 -        return OP_JL;
   44.67 -      case OP_JL:
   44.68 -        return OP_JGE;
   44.69 -      default:
   44.70 -        assert(op == OP_JLE);
   44.71 -        return OP_JG;
   44.72 -    }
   44.73 -}
   44.74 -
   44.75 -static inline int
   44.76 -READ_INT32(bytecode *pc)
   44.77 -{
   44.78 -    return *reinterpret_cast<int *>(pc + 1);
   44.79 -}
   44.80 -static inline unsigned
   44.81 -READ_UINT32(bytecode *pc)
   44.82 -{
   44.83 -    return *reinterpret_cast<unsigned *>(pc + 1);
   44.84 -}
   44.85 -static inline float
   44.86 -READ_FLOAT(bytecode *pc)
   44.87 -{
   44.88 -    return *reinterpret_cast<float *>(pc + 1);
   44.89 -}
   44.90 -
   44.91 -class Code;
   44.92 -
   44.93 -void Disassemble(Code *code, FILE *fp);
   44.94 -
   44.95 -}
   44.96 -
   44.97 -#endif // _include_opcodes_h_
    45.1 --- a/jitcraft/Opcodes.tbl	Tue Jul 24 23:53:34 2012 -0700
    45.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    45.3 @@ -1,246 +0,0 @@
    45.4 -/* vim: set ts=4 sw=4 tw=99 et:
    45.5 - *
    45.6 - * Copyright (C) 2012 David Anderson
    45.7 - *
    45.8 - * This file is part of JITCraft.
    45.9 - *
   45.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   45.11 - * the terms of the GNU General Public License as published by the Free
   45.12 - * Software Foundation, either version 3 of the License, or (at your option)
   45.13 - * any later version.
   45.14 - * 
   45.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   45.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   45.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   45.18 - *
   45.19 - * You should have received a copy of the GNU General Public License along with
   45.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   45.21 - */
   45.22 -// Opcode macros:
   45.23 -//  NAME            NUMBER      TEXT                LENGTH  USES  DEFS   
   45.24 -//
   45.25 -// Type suffixes:
   45.26 -//  I = 32-bit integer
   45.27 -//  F = 32-bit IEEE-754 float
   45.28 -//  O = object reference
   45.29 -
   45.30 -// No operation.
   45.31 -OPDEF(OP_NOP,           0,          "nop",          1,      0,  0)
   45.32 -
   45.33 -// Pushes a signed integer immediate onto the stack.
   45.34 -OPDEF(OP_INT,           1,          "int",          5,      0,  1)    
   45.35 -
   45.36 -// Returns from the current routine, propagating the value at the top of the
   45.37 -// stack to the caller.
   45.38 -OPDEF(OP_RETURN,        2,          "return",       1,      1,  0)
   45.39 -
   45.40 -// Stack transitions for these comparison ops:
   45.41 -// rhs = pop()
   45.42 -// lhs = pop()
   45.43 -// if (lhs COMPARE rhs)
   45.44 -//    goto target (immediate, relative to the beginning of the jump instruction)
   45.45 -OPDEF(OP_JL,            3,          "jl",           5,      2,  0)
   45.46 -OPDEF(OP_JLE,           4,          "jle",          5,      2,  0)
   45.47 -OPDEF(OP_JG,            5,          "jg",           5,      2,  0)
   45.48 -OPDEF(OP_JGE,           6,          "jge",          5,      2,  0)
   45.49 -OPDEF(OP_JEQ,           7,          "jeq",          5,      2,  0)
   45.50 -OPDEF(OP_JNE,           8,          "jne",          5,      2,  0)
   45.51 -
   45.52 -// value = pop()
   45.53 -// if (value == [true, false])
   45.54 -//    goto target
   45.55 -OPDEF(OP_JT,            9,          "jt",           5,      1,  0)
   45.56 -OPDEF(OP_JF,            10,         "jf",           5,      1,  0)
   45.57 -
   45.58 -OPDEF(OP_JL_F,          11,         "jl.f",         5,      2,  0)
   45.59 -OPDEF(OP_JLE_F,         12,         "jle.f",        5,      2,  0)
   45.60 -OPDEF(OP_JG_F,          13,         "jg.f",         5,      2,  0)
   45.61 -OPDEF(OP_JGE_F,         14,         "jge.f",        5,      2,  0)
   45.62 -OPDEF(OP_JEQ_F,         15,         "jeq.f",        5,      2,  0)
   45.63 -OPDEF(OP_JNE_F,         16,         "jne.f",        5,      2,  0)
   45.64 -OPDEF(OP_JT_F,          17,         "jt.f",         5,      1,  0)
   45.65 -OPDEF(OP_JF_F,          18,         "jf.f",         5,      1,  0)
   45.66 -
   45.67 -// Unconditional jump.
   45.68 -OPDEF(OP_JUMP,          19,         "jump",         5,      0,  0)
   45.69 -
   45.70 -// Gets or sets the value of a local variable onto the stack. The local
   45.71 -// variable is given by an immediate index.
   45.72 -OPDEF(OP_GETLOCAL,      20,         "getlocal",     5,      0,  1)
   45.73 -OPDEF(OP_SETLOCAL,      21,         "setlocal",     5,      1,  1)
   45.74 -
   45.75 -// Stack transitions for these binary operators:
   45.76 -// rhs = pop()
   45.77 -// lhs = pop()
   45.78 -// push(lhs OP rhs)
   45.79 -OPDEF(OP_ADD,           22,         "add",          1,      2,  1)
   45.80 -OPDEF(OP_SUB,           23,         "sub",          1,      2,  1)
   45.81 -OPDEF(OP_MUL,           24,         "mul",          1,      2,  1)
   45.82 -OPDEF(OP_DIV,           25,         "div",          1,      2,  1)
   45.83 -OPDEF(OP_MOD,           26,         "mod",          1,      2,  1)
   45.84 -
   45.85 -OPDEF(OP_LT,            27,         "lt",           1,      2,  1)
   45.86 -OPDEF(OP_LE,            28,         "le",           1,      2,  1)
   45.87 -OPDEF(OP_GE,            29,         "ge",           1,      2,  1)
   45.88 -OPDEF(OP_GT,            30,         "gt",           1,      2,  1)
   45.89 -OPDEF(OP_EQ,            31,         "eq",           1,      2,  1)
   45.90 -OPDEF(OP_NE,            32,         "ne",           1,      2,  1)
   45.91 -
   45.92 -OPDEF(OP_NOT,           33,         "not",          1,      1,  1)
   45.93 -OPDEF(OP_NEG,           34,         "neg",          1,      1,  1)
   45.94 -
   45.95 -OPDEF(OP_POP,           35,         "pop",          1,      1,  0)
   45.96 -
   45.97 -// Unconditional terminator placed at the end of code. If a function returns
   45.98 -// void, this acts as a RETURNVOID. Otherwise, it must be unreachable.
   45.99 -OPDEF(OP_STOP,          36,         "stop",         1,      0,  0)
  45.100 -
  45.101 -// Call a function with N arguments. The target function must be the last item
  45.102 -// on the stack.
  45.103 -OPDEF(OP_CALL,          37,         "call",         1,      -1, 1)
  45.104 -
  45.105 -// Similar to GET/LOCAL, except for arguments.
  45.106 -OPDEF(OP_GETARG,        38,         "getarg",       5,      0,  1)
  45.107 -OPDEF(OP_SETARG,        39,         "setarg",       5,      1,  1)
  45.108 -
  45.109 -// Reads or writes an integer element to an unsafe array.
  45.110 -//  index = pop()
  45.111 -//  ref = pop()
  45.112 -//  ref[index]
  45.113 -//
  45.114 -OPDEF(OP_GETARRAY_I,    40,         "getarray.i",   1,      2,  1)
  45.115 -OPDEF(OP_SETARRAY_I,    41,         "setarray.i",   1,      3,  1)
  45.116 -OPDEF(OP_GETARRAY_F,    42,         "getarray.f",   1,      2,  1)
  45.117 -OPDEF(OP_SETARRAY_F,    43,         "setarray.f",   1,      3,  1)
  45.118 -OPDEF(OP_GETARRAY_C,    44,         "getarray.c",   1,      2,  1)
  45.119 -OPDEF(OP_SETARRAY_C,    45,         "setarray.c",   1,      3,  1)
  45.120 -OPDEF(OP_GETARRAY_O,    46,         "getarray.o",   1,      2,  1)
  45.121 -
  45.122 -// Allocate an array. The HeapTenure is stored as a byte following pc. The
  45.123 -// ArrayMap to use is specified as an index into the script's Map table.
  45.124 -//
  45.125 -// Format:
  45.126 -//  [u8 op] [u32 index]
  45.127 -OPDEF(OP_NEWARRAY,      47,         "newarray",     6,      0,  1)
  45.128 -
  45.129 -// Performs a bounds check on an unsafe array.
  45.130 -//
  45.131 -// index = pop()
  45.132 -// array = pop()
  45.133 -// push(array)
  45.134 -// push(index)
  45.135 -OPDEF(OP_BOUNDS,        48,         "bounds",       1,      2,  2)
  45.136 -
  45.137 -// Pushes a 32-bit IEEE-754 floating point immediate onto the stack.
  45.138 -OPDEF(OP_FLOAT,         49,         "float",        5,      0,  1)
  45.139 -
  45.140 -// Converts an integer to a 32-bit IEEE-754 floating point immediate.
  45.141 -OPDEF(OP_CVT_I2F,       50,         "cvt.i2f",      1,      1,  1)
  45.142 -
  45.143 -// Stack transitions for these binary operators:
  45.144 -// rhs = pop()
  45.145 -// lhs = pop()
  45.146 -// push(lhs OP rhs)
  45.147 -OPDEF(OP_ADD_F,         51,         "add.f",        1,      2,  1)
  45.148 -OPDEF(OP_SUB_F,         52,         "sub.f",        1,      2,  1)
  45.149 -OPDEF(OP_MUL_F,         53,         "mul.f",        1,      2,  1)
  45.150 -OPDEF(OP_DIV_F,         54,         "div.f",        1,      2,  1)
  45.151 -OPDEF(OP_UNUSED1,       55,         "unused0",      1,      0,  0)
  45.152 -
  45.153 -OPDEF(OP_LT_F,          56,         "lt.f",         1,      2,  1)
  45.154 -OPDEF(OP_LE_F,          57,         "le.f",         1,      2,  1)
  45.155 -OPDEF(OP_GE_F,          58,         "ge.f",         1,      2,  1)
  45.156 -OPDEF(OP_GT_F,          59,         "gt.f",         1,      2,  1)
  45.157 -OPDEF(OP_EQ_F,          60,         "eq.f",         1,      2,  1)
  45.158 -OPDEF(OP_NE_F,          61,         "ne.f",         1,      2,  1)
  45.159 -
  45.160 -OPDEF(OP_NOT_F,         62,         "not.f",        1,      1,  1)
  45.161 -OPDEF(OP_NEG_F,         63,         "neg.f",        1,      1,  1)
  45.162 -
  45.163 -// Bitwise operators.
  45.164 -OPDEF(OP_SHL,           64,         "shl",          1,      2,  1)
  45.165 -OPDEF(OP_SHR,           65,         "shr",          1,      2,  1)
  45.166 -OPDEF(OP_USHR,          66,         "ushr",         1,      2,  1)
  45.167 -OPDEF(OP_BITAND,        67,         "bitand",       1,      2,  1)
  45.168 -OPDEF(OP_BITOR,         68,         "bitor",        1,      2,  1)
  45.169 -OPDEF(OP_BITXOR,        69,         "bitxor",       1,      2,  1)
  45.170 -OPDEF(OP_BITNOT,        70,         "bitnot",       1,      1,  1)
  45.171 -
  45.172 -// Saves or restores the position of the LIFO heap to/from a local slot.
  45.173 -OPDEF(OP_SAVELIFO,      71,         "savelifo",     5,      0,  0)
  45.174 -OPDEF(OP_UNWINDLIFO,    72,         "unwindlifo",   5,      0,  0)
  45.175 -
  45.176 -// Composes a variable reference to a stack slot or argument.
  45.177 -OPDEF(OP_VARREF_LIFO,   73,         "varref.lifo",  5,      0,  1)
  45.178 -OPDEF(OP_ARGREF_LIFO,   74,         "argref.lifo",  5,      0,  1)
  45.179 -OPDEF(OP_SLOTREF_LIFO,  75,         "slotref.lifo", 1,      1,  1)
  45.180 -OPDEF(OP_ARRAYREF_LIFO, 76,         "arrayref.lifo",1,      2,  1)
  45.181 -OPDEF(OP_GETREF_I,      77,         "getref.i",     1,      1,  1)
  45.182 -OPDEF(OP_SETREF_I,      78,         "setref.i",     1,      2,  1)
  45.183 -OPDEF(OP_GETREF_F,      79,         "getref.f",     1,      1,  1)
  45.184 -OPDEF(OP_SETREF_F,      80,         "setref.f",     1,      2,  1)
  45.185 -
  45.186 -// Pushes an object reference onto the stack.
  45.187 -OPDEF(OP_OBJECT,        81,         "object",       5,      0,  1)
  45.188 -
  45.189 -// Performs an array-to-array assignment.
  45.190 -//   Left = pop()
  45.191 -//   Right = pop()
  45.192 -//   copy(Left, Right)
  45.193 -//   push(Left)
  45.194 -OPDEF(OP_ARRAYCOPY,     82,         "arraycopy",    1,      2,  1)
  45.195 -
  45.196 -// Duplicates the top item on the stack.
  45.197 -OPDEF(OP_DUP,           83,         "dup",          1,      1,  2)
  45.198 -
  45.199 -// Duplicates the top two items on the stack.
  45.200 -OPDEF(OP_DUP2,          84,         "dup2",         1,      2,  4)
  45.201 -
  45.202 -// Swaps the two items at the top of the stack.
  45.203 -OPDEF(OP_SWAP,          85,         "swap",         1,      2,  2)
  45.204 -
  45.205 -// Roll operation is the same as Forth. It steals a value on the stack,
  45.206 -// shifting all stack values down, and then places the stolen value back at
  45.207 -// the top of the stack.
  45.208 -//
  45.209 -//  p = sp[-3]
  45.210 -//  sp[-3] = sp[-2]
  45.211 -//  sp[-2] = sp[-1]
  45.212 -//  sp[-1] = p
  45.213 -OPDEF(OP_ROLL3,         86,         "roll3",        1,      3, 3)
  45.214 -
  45.215 -// Pick operation is the same as Forth. It pushes a copy of a slot at a
  45.216 -// specific depth.
  45.217 -//
  45.218 -// push(sp[-n])
  45.219 -OPDEF(OP_PICK2,         87,         "pick2",        1,      2, 3)
  45.220 -OPDEF(OP_PICK3,         88,         "pick3",        1,      3, 4)
  45.221 -
  45.222 -// Calls a native function. During the course of calling a native, arguments
  45.223 -// on the stack are re-pushed to match the cell-based native calling
  45.224 -// convention expected by ISourcePawnEngine.
  45.225 -//
  45.226 -// Unlike the normal CALL instruction, natives take truly variadic arguments
  45.227 -// and so we must specify the number of arguments. The format is:
  45.228 -//
  45.229 -// [u8 Opcode] [u32 Index] [u32 ArgCount]
  45.230 -//
  45.231 -OPDEF(OP_CALLNATIVE,    89,         "callnative",   9,      -1, 1)
  45.232 -
  45.233 -// Returns from a function that does return a value.
  45.234 -OPDEF(OP_RETURNVOID,    90,         "returnvoid",   1,      0, 0)
  45.235 -
  45.236 -// Loads the module of the running function.
  45.237 -OPDEF(OP_MODULE,        91,         "module",       1,      0, 1)
  45.238 -
  45.239 -// Loads a function from a module object. The operand is the slot number
  45.240 -// in the module.
  45.241 -OPDEF(OP_GETMODULE_FN,  92,         "getmodule.fn", 5,      1, 1)
  45.242 -
  45.243 -// Opcodes for accessing an environment slot in the global scope.
  45.244 -OPDEF(OP_SETGLOBAL_I,   93,         "setglobal.i",  5,      1, 1)
  45.245 -OPDEF(OP_SETGLOBAL_F,   94,         "setglobal.f",  5,      1, 1)
  45.246 -OPDEF(OP_SETGLOBAL_O,   95,         "setglobal.o",  5,      1, 1)
  45.247 -OPDEF(OP_GETGLOBAL_I,   96,         "getglobal.i",  5,      0, 1)
  45.248 -OPDEF(OP_GETGLOBAL_F,   97,         "getglobal.f",  5,      0, 1)
  45.249 -OPDEF(OP_GETGLOBAL_O,   98,         "getglobal.o",  5,      0, 1)
  45.250 \ No newline at end of file
    46.1 --- a/jitcraft/Parser.cpp	Tue Jul 24 23:53:34 2012 -0700
    46.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    46.3 @@ -1,1314 +0,0 @@
    46.4 -/* vim: set ts=4 sw=4 tw=99 et:
    46.5 - *
    46.6 - * Copyright (C) 2012 David Anderson
    46.7 - *
    46.8 - * This file is part of JITCraft.
    46.9 - *
   46.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   46.11 - * the terms of the GNU General Public License as published by the Free
   46.12 - * Software Foundation, either version 3 of the License, or (at your option)
   46.13 - * any later version.
   46.14 - * 
   46.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   46.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   46.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   46.18 - *
   46.19 - * You should have received a copy of the GNU General Public License along with
   46.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   46.21 - */
   46.22 -#include "Zone.h"
   46.23 -#include "Parser.h"
   46.24 -#include "FixedArray.h"
   46.25 -#include "Heap.h"
   46.26 -#include "Strings.h"
   46.27 -#include "Heap-inl.h"
   46.28 -
   46.29 -using namespace ke;
   46.30 -
   46.31 -Parser::Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length)
   46.32 -  : zone_(zone),
   46.33 -    cc_(cc),
   46.34 -    pool_(zone_->pool()),
   46.35 -    scanner_(cc, stream, length),
   46.36 -    scope_(NULL),
   46.37 -    unbound_(NULL)
   46.38 -{
   46.39 -    unbound_ = new (pool_) PoolList<NameProxy *>();
   46.40 -}
   46.41 -
   46.42 -bool
   46.43 -Parser::match(TokenKind kind)
   46.44 -{
   46.45 -    if (scanner_.peek() != kind)
   46.46 -        return false;
   46.47 -    scanner_.scan();
   46.48 -    return true;
   46.49 -}
   46.50 -
   46.51 -bool
   46.52 -Parser::matchSemicolon()
   46.53 -{
   46.54 -    return expect(TOK_SEMICOLON);
   46.55 -}
   46.56 -
   46.57 -bool
   46.58 -Parser::expect(TokenKind kind)
   46.59 -{
   46.60 -    TokenKind got = scanner_.scan();
   46.61 -    if (got == kind)
   46.62 -        return true;
   46.63 -    cc_.reportError(scanner_.begin(), Message_WrongToken, TokenNames[kind], TokenNames[got]);
   46.64 -    return false;
   46.65 -}
   46.66 -
   46.67 -Scope *
   46.68 -Parser::enterScope(Scope::Kind kind)
   46.69 -{
   46.70 -    scope_ = new (pool_) Scope(pool_, kind, scope_);
   46.71 -    if (!scope_->initialize())
   46.72 -        return NULL;
   46.73 -    return scope_;
   46.74 -}
   46.75 -
   46.76 -NameProxy *
   46.77 -Parser::bind(Handle<String> name)
   46.78 -{
   46.79 -    BoundName *bound = scope_->lookup(name);
   46.80 -    NameProxy *proxy = new (pool_) NameProxy(scanner_.begin(), name, bound);
   46.81 -    if (!bound && !unbound_->append(proxy))
   46.82 -        return NULL;
   46.83 -    return proxy;
   46.84 -}
   46.85 -
   46.86 -bool
   46.87 -Parser::matchName(String **name, TokenKind kind)
   46.88 -{
   46.89 -    assert(kind == TOK_NAME || kind == TOK_LABEL);
   46.90 -    *name = NULL;
   46.91 -    if (!match(kind))
   46.92 -        return false;
   46.93 -    *name = zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
   46.94 -    return true;
   46.95 -}
   46.96 -
   46.97 -String *
   46.98 -Parser::expectName()
   46.99 -{
  46.100 -    if (!expect(TOK_NAME))
  46.101 -        return NULL;
  46.102 -    return zone_->makeSymbol(scanner_.literal(), scanner_.literal_length());
  46.103 -}
  46.104 -
  46.105 -void
  46.106 -Parser::redeclarationError(BoundName *other)
  46.107 -{
  46.108 -    cc_.reportError(scanner_.begin(), Message_RedeclaredName, other->name()->chars(),
  46.109 -                    other->pos().line, other->pos().col);
  46.110 -}
  46.111 -
  46.112 -Expression *
  46.113 -Parser::primitive()
  46.114 -{
  46.115 -    TokenKind kind = scanner_.peek();
  46.116 -    switch (kind) {
  46.117 -      case TOK_NAME:
  46.118 -      {
  46.119 -        Local<String> name(zone_, expectName());
  46.120 -        if (!name)
  46.121 -            return NULL;
  46.122 -        return bind(name);
  46.123 -      }
  46.124 -
  46.125 -      case TOK_FLOAT_LITERAL:
  46.126 -      {
  46.127 -        scanner_.scan();
  46.128 -        double value = Scanner::ParseDouble(scanner_.literal());
  46.129 -        return new (pool_) FloatLiteral(scanner_.begin(), value);
  46.130 -      }
  46.131 -
  46.132 -      case TOK_INTEGER_LITERAL:
  46.133 -      {
  46.134 -        scanner_.scan();
  46.135 -        int value = atoi(scanner_.literal());
  46.136 -        return new (pool_) IntegerLiteral(scanner_.begin(), value);
  46.137 -      }
  46.138 -
  46.139 -      case TOK_STRING_LITERAL:
  46.140 -      {
  46.141 -        scanner_.scan();
  46.142 -        Local<ByteArray> array(zone_, ByteArray::New(zone_, scanner_.literal_length() + 1));
  46.143 -        if (!array)
  46.144 -            return NULL;
  46.145 -        memcpy(array->raw(), scanner_.literal(), scanner_.literal_length() + 1);
  46.146 -        return new (pool_) StringLiteral(scanner_.begin(), array);
  46.147 -      }
  46.148 -
  46.149 -      default:
  46.150 -      {
  46.151 -        if (kind != TOK_ERROR)
  46.152 -            cc_.reportError(scanner_.begin(), Message_ExpectedExpression, TokenNames[kind]);
  46.153 -        return NULL;
  46.154 -      }
  46.155 -    }
  46.156 -}
  46.157 -
  46.158 -Expression *
  46.159 -Parser::prefix()
  46.160 -{
  46.161 -    switch (scanner_.peek()) {
  46.162 -      case TOK_LPAREN:
  46.163 -      {
  46.164 -        scanner_.scan();
  46.165 -        Expression *expr = expression();
  46.166 -        if (!expr)
  46.167 -            return NULL;
  46.168 -        if (!expect(TOK_RPAREN))
  46.169 -            return NULL;
  46.170 -        return expr;
  46.171 -      }
  46.172 -
  46.173 -      default:
  46.174 -        return primitive();
  46.175 -    }
  46.176 -}
  46.177 -
  46.178 -Expression *
  46.179 -Parser::call(Expression *callee)
  46.180 -{
  46.181 -    ExpressionList *arguments = new (pool_) ExpressionList();
  46.182 -
  46.183 -    SourcePosition pos = scanner_.begin();
  46.184 -    expect(TOK_LPAREN);
  46.185 -    
  46.186 -    if (!match(TOK_RPAREN)) {
  46.187 -        while (true) {
  46.188 -            Expression *expr = expression();
  46.189 -            if (!expr)
  46.190 -                return NULL;
  46.191 -
  46.192 -            if (!arguments->append(expr))
  46.193 -                return NULL;
  46.194 -
  46.195 -            if (!match(TOK_COMMA))
  46.196 -                break;
  46.197 -        }
  46.198 -
  46.199 -        if (!expect(TOK_RPAREN))
  46.200 -            return NULL;
  46.201 -    }
  46.202 -
  46.203 -    return new (pool_) CallExpression(pos, callee, arguments);
  46.204 -}
  46.205 -
  46.206 -Expression *
  46.207 -Parser::index(Expression *left)
  46.208 -{
  46.209 -    expect(TOK_LBRACKET);
  46.210 -    
  46.211 -    SourcePosition pos = scanner_.begin();
  46.212 -    Expression *expr = expression();
  46.213 -    if (!expr)
  46.214 -        return NULL;
  46.215 -
  46.216 -    if (!expect(TOK_RBRACKET))
  46.217 -        return NULL;
  46.218 -
  46.219 -    return new (pool_) IndexExpression(pos, left, expr);
  46.220 -}
  46.221 -
  46.222 -Expression *
  46.223 -Parser::primary()
  46.224 -{
  46.225 -    Expression *expr = prefix();
  46.226 -    if (!expr)
  46.227 -        return NULL;
  46.228 -
  46.229 -    for (;;) {
  46.230 -        switch (scanner_.peek()) {
  46.231 -          case TOK_LPAREN:
  46.232 -            expr = call(expr);
  46.233 -            if (!expr)
  46.234 -                return NULL;
  46.235 -            break;
  46.236 -
  46.237 -          case TOK_LBRACKET:
  46.238 -            expr = index(expr);
  46.239 -            if (!expr)
  46.240 -                return NULL;
  46.241 -            break;
  46.242 -
  46.243 -          default:
  46.244 -            return expr;
  46.245 -        }
  46.246 -    }
  46.247 -}
  46.248 -
  46.249 -Expression *
  46.250 -Parser::unary()
  46.251 -{
  46.252 -    TokenKind token = scanner_.peek();
  46.253 -
  46.254 -    SourcePosition pos = scanner_.begin();
  46.255 -    switch (token) {
  46.256 -      case TOK_INCREMENT:
  46.257 -      case TOK_DECREMENT:
  46.258 -      {
  46.259 -        scanner_.scan();
  46.260 -        Expression *expr = expression();
  46.261 -        if (!expr)
  46.262 -            return NULL;
  46.263 -        return new (pool_) IncDecExpression(pos, token, expr, false);
  46.264 -      }
  46.265 -
  46.266 -      case TOK_MINUS:
  46.267 -      case TOK_NOT:
  46.268 -      case TOK_TILDE:
  46.269 -      {
  46.270 -        scanner_.scan();
  46.271 -        Expression *expr = expression();
  46.272 -        if (!expr)
  46.273 -            return NULL;
  46.274 -        return new (pool_) UnaryExpression(pos, token, expr);
  46.275 -      }
  46.276 -
  46.277 -      default:
  46.278 -        break;
  46.279 -    }
  46.280 -
  46.281 -    Expression *expr = primary();
  46.282 -
  46.283 -    token = scanner_.peek();
  46.284 -    if (token == TOK_INCREMENT || token == TOK_DECREMENT) {
  46.285 -        scanner_.scan();
  46.286 -        return new (pool_) IncDecExpression(pos, token, expr, true);
  46.287 -    }
  46.288 -
  46.289 -    return expr;
  46.290 -}
  46.291 -
  46.292 -Expression *
  46.293 -Parser::multiplication()
  46.294 -{
  46.295 -    Expression *left = unary();
  46.296 -    do {
  46.297 -        if (!match(TOK_SLASH) && !match(TOK_STAR) && !match(TOK_PERCENT))
  46.298 -            break;
  46.299 -        SourcePosition pos = scanner_.begin();
  46.300 -        TokenKind kind = scanner_.last();
  46.301 -        Expression *right = unary();
  46.302 -        if (!right)
  46.303 -            return NULL;
  46.304 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
  46.305 -    } while (left);
  46.306 -    return left;
  46.307 -}
  46.308 -
  46.309 -Expression *
  46.310 -Parser::addition()
  46.311 -{
  46.312 -    Expression *left = multiplication();
  46.313 -    while (left) {
  46.314 -        if (!match(TOK_PLUS) && !match(TOK_MINUS))
  46.315 -            break;
  46.316 -        SourcePosition pos = scanner_.begin();
  46.317 -        TokenKind kind = scanner_.last();
  46.318 -        Expression *right = multiplication();
  46.319 -        if (!right)
  46.320 -            return NULL;
  46.321 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
  46.322 -    }
  46.323 -    return left;
  46.324 -}
  46.325 -
  46.326 -Expression *
  46.327 -Parser::shift()
  46.328 -{
  46.329 -    Expression *left = addition();
  46.330 -    while (left) {
  46.331 -        if (!match(TOK_SHL) && !match(TOK_SHR) && !match(TOK_USHR))
  46.332 -            break;
  46.333 -        SourcePosition pos = scanner_.begin();
  46.334 -        TokenKind kind = scanner_.last();
  46.335 -        Expression *right = addition();
  46.336 -        if (!right)
  46.337 -            return NULL;
  46.338 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
  46.339 -    }
  46.340 -    return left;
  46.341 -}
  46.342 -
  46.343 -Expression *
  46.344 -Parser::bitand_()
  46.345 -{
  46.346 -    Expression *left = shift();
  46.347 -    while (left) {
  46.348 -        if (!match(TOK_BITAND))
  46.349 -            break;
  46.350 -        SourcePosition pos = scanner_.begin();
  46.351 -        Expression *right = shift();
  46.352 -        if (!right)
  46.353 -            return NULL;
  46.354 -        left = new (pool_) BinaryExpression(pos, TOK_BITAND, left, right);
  46.355 -    }
  46.356 -    return left;
  46.357 -}
  46.358 -
  46.359 -Expression *
  46.360 -Parser::bitxor()
  46.361 -{
  46.362 -    Expression *left = bitand_();
  46.363 -    while (left) {
  46.364 -        if (!match(TOK_BITXOR))
  46.365 -            break;
  46.366 -        SourcePosition pos = scanner_.begin();
  46.367 -        Expression *right = shift();
  46.368 -        if (!right)
  46.369 -            return NULL;
  46.370 -        left = new (pool_) BinaryExpression(pos, TOK_BITXOR, left, right);
  46.371 -    }
  46.372 -    return left;
  46.373 -}
  46.374 -
  46.375 -Expression *
  46.376 -Parser::bitor_()
  46.377 -{
  46.378 -    Expression *left = bitxor();
  46.379 -    while (left) {
  46.380 -        if (!match(TOK_BITOR))
  46.381 -            break;
  46.382 -        SourcePosition pos = scanner_.begin();
  46.383 -        Expression *right = bitxor();
  46.384 -        if (!right)
  46.385 -            return NULL;
  46.386 -        left = new (pool_) BinaryExpression(pos, TOK_BITOR, left, right);
  46.387 -    }
  46.388 -    return left;
  46.389 -}
  46.390 -
  46.391 -Expression *
  46.392 -Parser::relational()
  46.393 -{
  46.394 -    Expression *left = bitor_();
  46.395 -    while (left) {
  46.396 -        TokenKind kind = scanner_.peek();
  46.397 -        if (kind < TOK_LT || kind > TOK_GE)
  46.398 -            break;
  46.399 -        scanner_.scan();
  46.400 -        SourcePosition pos = scanner_.begin();
  46.401 -        Expression *right = shift();
  46.402 -        if (!right)
  46.403 -            return NULL;
  46.404 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
  46.405 -    }
  46.406 -    return left;
  46.407 -}
  46.408 -
  46.409 -Expression *
  46.410 -Parser::equals()
  46.411 -{
  46.412 -    Expression *left = relational();
  46.413 -    while (left) {
  46.414 -        if (!match(TOK_EQUALS) && !match(TOK_NOTEQUALS))
  46.415 -            break;
  46.416 -        TokenKind kind = scanner_.last();
  46.417 -        SourcePosition pos = scanner_.begin();
  46.418 -        Expression *right = relational();
  46.419 -        if (!right)
  46.420 -            return NULL;
  46.421 -        left = new (pool_) BinaryExpression(pos, kind, left, right);
  46.422 -    }
  46.423 -    return left;
  46.424 -}
  46.425 -
  46.426 -Expression *
  46.427 -Parser::and_()
  46.428 -{
  46.429 -    Expression *left = equals();
  46.430 -    while (left) {
  46.431 -        if (!match(TOK_AND))
  46.432 -            break;
  46.433 -        SourcePosition pos = scanner_.begin();
  46.434 -        Expression *right = equals();
  46.435 -        if (!right)
  46.436 -            return NULL;
  46.437 -        left = new (pool_) BinaryExpression(pos, TOK_AND, left, right);
  46.438 -    }
  46.439 -    return left;
  46.440 -}
  46.441 -
  46.442 -Expression *
  46.443 -Parser::or_()
  46.444 -{
  46.445 -    Expression *left = and_();
  46.446 -    while (left) {
  46.447 -        if (!match(TOK_OR))
  46.448 -            break;
  46.449 -        SourcePosition pos = scanner_.begin();
  46.450 -        Expression *right = and_();
  46.451 -        if (!right)
  46.452 -            return NULL;
  46.453 -        left = new (pool_) BinaryExpression(pos, TOK_OR, left, right);
  46.454 -    }
  46.455 -    return left;
  46.456 -}
  46.457 -
  46.458 -Expression *
  46.459 -Parser::ternary()
  46.460 -{
  46.461 -    Expression *cond = or_();
  46.462 -    if (!cond)
  46.463 -        return NULL;
  46.464 -    
  46.465 -    if (!match(TOK_QMARK))
  46.466 -        return cond;
  46.467 -
  46.468 -    SourcePosition pos = scanner_.begin();
  46.469 -    Expression *left = expression();
  46.470 -    if (!left)
  46.471 -        return NULL;
  46.472 -
  46.473 -    if (!expect(TOK_COLON))
  46.474 -        return NULL;
  46.475 -
  46.476 -    Expression *right = expression();
  46.477 -    if (!right)
  46.478 -        return NULL;
  46.479 -
  46.480 -    return new (pool_) TernaryExpression(pos, cond, left, right);
  46.481 -}
  46.482 -
  46.483 -Expression *
  46.484 -Parser::assignment()
  46.485 -{
  46.486 -    Expression *left = ternary();
  46.487 -    while (left) {
  46.488 -        TokenKind token = scanner_.peek();
  46.489 -        if (token != TOK_ASSIGN && (token < TOK_ASSIGN_ADD || token > TOK_ASSIGN_SHL))
  46.490 -            break;
  46.491 -        scanner_.scan();
  46.492 -        SourcePosition pos = scanner_.begin();
  46.493 -        Expression *expr = ternary();
  46.494 -        if (!expr)
  46.495 -            return NULL;
  46.496 -
  46.497 -        left = new (pool_) Assignment(pos, token, left, expr);
  46.498 -    }
  46.499 -    return left;
  46.500 -}
  46.501 -
  46.502 -Expression *
  46.503 -Parser::expression()
  46.504 -{
  46.505 -    return assignment();
  46.506 -}
  46.507 -
  46.508 -Statement *
  46.509 -Parser::while_()
  46.510 -{
  46.511 -    SourcePosition pos = scanner_.begin();
  46.512 -    scanner_.scan();
  46.513 -
  46.514 -    if (!expect(TOK_LPAREN))
  46.515 -        return NULL;
  46.516 -
  46.517 -    Expression *condition = expression();
  46.518 -    if (!condition)
  46.519 -        return NULL;
  46.520 -
  46.521 -    if (!expect(TOK_RPAREN))
  46.522 -        return NULL;
  46.523 -
  46.524 -    // Inside a loop, we force the creation of a scope object. Normally, we
  46.525 -    // will cull scopes if they have no variables. However inside a loop,
  46.526 -    // function calls that take references may compute a LIFO object, and to
  46.527 -    // avoid temporarily leaking many such objects, we ensure that a scope
  46.528 -    // is present so a LIFO slot can be allocated.
  46.529 -    if (!enterScope(Scope::BLOCK))
  46.530 -        return NULL;
  46.531 -
  46.532 -    Statement *body;
  46.533 -    if (scanner_.peek() == TOK_LBRACE)
  46.534 -        body = block(scope_);
  46.535 -    else
  46.536 -        body = localStatement();
  46.537 -    if (!body)
  46.538 -        return NULL;
  46.539 -
  46.540 -    scope_ = scope_->enclosing();
  46.541 -    return new (pool_) WhileStatement(pos, TOK_WHILE, condition, body);
  46.542 -}
  46.543 -
  46.544 -Statement *
  46.545 -Parser::do_()
  46.546 -{
  46.547 -    SourcePosition pos = scanner_.begin();
  46.548 -    scanner_.scan();
  46.549 -
  46.550 -    // See the comment in ::while_() as to why we force a scope.
  46.551 -    if (!enterScope(Scope::BLOCK))
  46.552 -        return NULL;
  46.553 -
  46.554 -    Statement *body;
  46.555 -    if (scanner_.peek() == TOK_LBRACE)
  46.556 -        body = block(scope_);
  46.557 -    else
  46.558 -        body = localStatement();
  46.559 -    if (!body)
  46.560 -        return NULL;
  46.561 -
  46.562 -    scope_ = scope_->enclosing();
  46.563 -
  46.564 -    if (!expect(TOK_WHILE))
  46.565 -        return NULL;
  46.566 -
  46.567 -    if (!expect(TOK_LPAREN))
  46.568 -        return NULL;
  46.569 -    Expression *condition = expression();
  46.570 -    if (!condition)
  46.571 -        return NULL;
  46.572 -    if (!expect(TOK_RPAREN))
  46.573 -        return NULL;
  46.574 -
  46.575 -    return new (pool_) WhileStatement(pos, TOK_DO, condition, body);
  46.576 -}
  46.577 -
  46.578 -Statement *
  46.579 -Parser::forStatement()
  46.580 -{
  46.581 -    SourcePosition pos = scanner_.begin();
  46.582 -    scanner_.scan();
  46.583 -    if (!expect(TOK_LPAREN))
  46.584 -        return NULL;
  46.585 -
  46.586 -    Statement *decl = NULL;
  46.587 -    if (!match(TOK_SEMICOLON)) {
  46.588 -        if (scanner_.peek() == TOK_NEW) {
  46.589 -            if (!enterScope(Scope::BLOCK))
  46.590 -                return NULL;
  46.591 -            if ((decl = variableDeclaration()) == NULL)
  46.592 -                return NULL;
  46.593 -        } else {
  46.594 -            if ((decl = expressionStatement()) == NULL)
  46.595 -                return NULL;
  46.596 -        }
  46.597 -        if (!expect(TOK_SEMICOLON))
  46.598 -            return NULL;
  46.599 -    }
  46.600 -
  46.601 -    Expression *condition = NULL;
  46.602 -    if (!match(TOK_SEMICOLON)) {
  46.603 -        if ((condition = expression()) == NULL)
  46.604 -            return NULL;
  46.605 -        if (!expect(TOK_SEMICOLON))
  46.606 -            return NULL;
  46.607 -    }
  46.608 -
  46.609 -    Statement *update = NULL;
  46.610 -    if (!match(TOK_RPAREN)) {
  46.611 -        if ((update = expressionStatement()) == NULL)
  46.612 -            return NULL;
  46.613 -        if (!expect(TOK_RPAREN))
  46.614 -            return NULL;
  46.615 -    }
  46.616 -
  46.617 -    // See the comment in ::while_() as to why we force a scope.
  46.618 -    if (!enterScope(Scope::BLOCK))
  46.619 -        return NULL;
  46.620 -
  46.621 -    Statement *body;
  46.622 -    if (scanner_.peek() == TOK_LBRACE)
  46.623 -        body = block(scope_);
  46.624 -    else
  46.625 -        body = localStatement();
  46.626 -    if (!body)
  46.627 -        return NULL;
  46.628 -
  46.629 -    scope_ = scope_->enclosing();
  46.630 -
  46.631 -    Scope *declScope = NULL;
  46.632 -    if (decl && decl->isVariableDeclaration()) {
  46.633 -        declScope = scope_->unlinkIfEmpty();
  46.634 -        scope_ = scope_->enclosing();
  46.635 -    }
  46.636 -    return new (pool_) ForStatement(pos, declScope, decl, condition, update, body);
  46.637 -}
  46.638 -
  46.639 -VariableDeclaration *
  46.640 -Parser::variableDeclaration()
  46.641 -{
  46.642 -    if (!expect(TOK_NEW))
  46.643 -        return NULL;
  46.644 -
  46.645 -    Local<String> tag(zone_);
  46.646 -    if (matchName(tag.ref(), TOK_LABEL) && !tag)
  46.647 -        return NULL;
  46.648 -
  46.649 -    Local<String> name(zone_, expectName());
  46.650 -    if (!name)
  46.651 -        return NULL;
  46.652 -
  46.653 -    if (BoundName *other = scope_->localLookup(name)) {
  46.654 -        redeclarationError(other);
  46.655 -        return NULL;
  46.656 -    }
  46.657 -
  46.658 -    Variable *var = scope_->declareVariable(name, scanner_.begin());
  46.659 -    if (!var)
  46.660 -        return NULL;
  46.661 -
  46.662 -    ExpressionList *postDimensions = NULL;
  46.663 -    if (scanner_.peek() == TOK_LBRACKET) {
  46.664 -        postDimensions = new (pool_) ExpressionList();
  46.665 -        while (match(TOK_LBRACKET)) {
  46.666 -            Expression *dim = expression();
  46.667 -            if (!dim)
  46.668 -                return NULL;
  46.669 -
  46.670 -            if (!expect(TOK_RBRACKET))
  46.671 -                return NULL;
  46.672 -
  46.673 -            if (!postDimensions->append(dim))
  46.674 -                return NULL;
  46.675 -        }
  46.676 -    }
  46.677 -    
  46.678 -    Expression *expr = NULL;
  46.679 -    if (match(TOK_ASSIGN)) {
  46.680 -        if ((expr = expression()) == NULL)
  46.681 -            return NULL;
  46.682 -    }
  46.683 -
  46.684 -    return new (pool_) VariableDeclaration(var->pos(), var, tag, postDimensions, expr);
  46.685 -}
  46.686 -
  46.687 -Statement *
  46.688 -Parser::returnStatement()
  46.689 -{
  46.690 -    SourcePosition pos = scanner_.begin();
  46.691 -    if (!expect(TOK_RETURN))
  46.692 -        return NULL;
  46.693 -
  46.694 -    Expression *expr = NULL;
  46.695 -    if (scanner_.peek() != TOK_SEMICOLON) {
  46.696 -        if ((expr = expression()) == NULL)
  46.697 -            return NULL;
  46.698 -
  46.699 -        // We only care about non-void returns when determining whether a
  46.700 -        // tagless function is non-void.
  46.701 -        encounteredReturn_ = true;
  46.702 -    }
  46.703 -
  46.704 -    return new (pool_) ReturnStatement(pos, expr);
  46.705 -}
  46.706 -
  46.707 -Statement *
  46.708 -Parser::expressionStatement()
  46.709 -{
  46.710 -    Expression *left = assignment();
  46.711 -    if (!left)
  46.712 -        return NULL;
  46.713 -
  46.714 -    return new (pool_) ExpressionStatement(left);
  46.715 -}
  46.716 -
  46.717 -Statement *
  46.718 -Parser::block(Scope *scope)
  46.719 -{
  46.720 -    if (!expect(TOK_LBRACE))
  46.721 -        return NULL;
  46.722 -
  46.723 -    SourcePosition pos = scanner_.begin();
  46.724 -    if (!scope && !enterScope(Scope::BLOCK))
  46.725 -        return NULL;
  46.726 -
  46.727 -    StatementList *statements = new (pool_) StatementList();
  46.728 -    while (!match(TOK_RBRACE)) {
  46.729 -        Statement *statement = localStatement();
  46.730 -        if (statement == NULL)
  46.731 -            return NULL;
  46.732 -        if (!statements->append(statement))
  46.733 -            return NULL;
  46.734 -    }
  46.735 -
  46.736 -    if (!scope) {
  46.737 -    	scope = scope_->unlinkIfEmpty();
  46.738 -        scope_ = scope_->enclosing();
  46.739 -    }
  46.740 -    BlockStatement *block = new (pool_) BlockStatement(pos, scope, statements);
  46.741 -    return block;
  46.742 -}
  46.743 -
  46.744 -Statement *
  46.745 -Parser::if_()
  46.746 -{
  46.747 -    expect(TOK_IF);
  46.748 -    
  46.749 -    SourcePosition pos = scanner_.begin();
  46.750 -    if (!expect(TOK_LPAREN))
  46.751 -        return NULL;
  46.752 -
  46.753 -    Expression *cond = expression();
  46.754 -    if (!cond)
  46.755 -        return NULL;
  46.756 -
  46.757 -    if (!expect(TOK_RPAREN))
  46.758 -        return NULL;
  46.759 -
  46.760 -    Statement *ifTrue = localStatement();
  46.761 -    if (!ifTrue)
  46.762 -        return NULL;
  46.763 -
  46.764 -    IfStatement *outer = new (pool_) IfStatement(pos, cond, ifTrue);
  46.765 -
  46.766 -    IfStatement *last = outer;
  46.767 -    while (match(TOK_ELSE)) {
  46.768 -        if (!match(TOK_IF)) {
  46.769 -            Statement *ifFalse = localStatement();
  46.770 -            if (!ifFalse)
  46.771 -                return NULL;
  46.772 -
  46.773 -            last->setIfFalse(ifFalse);
  46.774 -            break;
  46.775 -        }
  46.776 -
  46.777 -        SourcePosition pos = scanner_.begin();
  46.778 -        if (!expect(TOK_LPAREN))
  46.779 -            return NULL;
  46.780 -
  46.781 -        Expression *otherCond = expression();
  46.782 -        if (!otherCond)
  46.783 -            return NULL;
  46.784 -
  46.785 -        if (!expect(TOK_RPAREN))
  46.786 -            return NULL;
  46.787 -
  46.788 -        Statement *otherIfTrue = localStatement();
  46.789 -        if (!otherIfTrue)
  46.790 -            return NULL;
  46.791 -
  46.792 -        IfStatement *inner = new (pool_) IfStatement(pos, otherCond, otherIfTrue);
  46.793 -        last->setIfFalse(inner);
  46.794 -        last = inner;
  46.795 -    }
  46.796 -
  46.797 -    return outer;
  46.798 -}
  46.799 -
  46.800 -Statement *
  46.801 -Parser::localStatement()
  46.802 -{
  46.803 -    Statement *statement = NULL;
  46.804 -
  46.805 -    // Statements which must be followed by a semicolon will break out of the
  46.806 -    // switch. If they may end in BlockStatements, they'll immediately return.
  46.807 -
  46.808 -    switch (scanner_.peek()) {
  46.809 -        case TOK_NEW:
  46.810 -          if ((statement = variableDeclaration()) == NULL)
  46.811 -              return NULL;
  46.812 -          break;
  46.813 -
  46.814 -        case TOK_FOR:
  46.815 -          return forStatement();
  46.816 -
  46.817 -        case TOK_WHILE:
  46.818 -          return while_();
  46.819 -
  46.820 -        case TOK_BREAK:
  46.821 -          scanner_.scan();
  46.822 -          statement = new (pool_) BreakStatement(scanner_.begin());
  46.823 -          break;
  46.824 -
  46.825 -        case TOK_CONTINUE:
  46.826 -          scanner_.scan();
  46.827 -          statement = new (pool_) ContinueStatement(scanner_.begin());
  46.828 -          break;
  46.829 -
  46.830 -        case TOK_DO:
  46.831 -          if ((statement = do_()) == NULL)
  46.832 -              return NULL;
  46.833 -          break;
  46.834 -
  46.835 -        case TOK_RETURN:
  46.836 -          if ((statement = returnStatement()) == NULL)
  46.837 -              return NULL;
  46.838 -          break;
  46.839 -
  46.840 -        case TOK_ENUM:
  46.841 -          if ((statement = enum_()) == NULL)
  46.842 -              return NULL;
  46.843 -          break;
  46.844 -
  46.845 -        case TOK_IF:
  46.846 -          return if_();
  46.847 -
  46.848 -        case TOK_LBRACE:
  46.849 -          return block();
  46.850 -
  46.851 -	default:
  46.852 -	  break;
  46.853 -    }
  46.854 -
  46.855 -    if (!statement) {
  46.856 -        if ((statement = expressionStatement()) == NULL)
  46.857 -            return NULL;
  46.858 -    }
  46.859 -
  46.860 -    if (!expect(TOK_SEMICOLON))
  46.861 -        return NULL;
  46.862 -
  46.863 -    return statement;
  46.864 -}
  46.865 -
  46.866 -Statement *
  46.867 -Parser::enum_()
  46.868 -{
  46.869 -    expect(TOK_ENUM);
  46.870 -
  46.871 -    SourcePosition pos = scanner_.begin();
  46.872 -
  46.873 -    Local<String> name(zone_);
  46.874 -    if (matchName(name.ref())) {
  46.875 -        if (!name)
  46.876 -            return NULL;
  46.877 -
  46.878 -        if (BoundName *other = scope_->localLookup(name)) {
  46.879 -            redeclarationError(other);
  46.880 -            return NULL;
  46.881 -        }
  46.882 -
  46.883 -        if (!scope_->declareEnum(name, scanner_.begin()))
  46.884 -            return NULL;
  46.885 -    }
  46.886 -
  46.887 -    EnumStatement::EntryList *entries = new (pool_) EnumStatement::EntryList();
  46.888 -
  46.889 -    if (!expect(TOK_LBRACE))
  46.890 -        return NULL;
  46.891 -
  46.892 -    do {
  46.893 -        if (scanner_.peek() == TOK_RBRACE)
  46.894 -            break;
  46.895 -
  46.896 -        Local<String> name(zone_, expectName());
  46.897 -        if (!name)
  46.898 -            return NULL;
  46.899 -
  46.900 -        if (BoundName *other = scope_->localLookup(name)) {
  46.901 -            redeclarationError(other);
  46.902 -            return NULL;
  46.903 -        }
  46.904 -
  46.905 -        NamedConstant *constant = scope_->declareConstant(name, scanner_.begin());
  46.906 -        if (!constant)
  46.907 -            return NULL;
  46.908 -
  46.909 -        Expression *expr = NULL;
  46.910 -        if (match(TOK_ASSIGN)) {
  46.911 -            if ((expr = expression()) == NULL)
  46.912 -                return NULL;
  46.913 -        }
  46.914 -
  46.915 -        if (!entries->append(EnumStatement::Entry(constant, expr)))
  46.916 -            return NULL;
  46.917 -    } while (match(TOK_COMMA));
  46.918 -    if (!expect(TOK_RBRACE))
  46.919 -        return NULL;
  46.920 -
  46.921 -    return new (pool_) EnumStatement(pos, name, entries);
  46.922 -}
  46.923 -
  46.924 -Statement *
  46.925 -Parser::function(TokenKind token)
  46.926 -{
  46.927 -    Local<String> name(zone_, expectName());
  46.928 -    if (!name)
  46.929 -        return NULL;
  46.930 -
  46.931 -    SourcePosition pos = scanner_.begin();
  46.932 -
  46.933 -    // The function name goes into the outer (global) scope.
  46.934 -    assert(!scope_->enclosing());
  46.935 -
  46.936 -    NamedFunction *fun;
  46.937 -    if (BoundName *other = scope_->localLookup(name)) {
  46.938 -        // We allow a redeclaration if the new type is a public, and the old
  46.939 -        // type was a forward. However, the forward must come first.
  46.940 -        if (other->kind() != BoundName::FUNCTION) {
  46.941 -            redeclarationError(other);
  46.942 -            return NULL;
  46.943 -        }
  46.944 -
  46.945 -        fun = other->toNamedFunction();
  46.946 -        if (!fun->isForward() || token != TOK_PUBLIC) {
  46.947 -            redeclarationError(other);
  46.948 -            return NULL;
  46.949 -        }
  46.950 -        
  46.951 -        // We've got the same name, but the original is a forward, so let it
  46.952 -        // slide and re-use the original declaration.
  46.953 -        fun->setImplemented(scanner_.begin());
  46.954 -    } else {
  46.955 -        fun = scope_->declareFunction(name, scanner_.begin(), token);
  46.956 -        if (!fun)
  46.957 -            return NULL;
  46.958 -    }
  46.959 -
  46.960 -    Scope *scope = enterScope(Scope::FUNCTION);
  46.961 -    if (!scope)
  46.962 -        return NULL;
  46.963 -
  46.964 -    ParameterList *parameters = new (pool_) ParameterList();
  46.965 -
  46.966 -    if (!expect(TOK_LPAREN))
  46.967 -        return NULL;
  46.968 -    if (!match(TOK_RPAREN)) {
  46.969 -        while (true) {
  46.970 -            bool isConst = match(TOK_CONST);
  46.971 -            bool ref = match(TOK_AMPERSAND);
  46.972 -
  46.973 -            SourcePosition begin = scanner_.begin();
  46.974 -            Local<String> tag(zone_);
  46.975 -            if (matchName(tag.ref(), TOK_LABEL) && !tag)
  46.976 -                return NULL;
  46.977 -
  46.978 -            if (match(TOK_ELLIPSES)) {
  46.979 -                if (isConst || ref) {
  46.980 -                    cc_.reportError(begin, Message_InvalidVarArgs);
  46.981 -                    return NULL;
  46.982 -                }
  46.983 -
  46.984 -                if (token != TOK_NATIVE) {
  46.985 -                    cc_.reportError(begin, Message_VarArgsOutsideNative);
  46.986 -                    return NULL;
  46.987 -                }
  46.988 -
  46.989 -                fun->markNativeVariadic();
  46.990 -                break;
  46.991 -            }
  46.992 -
  46.993 -            Local<String> name(zone_, expectName());
  46.994 -            if (!name)
  46.995 -                return NULL;
  46.996 -
  46.997 -            if (BoundName *other = scope_->localLookup(name)) {
  46.998 -                redeclarationError(other);
  46.999 -                return NULL;
 46.1000 -            }
 46.1001 -            Variable *arg = scope_->declareArgument(name, scanner_.begin());
 46.1002 -            if (!arg)
 46.1003 -                return NULL;
 46.1004 -
 46.1005 -            // Look for dimensions.
 46.1006 -            ExpressionList *postDimensions = NULL;
 46.1007 -            while (match(TOK_LBRACKET)) {
 46.1008 -                if (!postDimensions)
 46.1009 -                    postDimensions = new (pool_) ExpressionList();
 46.1010 -
 46.1011 -                Expression *dim = NULL;
 46.1012 -                if (!match(TOK_RBRACKET)) {
 46.1013 -                    if ((dim = expression()) == NULL)
 46.1014 -                        return NULL;
 46.1015 -                    if (!expect(TOK_RBRACKET))
 46.1016 -                        return NULL;
 46.1017 -                }
 46.1018 -
 46.1019 -                if (!postDimensions->append(dim))
 46.1020 -                    return NULL;
 46.1021 -            }
 46.1022 -
 46.1023 -            Parameter *parameter = new (pool_) Parameter(arg, tag, ref, isConst, postDimensions);
 46.1024 -            if (!parameters->append(parameter))
 46.1025 -                return NULL;
 46.1026 -
 46.1027 -            if (!match(TOK_COMMA))
 46.1028 -                break;
 46.1029 -        }
 46.1030 -        if (!expect(TOK_RPAREN))
 46.1031 -            return NULL;
 46.1032 -    }
 46.1033 -
 46.1034 -    encounteredReturn_ = false;
 46.1035 -
 46.1036 -    Statement *body = NULL;
 46.1037 -    if (token != TOK_FORWARD && token != TOK_NATIVE) {
 46.1038 -        body = block();
 46.1039 -        if (!body)
 46.1040 -            return NULL;
 46.1041 -    }
 46.1042 -
 46.1043 -    scope_ = scope_->enclosing();
 46.1044 -    return new (pool_) FunctionStatement(pos, scope, fun, body, parameters, encounteredReturn_);
 46.1045 -}
 46.1046 -
 46.1047 -ParseTree *
 46.1048 -Parser::parse()
 46.1049 -{
 46.1050 -    StatementList *statements = new (pool_) StatementList();
 46.1051 -
 46.1052 -    if (!enterScope(Scope::GLOBAL))
 46.1053 -        return NULL;
 46.1054 -
 46.1055 -    for (;;) {
 46.1056 -        Statement *statement = NULL;
 46.1057 -
 46.1058 -        switch (scanner_.peek()) {
 46.1059 -          case TOK_ERROR:
 46.1060 -            return NULL;
 46.1061 -
 46.1062 -          case TOK_EOF:
 46.1063 -            break;
 46.1064 -
 46.1065 -          case TOK_NAME:
 46.1066 -            if ((statement = function(TOK_NAME)) == NULL)
 46.1067 -                return NULL;
 46.1068 -            break;
 46.1069 -
 46.1070 -          case TOK_FORWARD:
 46.1071 -          case TOK_PUBLIC:
 46.1072 -          case TOK_NATIVE:
 46.1073 -          {
 46.1074 -            TokenKind kind = scanner_.scan();
 46.1075 -            if ((statement = function(kind)) == NULL)
 46.1076 -                return NULL;
 46.1077 -            if ((kind == TOK_FORWARD || kind == TOK_NATIVE) && !matchSemicolon())
 46.1078 -                return NULL;
 46.1079 -            break;
 46.1080 -          }
 46.1081 -
 46.1082 -          case TOK_NEW:
 46.1083 -          {
 46.1084 -            if ((statement = variableDeclaration()) == NULL)
 46.1085 -               return NULL;
 46.1086 -            if (!matchSemicolon())
 46.1087 -                return NULL;
 46.1088 -            break;
 46.1089 -          }
 46.1090 -
 46.1091 -          case TOK_ENUM:
 46.1092 -            if ((statement = enum_()) == NULL)
 46.1093 -                return NULL;
 46.1094 -            if (!matchSemicolon())
 46.1095 -                return NULL;
 46.1096 -            break;
 46.1097 -
 46.1098 -          default:
 46.1099 -            cc_.reportError(scanner_.begin(), Message_ExpectedGlobal);
 46.1100 -            return NULL;
 46.1101 -        }
 46.1102 -
 46.1103 -        if (!statement)
 46.1104 -            break;
 46.1105 -
 46.1106 -        if (!statements->append(statement))
 46.1107 -            return NULL;
 46.1108 -    }
 46.1109 -
 46.1110 -    return new (pool_) ParseTree(scope_, statements, unbound_);
 46.1111 -}
 46.1112 -
 46.1113 -class AstPrinter : public AstVisitor
 46.1114 -{
 46.1115 -    FILE *fp_;
 46.1116 -    size_t level_;
 46.1117 -
 46.1118 -  private:
 46.1119 -    void prefix() {
 46.1120 -        for (size_t i = 0; i < level_; i++)
 46.1121 -            fprintf(fp_, "  ");
 46.1122 -    }
 46.1123 -    void indent() {
 46.1124 -        level_++;
 46.1125 -    }
 46.1126 -    void unindent() {
 46.1127 -        level_--;
 46.1128 -    }
 46.1129 -
 46.1130 -  public:
 46.1131 -    AstPrinter(FILE *fp)
 46.1132 -      : fp_(fp),
 46.1133 -        level_(0)
 46.1134 -    {
 46.1135 -    }
 46.1136 -
 46.1137 -    void visit(NameProxy *name) {
 46.1138 -        prefix();
 46.1139 -        fprintf(fp_, "[ NameProxy (%s)%s\n", name->name()->chars(),
 46.1140 -                (name->binding() ? "" : " unbound"));
 46.1141 -    }
 46.1142 -    void visit(CallExpression *node) {
 46.1143 -        prefix();
 46.1144 -        fprintf(fp_, "[ CallExpression\n");
 46.1145 -        indent();
 46.1146 -        node->callee()->accept(this);
 46.1147 -        for (size_t i = 0; i < node->arguments()->length(); i++)
 46.1148 -            node->arguments()->at(i)->accept(this);
 46.1149 -        unindent();
 46.1150 -    }
 46.1151 -    void visit(FunctionStatement *node) {
 46.1152 -        prefix();
 46.1153 -        fprintf(fp_, "[ FunctionStatement (%s)\n", node->fun()->name()->chars());
 46.1154 -        indent();
 46.1155 -        if (node->body())
 46.1156 -            node->body()->accept(this);
 46.1157 -        unindent();
 46.1158 -    }
 46.1159 -    void visit(ExpressionStatement *node) {
 46.1160 -        prefix();
 46.1161 -        fprintf(fp_, "[ ExpressionStatement\n");
 46.1162 -        indent();
 46.1163 -        node->expression()->accept(this);
 46.1164 -        unindent();
 46.1165 -    }
 46.1166 -    void visit(Assignment *node) {
 46.1167 -        prefix();
 46.1168 -        fprintf(fp_, "[ Assignment\n");
 46.1169 -        indent();
 46.1170 -        node->lvalue()->accept(this);
 46.1171 -        node->expression()->accept(this);
 46.1172 -        unindent();
 46.1173 -    }
 46.1174 -    void visit(TernaryExpression *node) {
 46.1175 -        prefix();
 46.1176 -        fprintf(fp_, "[ TernaryExpression\n");
 46.1177 -        indent();
 46.1178 -        node->condition()->accept(this);
 46.1179 -        node->left()->accept(this);
 46.1180 -        node->right()->accept(this);
 46.1181 -        unindent();
 46.1182 -    }
 46.1183 -    void visit(BinaryExpression *node) {
 46.1184 -        prefix();
 46.1185 -        fprintf(fp_, "[ BinaryExpression (%s)\n", TokenNames[node->token()]);
 46.1186 -        indent();
 46.1187 -        node->left()->accept(this);
 46.1188 -        node->right()->accept(this);
 46.1189 -        unindent();
 46.1190 -    }
 46.1191 -    void visit(UnaryExpression *node) {
 46.1192 -        prefix();
 46.1193 -        fprintf(fp_, "[ UnaryExpression (%s)\n", TokenNames[node->token()]);
 46.1194 -        indent();
 46.1195 -        node->expression()->accept(this);
 46.1196 -        unindent();
 46.1197 -    }
 46.1198 -    void visit(ReturnStatement *node) {
 46.1199 -        prefix();
 46.1200 -        fprintf(fp_, "[ ReturnStatement\n");
 46.1201 -        indent();
 46.1202 -        if (node->expression())
 46.1203 -            node->expression()->accept(this);
 46.1204 -        unindent();
 46.1205 -    }
 46.1206 -    void visit(ForStatement *node) {
 46.1207 -        prefix();
 46.1208 -        fprintf(fp_, "[ ForStatement\n");
 46.1209 -        indent();
 46.1210 -        if (node->initialization())
 46.1211 -            node->initialization()->accept(this);
 46.1212 -        if (node->condition())
 46.1213 -            node->condition()->accept(this);
 46.1214 -        if (node->update())
 46.1215 -            node->update()->accept(this);
 46.1216 -        node->body()->accept(this);
 46.1217 -        unindent();
 46.1218 -    }
 46.1219 -    void visit(BlockStatement *node) {
 46.1220 -        prefix();
 46.1221 -        fprintf(fp_, "[ BlockStatement\n");
 46.1222 -        indent();
 46.1223 -        for (size_t i = 0; i < node->statements()->length(); i++)
 46.1224 -            node->statements()->at(i)->accept(this);
 46.1225 -        unindent();
 46.1226 -    }
 46.1227 -    void visit(VariableDeclaration *node) {
 46.1228 -        prefix();
 46.1229 -        fprintf(fp_, "[ VariableDeclaration (%s)\n", node->variable()->name()->chars());
 46.1230 -        indent();
 46.1231 -        if (node->initialization())
 46.1232 -            node->initialization()->accept(this);
 46.1233 -        unindent();
 46.1234 -    }
 46.1235 -    void visit(IntegerLiteral *node) {
 46.1236 -        prefix();
 46.1237 -        fprintf(fp_, "[ IntegerLiteral (%d)\n", node->value());
 46.1238 -    }
 46.1239 -    void visit(FloatLiteral *node) {
 46.1240 -        prefix();
 46.1241 -        fprintf(fp_, "[ FloatLiteral (%f)\n", node->value());
 46.1242 -    }
 46.1243 -    void visit(IfStatement *node) {
 46.1244 -        prefix();
 46.1245 -        fprintf(fp_, "[ IfStatement\n");
 46.1246 -        indent();
 46.1247 -        node->ifTrue()->accept(this);
 46.1248 -        if (node->ifFalse())
 46.1249 -            node->ifFalse()->accept(this);
 46.1250 -        unindent();
 46.1251 -    }
 46.1252 -    void visit(IndexExpression *node) {
 46.1253 -        prefix();
 46.1254 -        fprintf(fp_, "[ IndexExpression\n");
 46.1255 -        indent();
 46.1256 -        node->left()->accept(this);
 46.1257 -        node->right()->accept(this);
 46.1258 -        unindent();
 46.1259 -    }
 46.1260 -    void visit(EnumStatement *node) {
 46.1261 -        prefix();
 46.1262 -        fprintf(fp_, "[ EnumStatement (%s)\n", node->name() ? node->name()->chars() : "<anonymous>");
 46.1263 -        indent();
 46.1264 -        for (size_t i = 0; i < node->entries()->length(); i++) {
 46.1265 -            prefix();
 46.1266 -            fprintf(fp_, "%s =\n", node->entries()->at(i).name->name()->chars());
 46.1267 -            if (node->entries()->at(i).expr) {
 46.1268 -                indent();
 46.1269 -                node->entries()->at(i).expr->accept(this);
 46.1270 -                unindent();
 46.1271 -            }
 46.1272 -        }
 46.1273 -        unindent();
 46.1274 -    }
 46.1275 -    void visit(WhileStatement *node) {
 46.1276 -        prefix();
 46.1277 -        fprintf(fp_, "[ WhileStatement (%s)\n",
 46.1278 -                (node->token() == TOK_DO) ? "do" : "while");
 46.1279 -        indent();
 46.1280 -        if (node->token() == TOK_DO) {
 46.1281 -            node->condition()->accept(this);
 46.1282 -            node->body()->accept(this);
 46.1283 -        } else {
 46.1284 -            node->condition()->accept(this);
 46.1285 -            node->body()->accept(this);
 46.1286 -        }
 46.1287 -        unindent();
 46.1288 -    }
 46.1289 -    void visit(BreakStatement *node) {
 46.1290 -        prefix();
 46.1291 -        fprintf(fp_, "[ BreakStatement\n");
 46.1292 -    }
 46.1293 -    void visit(ContinueStatement *node) {
 46.1294 -        prefix();
 46.1295 -        fprintf(fp_, "[ ContinueStatement\n");
 46.1296 -    }
 46.1297 -    void visit(StringLiteral *node) {
 46.1298 -        prefix();
 46.1299 -        fprintf(fp_, "[ StringLiteral\n");
 46.1300 -    }
 46.1301 -    void visit(IncDecExpression *node) {
 46.1302 -        prefix();
 46.1303 -        fprintf(fp_, "[ IncDecExpression (postfix=%d)\n", node->postfix());
 46.1304 -        indent();
 46.1305 -        node->expression()->accept(this);
 46.1306 -        unindent();
 46.1307 -    }
 46.1308 -};
 46.1309 -
 46.1310 -void
 46.1311 -ParseTree::dump(FILE *fp)
 46.1312 -{
 46.1313 -    AstPrinter printer(fp);
 46.1314 -
 46.1315 -    for (size_t i = 0; i < statements_->length(); i++)
 46.1316 -        statements_->at(i)->accept(&printer);
 46.1317 -}
    47.1 --- a/jitcraft/Parser.h	Tue Jul 24 23:53:34 2012 -0700
    47.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    47.3 @@ -1,91 +0,0 @@
    47.4 -/*
    47.5 - * Copyright (C) 2012 David Anderson
    47.6 - *
    47.7 - * This file is part of JITCraft.
    47.8 - *
    47.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   47.10 - * the terms of the GNU General Public License as published by the Free
   47.11 - * Software Foundation, either version 3 of the License, or (at your option)
   47.12 - * any later version.
   47.13 - * 
   47.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   47.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   47.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   47.17 - *
   47.18 - * You should have received a copy of the GNU General Public License along with
   47.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   47.20 - */
   47.21 -#ifndef _include_jitcraft_parser_h_
   47.22 -#define _include_jitcraft_parser_h_
   47.23 -
   47.24 -#include <stdio.h>
   47.25 -#include "AST.h"
   47.26 -#include "Scanner.h"
   47.27 -#include "Scopes.h"
   47.28 -#include "Strings.h"
   47.29 -
   47.30 -namespace ke {
   47.31 -
   47.32 -class Parser
   47.33 -{
   47.34 -    Zone *zone_;
   47.35 -    CompileContext &cc_;
   47.36 -    PoolAllocator &pool_;
   47.37 -    Scanner scanner_;
   47.38 -    Scope *scope_;
   47.39 -    PoolList<NameProxy *> *unbound_;
   47.40 -    bool encounteredReturn_;
   47.41 -
   47.42 -  private:
   47.43 -    void redeclarationError(BoundName *name);
   47.44 -    bool match(TokenKind kind);
   47.45 -    bool expect(TokenKind kind);
   47.46 -    bool matchSemicolon();
   47.47 -
   47.48 -    Scope *enterScope(Scope::Kind kind);
   47.49 -
   47.50 -    VariableDeclaration *variableDeclaration();
   47.51 -    bool matchName(String **name, TokenKind kind = TOK_NAME);
   47.52 -    String *expectName();
   47.53 -    NameProxy *bind(Handle<String> name);
   47.54 -    Expression *primitive();
   47.55 -    Expression *call(Expression *callee);
   47.56 -    Expression *index(Expression *left);
   47.57 -    Expression *prefix();
   47.58 -    Expression *primary();
   47.59 -    Expression *unary();
   47.60 -    Expression *multiplication();
   47.61 -    Expression *addition();
   47.62 -    Expression *shift();
   47.63 -    Expression *bitand_();
   47.64 -    Expression *bitxor();
   47.65 -    Expression *bitor_();
   47.66 -    Expression *relational();
   47.67 -    Expression *equals();
   47.68 -    Expression *and_();
   47.69 -    Expression *or_();
   47.70 -    Expression *ternary();
   47.71 -    Expression *assignment();
   47.72 -    Expression *expression();
   47.73 -
   47.74 -    Statement *enum_();
   47.75 -    Statement *if_();
   47.76 -    Statement *block(Scope *scope = NULL);
   47.77 -    Statement *function(TokenKind tok);
   47.78 -    Statement *expressionStatement();
   47.79 -    Statement *while_();
   47.80 -    Statement *do_();
   47.81 -    Statement *forStatement();
   47.82 -    Statement *localStatement();
   47.83 -    Statement *globalStatement();
   47.84 -    Statement *returnStatement();
   47.85 -
   47.86 -  public:
   47.87 -    Parser(Zone *zone, CompileContext &cc, const char *stream, size_t length);
   47.88 -
   47.89 -    ParseTree *parse();
   47.90 -};
   47.91 -
   47.92 -}
   47.93 -
   47.94 -#endif // _include_jitcraft_parser_h_
    48.1 --- a/jitcraft/Platform-Posix.cpp	Tue Jul 24 23:53:34 2012 -0700
    48.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    48.3 @@ -1,101 +0,0 @@
    48.4 -/* vim: set ts=4 sw=4 tw=99 et:
    48.5 - *
    48.6 - * Copyright (C) 2012 David Anderson
    48.7 - *
    48.8 - * This file is part of JITCraft.
    48.9 - *
   48.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   48.11 - * the terms of the GNU General Public License as published by the Free
   48.12 - * Software Foundation, either version 3 of the License, or (at your option)
   48.13 - * any later version.
   48.14 - * 
   48.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   48.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   48.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   48.18 - *
   48.19 - * You should have received a copy of the GNU General Public License along with
   48.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   48.21 - */
   48.22 -#include <sys/mman.h>
   48.23 -#include "Platform.h"
   48.24 -
   48.25 -using namespace jc;
   48.26 -
   48.27 -static inline int
   48.28 -ToProtBits(OS::Protection prot)
   48.29 -{
   48.30 -    switch (prot) {
   48.31 -      case OS::Prot_ReadWrite:
   48.32 -        return PROT_READ | PROT_WRITE;
   48.33 -      case OS::Prot_ReadWriteExecute:
   48.34 -        return PROT_READ | PROT_WRITE | PROT_EXEC;
   48.35 -      default:
   48.36 -        assert(prot == OS::Prot_ReadExecute);
   48.37 -        return PROT_READ | PROT_EXEC;
   48.38 -    }
   48.39 -}
   48.40 -
   48.41 -Address
   48.42 -OS::MapMemory(size_t amount, MapMode mode, Protection prot_)
   48.43 -{
   48.44 -    int prot = ToProtBits(prot_);
   48.45 -    void *addr = mmap(NULL, amount, prot, MAP_ANON | MAP_PRIVATE, -1, 0);
   48.46 -    if (addr == MAP_FAILED)
   48.47 -        return NULL;
   48.48 -
   48.49 -    return Address(addr);
   48.50 -}
   48.51 -
   48.52 -bool
   48.53 -OS::CommitMemory(Address address, size_t amount, Protection prot_)
   48.54 -{
   48.55 -    return true;
   48.56 -}
   48.57 -
   48.58 -void
   48.59 -OS::UnmapMemory(Address address, size_t size)
   48.60 -{
   48.61 -    munmap(address, size);
   48.62 -}
   48.63 -
   48.64 -OS::AlignableMapping
   48.65 -OS::MapAlignedMemory(size_t amount, size_t alignment, MapMode mode)
   48.66 -{
   48.67 -    assert(amount >= alignment);
   48.68 -    assert(IsPowerOfTwo(alignment));
   48.69 -
   48.70 -    if (alignment == kPageAlignment) {
   48.71 -        Address address = MapMemory(amount, mode, Prot_ReadWrite);
   48.72 -        if (!address)
   48.73 -            return AlignableMapping();
   48.74 -        return AlignableMapping(address, alignment, amount);
   48.75 -    }
   48.76 -
   48.77 -    size_t requested = Min(amount * 2, amount + 2 * alignment);
   48.78 -    Address address = MapMemory(amount, mode, Prot_ReadWrite);
   48.79 -    if (!address)
   48.80 -        return AlignableMapping();
   48.81 -
   48.82 -    size_t begin = 0;
   48.83 -    Address aligned = AlignedBase(address, alignment);
   48.84 -    if (!IsAligned(address, alignment)) {
   48.85 -        // Shave off the first part of the unaligned region.
   48.86 -        aligned += alignment;
   48.87 -        begin = size_t(aligned - address);
   48.88 -        UnmapAlignedMemory(address, begin);
   48.89 -    }
   48.90 -
   48.91 -    if (requested - begin > amount) {
   48.92 -        // Shave off the last part of the unaligned region.
   48.93 -        UnmapAlignedMemory(address + amount, requested - amount - begin);
   48.94 -    }
   48.95 -
   48.96 -    return AlignableMapping(aligned, alignment, amount);
   48.97 -}
   48.98 -
   48.99 -void
  48.100 -OS::UnmapAlignedMemory(Address address, size_t size)
  48.101 -{
  48.102 -    OS::UnmapMemory(address, size);
  48.103 -}
  48.104 -
    49.1 --- a/jitcraft/Platform-Windows.cpp	Tue Jul 24 23:53:34 2012 -0700
    49.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    49.3 @@ -1,111 +0,0 @@
    49.4 -/* vim: set ts=4 sw=4 tw=99 et:
    49.5 - *
    49.6 - * Copyright (C) 2012 David Anderson
    49.7 - *
    49.8 - * This file is part of JITCraft.
    49.9 - *
   49.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   49.11 - * the terms of the GNU General Public License as published by the Free
   49.12 - * Software Foundation, either version 3 of the License, or (at your option)
   49.13 - * any later version.
   49.14 - * 
   49.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   49.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   49.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   49.18 - *
   49.19 - * You should have received a copy of the GNU General Public License along with
   49.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   49.21 - */
   49.22 -
   49.23 -// :TODO: move into utility-style include
   49.24 -#define WIN32_LEAN_AND_MEAN
   49.25 -#include <Windows.h>
   49.26 -#include "Platform.h"
   49.27 -
   49.28 -using namespace ke;
   49.29 -
   49.30 -static inline DWORD
   49.31 -ToProtBits(OS::Protection prot)
   49.32 -{
   49.33 -    switch (prot) {
   49.34 -      case OS::Prot_ReadWrite:
   49.35 -        return PAGE_READWRITE;
   49.36 -      case OS::Prot_ReadWriteExecute:
   49.37 -        return PAGE_EXECUTE_READWRITE;
   49.38 -      default:
   49.39 -        assert(prot == OS::Prot_ReadExecute);
   49.40 -        return PAGE_EXECUTE_READ;
   49.41 -    }
   49.42 -}
   49.43 -
   49.44 -Address
   49.45 -OS::MapMemory(size_t amount, MapMode mode, Protection prot_)
   49.46 -{
   49.47 -    DWORD prot = ToProtBits(prot_);
   49.48 -    DWORD type = MEM_RESERVE;
   49.49 -    if (mode == Map_Commit)
   49.50 -        type |= MEM_COMMIT;
   49.51 -
   49.52 -    return (Address)VirtualAlloc(NULL, amount, type, prot);
   49.53 -}
   49.54 -
   49.55 -bool
   49.56 -OS::CommitMemory(Address address, size_t amount, Protection prot_)
   49.57 -{
   49.58 -    DWORD prot = ToProtBits(prot_);
   49.59 -    return !!VirtualAlloc(address, amount, MEM_COMMIT, prot);
   49.60 -}
   49.61 -
   49.62 -void
   49.63 -OS::UnmapMemory(Address address, size_t size)
   49.64 -{
   49.65 -    VirtualFree(address, 0, MEM_RELEASE);
   49.66 -}
   49.67 -
   49.68 -static Address
   49.69 -MapMemoryAt(Address address, size_t amount, OS::MapMode mode, OS::Protection prot_)
   49.70 -{
   49.71 -    DWORD bits = ToProtBits(prot_);
   49.72 -    DWORD flags = MEM_RESERVE;
   49.73 -    if (mode == OS::Map_Commit)
   49.74 -        flags |= MEM_COMMIT;
   49.75 -
   49.76 -    return (Address)VirtualAlloc((LPVOID)address, amount, flags, bits);
   49.77 -}
   49.78 -
   49.79 -OS::AlignableMapping
   49.80 -OS::MapAlignedMemory(size_t amount, size_t alignment, MapMode mode)
   49.81 -{
   49.82 -    Address addr = MapMemory(amount, mode, OS::Prot_ReadWrite);
   49.83 -    if (!addr)
   49.84 -        return AlignableMapping(NULL, alignment, 0);
   49.85 -
   49.86 -    if (!IsAligned(addr, alignment)) {
   49.87 -        UnmapMemory(addr, amount);
   49.88 -
   49.89 -        // Try to grab the next available aligned address.
   49.90 -        addr = AlignedBase(addr, alignment);
   49.91 -        addr = MapMemoryAt(addr + alignment, amount, mode, OS::Prot_ReadWrite);
   49.92 -        while (!addr) {
   49.93 -            // Try to over-allocate to get the right region. This can race
   49.94 -            // with other threads; we expect this to be rare. If this turns
   49.95 -            // out to be a problem, the API is set up such that we can just
   49.96 -            // return two pointers: the base, and the aligned address into
   49.97 -            // the over-allocated region.
   49.98 -            addr = MapMemory(amount + alignment, mode, OS::Prot_ReadWrite);
   49.99 -            if (!addr)
  49.100 -                return AlignableMapping(NULL, alignment, 0);
  49.101 -            UnmapMemory(addr, amount + alignment);
  49.102 -            addr = AlignedBase(addr, alignment);
  49.103 -            addr = MapMemoryAt(addr + alignment, amount, mode, OS::Prot_ReadWrite);
  49.104 -        }
  49.105 -    }
  49.106 -
  49.107 -    return AlignableMapping(addr, alignment, amount);
  49.108 -}
  49.109 -
  49.110 -void
  49.111 -OS::UnmapAlignedMemory(Address address, size_t size)
  49.112 -{
  49.113 -    OS::UnmapMemory(address, size);
  49.114 -}
    50.1 --- a/jitcraft/Platform.h	Tue Jul 24 23:53:34 2012 -0700
    50.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    50.3 @@ -1,91 +0,0 @@
    50.4 -/* vim: set ts=4 sw=4 tw=99 et:
    50.5 - *
    50.6 - * Copyright (C) 2012 David Anderson
    50.7 - *
    50.8 - * This file is part of JITCraft.
    50.9 - *
   50.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   50.11 - * the terms of the GNU General Public License as published by the Free
   50.12 - * Software Foundation, either version 3 of the License, or (at your option)
   50.13 - * any later version.
   50.14 - * 
   50.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   50.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   50.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   50.18 - *
   50.19 - * You should have received a copy of the GNU General Public License along with
   50.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   50.21 - */
   50.22 -#ifndef _include_jitcraft_platform_h_
   50.23 -#define _include_jitcraft_platform_h_
   50.24 -
   50.25 -#include "Utility.h"
   50.26 -
   50.27 -namespace ke {
   50.28 -
   50.29 -namespace OS {
   50.30 -    enum Protection {
   50.31 -        Prot_ReadWrite,         // rw-, for the heap
   50.32 -        Prot_ReadExecute,       // r-x, for code
   50.33 -        Prot_ReadWriteExecute   // rwx, if disabling r-x for code.
   50.34 -    };
   50.35 -
   50.36 -    enum MapMode {
   50.37 -        Map_Reserve,            // don't ask for actual pages yet
   50.38 -        Map_Commit              // ask for pages right away
   50.39 -    };
   50.40 -
   50.41 -    Address MapMemory(size_t amount, MapMode mode, Protection prot);
   50.42 -    bool CommitMemory(Address address, size_t amount, Protection prot);
   50.43 -    void UnmapMemory(Address address, size_t size);
   50.44 -
   50.45 -    class AlignableMapping {
   50.46 -        Address base_;
   50.47 -        Address aligned_;
   50.48 -        size_t size_;
   50.49 -
   50.50 -      public:
   50.51 -        AlignableMapping(Address ptr, size_t alignment, size_t size)
   50.52 -          : base_(ptr),
   50.53 -            size_(size)
   50.54 -        {
   50.55 -            aligned_ = base_;
   50.56 -            if (!IsAligned(aligned_, alignment))
   50.57 -                aligned_ = AlignedBase(aligned_, alignment) + alignment;
   50.58 -        }
   50.59 -
   50.60 -        AlignableMapping() : base_(NULL), aligned_(NULL), size_(0)
   50.61 -        {
   50.62 -        }
   50.63 -
   50.64 -        Address base() const {
   50.65 -            return base_;
   50.66 -        }
   50.67 -        bool isValid() const {
   50.68 -            return !!base_;
   50.69 -        }
   50.70 -        size_t size() const {
   50.71 -            return size_;
   50.72 -        }
   50.73 -        Address aligned() const {
   50.74 -            return aligned_;
   50.75 -        }
   50.76 -    };
   50.77 -
   50.78 -    // MapAlignedMemory is guaranteed to return zeroed memory.
   50.79 -    AlignableMapping MapAlignedMemory(size_t amount, size_t alignment, MapMode mode);
   50.80 -    void UnmapAlignedMemory(Address address, size_t size);
   50.81 -
   50.82 -    // The default alignment of memory returned via MapMemory().
   50.83 -    // :TODO: better ifdefs
   50.84 -#ifdef _MSC_VER
   50.85 -    static const size_t kPageAlignment = 64 * kKB;
   50.86 -#else
   50.87 -    static const size_t kPageAlignment = 4 * kKB;
   50.88 -#endif
   50.89 -
   50.90 -}
   50.91 -
   50.92 -}
   50.93 -
   50.94 -#endif // _include_jitcraft_platform_h_
    51.1 --- a/jitcraft/PoolAllocator.cpp	Tue Jul 24 23:53:34 2012 -0700
    51.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    51.3 @@ -1,129 +0,0 @@
    51.4 -/*
    51.5 - * Copyright (C) 2012 David Anderson
    51.6 - *
    51.7 - * This file is part of JITCraft.
    51.8 - *
    51.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   51.10 - * the terms of the GNU General Public License as published by the Free
   51.11 - * Software Foundation, either version 3 of the License, or (at your option)
   51.12 - * any later version.
   51.13 - * 
   51.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   51.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   51.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   51.17 - *
   51.18 - * You should have received a copy of the GNU General Public License along with
   51.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   51.20 - */
   51.21 -#include <assert.h>
   51.22 -#include <stdlib.h>
   51.23 -#include <new>
   51.24 -#include "PoolAllocator.h"
   51.25 -#include "Zone.h"
   51.26 -
   51.27 -using namespace ke;
   51.28 -
   51.29 -PoolAllocator::PoolAllocator()
   51.30 -  : reserved_(NULL),
   51.31 -    last_(NULL)
   51.32 -{
   51.33 -}
   51.34 -
   51.35 -PoolAllocator::~PoolAllocator()
   51.36 -{
   51.37 -    unwind(NULL);
   51.38 -    if (reserved_)
   51.39 -        free(reserved_);
   51.40 -}
   51.41 -
   51.42 -char *
   51.43 -PoolAllocator::enter()
   51.44 -{
   51.45 -    if (!last_)
   51.46 -        return NULL;
   51.47 -    return last_->ptr;
   51.48 -}
   51.49 -
   51.50 -void
   51.51 -PoolAllocator::leave(char *pos)
   51.52 -{
   51.53 -    unwind(pos);
   51.54 -}
   51.55 -
   51.56 -void
   51.57 -PoolAllocator::unwind(char *pos)
   51.58 -{
   51.59 -    while (last_) {
   51.60 -        if (pos && pos >= last_->base && pos < last_->end)
   51.61 -            break;
   51.62 -        Pool *prev = last_->prev;
   51.63 -        {
   51.64 -            if (last_->size() <= kMaxReserveSize &&
   51.65 -                (!reserved_ || reserved_->size() < last_->size()))
   51.66 -            {
   51.67 -                if (reserved_)
   51.68 -                    free(reserved_);
   51.69 -                reserved_ = last_;
   51.70 -            } else {
   51.71 -                free(last_);
   51.72 -            }
   51.73 -        }
   51.74 -        last_ = prev;
   51.75 -    }
   51.76 -
   51.77 -    if (!last_) {
   51.78 -        assert(!pos);
   51.79 -        return;
   51.80 -    }
   51.81 -
   51.82 -    last_->ptr = pos;
   51.83 -}
   51.84 -
   51.85 -void *
   51.86 -PoolAllocator::slowAllocate(size_t actualBytes)
   51.87 -{
   51.88 -    size_t bytesNeeded = actualBytes + sizeof(Pool);
   51.89 -    if (bytesNeeded < kDefaultPoolSize)
   51.90 -        bytesNeeded = kDefaultPoolSize;
   51.91 -
   51.92 -    Pool *pool;
   51.93 -    if (reserved_ && reserved_->size() >= bytesNeeded) {
   51.94 -        pool = reserved_;
   51.95 -        reserved_ = NULL;
   51.96 -    } else {
   51.97 -        pool = (Pool *)malloc(bytesNeeded);
   51.98 -        if (!pool) {
   51.99 -            ZONE()->reportOutOfMemory();
  51.100 -            return NULL;
  51.101 -        }
  51.102 -        pool->base = (char *)(pool + 1);
  51.103 -        pool->end = (char *)pool + bytesNeeded;
  51.104 -    }
  51.105 -    pool->ptr = pool->base + actualBytes;
  51.106 -    pool->prev = last_;
  51.107 -    last_ = pool;
  51.108 -    return pool->base;
  51.109 -}
  51.110 -
  51.111 -void
  51.112 -PoolAllocationPolicy::reportOutOfMemory()
  51.113 -{
  51.114 -    ZONE()->reportOutOfMemory();
  51.115 -}
  51.116 -
  51.117 -void
  51.118 -PoolAllocationPolicy::reportAllocationOverflow()
  51.119 -{
  51.120 -    ZONE()->reportError(Message_AllocationOverflow);
  51.121 -}
  51.122 -
  51.123 -void *
  51.124 -PoolAllocationPolicy::malloc(size_t bytes)
  51.125 -{
  51.126 -    return ZONE()->pool().allocate(bytes);
  51.127 -}
  51.128 -
  51.129 -void
  51.130 -PoolAllocationPolicy::free(void *ptr)
  51.131 -{
  51.132 -}
    52.1 --- a/jitcraft/PoolAllocator.h	Tue Jul 24 23:53:34 2012 -0700
    52.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    52.3 @@ -1,136 +0,0 @@
    52.4 -/*
    52.5 - * Copyright (C) 2012 David Anderson
    52.6 - *
    52.7 - * This file is part of JITCraft.
    52.8 - *
    52.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   52.10 - * the terms of the GNU General Public License as published by the Free
   52.11 - * Software Foundation, either version 3 of the License, or (at your option)
   52.12 - * any later version.
   52.13 - * 
   52.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   52.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   52.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   52.17 - *
   52.18 - * You should have received a copy of the GNU General Public License along with
   52.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   52.20 - */
   52.21 -#ifndef _include_jitcraft_pool_allocator_h_
   52.22 -#define _include_jitcraft_pool_allocator_h_
   52.23 -
   52.24 -#include <new>
   52.25 -#include <stddef.h>
   52.26 -#include <limits.h>
   52.27 -#include "Utility.h"
   52.28 -#include "Vector.h"
   52.29 -
   52.30 -namespace ke {
   52.31 -
   52.32 -// Allocates memory in chunks that are not freed until the entire allocator
   52.33 -// is freed. This is intended for use with large, temporary data structures.
   52.34 -class PoolAllocator
   52.35 -{
   52.36 -    friend class PoolAllocationScope;
   52.37 -
   52.38 -    struct Pool {
   52.39 -        char *base;
   52.40 -        char *ptr;
   52.41 -        char *end;
   52.42 -        Pool *prev;
   52.43 -
   52.44 -        size_t size() const {
   52.45 -            return size_t(end - base);
   52.46 -        }
   52.47 -    };
   52.48 -
   52.49 -    static const size_t kDefaultPoolSize = 8 * 1024;
   52.50 -    static const size_t kMaxReserveSize = 64 * 1024;
   52.51 -
   52.52 -  private:
   52.53 -    Pool *reserved_;
   52.54 -    Pool *last_;
   52.55 -
   52.56 -  private:
   52.57 -    void unwind(char *pos);
   52.58 -    void *slowAllocate(size_t actualBytes);
   52.59 -
   52.60 -  public:
   52.61 -    PoolAllocator();
   52.62 -    ~PoolAllocator();
   52.63 -
   52.64 -    void *allocate(size_t bytes) {
   52.65 -        // Guarantee malloc alignment.
   52.66 -        size_t actualBytes = Align(bytes, kMallocAlignment);
   52.67 -        if (!last_ || (size_t(last_->end - last_->ptr) < actualBytes))
   52.68 -            return slowAllocate(actualBytes);
   52.69 -        char *ptr = last_->ptr;
   52.70 -        last_->ptr += actualBytes;
   52.71 -        return ptr;
   52.72 -    }
   52.73 -
   52.74 -    char *enter();
   52.75 -    void leave(char *position);
   52.76 -};
   52.77 -
   52.78 -class PoolScope
   52.79 -{
   52.80 -    PoolAllocator &pool_;
   52.81 -    char *position_;
   52.82 -
   52.83 -  public:
   52.84 -    PoolScope(PoolAllocator &allocator)
   52.85 -      : pool_(allocator),
   52.86 -        position_(allocator.enter())
   52.87 -    {
   52.88 -    }
   52.89 -    ~PoolScope()
   52.90 -    {
   52.91 -        pool_.leave(position_);
   52.92 -    }
   52.93 -};
   52.94 -
   52.95 -class PoolObject
   52.96 -{
   52.97 -  public:
   52.98 -    void *operator new(size_t size, PoolAllocator &pool) {
   52.99 -        return pool.allocate(size);
  52.100 -    }
  52.101 -    void *operator new [](size_t size, PoolAllocator &pool) {
  52.102 -        return pool.allocate(size);
  52.103 -    }
  52.104 -    
  52.105 -    // Using delete on pool-allocated objects is illegal.
  52.106 -    void operator delete(void *ptr, PoolAllocator &pool) {
  52.107 -        assert(false);
  52.108 -    }
  52.109 -    void operator delete [](void *ptr, PoolAllocator &pool) {
  52.110 -        assert(false);
  52.111 -    }
  52.112 -};
  52.113 -
  52.114 -class PoolAllocationPolicy
  52.115 -{
  52.116 -  protected:
  52.117 -    void reportAllocationOverflow();
  52.118 -    void reportOutOfMemory();
  52.119 -
  52.120 -  public:
  52.121 -    void *malloc(size_t bytes);
  52.122 -    void free(void *ptr);
  52.123 -};
  52.124 -
  52.125 -template <typename T>
  52.126 -class PoolList
  52.127 -  : public Vector<T, PoolAllocationPolicy>,
  52.128 -    public PoolObject
  52.129 -{
  52.130 -  public:
  52.131 -    PoolList()
  52.132 -      : Vector(PoolAllocationPolicy())
  52.133 -    {
  52.134 -    }
  52.135 -};
  52.136 -
  52.137 -}
  52.138 -
  52.139 -#endif // _include_jitcraft_pool_allocator_h_
    53.1 --- a/jitcraft/Reference.cpp	Tue Jul 24 23:53:34 2012 -0700
    53.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    53.3 @@ -1,58 +0,0 @@
    53.4 -/*
    53.5 - * Copyright (C) 2012 David Anderson
    53.6 - *
    53.7 - * This file is part of JITCraft.
    53.8 - *
    53.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   53.10 - * the terms of the GNU General Public License as published by the Free
   53.11 - * Software Foundation, either version 3 of the License, or (at your option)
   53.12 - * any later version.
   53.13 - * 
   53.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   53.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   53.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   53.17 - *
   53.18 - * You should have received a copy of the GNU General Public License along with
   53.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   53.20 - */
   53.21 -#include "Reference.h"
   53.22 -#include "Zone.h"
   53.23 -#include "Array.h"
   53.24 -#include "Heap-inl.h"
   53.25 -
   53.26 -using namespace ke;
   53.27 -
   53.28 -Reference *
   53.29 -Reference::NewStack(Zone *zone, void *location, Heap::Tenure tenure)
   53.30 -{
   53.31 -    Local<Reference> ref(zone, Reference::cast(zone->allocate(MapKind_Reference, sizeof(Reference), tenure)));
   53.32 -    if (!ref)
   53.33 -        return NULL;
   53.34 -
   53.35 -    ref->location_ = location;
   53.36 -    return ref;
   53.37 -}
   53.38 -
   53.39 -Reference *
   53.40 -Reference::NewStack(Zone *zone, const LocalSlot &slot, Heap::Tenure tenure)
   53.41 -{
   53.42 -    Local<Reference> ref(zone, Reference::cast(zone->allocate(MapKind_Reference, sizeof(Reference), tenure)));
   53.43 -    if (!ref)
   53.44 -        return NULL;
   53.45 -
   53.46 -    ref->location_ = &ref->slot_;
   53.47 -    ref->slot_ = slot;
   53.48 -    return ref;
   53.49 -}
   53.50 -
   53.51 -Reference *
   53.52 -Reference::NewArray(Zone *zone, Handle<Array> base, size_t index, Heap::Tenure tenure)
   53.53 -{
   53.54 -    Local<Reference> ref(zone, Reference::cast(zone->allocate(MapKind_Reference, sizeof(Reference), tenure)));
   53.55 -    if (!ref)
   53.56 -        return NULL;
   53.57 -
   53.58 -    ref->location_ = base->slotPtr(index);
   53.59 -    ref->base_ = base;
   53.60 -    return ref;
   53.61 -}
    54.1 --- a/jitcraft/Reference.h	Tue Jul 24 23:53:34 2012 -0700
    54.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    54.3 @@ -1,73 +0,0 @@
    54.4 -/*
    54.5 - * Copyright (C) 2012 David Anderson
    54.6 - *
    54.7 - * This file is part of JITCraft.
    54.8 - *
    54.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   54.10 - * the terms of the GNU General Public License as published by the Free
   54.11 - * Software Foundation, either version 3 of the License, or (at your option)
   54.12 - * any later version.
   54.13 - * 
   54.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   54.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   54.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   54.17 - *
   54.18 - * You should have received a copy of the GNU General Public License along with
   54.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   54.20 - */
   54.21 -#ifndef _include_jitcraft_reference_h_
   54.22 -#define _include_jitcraft_reference_h_
   54.23 -
   54.24 -#include "Heap.h"
   54.25 -#include "Barriers.h"
   54.26 -#include "Stack.h"
   54.27 -
   54.28 -namespace ke {
   54.29 -
   54.30 -class Array;
   54.31 -
   54.32 -// A Reference is a typed pointer to another location in memory.
   54.33 -class Reference : public Object
   54.34 -{
   54.35 -    void *location_;
   54.36 -    LocalSlot slot_;
   54.37 -    Barriered<Array> base_;
   54.38 -
   54.39 -  public:
   54.40 -    static Reference *NewStack(Zone *zone, void *location, Heap::Tenure tenure = Heap::Tenure_Default);
   54.41 -    static Reference *NewStack(Zone *zone, const LocalSlot &slot, Heap::Tenure tenure = Heap::Tenure_Default);
   54.42 -    static Reference *NewArray(Zone *zone, Handle<Array> base, size_t index, Heap::Tenure tenure = Heap::Tenure_Default);
   54.43 -
   54.44 -    int getInt() {
   54.45 -        return *reinterpret_cast<int *>(location_);
   54.46 -    }
   54.47 -    void setInt(int i) {
   54.48 -        *reinterpret_cast<int *>(location_) = i;
   54.49 -    }
   54.50 -    float getFloat() {
   54.51 -        return *reinterpret_cast<float *>(location_);
   54.52 -    }
   54.53 -    void setFloat(float f) {
   54.54 -        *reinterpret_cast<float *>(location_) = f;
   54.55 -    }
   54.56 -
   54.57 -    // WARNING! This should only be for Native calls.
   54.58 -    void *location() {
   54.59 -        return location_;
   54.60 -    }
   54.61 -
   54.62 -    // Begin GC Descriptor.
   54.63 -    static inline size_t offsetOfBase() {
   54.64 -        return offsetof(Reference, base_);
   54.65 -    }
   54.66 -    // End GC Descriptor.
   54.67 -
   54.68 -    static inline Reference *cast(Object *obj) {
   54.69 -        assert(!obj || obj->is(MapKind_Reference));
   54.70 -        return reinterpret_cast<Reference *>(obj);
   54.71 -    }
   54.72 -};
   54.73 -
   54.74 -}
   54.75 -
   54.76 -#endif // _include_jitcraft_reference_h_
    55.1 --- a/jitcraft/RootScopes.cpp	Tue Jul 24 23:53:34 2012 -0700
    55.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    55.3 @@ -1,85 +0,0 @@
    55.4 -/* vim: set ts=4 sw=4 tw=99 et:
    55.5 - *
    55.6 - * Copyright (C) 2012 David Anderson
    55.7 - *
    55.8 - * This file is part of JITCraft.
    55.9 - *
   55.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   55.11 - * the terms of the GNU General Public License as published by the Free
   55.12 - * Software Foundation, either version 3 of the License, or (at your option)
   55.13 - * any later version.
   55.14 - * 
   55.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   55.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   55.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   55.18 - *
   55.19 - * You should have received a copy of the GNU General Public License along with
   55.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   55.21 - */
   55.22 -#include <stdio.h>
   55.23 -#include <stdlib.h>
   55.24 -#include "RootScopes.h"
   55.25 -
   55.26 -using namespace ke;
   55.27 -
   55.28 -RootScopeManager::RootScopeManager()
   55.29 -  : blocks_(&first_),
   55.30 -    first_(NULL),
   55.31 -    scope_(NULL)
   55.32 -{
   55.33 -}
   55.34 -
   55.35 -RootScopeManager::~RootScopeManager()
   55.36 -{
   55.37 -    while (blocks_ != &first_) {
   55.38 -        Block *temp = blocks_;
   55.39 -        delete blocks_;
   55.40 -        blocks_ = temp;
   55.41 -    }
   55.42 -}
   55.43 -
   55.44 -bool
   55.45 -RootScopeManager::grow()
   55.46 -{
   55.47 -    assert(blocks_->cur == blocks_->end);
   55.48 -
   55.49 -    Block *block = new Block(blocks_);
   55.50 -    if (!block) {
   55.51 -        // We are not prepared for this. We'll start dishing out NULL-valued
   55.52 -        // ScopedRoots, and the engine generally assumes infallbility. Rather
   55.53 -        // then NULL check all sorts of nodes on parse trees, or add boolean
   55.54 -        // setters, for now we just abort.
   55.55 -        fprintf(stderr, "Unrecoverable error: could not allocate a local root scope. Aborting!\n");
   55.56 -        abort();
   55.57 -        return false;
   55.58 -    }
   55.59 -
   55.60 -    blocks_ = block;
   55.61 -    return true;
   55.62 -}
   55.63 -
   55.64 -void
   55.65 -RootScopeManager::unwindSlow(Object **pos)
   55.66 -{
   55.67 -    for (;;) {
   55.68 -        if (pos >= blocks_->objects && pos <= blocks_->end)
   55.69 -            break;
   55.70 -        assert(blocks_ != &first_);
   55.71 -        Block *temp = blocks_;
   55.72 -        delete blocks_;
   55.73 -        blocks_ = temp;
   55.74 -    }
   55.75 -
   55.76 -    blocks_->cur = pos;
   55.77 -}
   55.78 -
   55.79 -void
   55.80 -RootScopeManager::accept(VirtualObjectVisitor *visitor)
   55.81 -{
   55.82 -    Block *block = blocks_;
   55.83 -    while (block) {
   55.84 -        for (Object **ptr = block->objects; ptr < block->cur; ptr++)
   55.85 -            visitor->visit(ptr);
   55.86 -        block = block->prev;
   55.87 -    }
   55.88 -}
    56.1 --- a/jitcraft/RootScopes.h	Tue Jul 24 23:53:34 2012 -0700
    56.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    56.3 @@ -1,106 +0,0 @@
    56.4 -/* vim: set ts=4 sw=4 tw=99 et:
    56.5 - *
    56.6 - * Copyright (C) 2012 David Anderson
    56.7 - *
    56.8 - * This file is part of JITCraft.
    56.9 - *
   56.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   56.11 - * the terms of the GNU General Public License as published by the Free
   56.12 - * Software Foundation, either version 3 of the License, or (at your option)
   56.13 - * any later version.
   56.14 - * 
   56.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   56.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   56.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   56.18 - *
   56.19 - * You should have received a copy of the GNU General Public License along with
   56.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   56.21 - */
   56.22 -#ifndef _include_jc_root_scopes_h_
   56.23 -#define _include_jc_root_scopes_h_
   56.24 -
   56.25 -#include "../include/keima.h"
   56.26 -#include "Objects.h"
   56.27 -#include "VirtualObjectVisitor.h"
   56.28 -
   56.29 -namespace ke {
   56.30 -
   56.31 -class RootScope;
   56.32 -
   56.33 -// A RootScopeManager is essentially a specialized PoolAllocator that can
   56.34 -// only allocate Object ** entries. It is used to allow huge, temporary
   56.35 -// heap data structures like ASTs to hold safe references to objects. When
   56.36 -// the data structures is no longer needed, all of the roots are removed
   56.37 -// at once.
   56.38 -class RootScopeManager
   56.39 -{
   56.40 -    static const size_t kObjectsPerBlock = 4096;
   56.41 -
   56.42 -    struct Block {
   56.43 -        Object *objects[kObjectsPerBlock];
   56.44 -        Object **cur;
   56.45 -        Object **end;
   56.46 -        Block *prev;
   56.47 -
   56.48 -        Block(Block *prev)
   56.49 -          : cur(objects),
   56.50 -            end(objects + kObjectsPerBlock),
   56.51 -            prev(prev)
   56.52 -        {
   56.53 -        }
   56.54 -    };
   56.55 -
   56.56 -  private:
   56.57 -    bool grow();
   56.58 -    void unwindSlow(Object **position);
   56.59 -
   56.60 -  public:
   56.61 -    RootScopeManager();
   56.62 -    ~RootScopeManager();
   56.63 -
   56.64 -    Object **position() const {
   56.65 -        return blocks_->cur;
   56.66 -    }
   56.67 -
   56.68 -    void unwind(Object **position) {
   56.69 -        if (position >= blocks_->cur && position <= blocks_->end) {
   56.70 -            blocks_->cur = position;
   56.71 -            return;
   56.72 -        }
   56.73 -        unwindSlow(position);
   56.74 -    }
   56.75 -
   56.76 -    Object **make(Object *obj) {
   56.77 -        assert(scope_);
   56.78 -        if (blocks_->cur + 1 > blocks_->end) {
   56.79 -            if (!grow())
   56.80 -                return NULL;
   56.81 -        }
   56.82 -        Object **ptr = blocks_->cur;
   56.83 -        blocks_->cur++;
   56.84 -        *ptr = obj;
   56.85 -        return ptr;
   56.86 -    }
   56.87 -
   56.88 -    Ke::HandleScope **scope() {
   56.89 -        return &scope_;
   56.90 -    }
   56.91 -
   56.92 -    void accept(VirtualObjectVisitor *visitor);
   56.93 -
   56.94 -  private:
   56.95 -    Block *blocks_;
   56.96 -    Block first_;
   56.97 -    Ke::HandleScope *scope_;
   56.98 -};
   56.99 -
  56.100 -class RootScope : public Ke::HandleScope
  56.101 -{
  56.102 -  public:
  56.103 -    // These are implemented in Zone.h.
  56.104 -    inline RootScope(Zone *zone);
  56.105 -};
  56.106 -
  56.107 -}
  56.108 -
  56.109 -#endif // _include_jc_root_scope_h_
    57.1 --- a/jitcraft/Scanner.cpp	Tue Jul 24 23:53:34 2012 -0700
    57.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    57.3 @@ -1,576 +0,0 @@
    57.4 -/*
    57.5 - * Copyright (C) 2012 David Anderson
    57.6 - *
    57.7 - * This file is part of JITCraft.
    57.8 - *
    57.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   57.10 - * the terms of the GNU General Public License as published by the Free
   57.11 - * Software Foundation, either version 3 of the License, or (at your option)
   57.12 - * any later version.
   57.13 - * 
   57.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   57.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   57.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   57.17 - *
   57.18 - * You should have received a copy of the GNU General Public License along with
   57.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   57.20 - */
   57.21 -#include <assert.h>
   57.22 -#include <ctype.h>
   57.23 -#include <math.h>
   57.24 -#include "Scanner.h"
   57.25 -#include "Utility.h"
   57.26 -
   57.27 -using namespace ke;
   57.28 -
   57.29 -const char *ke::TokenNames[] =
   57.30 -{
   57.31 -#define _(name, str) str,
   57.32 -    TOKENMAP(_)
   57.33 -#undef _
   57.34 -    NULL
   57.35 -};
   57.36 -
   57.37 -Scanner::Scanner(CompileContext &cc, const char *stream, size_t length)
   57.38 -  : cc_(cc),
   57.39 -    stream_(stream),
   57.40 -    length_(length),
   57.41 -    pushed_(false),
   57.42 -    saved_('\0'),
   57.43 -    pos_(stream_)
   57.44 -{
   57.45 -    cur_.line = 1;
   57.46 -    cur_.col = 1;
   57.47 -    last_ = cur_;
   57.48 -}
   57.49 -
   57.50 -char
   57.51 -Scanner::getChar()
   57.52 -{
   57.53 -    if (saved_ != '\0') {
   57.54 -        char temp = saved_;
   57.55 -        saved_ = '\0';
   57.56 -        return temp;
   57.57 -    }
   57.58 -    if (pos_ >= stream_ + length_)
   57.59 -        return '\0';
   57.60 -    last_.col = cur_.col++;
   57.61 -    return *pos_++;
   57.62 -}
   57.63 -
   57.64 -void
   57.65 -Scanner::putChar(char c)
   57.66 -{
   57.67 -    assert(saved_ == '\0');
   57.68 -    saved_ = c;
   57.69 -    cur_.col = last_.col;
   57.70 -}
   57.71 -
   57.72 -void
   57.73 -Scanner::calcNewLine(char c)
   57.74 -{
   57.75 -    cur_.line++;
   57.76 -    cur_.col = 1;
   57.77 -    last_ = cur_;
   57.78 -
   57.79 -    char o;
   57.80 -    if (c == '\r' && ((o = getChar()) != '\n'))
   57.81 -        putChar(o);
   57.82 -}
   57.83 -
   57.84 -void
   57.85 -Scanner::eatSingleLine()
   57.86 -{
   57.87 -    char c;
   57.88 -    while ((c = getChar()) != '\0') {
   57.89 -        if (c == '\n' || c == '\r') {
   57.90 -            calcNewLine(c);
   57.91 -            break;
   57.92 -        }
   57.93 -    }
   57.94 -}
   57.95 -
   57.96 -bool
   57.97 -Scanner::eatComment()
   57.98 -{
   57.99 -    char c;
  57.100 -
  57.101 -    while ((c = getChar()) != '\0') {
  57.102 -        while (c == '*') {
  57.103 -            c = getChar();
  57.104 -            if (c == '\0')
  57.105 -                return false;
  57.106 -            if (c == '/')
  57.107 -                return true;
  57.108 -        }
  57.109 -        if (c == '\r' || c == '\n')
  57.110 -            calcNewLine(c);
  57.111 -    }
  57.112 -
  57.113 -    return false;
  57.114 -}
  57.115 -
  57.116 -static inline bool
  57.117 -IsDigit(char c)
  57.118 -{
  57.119 -    return c >= '0' && c <= '9';
  57.120 -}
  57.121 -
  57.122 -// Based off the logic in sc2.c's ftoi()...
  57.123 -double
  57.124 -Scanner::ParseDouble(const char *string)
  57.125 -{
  57.126 -    const char *ptr = string;
  57.127 -
  57.128 -    double number = 0.0;
  57.129 -    while (IsDigit(*ptr)) {
  57.130 -        number = (number * 10) + (*ptr - '0');
  57.131 -        ptr++;
  57.132 -    }
  57.133 -
  57.134 -    assert(*ptr == '.');
  57.135 -    ptr++;
  57.136 -
  57.137 -    double fraction = 0.0;
  57.138 -    double multiplier = 1.0;
  57.139 -    while (IsDigit(*ptr)) {
  57.140 -        fraction = (fraction * 10) + (*ptr - '0');
  57.141 -        multiplier = multiplier / 10.0;
  57.142 -        ptr++;
  57.143 -    }
  57.144 -
  57.145 -    number += fraction * multiplier;
  57.146 -
  57.147 -    if (*ptr++ == 'e') {
  57.148 -        int sign = 1;
  57.149 -        if (*ptr == '-') {
  57.150 -            sign = -1;
  57.151 -            ptr++;
  57.152 -        }
  57.153 -
  57.154 -        int exponent = 0;
  57.155 -        while (IsDigit(*ptr)) {
  57.156 -            exponent = (exponent * 10) + (*ptr - '0');
  57.157 -            ptr++;
  57.158 -        }
  57.159 -
  57.160 -        multiplier = pow(10.0, exponent * sign);
  57.161 -        number *= multiplier;
  57.162 -    }
  57.163 -
  57.164 -    return number;
  57.165 -}
  57.166 -
  57.167 -static inline bool
  57.168 -IsHexDigit(char c)
  57.169 -{
  57.170 -    return IsDigit(c) ||
  57.171 -           (c >= 'a' && c <= 'f') ||
  57.172 -           (c >= 'A' && c <= 'F');
  57.173 -}
  57.174 -
  57.175 -// Based on the logic for litchar() in sc2.c.
  57.176 -int
  57.177 -Scanner::readEscapeCode()
  57.178 -{
  57.179 -    char c = getChar();
  57.180 -    if (c == '\\')
  57.181 -        return c;
  57.182 -
  57.183 -    switch (c) {
  57.184 -      case 'a':
  57.185 -        return '\a';
  57.186 -      case 'b':
  57.187 -        return '\b';
  57.188 -      case 'e':
  57.189 -        return 27;          // Apparently \e is non-standard.
  57.190 -      case 'f':
  57.191 -        return '\f';
  57.192 -      case 'n':
  57.193 -        return '\n';
  57.194 -      case 'r':
  57.195 -        return '\r';
  57.196 -      case 't':
  57.197 -        return '\t';
  57.198 -      case '\v':
  57.199 -        return '\v';
  57.200 -
  57.201 -      case 'x':
  57.202 -      {
  57.203 -          unsigned digits = 0;
  57.204 -          char r = 0;
  57.205 -  
  57.206 -          c = getChar();
  57.207 -          while (IsHexDigit(c) && digits < 2) {
  57.208 -              if (IsDigit(c))
  57.209 -                  c = (c << 4) + (c - '0');
  57.210 -              else
  57.211 -                  c = (c << 4) + (tolower(c) - 'a' + 10);
  57.212 -              digits++;
  57.213 -              c = getChar();
  57.214 -           }
  57.215 -                
  57.216 -          // Swallow a trailing ';'
  57.217 -          if (c != ';')
  57.218 -              putChar(c);
  57.219 -  
  57.220 -          return r;
  57.221 -      }
  57.222 -
  57.223 -      case '\'':
  57.224 -      case '\"':
  57.225 -      case '%':
  57.226 -        return c;
  57.227 -
  57.228 -      default:
  57.229 -      {
  57.230 -        if (IsDigit(c)) {
  57.231 -            // \ddd
  57.232 -            char r = 0;
  57.233 -            while (IsDigit(c)) {
  57.234 -                r = r * 10 + (c - '0');
  57.235 -                c = getChar();
  57.236 -            }
  57.237 -
  57.238 -            // Swallow a trailing ;
  57.239 -            if (c != ';')
  57.240 -                putChar(c);
  57.241 -
  57.242 -            return r;
  57.243 -        }
  57.244 -        cc_.reportError(begin(), Message_UnknownEscapeCode, c);
  57.245 -        return INT_MAX;
  57.246 -      }
  57.247 -    }
  57.248 -}
  57.249 -
  57.250 -TokenKind
  57.251 -Scanner::stringLiteral()
  57.252 -{
  57.253 -    literal_.clear();
  57.254 -
  57.255 -    for (;;) {
  57.256 -        char c = getChar();
  57.257 -        if (c == '\"')
  57.258 -            break;
  57.259 -        if (c == '\r' || c == '\n' || c == '\0') {
  57.260 -            cc_.reportError(begin(), Message_UnterminatedString);
  57.261 -            return TOK_ERROR;
  57.262 -        }
  57.263 -        if (c == '\\') {
  57.264 -            int code = readEscapeCode();
  57.265 -            if (code == INT_MAX)
  57.266 -                return TOK_ERROR;
  57.267 -            c = char(code);
  57.268 -        }
  57.269 -        literal_ += c;
  57.270 -    }
  57.271 -
  57.272 -    return TOK_STRING_LITERAL;
  57.273 -}
  57.274 -
  57.275 -TokenKind
  57.276 -Scanner::numberLiteral(char first)
  57.277 -{
  57.278 -    literal_ = first;
  57.279 -
  57.280 -    char c;
  57.281 -    for (;;) {
  57.282 -        c = getChar();
  57.283 -        if (!IsDigit(c))
  57.284 -            break;
  57.285 -        literal_ += c;
  57.286 -    }
  57.287 -
  57.288 -    if (c != '.') {
  57.289 -        putChar(c);
  57.290 -        return TOK_INTEGER_LITERAL;
  57.291 -    }
  57.292 -    literal_ += c;
  57.293 -
  57.294 -    c = getChar();
  57.295 -    if (!IsDigit(c)) {
  57.296 -        cc_.reportError(begin(), Message_ExpectedDigitForFloat, c);
  57.297 -        return TOK_ERROR;
  57.298 -    }
  57.299 -    literal_ += c;
  57.300 -
  57.301 -    for (;;) {
  57.302 -        c = getChar();
  57.303 -        if (!IsDigit(c))
  57.304 -            break;
  57.305 -        literal_ += c;
  57.306 -    }
  57.307 -
  57.308 -    if (c != 'e') {
  57.309 -        putChar(c);
  57.310 -    } else {
  57.311 -        literal_ += c;
  57.312 -        c = getChar();
  57.313 -        if (c == '-') {
  57.314 -            literal_ += c;
  57.315 -            c = getChar();
  57.316 -        }
  57.317 -        if (!IsDigit(c)) {
  57.318 -            cc_.reportError(begin(), Message_ExpectedDigitForFloat, c);
  57.319 -            return TOK_ERROR;
  57.320 -        }
  57.321 -        literal_ += c;
  57.322 -        for (;;) {
  57.323 -            c = getChar();
  57.324 -            if (!IsDigit(c)) {
  57.325 -                putChar(c);
  57.326 -                break;
  57.327 -            }
  57.328 -            literal_ += c;
  57.329 -        }
  57.330 -    }
  57.331 -
  57.332 -    return TOK_FLOAT_LITERAL;
  57.333 -}
  57.334 -
  57.335 -TokenKind
  57.336 -Scanner::identifier(char first)
  57.337 -{
  57.338 -    literal_ = first;
  57.339 -
  57.340 -    char c;
  57.341 -    for (;;) {
  57.342 -        c = getChar();
  57.343 -        if (!isascii(c) || (!isalnum(c) && c != '_')) {
  57.344 -            if (c != ':')
  57.345 -                putChar(c);
  57.346 -            break;
  57.347 -        }
  57.348 -        literal_ += c;
  57.349 -    }
  57.350 -
  57.351 -    if (literal_ == "new")
  57.352 -        return TOK_NEW;
  57.353 -    if (literal_ == "for")
  57.354 -        return TOK_FOR;
  57.355 -    if (literal_ == "return")
  57.356 -        return TOK_RETURN;
  57.357 -    if (literal_ == "if")
  57.358 -        return TOK_IF;
  57.359 -    if (literal_ == "else")
  57.360 -        return TOK_ELSE;
  57.361 -    if (literal_ == "enum")
  57.362 -        return TOK_ENUM;
  57.363 -    if (literal_ == "while")
  57.364 -        return TOK_WHILE;
  57.365 -    if (literal_ == "do")
  57.366 -        return TOK_DO;
  57.367 -    if (literal_ == "break")
  57.368 -        return TOK_BREAK;
  57.369 -    if (literal_ == "continue")
  57.370 -        return TOK_CONTINUE;
  57.371 -    if (literal_ == "forward")
  57.372 -        return TOK_FORWARD;
  57.373 -    if (literal_ == "public")
  57.374 -        return TOK_PUBLIC;
  57.375 -    if (literal_ == "const")
  57.376 -        return TOK_CONST;
  57.377 -    if (literal_ == "native")
  57.378 -        return TOK_NATIVE;
  57.379 -    return (c == ':') ? TOK_LABEL : TOK_NAME;
  57.380 -}
  57.381 -
  57.382 -TokenKind
  57.383 -Scanner::next()
  57.384 -{
  57.385 -    assert(!pushed_);
  57.386 -
  57.387 -    for (;;) {
  57.388 -        begin_ = cur_;
  57.389 -
  57.390 -        char c = getChar();
  57.391 -        switch (c) {
  57.392 -          case '/':
  57.393 -          {
  57.394 -            c = getChar();
  57.395 -            if (c == '/') {
  57.396 -                eatSingleLine();
  57.397 -                break;
  57.398 -            }
  57.399 -            if (c == '*') {
  57.400 -                if (!eatComment()) {
  57.401 -                    cc_.reportError(begin(), Message_UnterminatedComment);
  57.402 -                    return TOK_ERROR;
  57.403 -                }
  57.404 -                break;
  57.405 -            }
  57.406 -            putChar(c);
  57.407 -            return TOK_SLASH;
  57.408 -          }
  57.409 -
  57.410 -          case '\n':
  57.411 -          case '\r':
  57.412 -            calcNewLine(c);
  57.413 -            break;
  57.414 -
  57.415 -          case ';': return TOK_SEMICOLON;
  57.416 -          case '{': return TOK_LBRACE;
  57.417 -          case '}': return TOK_RBRACE;
  57.418 -          case '(': return TOK_LPAREN;
  57.419 -          case ')': return TOK_RPAREN;
  57.420 -          case '[': return TOK_LBRACKET;
  57.421 -          case ']': return TOK_RBRACKET;
  57.422 -          case '~': return TOK_TILDE;
  57.423 -          case '?': return TOK_QMARK;
  57.424 -          case ':': return TOK_COLON;
  57.425 -
  57.426 -          case '.':
  57.427 -            c = getChar();
  57.428 -            if (c == '.') {
  57.429 -                c = getChar();
  57.430 -                if (c == '.')
  57.431 -                    return TOK_ELLIPSES;
  57.432 -            }
  57.433 -            cc_.reportError(begin_, Message_UnexpectedCharacter, c, uint8(c));
  57.434 -            return TOK_ERROR;
  57.435 -
  57.436 -          case '*':
  57.437 -            c = getChar();
  57.438 -            if (c == '=')
  57.439 -                return TOK_ASSIGN_MUL;
  57.440 -            putChar(c);
  57.441 -            return TOK_STAR;
  57.442 -
  57.443 -          case '+':
  57.444 -            c = getChar();
  57.445 -            if (c == '=')
  57.446 -                return TOK_ASSIGN_ADD;
  57.447 -            if (c == '+')
  57.448 -                return TOK_INCREMENT;
  57.449 -            putChar(c);
  57.450 -            return TOK_PLUS;
  57.451 -
  57.452 -          case '&':
  57.453 -            c = getChar();
  57.454 -            if (c == '=')
  57.455 -                return TOK_ASSIGN_BITAND;
  57.456 -            if (c == '&')
  57.457 -                return TOK_AND;
  57.458 -            putChar(c);
  57.459 -            return TOK_BITAND;
  57.460 -
  57.461 -          case '|':
  57.462 -            c = getChar();
  57.463 -            if (c == '=')
  57.464 -                return TOK_ASSIGN_BITOR;
  57.465 -            if (c == '|')
  57.466 -                return TOK_OR;
  57.467 -            putChar(c);
  57.468 -            return TOK_BITOR;
  57.469 -
  57.470 -          case '^':
  57.471 -            c = getChar();
  57.472 -            if (c == '=')
  57.473 -                return TOK_ASSIGN_BITXOR;
  57.474 -            putChar(c);
  57.475 -            return TOK_BITXOR;
  57.476 -
  57.477 -          case '%':
  57.478 -            c = getChar();
  57.479 -            if (c == '=')
  57.480 -                return TOK_ASSIGN_MOD;
  57.481 -            putChar(c);
  57.482 -            return TOK_PERCENT;
  57.483 -
  57.484 -          case '-':
  57.485 -            c = getChar();
  57.486 -            if (c == '=')
  57.487 -                return TOK_ASSIGN_SUB;
  57.488 -            if (c == '-')
  57.489 -                return TOK_DECREMENT;
  57.490 -            putChar(c);
  57.491 -            return TOK_MINUS;
  57.492 -
  57.493 -          case ',': return TOK_COMMA;
  57.494 -          case '\0': return TOK_EOF;
  57.495 -
  57.496 -          case '!':
  57.497 -            c = getChar();
  57.498 -            if (c == '=')
  57.499 -                return TOK_NOTEQUALS;
  57.500 -            putChar(c);
  57.501 -            return TOK_NOT;
  57.502 -
  57.503 -          case '=':
  57.504 -            c = getChar();
  57.505 -            if (c == '=')
  57.506 -                return TOK_EQUALS;
  57.507 -            putChar(c);
  57.508 -            return TOK_ASSIGN;
  57.509 -
  57.510 -          case '<':
  57.511 -            c = getChar();
  57.512 -            if (c == '=')
  57.513 -                return TOK_LE;
  57.514 -            if (c == '<') {
  57.515 -                c = getChar();
  57.516 -                if (c == '=')
  57.517 -                    return TOK_ASSIGN_SHL;
  57.518 -                return TOK_SHL;
  57.519 -            }
  57.520 -            putChar(c);
  57.521 -            return TOK_LT;
  57.522 -
  57.523 -          case '>':
  57.524 -            c = getChar();
  57.525 -            if (c == '=')
  57.526 -                return TOK_GE;
  57.527 -            if (c == '>') {
  57.528 -                c = getChar();
  57.529 -                if (c == '>') {
  57.530 -                    c = getChar();
  57.531 -                    if (c == '=')
  57.532 -                        return TOK_ASSIGN_USHR;
  57.533 -                    putChar(c);
  57.534 -                    return TOK_USHR;
  57.535 -                }
  57.536 -                return TOK_SHR;
  57.537 -            }
  57.538 -            putChar(c);
  57.539 -            return TOK_GT;
  57.540 -
  57.541 -          case ' ':
  57.542 -          case '\t':
  57.543 -          case '\f':
  57.544 -            break;
  57.545 -
  57.546 -          case '"':
  57.547 -            return stringLiteral();
  57.548 -
  57.549 -          default:
  57.550 -            if (c >= '0' && c <= '9')
  57.551 -                return numberLiteral(c);
  57.552 -            if (c == '_' || (isascii(c) && isalpha(c)))
  57.553 -                return identifier(c);
  57.554 -            cc_.reportError(begin_, Message_UnexpectedCharacter, c, uint8(c));
  57.555 -            return TOK_ERROR;
  57.556 -        }
  57.557 -    }
  57.558 -}
  57.559 -
  57.560 -TokenKind
  57.561 -Scanner::scan()
  57.562 -{
  57.563 -    if (pushed_) {
  57.564 -        pushed_ = false;
  57.565 -        return lastToken_;
  57.566 -    }
  57.567 -    lastToken_ = next();
  57.568 -    return lastToken_;
  57.569 -}
  57.570 -
  57.571 -TokenKind
  57.572 -Scanner::peek()
  57.573 -{
  57.574 -    if (pushed_)
  57.575 -        return lastToken_;
  57.576 -    scan();
  57.577 -    pushed_ = true;
  57.578 -    return lastToken_;
  57.579 -}
    58.1 --- a/jitcraft/Scanner.h	Tue Jul 24 23:53:34 2012 -0700
    58.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    58.3 @@ -1,81 +0,0 @@
    58.4 -/*
    58.5 - * Copyright (C) 2012 David Anderson
    58.6 - *
    58.7 - * This file is part of JITCraft.
    58.8 - *
    58.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   58.10 - * the terms of the GNU General Public License as published by the Free
   58.11 - * Software Foundation, either version 3 of the License, or (at your option)
   58.12 - * any later version.
   58.13 - * 
   58.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   58.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   58.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   58.17 - *
   58.18 - * You should have received a copy of the GNU General Public License along with
   58.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   58.20 - */
   58.21 -#ifndef _include_jitcraft_scanner_h_
   58.22 -#define _include_jitcraft_scanner_h_
   58.23 -
   58.24 -#include <string>
   58.25 -#include "Token.h"
   58.26 -#include "CompileContext.h"
   58.27 -
   58.28 -namespace ke {
   58.29 -
   58.30 -class Scanner
   58.31 -{
   58.32 -    CompileContext &cc_;
   58.33 -    const char *stream_;
   58.34 -    size_t length_;
   58.35 -    bool pushed_;
   58.36 -    char saved_;
   58.37 -    const char *pos_;
   58.38 -    std::string literal_;
   58.39 -    TokenKind lastToken_;
   58.40 -    SourcePosition last_;
   58.41 -    SourcePosition cur_;
   58.42 -    SourcePosition begin_;
   58.43 -
   58.44 -  private:
   58.45 -    char getChar();
   58.46 -    void putChar(char c);
   58.47 -    void eatSingleLine();
   58.48 -    bool eatComment();
   58.49 -    void calcNewLine(char c);
   58.50 -    int readEscapeCode();
   58.51 -    TokenKind stringLiteral();
   58.52 -    TokenKind numberLiteral(char first);
   58.53 -    TokenKind identifier(char first);
   58.54 -
   58.55 -    TokenKind next();
   58.56 -
   58.57 -  public:
   58.58 -    Scanner(CompileContext &cc, const char *stream, size_t length);
   58.59 -
   58.60 -    static double ParseDouble(const char *string);
   58.61 -
   58.62 -    TokenKind scan();
   58.63 -    TokenKind peek();
   58.64 -    TokenKind last() const {
   58.65 -        return lastToken_;
   58.66 -    }
   58.67 -
   58.68 -    // Beginning source position of the last instruction.
   58.69 -    SourcePosition begin() const {
   58.70 -        return begin_;
   58.71 -    }
   58.72 -
   58.73 -    // Note: the literal may have embedded NUL characters.
   58.74 -    const char *literal() const {
   58.75 -        return literal_.c_str();
   58.76 -    }
   58.77 -    size_t literal_length() const {
   58.78 -        return literal_.size();
   58.79 -    }
   58.80 -};
   58.81 -
   58.82 -} // namespace ke
   58.83 -
   58.84 -#endif // _include_jitcraft_scanner_h_
    59.1 --- a/jitcraft/Scopes.cpp	Tue Jul 24 23:53:34 2012 -0700
    59.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    59.3 @@ -1,273 +0,0 @@
    59.4 -/* vim: set ts=4 sw=4 tw=99 et:
    59.5 - *
    59.6 - * Copyright (C) 2012 David Anderson
    59.7 - *
    59.8 - * This file is part of JITCraft.
    59.9 - *
   59.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   59.11 - * the terms of the GNU General Public License as published by the Free
   59.12 - * Software Foundation, either version 3 of the License, or (at your option)
   59.13 - * any later version.
   59.14 - * 
   59.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   59.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   59.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   59.18 - *
   59.19 - * You should have received a copy of the GNU General Public License along with
   59.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   59.21 - */
   59.22 -#include "Scopes.h"
   59.23 -#include "Zone.h"
   59.24 -#include "Types.h"
   59.25 -#include "TypeManager.h"
   59.26 -#include "Strings.h"
   59.27 -#include "CompileContext.h"
   59.28 -#include "Environments.h"
   59.29 -
   59.30 -using namespace ke;
   59.31 -
   59.32 -Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
   59.33 -  : pool_(pool),
   59.34 -    locals_(0),
   59.35 -    maxContainedLocals_(0),
   59.36 -    numFunctions_(0),
   59.37 -    numNatives_(0),
   59.38 -    lifoSlot_(NULL),
   59.39 -    kind_(kind),
   59.40 -    enclosing_(enclosing)
   59.41 -{
   59.42 -}
   59.43 -
   59.44 -bool
   59.45 -Scope::initialize()
   59.46 -{
   59.47 -    if (enclosing_ && !enclosing_->children_.append(this))
   59.48 -        return false;
   59.49 -    return true;
   59.50 -}
   59.51 -
   59.52 -void
   59.53 -Scope::unlink()
   59.54 -{
   59.55 -    assert(empty());
   59.56 -
   59.57 -    assert(enclosing_->children_[enclosing_->children_.length() - 1] == this);
   59.58 -    enclosing_->children_.pop();
   59.59 -
   59.60 -    // OOM here is swallowed and checked after compilation.
   59.61 -    // :TODO: make the above true.
   59.62 -    for (size_t i = 0; i < children_.length(); i++)
   59.63 -        enclosing_->children_.append(children_[i]);
   59.64 -}
   59.65 -
   59.66 -Scope *
   59.67 -Scope::unlinkIfEmpty()
   59.68 -{
   59.69 -    if (empty()) {
   59.70 -        unlink();
   59.71 -        return NULL;
   59.72 -    }
   59.73 -    return this;
   59.74 -}
   59.75 -
   59.76 -BoundName *
   59.77 -Scope::localLookup(Handle<String> name)
   59.78 -{
   59.79 -    for (size_t i = 0; i < names_.length(); i++) {
   59.80 -        if (names_[i]->name() == name)
   59.81 -            return names_[i];
   59.82 -    }
   59.83 -    return NULL;
   59.84 -}
   59.85 -
   59.86 -BoundName *
   59.87 -Scope::lookup(Handle<String> name)
   59.88 -{
   59.89 -    for (Scope *scope = this; scope; scope = scope->enclosing()) {
   59.90 -        if (BoundName *bound = scope->localLookup(name))
   59.91 -            return bound;
   59.92 -    }
   59.93 -    return NULL;
   59.94 -}
   59.95 -
   59.96 -Variable *
   59.97 -Scope::declareVariable(Handle<String> name, const SourcePosition &pos)
   59.98 -{
   59.99 -    assert(!localLookup(name));
  59.100 -    
  59.101 -    Variable *var = new (pool_) Variable(this, name, pos);
  59.102 -    if (!names_.append(var))
  59.103 -        return NULL;
  59.104 -    return var;
  59.105 -}
  59.106 -
  59.107 -Variable *
  59.108 -Scope::declareArgument(Handle<String> name, const SourcePosition &pos)
  59.109 -{
  59.110 -    assert(kind() == FUNCTION);
  59.111 -    Variable *var = declareVariable(name, pos);
  59.112 -    if (!names_.append(var))
  59.113 -        return NULL;
  59.114 -    if (!parameters_.append(var))
  59.115 -        return NULL;
  59.116 -    return var;
  59.117 -}
  59.118 -
  59.119 -NamedFunction *
  59.120 -Scope::declareFunction(Handle<String> name, const SourcePosition &pos, TokenKind token)
  59.121 -{
  59.122 -    assert(!localLookup(name));
  59.123 -    assert(kind() == GLOBAL);
  59.124 -
  59.125 -    NamedFunction *fun = new (pool_) NamedFunction(this, name, pos, token);
  59.126 -    if (!names_.append(fun))
  59.127 -        return NULL;
  59.128 -    return fun;
  59.129 -}
  59.130 -
  59.131 -NamedEnum *
  59.132 -Scope::declareEnum(Handle<String> name, const SourcePosition &pos)
  59.133 -{
  59.134 -    NamedEnum *e = new (pool_) NamedEnum(this, name, pos);
  59.135 -    if (!names_.append(e))
  59.136 -        return NULL;
  59.137 -    return e;
  59.138 -}
  59.139 -
  59.140 -NamedConstant *
  59.141 -Scope::declareConstant(Handle<String> name, const SourcePosition &pos)
  59.142 -{
  59.143 -    NamedConstant *constant = new (pool_) NamedConstant(this, name, pos);
  59.144 -    if (!names_.append(constant))
  59.145 -        return NULL;
  59.146 -    return constant;
  59.147 -}
  59.148 -
  59.149 -void
  59.150 -Scope::allocateGlobals()
  59.151 -{
  59.152 -    assert(kind() == GLOBAL);
  59.153 -
  59.154 -    for (size_t i = 0; i < children_.length(); i++) {
  59.155 -        assert(children_[i]->kind() == FUNCTION);
  59.156 -        children_[i]->allocate();
  59.157 -    }
  59.158 -
  59.159 -    Local<Type> type(ZONE());
  59.160 -    for (size_t i = 0; i < names_.length(); i++) {
  59.161 -        BoundName *name = names_[i];
  59.162 -        
  59.163 -        if (name->kind() == BoundName::FUNCTION) {
  59.164 -            NamedFunction *fun = name->toNamedFunction();
  59.165 -            if (fun->isNative())
  59.166 -                fun->allocate(numNatives_++);
  59.167 -            else
  59.168 -                fun->allocate(numFunctions_++);
  59.169 -        } else if (name->kind() == BoundName::VARIABLE) {
  59.170 -            allocate(name->toVariable());
  59.171 -        }
  59.172 -    }
  59.173 -}
  59.174 -
  59.175 -void
  59.176 -Scope::allocate(Variable *var)
  59.177 -{
  59.178 -    if (!var->unallocated())
  59.179 -        return;
  59.180 -
  59.181 -    if (kind() == GLOBAL) {
  59.182 -        var->allocate(Variable::ENVIRONMENT, envVars_.length());
  59.183 -        envVars_.append(var);
  59.184 -    } else {
  59.185 -        var->allocate(Variable::STACK, maxContainedLocals_ + locals_);
  59.186 -        locals_++;
  59.187 -    }
  59.188 -}
  59.189 -
  59.190 -void
  59.191 -Scope::allocate()
  59.192 -{
  59.193 -    maxContainedLocals_ = 0;
  59.194 -    for (size_t i = 0; i < children_.length(); i++) {
  59.195 -        Scope *scope = children_[i];
  59.196 -        scope->allocate();
  59.197 -        if (scope->maxContainedLocals() > maxContainedLocals_)
  59.198 -            maxContainedLocals_ = scope->maxContainedLocals();
  59.199 -    }
  59.200 -
  59.201 -    for (size_t i = 0; i < parameters_.length(); i++)
  59.202 -        parameters_[i]->allocate(Variable::PARAMETER, i);
  59.203 -
  59.204 -    if (lifoSlot_)
  59.205 -        allocate(lifoSlot_);
  59.206 -    for (size_t i = 0; i < names_.length(); i++) {
  59.207 -        if (names_[i]->kind() != BoundName::VARIABLE)
  59.208 -            continue;
  59.209 -
  59.210 -        allocate(names_[i]->toVariable());
  59.211 -    }
  59.212 -
  59.213 -    maxContainedLocals_ += locals_;
  59.214 -}
  59.215 -
  59.216 -bool
  59.217 -Scope::Bind(CompileContext &cc, ParseTree *tree)
  59.218 -{
  59.219 -    Local<String> name(ZONE());
  59.220 -    for (size_t i = 0; i < tree->unbound()->length(); i++) {
  59.221 -        NameProxy *proxy = tree->unbound()->at(i);
  59.222 -        name = proxy->name();
  59.223 -        BoundName *binding = tree->scope()->lookup(name);
  59.224 -
  59.225 -        if (!binding) {
  59.226 -            cc.reportError(proxy->pos(), Message_IdentifierNotFound, name->chars());
  59.227 -            return false;
  59.228 -        }
  59.229 -
  59.230 -        // We only allow global functions to be late-bound.
  59.231 -        if (binding->kind() != BoundName::FUNCTION ||
  59.232 -            binding->scope()->kind() != Scope::GLOBAL)
  59.233 -        {
  59.234 -            cc.reportError(proxy->pos(), Message_IdentifierNotFound, name->chars());
  59.235 -            return false;
  59.236 -        }
  59.237 -
  59.238 -        proxy->bind(binding);
  59.239 -    }
  59.240 -    return true;
  59.241 -}
  59.242 -
  59.243 -void
  59.244 -Scope::Allocate(ParseTree *tree)
  59.245 -{
  59.246 -    tree->scope()->allocateGlobals();
  59.247 -}
  59.248 -
  59.249 -void
  59.250 -Scope::setUsesLifoHeap()
  59.251 -{
  59.252 -    // Only one lifo slot is needed per scope.
  59.253 -    if (lifoSlot_)
  59.254 -        return;
  59.255 -
  59.256 -    // If the parent of this scope is the function scope, then this is the
  59.257 -    // function's block scope, and the lifo slot is part of the Frame instead.
  59.258 -    // Note we can get a function scope here if we're making a temporary in a
  59.259 -    // function with no local variables.
  59.260 -    if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
  59.261 -        return;
  59.262 -
  59.263 -    Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
  59.264 -    if (!type)
  59.265 -        return;
  59.266 -
  59.267 -    Local<String> name(ZONE());
  59.268 -    lifoSlot_ = new (pool_) Variable(this, name, SourcePosition());
  59.269 -    lifoSlot_->setType(type);
  59.270 -}
  59.271 -
  59.272 -EnvironmentMap *
  59.273 -Scope::createEnvironmentMap(Zone *zone)
  59.274 -{
  59.275 -    return EnvironmentMap::New(zone, envVars_.length(), envVars_.buffer());
  59.276 -}
    60.1 --- a/jitcraft/Scopes.h	Tue Jul 24 23:53:34 2012 -0700
    60.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    60.3 @@ -1,119 +0,0 @@
    60.4 -/*
    60.5 - * Copyright (C) 2012 David Anderson
    60.6 - *
    60.7 - * This file is part of JITCraft.
    60.8 - *
    60.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   60.10 - * the terms of the GNU General Public License as published by the Free
   60.11 - * Software Foundation, either version 3 of the License, or (at your option)
   60.12 - * any later version.
   60.13 - * 
   60.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   60.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   60.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   60.17 - *
   60.18 - * You should have received a copy of the GNU General Public License along with
   60.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   60.20 - */
   60.21 -#ifndef _include_jitcraft_scopes_h_
   60.22 -#define _include_jitcraft_scopes_h_
   60.23 -
   60.24 -#include "PoolAllocator.h"
   60.25 -#include "AST.h"
   60.26 -#include "NameBinding.h"
   60.27 -#include "Structures.h"
   60.28 -
   60.29 -namespace ke {
   60.30 -
   60.31 -class CompileContext;
   60.32 -class EnvironmentMap;
   60.33 -
   60.34 -class Scope : public PoolObject
   60.35 -{
   60.36 -    PoolAllocator &pool_;
   60.37 -    PoolList<BoundName *> names_;
   60.38 -    PoolList<Scope *> children_;
   60.39 -    PoolList<Variable *> parameters_;
   60.40 -    unsigned locals_;
   60.41 -    unsigned maxContainedLocals_;
   60.42 -    unsigned numFunctions_;
   60.43 -    unsigned numNatives_;
   60.44 -    PoolList<Variable *> envVars_;
   60.45 -    Variable *lifoSlot_;
   60.46 -    
   60.47 -    bool empty() const {
   60.48 -        return names_.length() == 0;
   60.49 -    }
   60.50 -    void unlink();
   60.51 -
   60.52 -  public:
   60.53 -    enum Kind {
   60.54 -        GLOBAL,
   60.55 -        FUNCTION,
   60.56 -        BLOCK
   60.57 -    };
   60.58 -
   60.59 -  public:
   60.60 -    Scope(PoolAllocator &pool, Kind kind, Scope *enclosing);
   60.61 -    bool initialize();
   60.62 -
   60.63 -    Kind kind() const {
   60.64 -        return kind_;
   60.65 -    }
   60.66 -    Scope *enclosing() const {
   60.67 -        return enclosing_;
   60.68 -    }
   60.69 -    unsigned locals() const {
   60.70 -        return locals_;
   60.71 -    }
   60.72 -    unsigned maxContainedLocals() const {
   60.73 -        return maxContainedLocals_;
   60.74 -    }
   60.75 -    unsigned numFunctions() const {
   60.76 -        return numFunctions_;
   60.77 -    }
   60.78 -    unsigned numNatives() const {
   60.79 -        return numNatives_;
   60.80 -    }
   60.81 -    unsigned numArguments() const {
   60.82 -        return parameters_.length();
   60.83 -    }
   60.84 -    unsigned numEnvironmentVars() const {
   60.85 -        return envVars_.length();
   60.86 -    }
   60.87 -    Variable *getArgument(size_t index) {
   60.88 -        return parameters_[index];
   60.89 -    }
   60.90 -    Variable *lifoSlot() {
   60.91 -        return lifoSlot_;
   60.92 -    }
   60.93 -    void setUsesLifoHeap();
   60.94 -
   60.95 -    Scope *unlinkIfEmpty();
   60.96 -    BoundName *localLookup(Handle<String> name);
   60.97 -    BoundName *lookup(Handle<String> name);
   60.98 -
   60.99 -    NamedFunction *declareFunction(Handle<String> name, const SourcePosition &pos, TokenKind token);
  60.100 -    Variable *declareVariable(Handle<String> name, const SourcePosition &pos);
  60.101 -    Variable *declareArgument(Handle<String> name, const SourcePosition &pos);
  60.102 -    NamedEnum *declareEnum(Handle<String> name, const SourcePosition &pos);
  60.103 -    NamedConstant *declareConstant(Handle<String> name, const SourcePosition &pos);
  60.104 -
  60.105 -    EnvironmentMap *createEnvironmentMap(Zone *zone);
  60.106 -
  60.107 -    void allocate(Variable *var);
  60.108 -    void allocate();
  60.109 -    void allocateGlobals();
  60.110 -
  60.111 -  public:
  60.112 -    static bool Bind(CompileContext &cc, ParseTree *tree);
  60.113 -    static void Allocate(ParseTree *tree);
  60.114 -
  60.115 -  private:
  60.116 -    Kind kind_;
  60.117 -    Scope *enclosing_;
  60.118 -};
  60.119 -
  60.120 -}
  60.121 -
  60.122 -#endif // _include_jitcraft_scopes_h_
    61.1 --- a/jitcraft/SemanticAnalysis.cpp	Tue Jul 24 23:53:34 2012 -0700
    61.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    61.3 @@ -1,1092 +0,0 @@
    61.4 -/* vim: set ts=4 sw=4 tw=99 et:
    61.5 - *
    61.6 - * Copyright (C) 2012 David Anderson
    61.7 - *
    61.8 - * This file is part of JITCraft.
    61.9 - *
   61.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   61.11 - * the terms of the GNU General Public License as published by the Free
   61.12 - * Software Foundation, either version 3 of the License, or (at your option)
   61.13 - * any later version.
   61.14 - * 
   61.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   61.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   61.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   61.18 - *
   61.19 - * You should have received a copy of the GNU General Public License along with
   61.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   61.21 - */
   61.22 -#include "SemanticAnalysis.h"
   61.23 -#include "Types.h"
   61.24 -#include "Zone.h"
   61.25 -#include "TypeManager.h"
   61.26 -#include "Scopes.h"
   61.27 -#include "NameBinding.h"
   61.28 -#include "Heap-inl.h"
   61.29 -#include "Strings.h"
   61.30 -
   61.31 -using namespace ke;
   61.32 -
   61.33 -static inline bool
   61.34 -IsPrimitiveType(Type *type, PrimitiveType primitive)
   61.35 -{
   61.36 -    if (!type)
   61.37 -        return false;
   61.38 -
   61.39 -    if (!type->isPrimitive())
   61.40 -        return false;
   61.41 -
   61.42 -    return primitive == type->primitive();
   61.43 -}
   61.44 -
   61.45 -static inline bool
   61.46 -EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
   61.47 -                        BoxedPrimitive *out)
   61.48 -{
   61.49 -    switch (kind) {
   61.50 -      case TOK_PLUS:
   61.51 -        *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
   61.52 -        return true;
   61.53 -
   61.54 -      case TOK_SHL:
   61.55 -        *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
   61.56 -        return true;
   61.57 -
   61.58 -      default:
   61.59 -        return false;
   61.60 -    }
   61.61 -}
   61.62 -
   61.63 -static bool
   61.64 -EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
   61.65 -{
   61.66 -    switch (expression->kind()) {
   61.67 -      case AstNode::kBinaryExpression:
   61.68 -      {
   61.69 -        BoxedPrimitive left;
   61.70 -        BoxedPrimitive right;
   61.71 -        BinaryExpression *b = expression->toBinaryExpression();
   61.72 -        if (!EvaluateForConstant(b->left(), &left) ||
   61.73 -            !EvaluateForConstant(b->right(), &right))
   61.74 -        {
   61.75 -            return false;
   61.76 -        }
   61.77 -        return EvaluateBinaryOperation(b->token(), left, right, out);
   61.78 -      }
   61.79 -
   61.80 -      case AstNode::kNameProxy:
   61.81 -      {
   61.82 -        NameProxy *proxy = expression->toNameProxy();
   61.83 -        if (proxy->binding()->kind() != BoundName::CONSTANT)
   61.84 -            return false;
   61.85 -
   61.86 -        NamedConstant *c = proxy->binding()->toNamedConstant();
   61.87 -        if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
   61.88 -            return false;
   61.89 -
   61.90 -        *out = c->value();
   61.91 -        return true;
   61.92 -      }
   61.93 -
   61.94 -      case AstNode::kIntegerLiteral:
   61.95 -        *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
   61.96 -        return true;
   61.97 -
   61.98 -      default:
   61.99 -        return false;
  61.100 -    }
  61.101 -}
  61.102 -
  61.103 -SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
  61.104 -  : zone_(zone),
  61.105 -    cc_(cc),
  61.106 -    tree_(tree),
  61.107 -    scope_(NULL),
  61.108 -    loop_(NULL)
  61.109 -{
  61.110 -}
  61.111 -
  61.112 -bool
  61.113 -SemanticAnalysis::analyze()
  61.114 -{
  61.115 -    if (cc_.failures())
  61.116 -        return false;
  61.117 -
  61.118 -    scope_ = tree_->scope();
  61.119 -
  61.120 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  61.121 -        Statement *statement = tree_->statements()->at(i);
  61.122 -        if (statement->isFunctionStatement()) {
  61.123 -            FunctionStatement *funstmt = statement->toFunctionStatement();
  61.124 -            if (!preanalyze(funstmt))
  61.125 -                return false;
  61.126 -        }
  61.127 -    }
  61.128 -
  61.129 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  61.130 -        Statement *statement = tree_->statements()->at(i);
  61.131 -        statement->accept(this);
  61.132 -    }
  61.133 -
  61.134 -    return !cc_.failures();
  61.135 -}
  61.136 -
  61.137 -Type *
  61.138 -SemanticAnalysis::visitAndApplyType(Expression *expression)
  61.139 -{
  61.140 -    expression->accept(this);
  61.141 -    return expression->type();
  61.142 -}
  61.143 -
  61.144 -Type *
  61.145 -SemanticAnalysis::visitForLoad(Expression *expression)
  61.146 -{
  61.147 -    Local<Type> type(zone_, visitAndApplyType(expression));
  61.148 -    if (!type)
  61.149 -        return NULL;
  61.150 -
  61.151 -    if (type->isReference()) {
  61.152 -        expression->setType(type->contained());
  61.153 -    } else if (expression->isIndexExpression()) {
  61.154 -        if (type->isArray())
  61.155 -            expression->setType(type->contained());
  61.156 -    } else if (expression->isCallExpression()) {
  61.157 -        if (type->isVoid()) {
  61.158 -            CallExpression *call = expression->toCallExpression();
  61.159 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  61.160 -            return NULL;
  61.161 -        }
  61.162 -    }
  61.163 -
  61.164 -    return expression->type();
  61.165 -}
  61.166 -
  61.167 -// :TODO: this leaks an interior pointer.
  61.168 -static inline const char *
  61.169 -GetTypeName(Type *type)
  61.170 -{
  61.171 -    if (type->isArray())
  61.172 -        return "array";
  61.173 -    if (type->isFunction())
  61.174 -        return "function";
  61.175 -    if (type->isReference())
  61.176 -        type = type->contained();
  61.177 -    if (type->tag())
  61.178 -        return type->tag()->chars();
  61.179 -    return "int";
  61.180 -}
  61.181 -
  61.182 -void
  61.183 -SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
  61.184 -{
  61.185 -    const char *op = TokenNames[token];
  61.186 -    const char *name = GetTypeName(type);
  61.187 -
  61.188 -    cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
  61.189 -}
  61.190 -
  61.191 -void
  61.192 -SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
  61.193 -{
  61.194 -    const char *op = TokenNames[token];
  61.195 -    const char *leftName = GetTypeName(left);
  61.196 -    const char *rightName = GetTypeName(right);
  61.197 -
  61.198 -    cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
  61.199 -}
  61.200 -
  61.201 -Type *
  61.202 -SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
  61.203 -{
  61.204 -    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
  61.205 -        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
  61.206 -    {
  61.207 -        // If either side is a float, the other side must be a float or int.
  61.208 -        if (left->isFloat() || right->isFloat()) {
  61.209 -            Type *floatType = left->isFloat() ? left : right;
  61.210 -            Type *other = left->isFloat() ? right : left;
  61.211 -            if (other->isFloat() || (other->isInt32() && !other->tag()))
  61.212 -                return floatType;
  61.213 -        }
  61.214 -    }
  61.215 -
  61.216 -    if (token == TOK_OR || token == TOK_AND) {
  61.217 -        if (!canTest(node, left) || !canTest(node, right))
  61.218 -            return NULL;
  61.219 -        return zone_->types()->getPrimitive(PrimitiveType_Int32);
  61.220 -    }
  61.221 -
  61.222 -    if (token >= TOK_EQUALS && token <= TOK_GE) {
  61.223 -        if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
  61.224 -            (right->isFloat() || (right->isInt32() && !right->tag())))
  61.225 -        {
  61.226 -            return zone_->types()->getPrimitive(PrimitiveType_Int32);
  61.227 -        }
  61.228 -        binaryTypeError(node, token, left, right);
  61.229 -        return NULL;
  61.230 -    }
  61.231 -
  61.232 -    if ((!left->isInt32() || left->tag()) ||
  61.233 -        (!right->isInt32() || right->tag()))
  61.234 -    {
  61.235 -        binaryTypeError(node, token, left, right);
  61.236 -        return NULL;
  61.237 -    }
  61.238 -
  61.239 -    return left;
  61.240 -}
  61.241 -
  61.242 -bool
  61.243 -SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
  61.244 -{
  61.245 -    if (type->isArray() || (type->isInt32() && type->tag())) {
  61.246 -        cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
  61.247 -        return false;
  61.248 -    }
  61.249 -    return true;
  61.250 -}
  61.251 -
  61.252 -Type *
  61.253 -SemanticAnalysis::visitForLValue(Expression *expression)
  61.254 -{
  61.255 -    if (expression->isIndexExpression()) {
  61.256 -        Type *type = visitAndApplyType(expression);
  61.257 -        if (!type)
  61.258 -            return NULL;
  61.259 -
  61.260 -        if (type->isConst()) {
  61.261 -            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
  61.262 -            return NULL;
  61.263 -        }
  61.264 -
  61.265 -        return type->contained();
  61.266 -    }
  61.267 -
  61.268 -    if (!expression->isNameProxy()) {
  61.269 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
  61.270 -        return NULL;
  61.271 -    }
  61.272 -
  61.273 -    NameProxy *proxy = expression->toNameProxy();
  61.274 -    if (!proxy->binding()->kind() == BoundName::VARIABLE) {
  61.275 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
  61.276 -        return NULL;
  61.277 -    }
  61.278 -
  61.279 -    Variable *var = proxy->binding()->toVariable();
  61.280 -    if (!var->type())
  61.281 -        return NULL;
  61.282 -
  61.283 -    if  (var->type()->isReference()) {
  61.284 -        if (var->type()->isConst()) {
  61.285 -            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
  61.286 -            return NULL;
  61.287 -        }
  61.288 -        return var->type()->contained();
  61.289 -    }
  61.290 -    return var->type();
  61.291 -}
  61.292 -
  61.293 -SemanticAnalysis::ControlStatus
  61.294 -SemanticAnalysis::visitForControl(Statement *statement)
  61.295 -{
  61.296 -    ControlScope scope(&control_);
  61.297 -    statement->accept(this);
  61.298 -    return scope.status();
  61.299 -}
  61.300 -
  61.301 -void
  61.302 -SemanticAnalysis::visit(NameProxy *name)
  61.303 -{
  61.304 -    name->setType(name->binding()->type());
  61.305 -}
  61.306 -
  61.307 -void
  61.308 -SemanticAnalysis::visit(Assignment *node)
  61.309 -{
  61.310 -    Local<Type> exprType(zone_, visitForLoad(node->expression()));
  61.311 -    if (!exprType)
  61.312 -        return ;
  61.313 -
  61.314 -    Local<Type> type(zone_, visitForLValue(node->lvalue()));
  61.315 -    if (!type)
  61.316 -        return;
  61.317 -
  61.318 -    if (node->token() != TOK_ASSIGN) {
  61.319 -        if (!typeCheckBinary(node, node->token(), type, exprType))
  61.320 -            return;
  61.321 -    }
  61.322 -
  61.323 -    if (!typeCheckAssignment(node, exprType, type, true))
  61.324 -        return;
  61.325 -
  61.326 -    node->setType(type);
  61.327 -}
  61.328 -
  61.329 -void
  61.330 -SemanticAnalysis::visit(IncDecExpression *node)
  61.331 -{
  61.332 -    Local<Type> type(zone_, visitForLValue(node->expression()));
  61.333 -    if (!type)
  61.334 -        return;
  61.335 -
  61.336 -    assert(!type->isReference());
  61.337 -
  61.338 -    if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
  61.339 -        unaryTypeError(node, node->token(), type);
  61.340 -        return;
  61.341 -    }
  61.342 -
  61.343 -    node->setType(type);
  61.344 -}
  61.345 -
  61.346 -void
  61.347 -SemanticAnalysis::visit(UnaryExpression *node)
  61.348 -{
  61.349 -    Local<Type> type(zone_, visitForLoad(node->expression()));
  61.350 -    if (!type)
  61.351 -        return;
  61.352 -
  61.353 -    switch (node->token())
  61.354 -    {
  61.355 -      case TOK_NOT:
  61.356 -        if (!canTest(node->expression(), type))
  61.357 -            return;
  61.358 -        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  61.359 -        if (!type)
  61.360 -            return;
  61.361 -        node->setType(type);
  61.362 -        break;
  61.363 -
  61.364 -      case TOK_MINUS:
  61.365 -        if (!type->isFloat() && (!type->isInt32() || type->tag())) {
  61.366 -            unaryTypeError(node, node->token(), type);
  61.367 -            return;
  61.368 -        }
  61.369 -        node->setType(type);
  61.370 -        break;
  61.371 -
  61.372 -      default:
  61.373 -        assert(node->token() == TOK_TILDE);
  61.374 -        if (!type->isInt32() || type->tag()) {
  61.375 -            unaryTypeError(node, node->token(), type);
  61.376 -            return;
  61.377 -        }
  61.378 -        node->setType(type);
  61.379 -        break;
  61.380 -    }
  61.381 -}
  61.382 -
  61.383 -void
  61.384 -SemanticAnalysis::visit(TernaryExpression *node)
  61.385 -{
  61.386 -    Local<Type> type(zone_, visitForLoad(node->condition()));
  61.387 -    if (!type)
  61.388 -        return;
  61.389 -
  61.390 -    if (!canTest(node->condition(), type))
  61.391 -        return;
  61.392 -
  61.393 -    Local<Type> left(zone_, visitForLoad(node->left()));
  61.394 -    Local<Type> right(zone_, visitForLoad(node->right()));
  61.395 -    if (!left || !right)
  61.396 -        return;
  61.397 -
  61.398 -    if (left != right) {
  61.399 -        binaryTypeError(node, TOK_QMARK, left, right);
  61.400 -        return;
  61.401 -    }
  61.402 -}
  61.403 -
  61.404 -void
  61.405 -SemanticAnalysis::visit(BinaryExpression *node)
  61.406 -{
  61.407 -    Local<Type> left(zone_, visitForLoad(node->left()));
  61.408 -    Local<Type> right(zone_, visitForLoad(node->right()));
  61.409 -    if (!left || !right)
  61.410 -        return;
  61.411 -
  61.412 -    Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
  61.413 -    if (!result)
  61.414 -        return;
  61.415 -
  61.416 -    node->setType(result);
  61.417 -}
  61.418 -
  61.419 -void
  61.420 -SemanticAnalysis::visit(ReturnStatement *node)
  61.421 -{
  61.422 -    // Set this early, so if we error we don't get more errors.
  61.423 -    control_->returns(Returns_Always);
  61.424 -
  61.425 -    if (!node->expression()) {
  61.426 -        if (!function_->returnType()->isVoid())
  61.427 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  61.428 -        return;
  61.429 -    }
  61.430 -
  61.431 -    Local<Type> type(zone_, visitForLoad(node->expression()));
  61.432 -    if (!type)
  61.433 -        return;
  61.434 -
  61.435 -    Local<Type> returnType(zone_, function_->returnType());
  61.436 -    if (!typeCheckAssignment(node, type, returnType, true))
  61.437 -        return;
  61.438 -}
  61.439 -
  61.440 -void
  61.441 -SemanticAnalysis::visit(ForStatement *node)
  61.442 -{
  61.443 -    LoopScope loop(&loop_);
  61.444 -
  61.445 -    if (node->scope())
  61.446 -        scope_ = node->scope();
  61.447 -
  61.448 -    if (node->initialization())
  61.449 -        node->initialization()->accept(this);
  61.450 -
  61.451 -    if (node->condition()) {
  61.452 -        Local<Type> type(zone_, visitForLoad(node->condition()));
  61.453 -        if (!type || !canTest(node->condition(), type)) {
  61.454 -            return;
  61.455 -        }
  61.456 -    }
  61.457 -
  61.458 -    if (node->update())
  61.459 -        node->update()->accept(this);
  61.460 -
  61.461 -    ControlStatus status = visitForControl(node->body());
  61.462 -
  61.463 -    // If there is a condition, we treat this like a while loop. Otherwise,
  61.464 -    // join point is only reachable if the loop contains a break. The
  61.465 -    // termination status doesn't tell us anything yet.
  61.466 -    if (node->condition() || loop.breaks())
  61.467 -        control_->merge(status, ControlStatus(false, Returns_Never));
  61.468 -    else
  61.469 -        control_->terminate(status.returns());
  61.470 -
  61.471 -    if (node->scope())
  61.472 -        scope_ = scope_->enclosing();
  61.473 -}
  61.474 -
  61.475 -void 
  61.476 -SemanticAnalysis::visit(WhileStatement *node)
  61.477 -{
  61.478 -    LoopScope loop(&loop_);
  61.479 -
  61.480 -    Local<Type> type(zone_, visitForLoad(node->condition()));
  61.481 -    if (!type || !canTest(node->condition(), type)) {
  61.482 -        return;
  61.483 -    }
  61.484 -
  61.485 -    ControlStatus status = visitForControl(node->body());
  61.486 -
  61.487 -    // Detect loops that will always have a fork in the control-flow graph.
  61.488 -    // This will be a |while| loop, or a |do-while| loop whose body does
  61.489 -    // not terminate.
  61.490 -    //
  61.491 -    // For now, we treat these as an |if| regardless of the direction the
  61.492 -    // branch can take. That means the control-flow is always conditional.
  61.493 -    if (node->token() == TOK_WHILE ||
  61.494 -        !status.terminates() ||
  61.495 -        loop.breaks())
  61.496 -    {
  61.497 -        control_->merge(status, ControlStatus(false, Returns_Never));
  61.498 -    } else {
  61.499 -        // At this point, we've got a do-while loop with a |return| or
  61.500 -        // |continue|, meaning that the rest of the block is unreachable.
  61.501 -        control_->terminate(status.returns());
  61.502 -    }
  61.503 -}
  61.504 -
  61.505 -void
  61.506 -SemanticAnalysis::visit(BlockStatement *node)
  61.507 -{
  61.508 -    if (node->scope())
  61.509 -        scope_ = node->scope();
  61.510 -    for (size_t i = 0; i < node->statements()->length(); i++) {
  61.511 -        Statement *statement = node->statements()->at(i);
  61.512 -        statement->accept(this);
  61.513 -    }
  61.514 -    if (node->scope())
  61.515 -        scope_ = scope_->enclosing();
  61.516 -}
  61.517 -
  61.518 -void
  61.519 -SemanticAnalysis::visit(VariableDeclaration *node)
  61.520 -{
  61.521 -    Local<String> tag(zone_, node->tag());
  61.522 -    Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
  61.523 -    if (!type)
  61.524 -        return;
  61.525 -
  61.526 -    if (node->postDimensions()) {
  61.527 -        Local<Type> init(zone_);
  61.528 -        if (node->initialization()) {
  61.529 -            if ((init = visitForLoad(node->initialization())) == NULL)
  61.530 -                return;
  61.531 -        }
  61.532 -
  61.533 -        if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
  61.534 -            cc_.reportError(node->pos(), Message_MaximumArrayDepth);
  61.535 -            return;
  61.536 -        }
  61.537 -
  61.538 -        // If we have an initializer, make sure it's the same type.
  61.539 -        if (init && node->postDimensions()->length() != init->levels()) {
  61.540 -            cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
  61.541 -            return;
  61.542 -        }
  61.543 -
  61.544 -        Local<Type> check(zone_, init);
  61.545 -        for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
  61.546 -            Expression *expr = node->postDimensions()->at(i);
  61.547 -            int size = -1;
  61.548 -
  61.549 -            if (expr) {
  61.550 -                Local<Type> exprType(zone_, visitForLoad(expr));
  61.551 -                if (!exprType)
  61.552 -                    return;
  61.553 -
  61.554 -                if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
  61.555 -                    cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
  61.556 -                    return;
  61.557 -                }
  61.558 -
  61.559 -                BoxedPrimitive box;
  61.560 -                if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
  61.561 -                    size = box.toInt();
  61.562 -                    if (size <= 0) {
  61.563 -                        cc_.reportError(expr->pos(), Message_BadArraySize);
  61.564 -                        return;
  61.565 -                    }
  61.566 -                    if (size >= INT_MAX / sizeof(int)) {
  61.567 -                        cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
  61.568 -                        return;
  61.569 -                    }
  61.570 -
  61.571 -                    if (check) {
  61.572 -                        if (check->elements() == -1) {
  61.573 -                            cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
  61.574 -                            return;
  61.575 -                        }
  61.576 -
  61.577 -                        if (check->isCharArray()) {
  61.578 -                            if (check->elements() > size) {
  61.579 -                                cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
  61.580 -                                return;
  61.581 -                            }
  61.582 -                        } else if (check->elements() != size) {
  61.583 -                            cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
  61.584 -                            return;
  61.585 -                        }
  61.586 -                    }
  61.587 -                } else {
  61.588 -                    if (init) {
  61.589 -                        cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
  61.590 -                        return;
  61.591 -                    }
  61.592 -
  61.593 -                    // here until we get dynamic array support.
  61.594 -                    cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
  61.595 -                    return;
  61.596 -                }
  61.597 -            } else {
  61.598 -                // Infer the size from the initializer.
  61.599 -                if (!init) {
  61.600 -                    cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
  61.601 -                    return;
  61.602 -                }
  61.603 -                if (init->elements() == -1) {
  61.604 -                    cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
  61.605 -                    return;
  61.606 -                }
  61.607 -                size = init->elements();
  61.608 -            }
  61.609 -
  61.610 -            type = zone_->types()->unsafeArray(type, size, false);
  61.611 -            if (!type)
  61.612 -                return;
  61.613 -
  61.614 -            if (check)
  61.615 -                check = check->contained();
  61.616 -        }
  61.617 -
  61.618 -        // If this variable is stack allocated, we could use the LIFO heap
  61.619 -        // to allocate it. If that's the case, make sure to reserve a slot
  61.620 -        // so we can unwind the LIFO heap at the end of this scope.
  61.621 -        if (!node->variable()->needsHeapAllocation())
  61.622 -            scope_->setUsesLifoHeap();
  61.623 -    } else {
  61.624 -        if (node->initialization()) {
  61.625 -            Local<Type> right(zone_, visitForLoad(node->initialization()));
  61.626 -            if (!right)
  61.627 -                return;
  61.628 -            if (!typeCheckAssignment(node, type, right, true))
  61.629 -                return;
  61.630 -        }
  61.631 -        if (type->primitive() == PrimitiveType_Char) {
  61.632 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  61.633 -            return;
  61.634 -        }
  61.635 -    }
  61.636 -
  61.637 -    node->variable()->setType(type);
  61.638 -}
  61.639 -
  61.640 -void
  61.641 -SemanticAnalysis::visit(IntegerLiteral *node)
  61.642 -{
  61.643 -    node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  61.644 -}
  61.645 -
  61.646 -void
  61.647 -SemanticAnalysis::visit(ExpressionStatement *node)
  61.648 -{
  61.649 -    visitAndApplyType(node->expression());
  61.650 -}
  61.651 -
  61.652 -bool
  61.653 -SemanticAnalysis::preanalyze(FunctionStatement *node)
  61.654 -{
  61.655 -    Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
  61.656 -    if (!args)
  61.657 -        return false;
  61.658 -
  61.659 -    // Apply types to arguments.
  61.660 -    for (size_t i = 0; i < node->parameters()->length(); i++) {
  61.661 -        Parameter *parameter = node->parameters()->at(i);
  61.662 -        
  61.663 -        Local<String> tag(zone_, parameter->tag());
  61.664 -        Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
  61.665 -        if (!type)
  61.666 -            return false;
  61.667 -
  61.668 -        if (parameter->reference()) {
  61.669 -            if (parameter->dimensions()) {
  61.670 -                cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
  61.671 -                return NULL;
  61.672 -            }
  61.673 -
  61.674 -            type = zone_->types()->getReference(type, parameter->isConst());
  61.675 -            if (!type)
  61.676 -                return false;
  61.677 -        } else if (parameter->dimensions()) {
  61.678 -            if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
  61.679 -                cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
  61.680 -                return false;
  61.681 -            }
  61.682 -
  61.683 -            if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
  61.684 -                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
  61.685 -                return false;
  61.686 -            }
  61.687 -
  61.688 -            for (size_t i = parameter->dimensions()->length() - 1;
  61.689 -                 i < parameter->dimensions()->length();
  61.690 -                 i++)
  61.691 -            {
  61.692 -                int size = Type::UNKNOWN_SIZE;
  61.693 -                if (Expression *expr = parameter->dimensions()->at(i)) {
  61.694 -                    BoxedPrimitive box;
  61.695 -                    if (!EvaluateForConstant(expr, &box)) {
  61.696 -                        cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
  61.697 -                        return false;
  61.698 -                    }
  61.699 -                    size = box.toInt();
  61.700 -                }
  61.701 -
  61.702 -                type = zone_->types()->unsafeArray(type, size, parameter->isConst());
  61.703 -                if (!type)
  61.704 -                    return false;
  61.705 -            }
  61.706 -        }
  61.707 -
  61.708 -        if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
  61.709 -            (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
  61.710 -        {
  61.711 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  61.712 -            return false;
  61.713 -        }
  61.714 -
  61.715 -        args->set(zone_, i, type);
  61.716 -        parameter->variable()->setType(type);
  61.717 -    }
  61.718 -
  61.719 -    Local<Type> returnType(zone_);
  61.720 -    if (node->hasExplicitReturn() || node->fun()->isNative())
  61.721 -        returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  61.722 -    else
  61.723 -        returnType = zone_->types()->getVoid();
  61.724 -    if (!returnType)
  61.725 -        return false;
  61.726 -
  61.727 -    Local<Type> funtype(zone_);
  61.728 -    if (node->fun()->isNative())
  61.729 -        funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
  61.730 -    else
  61.731 -        funtype = zone_->types()->newFunction(returnType, args);
  61.732 -    if (!funtype)
  61.733 -        return false;
  61.734 -    
  61.735 -    // If the function already has a type, it was forward declared before, and
  61.736 -    // now this is our chance to type check the second declaration.
  61.737 -    if (node->fun()->type()) {
  61.738 -        Local<Type> forward(zone_, node->fun()->type());
  61.739 -        if (!Type::Compare(funtype, forward)) {
  61.740 -            cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  61.741 -            return false;
  61.742 -        }
  61.743 -        node->fun()->setForwardType(forward);
  61.744 -    }
  61.745 -
  61.746 -    node->fun()->setType(funtype);
  61.747 -
  61.748 -    return true;
  61.749 -}
  61.750 -
  61.751 -void
  61.752 -SemanticAnalysis::visit(FunctionStatement *node)
  61.753 -{
  61.754 -    function_ = node->fun()->type();
  61.755 -    scope_ = node->scope();
  61.756 -
  61.757 -    ControlScope control(&control_);
  61.758 -    if (node->body()) {
  61.759 -        node->body()->accept(this);
  61.760 -
  61.761 -        ControlStatus status = control.status();
  61.762 -        if (status.returns() == Returns_Sometimes) {
  61.763 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  61.764 -        } else if (status.returns() == Returns_Never) {
  61.765 -            if (!function_->returnType()->isVoid())
  61.766 -                cc_.reportError(node->pos(), Message_MissingReturnValue);
  61.767 -        }
  61.768 -    }
  61.769 -
  61.770 -    scope_ = NULL;
  61.771 -    function_ = NULL;
  61.772 -}
  61.773 -
  61.774 -bool
  61.775 -SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
  61.776 -{
  61.777 -    Local<Type> actual(zone_, argActual);
  61.778 -    Local<Type> given(zone_, argGiven);
  61.779 -
  61.780 -    if (!given->isArray()) {
  61.781 -        cc_.reportError(node->pos(), Message_ExpectedArray);
  61.782 -        return false;
  61.783 -    }
  61.784 -    if (given->levels() != actual->levels()) {
  61.785 -        cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
  61.786 -        return false;
  61.787 -    }
  61.788 -
  61.789 -    unsigned level = 0;
  61.790 -    while (given->isArray()) {
  61.791 -        if (actual->elements() != -1) {
  61.792 -            if (forAssign) {
  61.793 -                if (given->elements() == -1 || actual->elements() == -1) {
  61.794 -                    cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
  61.795 -                    return false;
  61.796 -                }
  61.797 -
  61.798 -                if (actual->isCharArray()) {
  61.799 -                    // String assignment can have a truncated |given|.
  61.800 -                    if (given->elements() > actual->elements()) {
  61.801 -                        cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
  61.802 -                        return false;
  61.803 -                    }
  61.804 -                } else {
  61.805 -                    if (given->elements() != actual->elements()) {
  61.806 -                        cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
  61.807 -                        return false;
  61.808 -                    }
  61.809 -                }
  61.810 -            } else {
  61.811 -                if (actual->elements() != -1 && given->elements() != actual->elements()) {
  61.812 -                    cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
  61.813 -                    return false;
  61.814 -                }
  61.815 -            }
  61.816 -        }
  61.817 -        given = given->contained();
  61.818 -        actual = actual->contained();
  61.819 -    }
  61.820 -
  61.821 -    if (given->primitive() != actual->primitive()) {
  61.822 -        // :TODO: leaks an interior pointer.
  61.823 -        const char *givenTag = given->tag() ? given->tag()->chars() : "_";
  61.824 -        const char *actualTag = given->tag() ? given->tag()->chars() : "_";
  61.825 -        cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
  61.826 -        return false;
  61.827 -    }
  61.828 -
  61.829 -    return true;
  61.830 -}
  61.831 -
  61.832 -bool
  61.833 -SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
  61.834 -{
  61.835 -    Local<Type> actual(zone_, argActual);
  61.836 -    Local<Type> given(zone_, argGiven);
  61.837 -
  61.838 -    if (actual->isArray())
  61.839 -        return typeCheckArrayAssignment(node, given, actual, forAssign);
  61.840 -
  61.841 -    if (given->isArray()) {
  61.842 -        cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
  61.843 -        return false;
  61.844 -    }
  61.845 -
  61.846 -    // The given type may not have been dereferenced.
  61.847 -    if (given->isReference())
  61.848 -        given = given->contained();
  61.849 -    if (actual->isReference())
  61.850 -        actual = actual->contained();
  61.851 -
  61.852 -    if (!given->isPrimitive() || !actual->isPrimitive()) {
  61.853 -        cc_.reportError(node->pos(), Message_UnsupportedType);
  61.854 -        return false;
  61.855 -    }
  61.856 -    
  61.857 -    if (given->primitive() != actual->primitive()) {
  61.858 -        // :TODO: leaks an interior pointer
  61.859 -        const char *givenTag = given->tag() ? given->tag()->chars() : "_";
  61.860 -        const char *actualTag = actual->tag() ? actual->tag()->chars() : "_";
  61.861 -        cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
  61.862 -        return false;
  61.863 -    }
  61.864 -
  61.865 -    return true;
  61.866 -}
  61.867 -
  61.868 -bool
  61.869 -SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  61.870 -{
  61.871 -    return typeCheckAssignment(node, given, actual, false);
  61.872 -}
  61.873 -
  61.874 -void
  61.875 -SemanticAnalysis::visit(CallExpression *node)
  61.876 -{
  61.877 -    Local<Type> type(zone_, visitForLoad(node->callee()));
  61.878 -    if (!type)
  61.879 -        return;
  61.880 -
  61.881 -    if (!type->isFunction()) {
  61.882 -        cc_.reportError(node->pos(), Message_CalleeNotFunction);
  61.883 -        return;
  61.884 -    }
  61.885 -    if (node->arguments()->length() != type->parameters()->length()) {
  61.886 -        if (!type->isNative() ||
  61.887 -            !type->isNativeVariadic() ||
  61.888 -            node->arguments()->length() < type->parameters()->length())
  61.889 -        {
  61.890 -            cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  61.891 -            return;
  61.892 -        }
  61.893 -    }
  61.894 -
  61.895 -    // Currently, only calls from a NameProxy are possible.
  61.896 -    NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  61.897 -    if (fun->isForward()) {
  61.898 -        cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  61.899 -        return;
  61.900 -    }
  61.901 -
  61.902 -    for (unsigned i = 0; i < node->arguments()->length(); i++) {
  61.903 -        // Note: we don't compute references unless the callee needs a
  61.904 -        // reference type.
  61.905 -        Expression *expression = node->arguments()->at(i);
  61.906 -        Local<Type> given(zone_, visitAndApplyType(expression));
  61.907 -        if (!given)
  61.908 -            return;
  61.909 -
  61.910 -        // Since we skip a load, check for a call expression that returns void.
  61.911 -        if (given->isVoid()) {
  61.912 -            assert(expression->isCallExpression());
  61.913 -            CallExpression *call = expression->toCallExpression();
  61.914 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  61.915 -            return;
  61.916 -        }
  61.917 -        
  61.918 -        // If it's an IndexExpression, we special case the ability to compute
  61.919 -        // a reference.
  61.920 -        if (expression->isIndexExpression())
  61.921 -            given = given->contained();
  61.922 -
  61.923 -        bool mustComputeReference;
  61.924 -        if (i >= type->parameters()->length()) {
  61.925 -            // Special handling for natives. Arguments past the formal must
  61.926 -            // always have references computed. However, arrays are already
  61.927 -            // references for natives.  
  61.928 -            assert(type->isNative() && type->isNativeVariadic());
  61.929 -            mustComputeReference = !given->isReference() && !given->isArray();
  61.930 -        } else {
  61.931 -            Local<Type> actual(zone_, type->parameterAt(i));
  61.932 -            if (!typeCheckParameter(expression, given, actual))
  61.933 -                return;
  61.934 -            mustComputeReference = actual->isReference() && !given->isReference();
  61.935 -        }
  61.936 -
  61.937 -        // If the actual is a reference, and the given is not, we'll need to
  61.938 -        // compute a reference, which may be allocated on the stack.
  61.939 -        if (mustComputeReference)
  61.940 -            scope_->setUsesLifoHeap();
  61.941 -    }
  61.942 -
  61.943 -    node->setType(fun->type()->returnType());
  61.944 -}
  61.945 -
  61.946 -void
  61.947 -SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  61.948 -{
  61.949 -    // If both sides terminate in a return, we consider this a return as well.
  61.950 -    if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  61.951 -        terminate(Returns_Always);
  61.952 -        return;
  61.953 -    }
  61.954 -
  61.955 -    ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  61.956 -                          ? Returns_Never
  61.957 -                          : Returns_Sometimes;
  61.958 -
  61.959 -    if (left.terminates() && right.terminates())
  61.960 -        terminate(status);
  61.961 -    else
  61.962 -        returns(status);
  61.963 -}
  61.964 -
  61.965 -void
  61.966 -SemanticAnalysis::visit(IfStatement *node)
  61.967 -{
  61.968 -    Local<Type> type(zone_, visitForLoad(node->condition()));
  61.969 -    if (!type)
  61.970 -        return;
  61.971 -
  61.972 -    if (!canTest(node, type))
  61.973 -        return;
  61.974 -
  61.975 -    ControlStatus trueBranch = visitForControl(node->ifTrue());
  61.976 -    ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  61.977 -
  61.978 -    if (node->ifFalse())
  61.979 -        falseBranch = visitForControl(node->ifFalse());
  61.980 -
  61.981 -    control_->merge(trueBranch, falseBranch);
  61.982 -}
  61.983 -
  61.984 -void
  61.985 -SemanticAnalysis::visit(IndexExpression *node)
  61.986 -{
  61.987 -    Local<Type> left(zone_, visitForLoad(node->left()));
  61.988 -    Local<Type> right(zone_, visitForLoad(node->right()));
  61.989 -
  61.990 -    if (!left || !right)
  61.991 -        return;
  61.992 -
  61.993 -    if (!right->isInt32()) {
  61.994 -        cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  61.995 -        return;
  61.996 -    }
  61.997 -    if (!left->isArray()) {
  61.998 -        cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  61.999 -        return;
 61.1000 -    }
 61.1001 -    node->setType(left);
 61.1002 -}
 61.1003 -
 61.1004 -void
 61.1005 -SemanticAnalysis::visit(EnumStatement *node)
 61.1006 -{
 61.1007 -    // Forbid the blessed types.
 61.1008 -    Local<String> tag(zone_, node->name());
 61.1009 -    if (!strcmp(tag->chars(), "Float") ||
 61.1010 -        !strcmp(tag->chars(), "String") ||
 61.1011 -        !strcmp(tag->chars(), "any") ||
 61.1012 -        !strcmp(tag->chars(), "bool"))
 61.1013 -    {
 61.1014 -        cc_.reportError(node->pos(), Message_InvalidEnumName);
 61.1015 -        return;
 61.1016 -    }
 61.1017 -
 61.1018 -    Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
 61.1019 -    if (!type)
 61.1020 -        return;
 61.1021 -
 61.1022 -    int value = 0;
 61.1023 -    for (size_t i = 0; i < node->entries()->length(); i++) {
 61.1024 -        EnumStatement::Entry &entry = node->entries()->at(i);
 61.1025 -
 61.1026 -        BoxedPrimitive box = BoxedPrimitive::Int(value);
 61.1027 -        if (entry.expr) {
 61.1028 -            entry.expr->accept(this);
 61.1029 -            if (!EvaluateForConstant(entry.expr, &box)) {
 61.1030 -                cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
 61.1031 -                return;
 61.1032 -            }
 61.1033 -
 61.1034 -            assert(box.type() == PrimitiveType_Int32);
 61.1035 -            value = box.toInt();
 61.1036 -        }
 61.1037 -
 61.1038 -        entry.name->set(type, box);
 61.1039 -        value++;
 61.1040 -    }
 61.1041 -}
 61.1042 -
 61.1043 -void
 61.1044 -SemanticAnalysis::visit(StringLiteral *node)
 61.1045 -{
 61.1046 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
 61.1047 -    if (!type)
 61.1048 -        return;
 61.1049 -
 61.1050 -    type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
 61.1051 -    if (!type)
 61.1052 -        return;
 61.1053 -
 61.1054 -    node->setType(type);
 61.1055 -}
 61.1056 -
 61.1057 -void
 61.1058 -SemanticAnalysis::visit(FloatLiteral *node)
 61.1059 -{
 61.1060 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
 61.1061 -    if (!type)
 61.1062 -        return;
 61.1063 -
 61.1064 -    node->setType(type);
 61.1065 -}
 61.1066 -
 61.1067 -void
 61.1068 -SemanticAnalysis::visit(BreakStatement *node)
 61.1069 -{
 61.1070 -    if (!loop_) {
 61.1071 -        cc_.reportError(node->pos(), Message_BreakOutsideLoop);
 61.1072 -        return;
 61.1073 -    }
 61.1074 -
 61.1075 -    // Note: ignore breaks that occur in unreachable control-flow.
 61.1076 -    if (!control_->status().terminates())
 61.1077 -        loop_->addBreak();
 61.1078 -
 61.1079 -    control_->terminate(Returns_Never);
 61.1080 -}
 61.1081 -
 61.1082 -void
 61.1083 -SemanticAnalysis::visit(ContinueStatement *node)
 61.1084 -{
 61.1085 -    if (!loop_) {
 61.1086 -        cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
 61.1087 -        return;
 61.1088 -    }
 61.1089 -
 61.1090 -    // Note: ignore continues that occur in unreachable control-flow.
 61.1091 -    if (!control_->status().terminates())
 61.1092 -        loop_->addContinue();
 61.1093 -
 61.1094 -    control_->terminate(Returns_Never);
 61.1095 -}
    62.1 --- a/jitcraft/SemanticAnalysis.h	Tue Jul 24 23:53:34 2012 -0700
    62.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    62.3 @@ -1,204 +0,0 @@
    62.4 -/* vim: set ts=4 sw=4 tw=99 et:
    62.5 - *
    62.6 - * Copyright (C) 2012 David Anderson
    62.7 - *
    62.8 - * This file is part of JITCraft.
    62.9 - *
   62.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   62.11 - * the terms of the GNU General Public License as published by the Free
   62.12 - * Software Foundation, either version 3 of the License, or (at your option)
   62.13 - * any later version.
   62.14 - * 
   62.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   62.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   62.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   62.18 - *
   62.19 - * You should have received a copy of the GNU General Public License along with
   62.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   62.21 - */
   62.22 -#ifndef _include_semantic_analysis_h_
   62.23 -#define _include_semantic_analysis_h_
   62.24 -
   62.25 -#include <assert.h>
   62.26 -#include "AST.h"
   62.27 -
   62.28 -namespace ke {
   62.29 -
   62.30 -class SemanticAnalysis : public AstVisitor
   62.31 -{
   62.32 -    Zone *zone_;
   62.33 -    CompileContext &cc_;
   62.34 -    ParseTree *tree_;
   62.35 -    Scope *scope_;
   62.36 -    ScopedRoot<Type> function_;
   62.37 -
   62.38 -    enum ReturnStatus
   62.39 -    {
   62.40 -        Returns_Never,
   62.41 -        Returns_Sometimes,
   62.42 -        Returns_Always
   62.43 -    };
   62.44 -
   62.45 -    // Tuple that describes whether a path terminates control flow, and
   62.46 -    // if it is guaranteed to end in a return.
   62.47 -    class ControlStatus
   62.48 -    {
   62.49 -        bool terminates_;
   62.50 -        ReturnStatus returns_;
   62.51 -
   62.52 -      public:
   62.53 -        ControlStatus(bool terminates, ReturnStatus returns)
   62.54 -          : terminates_(terminates),
   62.55 -            returns_(returns)
   62.56 -        {
   62.57 -        }
   62.58 -
   62.59 -        bool terminates() const {
   62.60 -            return terminates_;
   62.61 -        }
   62.62 -        ReturnStatus returns() const {
   62.63 -            return returns_;
   62.64 -        }
   62.65 -    };
   62.66 -
   62.67 -    // Used to keep track of terminating control flow and return statements
   62.68 -    // inside control structures.
   62.69 -    class ControlScope
   62.70 -    {
   62.71 -        ReturnStatus returns_;
   62.72 -        ControlScope **prevp_;
   62.73 -        ControlScope *prev_;
   62.74 -        bool terminates_;
   62.75 -
   62.76 -      public:
   62.77 -        ControlScope(ControlScope **prev)
   62.78 -          : returns_(Returns_Never),
   62.79 -            prevp_(prev),
   62.80 -            prev_(*prev),
   62.81 -            terminates_(false)
   62.82 -        {
   62.83 -            *prevp_ = this;
   62.84 -        }
   62.85 -
   62.86 -        ControlStatus status() const {
   62.87 -            return ControlStatus(terminates_, returns_);
   62.88 -        }
   62.89 -
   62.90 -        // We allow multiple terminators, but only the first one takes effect.
   62.91 -        // For example, |break; continue;| is legal but the continue is
   62.92 -        // unreachable.
   62.93 -        void returns(ReturnStatus status) {
   62.94 -            if (terminates_)
   62.95 -                return;
   62.96 -            if (status > returns_)
   62.97 -                returns_ = status;
   62.98 -        }
   62.99 -        void terminate(ReturnStatus status) {
  62.100 -            if (terminates_)
  62.101 -                return;
  62.102 -            terminates_ = true;
  62.103 -            returns_ = status;
  62.104 -        }
  62.105 -        void merge(const ControlStatus &left, const ControlStatus &right);
  62.106 -
  62.107 -        ~ControlScope()
  62.108 -        {
  62.109 -            *prevp_ = prev_;
  62.110 -        }
  62.111 -    };
  62.112 -
  62.113 -    class LoopScope
  62.114 -    {
  62.115 -        LoopScope **prevp_;
  62.116 -        LoopScope *prev_;
  62.117 -        unsigned breaks_;
  62.118 -        unsigned continues_;
  62.119 -
  62.120 -      public:
  62.121 -        LoopScope(LoopScope **prev)
  62.122 -          : prevp_(prev),
  62.123 -            prev_(*prev),
  62.124 -            breaks_(0),
  62.125 -            continues_(0)
  62.126 -        {
  62.127 -            *prevp_ = this;
  62.128 -        }
  62.129 -
  62.130 -        ~LoopScope()
  62.131 -        {
  62.132 -            *prevp_ = prev_;
  62.133 -        }
  62.134 -
  62.135 -        void addBreak() {
  62.136 -            breaks_++;
  62.137 -        }
  62.138 -        void addContinue() {
  62.139 -            continues_++;
  62.140 -        }
  62.141 -        unsigned breaks() const {
  62.142 -            return breaks_;
  62.143 -        }
  62.144 -        unsigned continues() const {
  62.145 -            return continues_;
  62.146 -        }
  62.147 -    };
  62.148 -
  62.149 -    ControlScope *control_;
  62.150 -    LoopScope *loop_;
  62.151 -
  62.152 -  private:
  62.153 -    bool canTest(AstNode *node, Handle<Type> type);
  62.154 -    void unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type);
  62.155 -    void binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right);
  62.156 -    Type *typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right);
  62.157 -
  62.158 -    // These check if one type is compatible with another type, for various
  62.159 -    // purposes, like:
  62.160 -    //      return (expr) matches function return type
  62.161 -    //      call(a, b)    matches expected arg type
  62.162 -    //      a = b         matches declared type
  62.163 -    //
  62.164 -    bool typeCheckArrayAssignment(AstNode *node, Handle<Type> given, Handle<Type> actual, bool forAssign);
  62.165 -    bool typeCheckAssignment(AstNode *node, Handle<Type> given, Handle<Type> actual, bool forAssign);
  62.166 -    bool typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual);
  62.167 -
  62.168 -    Type *visitForLoad(Expression *expression);
  62.169 -    bool preanalyze(FunctionStatement *node);
  62.170 -    Type *visitForLValue(Expression *expression);
  62.171 -    Type *visitAndApplyType(Expression *expression);
  62.172 -    ControlStatus visitForControl(Statement *statement);
  62.173 -
  62.174 -    void markCallResultUsed(CallExpression *call);
  62.175 -
  62.176 -  public:
  62.177 -    SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree);
  62.178 -    bool analyze();
  62.179 -
  62.180 -  public:
  62.181 -    void visit(NameProxy *name);
  62.182 -    void visit(Assignment *node);
  62.183 -    void visit(BinaryExpression *node);
  62.184 -    void visit(ReturnStatement *node);
  62.185 -    void visit(ForStatement *node);
  62.186 -    void visit(BlockStatement *node);
  62.187 -    void visit(VariableDeclaration *node);
  62.188 -    void visit(IntegerLiteral *node);
  62.189 -    void visit(ExpressionStatement *node);
  62.190 -    void visit(FunctionStatement *node);
  62.191 -    void visit(CallExpression *node);
  62.192 -    void visit(IfStatement *node);
  62.193 -    void visit(IndexExpression *node);
  62.194 -    void visit(EnumStatement *node);
  62.195 -    void visit(FloatLiteral *node);
  62.196 -    void visit(WhileStatement *node);
  62.197 -    void visit(BreakStatement *node);
  62.198 -    void visit(ContinueStatement *node);
  62.199 -    void visit(StringLiteral *node);
  62.200 -    void visit(IncDecExpression *node);
  62.201 -    void visit(UnaryExpression *node);
  62.202 -    void visit(TernaryExpression *node);
  62.203 -};
  62.204 -
  62.205 -} // namespace ke
  62.206 -
  62.207 -#endif // _include_semantic_analysis_h_
    63.1 --- a/jitcraft/Spaces-inl.h	Tue Jul 24 23:53:34 2012 -0700
    63.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    63.3 @@ -1,59 +0,0 @@
    63.4 -/* vim: set ts=4 sw=4 tw=99 et:
    63.5 - *
    63.6 - * Copyright (C) 2012 David Anderson
    63.7 - *
    63.8 - * This file is part of JITCraft.
    63.9 - *
   63.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   63.11 - * the terms of the GNU General Public License as published by the Free
   63.12 - * Software Foundation, either version 3 of the License, or (at your option)
   63.13 - * any later version.
   63.14 - * 
   63.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   63.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   63.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   63.18 - *
   63.19 - * You should have received a copy of the GNU General Public License along with
   63.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   63.21 - */
   63.22 -#ifndef _include_jitcraft_spaces_inl_h_
   63.23 -#define _include_jitcraft_spaces_inl_h_
   63.24 -
   63.25 -namespace ke {
   63.26 -
   63.27 -inline Address
   63.28 -HeapStack::allocate(size_t nbytes)
   63.29 -{
   63.30 -    nbytes = Align(nbytes, kObjectAlignment);
   63.31 -
   63.32 -    if (cursor_ + nbytes > chunk_->end())
   63.33 -        return NULL;
   63.34 -
   63.35 -    Address ptr = cursor_;
   63.36 -    cursor_ += nbytes;
   63.37 -    return ptr;
   63.38 -}
   63.39 -
   63.40 -inline void
   63.41 -HeapStack::unwind(Address to)
   63.42 -{
   63.43 -    assert(to <= cursor_ && to >= chunk_->first());
   63.44 -    cursor_ = to;
   63.45 -}
   63.46 -
   63.47 -inline Address
   63.48 -OldSpace::allocate(size_t nbytes)
   63.49 -{
   63.50 -    assert(IsAligned(nbytes, kObjectAlignment));
   63.51 -
   63.52 -    if (cursor_ + nbytes > last_->end())
   63.53 -        return allocateSlow(nbytes);
   63.54 -
   63.55 -    Address addr = cursor_;
   63.56 -    cursor_ += nbytes;
   63.57 -    return addr;
   63.58 -}
   63.59 -
   63.60 -}
   63.61 -
   63.62 -#endif // _include_jitcraft_spaces_inl_h_
    64.1 --- a/jitcraft/Spaces.cpp	Tue Jul 24 23:53:34 2012 -0700
    64.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    64.3 @@ -1,307 +0,0 @@
    64.4 -/* vim: set ts=4 sw=4 tw=99 et:
    64.5 - *
    64.6 - * Copyright (C) 2012 David Anderson
    64.7 - *
    64.8 - * This file is part of JITCraft.
    64.9 - *
   64.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   64.11 - * the terms of the GNU General Public License as published by the Free
   64.12 - * Software Foundation, either version 3 of the License, or (at your option)
   64.13 - * any later version.
   64.14 - * 
   64.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   64.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   64.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   64.18 - *
   64.19 - * You should have received a copy of the GNU General Public License along with
   64.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   64.21 - */
   64.22 -#include "Zone.h"
   64.23 -#include "Spaces.h"
   64.24 -#include "Platform.h"
   64.25 -#include "Spaces-inl.h"
   64.26 -
   64.27 -using namespace ke;
   64.28 -
   64.29 -HeapStack::HeapStack()
   64.30 -  : chunk_(NULL),
   64.31 -    cursor_(NULL)
   64.32 -{
   64.33 -}
   64.34 -
   64.35 -HeapStack::~HeapStack()
   64.36 -{
   64.37 -    if (chunk_)
   64.38 -        HeapChunk::Destroy(chunk_);
   64.39 -}
   64.40 -
   64.41 -bool
   64.42 -HeapStack::initialize()
   64.43 -{
   64.44 -    chunk_ = HeapChunk::New(NULL, kStackSize);
   64.45 -    cursor_ = chunk_->first();
   64.46 -    return true;
   64.47 -}
   64.48 -
   64.49 -HeapChunk *
   64.50 -HeapChunk::New(HeapChunk *prev, size_t size)
   64.51 -{
   64.52 -    OS::AlignableMapping map = 
   64.53 -        OS::MapAlignedMemory(size, HeapChunk::kAlignment, OS::Map_Commit);
   64.54 -
   64.55 -    if (!map.base())
   64.56 -        return NULL;
   64.57 -
   64.58 -    HeapChunk *chunk = reinterpret_cast<HeapChunk *>(map.aligned());
   64.59 -    chunk->base_ = map.base();
   64.60 -    chunk->end_ = map.base() + map.size();
   64.61 -    if (prev)
   64.62 -        prev->next_ = chunk;
   64.63 -
   64.64 -    return chunk;
   64.65 -}
   64.66 -
   64.67 -void
   64.68 -HeapChunk::Destroy(HeapChunk *chunk)
   64.69 -{
   64.70 -    OS::UnmapAlignedMemory(chunk->base(), chunk->size());
   64.71 -}
   64.72 -
   64.73 -void
   64.74 -HeapChunk::resetMarkBits()
   64.75 -{
   64.76 -    memset(markBits(), 0, kMarkBytes);
   64.77 -}
   64.78 -
   64.79 -FreeList::FreeList()
   64.80 -  : small_objects_(NULL),
   64.81 -    medium_objects_(NULL),
   64.82 -    large_objects_(NULL),
   64.83 -    huge_objects_(NULL)
   64.84 -{
   64.85 -}
   64.86 -
   64.87 -void
   64.88 -FreeList::add(FreedObject *obj)
   64.89 -{
   64.90 -    if (obj->size() < kMinObjectSize) 
   64.91 -        return;
   64.92 -
   64.93 -    FreedObject **list;
   64.94 -    if (obj->size() < kMaxSmallObject)
   64.95 -        list = &small_objects_;
   64.96 -    else if (obj->size() < kMaxMediumObject)
   64.97 -        list = &medium_objects_;
   64.98 -    else if (obj->size() < kMaxLargeObject)
   64.99 -        list = &large_objects_;
  64.100 -    else
  64.101 -        list = &huge_objects_;
  64.102 -
  64.103 -    if (*list)
  64.104 -        (*list)->setNext(obj);
  64.105 -    *list = obj;
  64.106 -}
  64.107 -
  64.108 -FreedObject *
  64.109 -FreeList::pick(size_t size)
  64.110 -{
  64.111 -    if (size < kMinObjectSize && small_objects_) {
  64.112 -        FreedObject *obj = small_objects_;
  64.113 -        small_objects_ = small_objects_->next();
  64.114 -        return obj;
  64.115 -    }
  64.116 -    if (size < kMaxSmallObject && medium_objects_) {
  64.117 -        FreedObject *obj = medium_objects_;
  64.118 -        medium_objects_ = medium_objects_->next();
  64.119 -        return obj;
  64.120 -    }
  64.121 -    if (size < kMaxMediumObject && large_objects_) {
  64.122 -        FreedObject *obj = large_objects_;
  64.123 -        large_objects_ = large_objects_->next();
  64.124 -        return obj;
  64.125 -    }
  64.126 -    if (huge_objects_) {
  64.127 -        FreedObject *obj = huge_objects_;
  64.128 -        huge_objects_ = huge_objects_->next();
  64.129 -        return obj;
  64.130 -    }
  64.131 -    return NULL;
  64.132 -}
  64.133 -
  64.134 -void
  64.135 -FreeList::reset()
  64.136 -{
  64.137 -    small_objects_ = NULL;
  64.138 -    medium_objects_ = NULL;
  64.139 -    large_objects_ = NULL;
  64.140 -    huge_objects_ = NULL;
  64.141 -}
  64.142 -
  64.143 -OldSpace::OldSpace(Zone *zone)
  64.144 -  : zone_(zone),
  64.145 -    first_(NULL),
  64.146 -    last_(NULL)
  64.147 -{
  64.148 -}
  64.149 -
  64.150 -bool
  64.151 -OldSpace::initialize()
  64.152 -{
  64.153 -    first_ = HeapChunk::New(first_, HeapChunk::kDefaultSize);
  64.154 -    last_ = first_;
  64.155 -    cursor_ = first_->first();
  64.156 -
  64.157 -    return !!first_;
  64.158 -}
  64.159 -
  64.160 -OldSpace::~OldSpace()
  64.161 -{
  64.162 -    while (first_) {
  64.163 -        HeapChunk *temp = first_->next();
  64.164 -        HeapChunk::Destroy(first_);
  64.165 -        first_ = temp;
  64.166 -    }
  64.167 -}
  64.168 -
  64.169 -Address
  64.170 -OldSpace::allocateSlow(size_t nbytes)
  64.171 -{
  64.172 -    if (FreedObject *obj = freelist_.pick(nbytes)) {
  64.173 -        Address address = reinterpret_cast<Address>(obj);
  64.174 -        size_t actual = obj->size();
  64.175 -        assert(actual >= nbytes);
  64.176 -        if (actual != nbytes)
  64.177 -            markRegionFree(address + nbytes, actual - nbytes);
  64.178 -
  64.179 -        return address;
  64.180 -    }
  64.181 -
  64.182 -    // Free unused stuff at the end of the current chunk.
  64.183 -    if (cursor_ != last_->end())
  64.184 -        markRegionFree(cursor_, last_->end() - cursor_);
  64.185 -
  64.186 -    HeapChunk *chunk;
  64.187 -    if (last_->next()) {
  64.188 -        // The next chunk is guaranteed to be empty.
  64.189 -        chunk = last_->next();
  64.190 -    } else {
  64.191 -        chunk = HeapChunk::New(last_, HeapChunk::kDefaultSize);
  64.192 -        if (!chunk)
  64.193 -            return NULL;
  64.194 -    }
  64.195 -
  64.196 -    last_ = chunk;
  64.197 -    cursor_ = chunk->first();
  64.198 -
  64.199 -    assert(cursor_ + nbytes <= chunk->end());
  64.200 -
  64.201 -    Address address = cursor_;
  64.202 -    cursor_ += nbytes;
  64.203 -    return address;
  64.204 -}
  64.205 -
  64.206 -void
  64.207 -OldSpace::markRegionFree(Address start, size_t length)
  64.208 -{
  64.209 -    FreedObject *obj = reinterpret_cast<FreedObject *>(start);
  64.210 -    new (obj) FreedObject(zone_->getMap(MapKind_FreeRegion), length);
  64.211 -
  64.212 -    if (length < sizeof(FreedObject)) {
  64.213 -        // Can't encode a list in this object, but it's marked free, so we're done.
  64.214 -        return;
  64.215 -    }
  64.216 -
  64.217 -    freelist_.add(obj);
  64.218 -}
  64.219 -
  64.220 -void
  64.221 -OldSpace::freeUnusedPages()
  64.222 -{
  64.223 -    HeapChunk **prev = &first_;
  64.224 -    HeapChunk *empty = NULL;
  64.225 -    while (*prev) {
  64.226 -        HeapChunk *chunk = *prev;
  64.227 -        if (chunk->isEmpty()) {
  64.228 -            *prev = chunk->next();
  64.229 -            if (empty) {
  64.230 -                // Remove this chunk.
  64.231 -                HeapChunk::Destroy(chunk);
  64.232 -                continue;
  64.233 -            }
  64.234 -            empty = chunk;                
  64.235 -        }
  64.236 -        prev = chunk->nextp();
  64.237 -    }
  64.238 -
  64.239 -    if (empty) {
  64.240 -        *empty->nextp() = NULL;
  64.241 -        *last_->nextp() = empty;
  64.242 -    }
  64.243 -}
  64.244 -
  64.245 -void
  64.246 -OldSpace::resetFreeList()
  64.247 -{
  64.248 -    freelist_.reset();
  64.249 -}
  64.250 -
  64.251 -LargeObjectSpace::LargeObjectSpace()
  64.252 -  : first_(NULL),
  64.253 -    last_(NULL)
  64.254 -{
  64.255 -}
  64.256 -
  64.257 -LargeObjectSpace::~LargeObjectSpace()
  64.258 -{
  64.259 -    while (first_) {
  64.260 -        HeapChunk *temp = first_->next();
  64.261 -        HeapChunk::Destroy(first_);
  64.262 -        first_ = temp;
  64.263 -    }
  64.264 -}
  64.265 -
  64.266 -bool
  64.267 -LargeObjectSpace::initialize()
  64.268 -{
  64.269 -    return true;
  64.270 -}
  64.271 -
  64.272 -Address
  64.273 -LargeObjectSpace::allocate(size_t nbytes)
  64.274 -{
  64.275 -    assert(IsAligned(nbytes, kObjectAlignment));
  64.276 -
  64.277 -    // Always allocate a new chunk for large objects.
  64.278 -    HeapChunk *chunk = HeapChunk::New(last_, nbytes);
  64.279 -    if (!chunk)
  64.280 -        return NULL;
  64.281 -
  64.282 -    if (!first_)
  64.283 -        first_ = chunk;
  64.284 -    last_ = chunk;
  64.285 -
  64.286 -    return chunk->first();
  64.287 -}
  64.288 -
  64.289 -void
  64.290 -LargeObjectSpace::sweep()
  64.291 -{
  64.292 -    if (!first_)
  64.293 -        return;
  64.294 -
  64.295 -    HeapChunk **pprev = &first_;
  64.296 -    do {
  64.297 -        HeapChunk *chunk = *pprev;
  64.298 -        Object *obj = reinterpret_cast<Object *>(chunk->first());
  64.299 -        MarkBit bit = HeapChunk::GetMarkBit(obj);
  64.300 -        if (HeapChunk::IsWhite(bit)) {
  64.301 -            *pprev = chunk->next();
  64.302 -            HeapChunk::Destroy(chunk);
  64.303 -        } else {
  64.304 -            assert(HeapChunk::IsBlack(bit));
  64.305 -            HeapChunk::Clear(bit);
  64.306 -            pprev = chunk->nextp();
  64.307 -            last_ = chunk;
  64.308 -        }
  64.309 -    } while (*pprev);
  64.310 -}
    65.1 --- a/jitcraft/Spaces.h	Tue Jul 24 23:53:34 2012 -0700
    65.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    65.3 @@ -1,434 +0,0 @@
    65.4 -/* vim: set ts=4 sw=4 tw=99 et:
    65.5 - *
    65.6 - * Copyright (C) 2012 David Anderson
    65.7 - *
    65.8 - * This file is part of JITCraft.
    65.9 - *
   65.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   65.11 - * the terms of the GNU General Public License as published by the Free
   65.12 - * Software Foundation, either version 3 of the License, or (at your option)
   65.13 - * any later version.
   65.14 - * 
   65.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   65.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   65.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   65.18 - *
   65.19 - * You should have received a copy of the GNU General Public License along with
   65.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   65.21 - */
   65.22 -#ifndef _include_jitcraft_spaces_h_
   65.23 -#define _include_jitcraft_spaces_h_
   65.24 -
   65.25 -#include <limits.h>
   65.26 -#include "Utility.h"
   65.27 -#include "Platform.h"
   65.28 -
   65.29 -namespace ke {
   65.30 -
   65.31 -class Zone;
   65.32 -class Object;
   65.33 -class Map;
   65.34 -
   65.35 -static const size_t kObjectAlignment = sizeof(Object *);
   65.36 -
   65.37 -// Every object gets two successive mark bits. These bits represent various
   65.38 -// states during garbage collection:
   65.39 -//
   65.40 -//  WHITE (00): The object is dead or unmarked.
   65.41 -//  GREY  (11): The object is live but its children have not been marked.
   65.42 -//  BLACK (10): The object and all its children have been marked.
   65.43 -//
   65.44 -// These colors assist in maintaining the "tri-color invariant", explained
   65.45 -// in Heap.h. The bits are organized such that transitioning an object from
   65.46 -// White to Black requires one bit change, and Black to Grey requires another.
   65.47 -class MarkBit
   65.48 -{
   65.49 -    uint32 *word_;
   65.50 -    uint32 bit_;
   65.51 -
   65.52 -  public:
   65.53 -    MarkBit(uint32 *word, uint32 bit)
   65.54 -      : word_(word),
   65.55 -        bit_(bit)
   65.56 -    {
   65.57 -        assert(bit_ < sizeof(*word_) * 8);
   65.58 -    }
   65.59 -
   65.60 -    bool isSet() const {
   65.61 -        return !!(*word_ & (1 << bit_));
   65.62 -    }
   65.63 -    void set() {
   65.64 -        *word_ |= (1 << bit_);
   65.65 -    }
   65.66 -    void unset() {
   65.67 -        *word_ &= ~(1 << bit_);
   65.68 -    }
   65.69 -    uint32 *word() {
   65.70 -        return word_;
   65.71 -    }
   65.72 -    MarkBit next() const {
   65.73 -        if (bit_ == (sizeof(*word_) * 8) - 1)
   65.74 -            return MarkBit(word_ + 1, 0);
   65.75 -        return MarkBit(word_, bit_ + 1);
   65.76 -    }
   65.77 -};
   65.78 -
   65.79 -class HeapChunk
   65.80 -{
   65.81 -    HeapChunk *next_;
   65.82 -
   65.83 -    // Base address, from OS::AlignableMapping.
   65.84 -    Address base_;
   65.85 -
   65.86 -    // End of the allocated region.
   65.87 -    Address end_;
   65.88 -
   65.89 -    uintptr_t flags_;
   65.90 -
   65.91 -  public:
   65.92 -    enum Flag {
   65.93 -        HAS_OVERFLOWED_OBJECT = (1 << 0),
   65.94 -        EMPTY = (1 << 1)
   65.95 -    };
   65.96 -
   65.97 -  public:
   65.98 -    static const size_t kDefaultSize = 1 * kMB;
   65.99 -    static const size_t kAlignment = 1 * kMB;
  65.100 -
  65.101 -    // Maximum size of an object that will fit in a page. We limit this
  65.102 -    // specifically to help JITs: the computation of a[i] has a special
  65.103 -    // instruction form on most CPUs, but the index might not be sign-
  65.104 -    // extended on 64-bit architectures. We limit the size such that:
  65.105 -    //
  65.106 -    //    index * sizeof(Object *)
  65.107 -    //
  65.108 -    // Is guaranteed to not overflow a signed 32-bit integer.
  65.109 -    static const size_t kMaxObjectSize = INT_MAX / sizeof(Object *);
  65.110 -
  65.111 -    // Size of a HeapChunk header.
  65.112 -    static const size_t kHeaderSize =
  65.113 -        sizeof(HeapChunk *) +
  65.114 -        sizeof(Address) +
  65.115 -        sizeof(Address) +
  65.116 -        sizeof(Address);
  65.117 -
  65.118 -    // All objects must be allocated in the first kAlignment bytes of the
  65.119 -    // chunk. We need two mark bits for every allocatable object, since there
  65.120 -    // are three possible states: White (00), Black (11), and Grey (10). These
  65.121 -    // bits are stored immediately after the HeapChunk header, and before the
  65.122 -    // first allocatable object.
  65.123 -    //
  65.124 -    // Although object alignment is only at word boundaries, we guarantee that
  65.125 -    // every object is at least two words. This means we don't need to reserve
  65.126 -    // two mark bits for every object, just one mark bit for every allocatable
  65.127 -    // address. That also means a pair of mark bits can cross a byte boundary.
  65.128 -    //
  65.129 -    // --- Math ---
  65.130 -    //
  65.131 -    // The number of mark bits needed is:
  65.132 -    //
  65.133 -    // MaxObjectsPerChunk = (kAlignment / kObjectAlignment)
  65.134 -    //                    -> 256KB (128KB on 64-bit)
  65.135 -    //
  65.136 -    // The number of bytes needed for these mark bits is:
  65.137 -    //
  65.138 -    // NumMarkBytes       = MaxObjectsPerChunk / 8
  65.139 -    //                    = 32KB (16KB on 64-bit)
  65.140 -    //
  65.141 -    // The number of uint32s needed to store these bytes is:
  65.142 -    //
  65.143 -    // NumMarkWords       = NumMarkBytes / sizeof(uint32)
  65.144 -    //                    = 8KB (4KB on 64-bit)
  65.145 -    //
  65.146 -    static const size_t kMaxObjectsPerChunk = kAlignment / kObjectAlignment;
  65.147 -    static const size_t kMarkBits = kMaxObjectsPerChunk;
  65.148 -    static const size_t kMarkBytes = kMarkBits / 8;
  65.149 -    static const size_t kMarkWords = kMarkBytes / sizeof(uint32);
  65.150 -    static const size_t kMarkBitsPerWord = sizeof(uint32) * 8;
  65.151 -
  65.152 -    static const size_t kMarkBitsOffset = kHeaderSize;
  65.153 -    static const size_t kFirstObject = kMarkBitsOffset + kMarkBytes;
  65.154 -
  65.155 -    // Threshold for allocating an object in the large object space.
  65.156 -    static const size_t kLargeObjectThreshold = kAlignment - kFirstObject;
  65.157 -
  65.158 -    static inline void StaticAsserts() {
  65.159 -        STATIC_ASSERT(kHeaderSize == sizeof(HeapChunk));
  65.160 -        STATIC_ASSERT(IS_ALIGNED(kHeaderSize, kObjectAlignment));
  65.161 -        STATIC_ASSERT(IS_ALIGNED(kFirstObject, kObjectAlignment));
  65.162 -    }
  65.163 -
  65.164 -  public:
  65.165 -    static HeapChunk *New(HeapChunk *prev, size_t size);
  65.166 -    static void Destroy(HeapChunk *chunk);
  65.167 -
  65.168 -  public:
  65.169 -    HeapChunk *next() {
  65.170 -        return next_;
  65.171 -    }
  65.172 -    Address base() {
  65.173 -        return base_;
  65.174 -    }
  65.175 -    Address address() {
  65.176 -        return reinterpret_cast<Address>(this);
  65.177 -    }
  65.178 -    Address end() {
  65.179 -        return end_;
  65.180 -    }
  65.181 -    size_t size() {
  65.182 -        return end() - base();
  65.183 -    }
  65.184 -    Address first() {
  65.185 -        return reinterpret_cast<Address>(this) + kFirstObject;
  65.186 -    }
  65.187 -    HeapChunk **nextp() {
  65.188 -        return &next_;
  65.189 -    }
  65.190 -    uint32 *markBits() {
  65.191 -        return reinterpret_cast<uint32 *>(reinterpret_cast<Address>(this) + kMarkBitsOffset);
  65.192 -    }
  65.193 -    void resetMarkBits();
  65.194 -
  65.195 -    // Marking functions.
  65.196 -    static inline MarkBit GetMarkBit(Object *obj) {
  65.197 -        uintptr_t address = reinterpret_cast<uintptr_t>(obj);
  65.198 -
  65.199 -        HeapChunk *chunk = reinterpret_cast<HeapChunk *>(address & ~(kAlignment - 1));
  65.200 -        assert(Address(obj) >= chunk->first() && Address(obj) < chunk->end());
  65.201 -
  65.202 -        size_t index = (address & (kAlignment - 1)) / kObjectAlignment;
  65.203 -        assert(index < kMaxObjectsPerChunk);
  65.204 -
  65.205 -        uint32 *word = chunk->markBits() + (index / kMarkBitsPerWord);
  65.206 -        uint32 bit = index & (kMarkBitsPerWord - 1);
  65.207 -        return MarkBit(word, bit);
  65.208 -    }
  65.209 -    static inline Address FromMarkBit(HeapChunk *chunk, uint32 *word, uint32 bit) {
  65.210 -        // word = bits + (index / kMarkBitsPerWord)
  65.211 -        // word - bits = index / kMarkBitsPerWord
  65.212 -        // (word - bits) * kMarkBitsPerWord = index
  65.213 -        assert(word >= chunk->markBits() && word < chunk->markBits() + kMarkWords);
  65.214 -        uint32 index = ((word - chunk->markBits()) * kMarkBitsPerWord) + bit;
  65.215 -        return chunk->address() + (index * kObjectAlignment);
  65.216 -    }
  65.217 -    static inline bool IsWhite(const MarkBit &bit) {
  65.218 -        assert(bit.isSet() || !bit.next().isSet());
  65.219 -        return !bit.isSet();
  65.220 -    }
  65.221 -    static inline bool IsBlack(const MarkBit &bit) {
  65.222 -        return bit.isSet() && !bit.next().isSet();
  65.223 -    }
  65.224 -    static inline bool IsGrey(const MarkBit &bit) {
  65.225 -        return bit.isSet() && bit.next().isSet();
  65.226 -    }
  65.227 -    static inline bool IsBlackOrGrey(const MarkBit &bit) {
  65.228 -        return bit.isSet();
  65.229 -    }
  65.230 -    static inline void WhiteToBlack(MarkBit &bit) {
  65.231 -        assert(IsWhite(bit));
  65.232 -        bit.set();
  65.233 -    }
  65.234 -    static inline void BlackToGrey(MarkBit &bit) {
  65.235 -        assert(IsBlack(bit));
  65.236 -        bit.next().set();
  65.237 -    }
  65.238 -    static inline void GreyToBlack(MarkBit &bit) {
  65.239 -        assert(IsGrey(bit));
  65.240 -        bit.next().unset();
  65.241 -    }
  65.242 -    static inline void Clear(MarkBit &bit) {
  65.243 -        bit.unset();
  65.244 -        bit.next().unset();
  65.245 -    }
  65.246 -
  65.247 -    bool hasOverflowedObject() {
  65.248 -        return !!(flags_ & HAS_OVERFLOWED_OBJECT);
  65.249 -    }
  65.250 -    void setHasOverflowedObject() {
  65.251 -        flags_ |= HAS_OVERFLOWED_OBJECT;
  65.252 -    }
  65.253 -    bool isEmpty() {
  65.254 -        return !!(flags_ & EMPTY);
  65.255 -    }
  65.256 -    void setEmpty() {
  65.257 -        flags_ |= EMPTY;
  65.258 -    }
  65.259 -};
  65.260 -
  65.261 -template <typename SizeEvaluator>
  65.262 -class ChunkObjectIteratorBase
  65.263 -{
  65.264 -    HeapChunk *chunk_;
  65.265 -    Address top_;
  65.266 -    SizeEvaluator evaluator_;
  65.267 -    Address current_;
  65.268 -
  65.269 -  public:
  65.270 -    ChunkObjectIteratorBase(HeapChunk *start, Address top, const SizeEvaluator &evaluator)
  65.271 -      : chunk_(start),
  65.272 -        top_(top),
  65.273 -        evaluator_(evaluator),
  65.274 -        current_(start ? start->first() : NULL)
  65.275 -    {
  65.276 -    }
  65.277 -
  65.278 -    Object *next() {
  65.279 -        while (current_ && current_ != top_) {
  65.280 -            Object *obj = reinterpret_cast<Object *>(current_);
  65.281 -            size_t size = evaluator_(obj, obj->map());
  65.282 -            current_ += size;
  65.283 -            if (current_ == chunk_->end()) {
  65.284 -                chunk_ = chunk_->next();
  65.285 -                current_ = chunk_ ? chunk_->first() : NULL;
  65.286 -            }
  65.287 -            if (obj->is(MapKind_FreeRegion))
  65.288 -                continue;
  65.289 -        }
  65.290 -        return NULL;
  65.291 -    }
  65.292 -};
  65.293 -
  65.294 -class FreedObject
  65.295 -{
  65.296 -    Map *map_;
  65.297 -    size_t bytes_;
  65.298 -    FreedObject *next_;
  65.299 -
  65.300 -  public:
  65.301 -    FreedObject(Map *map, size_t bytes)
  65.302 -      : map_(map),
  65.303 -        bytes_(bytes)
  65.304 -    {
  65.305 -        assert(bytes_ >= sizeof(Map *) + sizeof(size_t));
  65.306 -        if (bytes_ >= sizeof(FreedObject))
  65.307 -            next_ = NULL;
  65.308 -    }
  65.309 -
  65.310 -    void setNext(FreedObject *obj) {
  65.311 -        assert(bytes_ >= sizeof(FreedObject));
  65.312 -        next_ = obj;
  65.313 -    }
  65.314 -    FreedObject *next() {
  65.315 -        assert(bytes_ >= sizeof(FreedObject));
  65.316 -        return next_;
  65.317 -    }
  65.318 -    size_t size() {
  65.319 -        return bytes_;
  65.320 -    }
  65.321 -};
  65.322 -
  65.323 -// Free-region list used in old spaces. Based on V8's. Each object pool
  65.324 -// is used to allocate objects of the previous pool's size. For example,
  65.325 -// the medium object pool is used to allocate small objects.
  65.326 -class FreeList
  65.327 -{
  65.328 -  private:
  65.329 -    static const size_t kMinObjectSize = 32;
  65.330 -    static const size_t kMaxSmallObject = 255;
  65.331 -    static const size_t kMaxMediumObject = (2 * kKB) - 1;
  65.332 -    static const size_t kMaxLargeObject = (16 * kKB) - 1;
  65.333 -
  65.334 -  public:
  65.335 -    FreeList();
  65.336 -
  65.337 -  public:
  65.338 -    void add(FreedObject *obj);
  65.339 -    FreedObject *pick(size_t size);
  65.340 -    void reset();
  65.341 -
  65.342 -  private:
  65.343 -    FreedObject *small_objects_;
  65.344 -    FreedObject *medium_objects_;
  65.345 -    FreedObject *large_objects_;
  65.346 -    FreedObject *huge_objects_;
  65.347 -};
  65.348 -
  65.349 -// The heap stack is designed for structures which are known to not escape the
  65.350 -// program stack, and can thus be quickly allocated in a LIFO manner.
  65.351 -// 
  65.352 -class HeapStack
  65.353 -{
  65.354 -    OS::AlignableMapping map_;
  65.355 -    HeapChunk *chunk_;
  65.356 -    Address cursor_;
  65.357 -    uintptr_t mask_;
  65.358 -
  65.359 -  private:
  65.360 -    static const size_t kStackSize = 1024 * 1024;
  65.361 -
  65.362 -  public:
  65.363 -    HeapStack();
  65.364 -    ~HeapStack();
  65.365 -    bool initialize();
  65.366 -
  65.367 -  public:
  65.368 -    Address position() const {
  65.369 -        return cursor_;
  65.370 -    }
  65.371 -    inline Address allocate(size_t nbytes);
  65.372 -    inline void unwind(Address to);
  65.373 -
  65.374 -    inline bool contains(Object *obj) {
  65.375 -        return (reinterpret_cast<uintptr_t>(obj) & mask_) == reinterpret_cast<uintptr_t>(chunk_);
  65.376 -    }
  65.377 -
  65.378 -    template <typename Evaluator>
  65.379 -    ChunkObjectIteratorBase<Evaluator> begin(const Evaluator &evaluator) {
  65.380 -        return ChunkObjectIteratorBase<Evaluator>(chunk_, cursor_, evaluator);
  65.381 -    }
  65.382 -};
  65.383 -
  65.384 -class OldSpace
  65.385 -{
  65.386 -    Zone *zone_;
  65.387 -    HeapChunk *first_;
  65.388 -    HeapChunk *last_;
  65.389 -    Address cursor_;
  65.390 -    FreeList freelist_;
  65.391 -
  65.392 -  public:
  65.393 -    OldSpace(Zone *zone);
  65.394 -    ~OldSpace();
  65.395 -
  65.396 -    bool initialize();
  65.397 -
  65.398 -  public:
  65.399 -    inline Address allocate(size_t nbytes);
  65.400 -    Address allocateSlow(size_t nbytes);
  65.401 -    void markRegionFree(Address start, size_t size);
  65.402 -    void freeUnusedPages();
  65.403 -
  65.404 -    template <typename Evaluator>
  65.405 -    ChunkObjectIteratorBase<Evaluator> begin(const Evaluator &evaluator) {
  65.406 -        return ChunkObjectIteratorBase<Evaluator>(first_, cursor_, evaluator);
  65.407 -    }
  65.408 -
  65.409 -    HeapChunk *first() {
  65.410 -        return first_;
  65.411 -    }
  65.412 -    void resetFreeList();
  65.413 -};
  65.414 -
  65.415 -class LargeObjectSpace
  65.416 -{
  65.417 -    HeapChunk *first_;
  65.418 -    HeapChunk *last_;
  65.419 -
  65.420 -  public:
  65.421 -    LargeObjectSpace();
  65.422 -    ~LargeObjectSpace();
  65.423 -
  65.424 -    bool initialize();
  65.425 -
  65.426 -  public:
  65.427 -    Address allocate(size_t nbytes);
  65.428 -
  65.429 -    HeapChunk *first() {
  65.430 -        return first_;
  65.431 -    }
  65.432 -    void sweep();
  65.433 -};
  65.434 -
  65.435 -}
  65.436 -
  65.437 -#endif // _include_jitcraft_spaces_h_
    66.1 --- a/jitcraft/Stack.cpp	Tue Jul 24 23:53:34 2012 -0700
    66.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    66.3 @@ -1,321 +0,0 @@
    66.4 -/* vim: set ts=4 sw=4 tw=99 et:
    66.5 - *
    66.6 - * Copyright (C) 2012 David Anderson
    66.7 - *
    66.8 - * This file is part of JITCraft.
    66.9 - *
   66.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   66.11 - * the terms of the GNU General Public License as published by the Free
   66.12 - * Software Foundation, either version 3 of the License, or (at your option)
   66.13 - * any later version.
   66.14 - * 
   66.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   66.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   66.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   66.18 - *
   66.19 - * You should have received a copy of the GNU General Public License along with
   66.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   66.21 - */
   66.22 -#include <new>
   66.23 -#include <stdlib.h>
   66.24 -#include "Stack.h"
   66.25 -#include "Zone.h"
   66.26 -#include "Strings.h"
   66.27 -#include "Modules.h"
   66.28 -#include "Heap-inl.h"
   66.29 -
   66.30 -using namespace ke;
   66.31 -
   66.32 -Stack::Stack(Zone *zone)
   66.33 -  : zone_(zone),
   66.34 -    buffer_(NULL),
   66.35 -    end_(NULL)
   66.36 -{
   66.37 -}
   66.38 -
   66.39 -Stack::~Stack()
   66.40 -{
   66.41 -    free(buffer_);
   66.42 -}
   66.43 -
   66.44 -bool
   66.45 -Stack::initialize()
   66.46 -{
   66.47 -    buffer_ = (char *)malloc(STACK_SIZE);
   66.48 -    if (!buffer_)
   66.49 -        return false;
   66.50 -
   66.51 -    top_.sp = reinterpret_cast<LocalSlot *>(buffer_);
   66.52 -    top_.pc = NULL;
   66.53 -    top_.fp = NULL;
   66.54 -    end_ = buffer_ + STACK_SIZE;
   66.55 -    return true;
   66.56 -}
   66.57 -
   66.58 -InvokeArgs::~InvokeArgs()
   66.59 -{
   66.60 -    stack_->popInvokeFrame(*this);
   66.61 -}
   66.62 -
   66.63 -NativeArgs::~NativeArgs()
   66.64 -{
   66.65 -    stack_->popNativeFrame(*this);
   66.66 -}
   66.67 -
   66.68 -static inline size_t
   66.69 -SizeForCodeFrame(Code *code)
   66.70 -{
   66.71 -    return sizeof(Frame) + sizeof(LocalSlot) * (code->nlocals() + code->maxStackDepth());
   66.72 -}
   66.73 -
   66.74 -bool
   66.75 -Stack::pushInvokeFrame(Handle<Function> fun, InvokeArgs &args)
   66.76 -{
   66.77 -    size_t nbytes = SizeForCodeFrame(fun->code()) +
   66.78 -                    sizeof(LocalSlot) * fun->nargs();
   66.79 -    if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
   66.80 -        assert(false);
   66.81 -        return false;
   66.82 -    }
   66.83 -
   66.84 -    memset(top_.sp, 0, sizeof(LocalSlot) * fun->nargs());
   66.85 -    args.args_ = top_.sp;
   66.86 -    args.nargs_ = fun->nargs();
   66.87 -    args.stack_ = this;
   66.88 -    top_.sp += fun->nargs();
   66.89 -    
   66.90 -    Frame *frame = reinterpret_cast<Frame *>(top_.sp);
   66.91 -    new (frame) Frame(top_.fp, top_.pc, fun, fun->code(), zone_->heap().lifoPosition());
   66.92 -    
   66.93 -    top_.pc = frame->code()->start();
   66.94 -    top_.sp = frame->stackBase();
   66.95 -    top_.fp = frame;
   66.96 -
   66.97 -    return true;
   66.98 -}
   66.99 -
  66.100 -bool
  66.101 -Stack::pushModuleFrame(Handle<Module> module, InvokeArgs &args)
  66.102 -{
  66.103 -    size_t nbytes = SizeForCodeFrame(module->code());
  66.104 -    if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
  66.105 -        assert(false);
  66.106 -        return false;
  66.107 -    }
  66.108 -
  66.109 -    args.args_ = top_.sp;
  66.110 -    args.nargs_ = 0;
  66.111 -    args.stack_ = this;
  66.112 -    
  66.113 -    Frame *frame = reinterpret_cast<Frame *>(top_.sp);
  66.114 -    new (frame) Frame(top_.fp, top_.pc, NULL, module->code(), zone_->heap().lifoPosition());
  66.115 -    
  66.116 -    top_.pc = frame->code()->start();
  66.117 -    top_.sp = frame->stackBase();
  66.118 -    top_.fp = frame;
  66.119 -
  66.120 -    return true;
  66.121 -}
  66.122 -
  66.123 -bool
  66.124 -Stack::pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc)
  66.125 -{
  66.126 -    size_t nbytes = sizeof(intptr_t) * argc + sizeof(Frame);
  66.127 -    if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
  66.128 -        assert(false);
  66.129 -        return false;
  66.130 -    }
  66.131 -
  66.132 -    memset(top_.sp, 0, sizeof(intptr_t) * argc);
  66.133 -    args.argsBase_ = top_.sp;
  66.134 -    args.stack_ = this;
  66.135 -    top_.sp = reinterpret_cast<LocalSlot *>(reinterpret_cast<intptr_t *>(top_.sp) + argc);
  66.136 -
  66.137 -    Frame *frame = reinterpret_cast<Frame *>(top_.sp);
  66.138 -    new (frame) Frame(top_.fp, top_.pc, native, zone_->heap().lifoPosition());
  66.139 -
  66.140 -    top_.pc = NULL;
  66.141 -    top_.sp = reinterpret_cast<LocalSlot *>(frame + 1);
  66.142 -    top_.fp = frame;
  66.143 -
  66.144 -    return true;
  66.145 -}
  66.146 -
  66.147 -Frame *
  66.148 -Stack::pushInlineFrame(Handle<Function> fun)
  66.149 -{
  66.150 -    Code *code = fun->code();
  66.151 -    size_t nbytes = SizeForCodeFrame(code);
  66.152 -    if (reinterpret_cast<char *>(top_.sp) + nbytes >= end_) {
  66.153 -        zone_->reportError(Message_TooMuchRecursion);
  66.154 -        return NULL;
  66.155 -    }
  66.156 -
  66.157 -    Frame *frame = reinterpret_cast<Frame *>(top_.sp);
  66.158 -    new (frame) Frame(top_.fp, top_.pc, fun, code, zone_->heap().lifoPosition());
  66.159 -    memset(frame->locals(), 0, sizeof(LocalSlot) * code->nlocals());
  66.160 -
  66.161 -    top_.pc = frame->code()->start();
  66.162 -    top_.sp = frame->stackBase();
  66.163 -    top_.fp = frame;
  66.164 -
  66.165 -    return frame;
  66.166 -}
  66.167 -
  66.168 -
  66.169 -Frame *
  66.170 -Stack::popInlineFrame()
  66.171 -{
  66.172 -    zone_->heap().unwindLifo(top_.fp->lifoPosition());
  66.173 -
  66.174 -    Frame *prev = top_.fp->prev();
  66.175 -    Function *fun = top_.fp->fun();
  66.176 -
  66.177 -    top_.pc = top_.fp->prevpc();
  66.178 -    top_.sp = reinterpret_cast<LocalSlot *>(top_.fp) - fun->nargs();
  66.179 -    top_.fp = prev;
  66.180 -    return prev;
  66.181 -}
  66.182 -
  66.183 -void
  66.184 -Stack::popInvokeFrame(InvokeArgs &args)
  66.185 -{
  66.186 -    zone_->heap().unwindLifo(top_.fp->lifoPosition());
  66.187 -
  66.188 -    top_.pc = top_.fp->prevpc();
  66.189 -    top_.sp = args.args_;
  66.190 -    top_.fp = top_.fp->prev();
  66.191 -}
  66.192 -
  66.193 -void
  66.194 -Stack::popNativeFrame(NativeArgs &args)
  66.195 -{
  66.196 -    zone_->heap().unwindLifo(top_.fp->lifoPosition());
  66.197 -
  66.198 -    top_.pc = top_.fp->prevpc();
  66.199 -    top_.sp = args.argsBase_;
  66.200 -    top_.fp = top_.fp->prev();
  66.201 -}
  66.202 -
  66.203 -void
  66.204 -Frame::accept(VirtualObjectVisitor *visitor)
  66.205 -{
  66.206 -    visitor->visit(reinterpret_cast<Object **>(&callee_));
  66.207 -    visitor->visit(reinterpret_cast<Object **>(&code_));
  66.208 -}
  66.209 -
  66.210 -static void
  66.211 -TraceFunctionFrame(VirtualObjectVisitor *visitor, Frame *fp, LocalSlot *sp, bytecode *pc)
  66.212 -{
  66.213 -    Code *code = fp->code();
  66.214 -    LocalSlot *slots = fp->locals();
  66.215 -
  66.216 -    // Trace local variables.
  66.217 -    for (unsigned i = 0; i < code->nlocals(); i++) {
  66.218 -        Type *type = code->localType(i);
  66.219 -        if (type->isTraceable())
  66.220 -            visitor->visit(&slots[i].obj);
  66.221 -    }
  66.222 -
  66.223 -    // Trace arguments, if a function call. Note that this means we usually
  66.224 -    // mark arguments twice, once on the caller side and once on the callee.
  66.225 -    // This makes it easier to deal with invoke frames which have no caller.
  66.226 -    if (Function *fun = fp->maybeFun()) {
  66.227 -        for (unsigned i = 0; i < fun->nargs(); i++) {
  66.228 -            Type *type = fun->argType(i);
  66.229 -            if (type->isTraceable())
  66.230 -                visitor->visit(&fp->arg(i).obj);
  66.231 -        }
  66.232 -    }
  66.233 -
  66.234 -    // Finally, trace stack slots. Not every gc-point in the bytecode will
  66.235 -    // have a safepoint; since they are actually uncommon, we don't emit
  66.236 -    // them unless at least one stack slot would be marked.
  66.237 -    if (uint8 *safepoint = code->safepointAt(code->pcToOffset(pc))) {
  66.238 -        LocalSlot *base = fp->stackBase();
  66.239 -        unsigned stackDepth = unsigned(sp - fp->stackBase());
  66.240 -        assert(stackDepth <= code->maxStackDepth());
  66.241 -
  66.242 -        for (unsigned i = 0; i < stackDepth; i++) {
  66.243 -            if (safepoint[i / 8] & (1 << (i % 8)))
  66.244 -                visitor->visit(&base[i].obj);
  66.245 -        }
  66.246 -    }
  66.247 -}
  66.248 -
  66.249 -void
  66.250 -Stack::accept(VirtualObjectVisitor *visitor)
  66.251 -{
  66.252 -    LocalSlot *sp = top_.sp;
  66.253 -    bytecode *pc = top_.pc;
  66.254 -
  66.255 -    for (Frame *frame = top_.fp; frame; frame = frame->prev()) {
  66.256 -        if (!frame->isNative())
  66.257 -            TraceFunctionFrame(visitor, frame, sp, pc);
  66.258 -        frame->accept(visitor);
  66.259 -
  66.260 -        sp = reinterpret_cast<LocalSlot *>(frame);
  66.261 -        pc = frame->prevpc();
  66.262 -    }
  66.263 -}
  66.264 -
  66.265 -bool
  66.266 -Stack::isInCallStack(Handle<Module> module)
  66.267 -{
  66.268 -    for (Frame *frame = top_.fp; frame; frame = frame->prev()) {
  66.269 -        if (frame->code()->module() == module)
  66.270 -            return true;
  66.271 -    }
  66.272 -    return false;
  66.273 -}
  66.274 -
  66.275 -StackIter::StackIter(Zone *zone)
  66.276 -  : pc_(zone->stack().top()->pc),
  66.277 -    fp_(zone->stack().top()->fp)
  66.278 -{
  66.279 -}
  66.280 -
  66.281 -bool
  66.282 -StackIter::done() const
  66.283 -{
  66.284 -    return !fp_;
  66.285 -}
  66.286 -
  66.287 -const char *
  66.288 -StackIter::function() const
  66.289 -{
  66.290 -    if (fp_->isNative())
  66.291 -        return fp_->native()->name()->chars();
  66.292 -    if (Function *fun = fp_->maybeFun())
  66.293 -        return fun->name()->chars();
  66.294 -    return "<toplevel>";
  66.295 -}
  66.296 -
  66.297 -unsigned
  66.298 -StackIter::lineNumber() const
  66.299 -{
  66.300 -    if (fp_->isNative())
  66.301 -        return 0;
  66.302 -    if (fp_->maybeFun()) {
  66.303 -        unsigned offs = fp_->code()->pcToOffset(pc_);
  66.304 -        return fp_->code()->pcToSource(offs).line;
  66.305 -    }
  66.306 -    return fp_->code()->lineNumber();
  66.307 -}
  66.308 -
  66.309 -const char *
  66.310 -StackIter::source() const
  66.311 -{
  66.312 -    if (fp_->isNative())
  66.313 -        return "<native>";
  66.314 -    return fp_->code()->module()->file()
  66.315 -           ? fp_->code()->module()->file()->chars()
  66.316 -           : "(anonymous)";
  66.317 -}
  66.318 -
  66.319 -void
  66.320 -StackIter::prev()
  66.321 -{
  66.322 -    pc_ = fp_->prevpc();
  66.323 -    fp_ = fp_->prev();
  66.324 -}
    67.1 --- a/jitcraft/Stack.h	Tue Jul 24 23:53:34 2012 -0700
    67.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    67.3 @@ -1,233 +0,0 @@
    67.4 -/* vim: set ts=4 sw=4 tw=99 et:
    67.5 - *
    67.6 - * Copyright (C) 2012 David Anderson
    67.7 - *
    67.8 - * This file is part of JITCraft.
    67.9 - *
   67.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   67.11 - * the terms of the GNU General Public License as published by the Free
   67.12 - * Software Foundation, either version 3 of the License, or (at your option)
   67.13 - * any later version.
   67.14 - * 
   67.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   67.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   67.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   67.18 - *
   67.19 - * You should have received a copy of the GNU General Public License along with
   67.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   67.21 - */
   67.22 -#ifndef _include_jc_stack_h_
   67.23 -#define _include_jc_stack_h_
   67.24 -
   67.25 -#include <stddef.h>
   67.26 -#include "Utility.h"
   67.27 -#include "Code.h"
   67.28 -#include "Functions.h"
   67.29 -#include "VirtualObjectVisitor.h"
   67.30 -
   67.31 -namespace ke {
   67.32 -
   67.33 -class Object;
   67.34 -class Array;
   67.35 -class Reference;
   67.36 -class Frame;
   67.37 -class Stack;
   67.38 -class Zone;
   67.39 -class Module;
   67.40 -    
   67.41 -union LocalSlot
   67.42 -{
   67.43 -    int i32;
   67.44 -    float f;
   67.45 -    Address address;
   67.46 -    Object *obj;
   67.47 -    Array *array;
   67.48 -    Reference *ref;
   67.49 -    Function *fun;
   67.50 -    Module *module;
   67.51 -};
   67.52 -
   67.53 -struct Top
   67.54 -{
   67.55 -    LocalSlot *sp;
   67.56 -    bytecode *pc;
   67.57 -    Frame *fp;
   67.58 -};
   67.59 -
   67.60 -class Frame
   67.61 -{
   67.62 -    friend class Stack;
   67.63 -
   67.64 -    Frame *prev_;
   67.65 -    bytecode *prevpc_;
   67.66 -    union {
   67.67 -        Function *fun_;
   67.68 -        Native *native_;
   67.69 -        Object *callee_;
   67.70 -    };
   67.71 -    Code *code_;
   67.72 -    Address lifoPosition_;
   67.73 -
   67.74 -  public:
   67.75 -    Frame(Frame *prev, bytecode *prevpc, Function *fun, Code *code, Address lifoPosition)
   67.76 -      : prev_(prev),
   67.77 -        prevpc_(prevpc),
   67.78 -        fun_(fun),
   67.79 -        code_(code),
   67.80 -        lifoPosition_(lifoPosition)
   67.81 -    {
   67.82 -    }
   67.83 -
   67.84 -    Frame(Frame *prev, bytecode *prevpc, Native *native, Address lifoPosition)
   67.85 -      : prev_(prev),
   67.86 -        prevpc_(prevpc),
   67.87 -        native_(native),
   67.88 -        code_(NULL),
   67.89 -        lifoPosition_(lifoPosition)
   67.90 -    {
   67.91 -    }
   67.92 -
   67.93 -    LocalSlot *locals() {
   67.94 -        return reinterpret_cast<LocalSlot *>(this + 1);
   67.95 -    }
   67.96 -    LocalSlot *stackBase() {
   67.97 -        return locals() + code_->nlocals();
   67.98 -    }
   67.99 -    Function *fun() const {
  67.100 -        assert(fun_ && callee_->is(MapKind_Function));
  67.101 -        return fun_;
  67.102 -    }
  67.103 -    Function *maybeFun() const {
  67.104 -        return (fun_ && callee_->is(MapKind_Function)) ? fun_ : NULL;
  67.105 -    }
  67.106 -    bool isNative() const {
  67.107 -        return callee_ && callee_->is(MapKind_Native);
  67.108 -    }
  67.109 -    Native *native() const {
  67.110 -        assert(isNative());
  67.111 -        return native_;
  67.112 -    }
  67.113 -    Code *code() const {
  67.114 -        assert(code_);
  67.115 -        return code_;
  67.116 -    }
  67.117 -    Frame *prev() const {
  67.118 -        return prev_;
  67.119 -    }
  67.120 -    bytecode *prevpc() const {
  67.121 -        return prevpc_;
  67.122 -    }
  67.123 -    Address lifoPosition() const {
  67.124 -        return lifoPosition_;
  67.125 -    }
  67.126 -    LocalSlot &arg(unsigned slot) {
  67.127 -        assert(slot < fun()->nargs());
  67.128 -        return *(reinterpret_cast<LocalSlot *>(this) - slot - 1);
  67.129 -    }
  67.130 -    void accept(VirtualObjectVisitor *visitor);
  67.131 -};
  67.132 -
  67.133 -// RAII object for calling a function from C++.
  67.134 -class InvokeArgs
  67.135 -{
  67.136 -    friend class Stack;
  67.137 -
  67.138 -    Stack *stack_;
  67.139 -    LocalSlot *args_;
  67.140 -    unsigned nargs_;
  67.141 -
  67.142 -  public:
  67.143 -    InvokeArgs()
  67.144 -      : stack_(NULL),
  67.145 -        args_(NULL),
  67.146 -        nargs_(0)
  67.147 -    {
  67.148 -    }
  67.149 -
  67.150 -    ~InvokeArgs();
  67.151 -
  67.152 -    LocalSlot &arg(unsigned index) {
  67.153 -        assert(index < nargs_);
  67.154 -        return args_[nargs_ - index - 1];
  67.155 -    }
  67.156 -};
  67.157 -
  67.158 -// RAII object for calling a native from C++.
  67.159 -class NativeArgs
  67.160 -{
  67.161 -    friend class Stack;
  67.162 -
  67.163 -    Stack *stack_;
  67.164 -    LocalSlot *argsBase_;
  67.165 -
  67.166 -  public:
  67.167 -    NativeArgs()
  67.168 -      : stack_(NULL),
  67.169 -        argsBase_(NULL)
  67.170 -    {
  67.171 -    }
  67.172 -
  67.173 -    ~NativeArgs();
  67.174 -
  67.175 -    intptr_t *args() {
  67.176 -        return reinterpret_cast<int *>(argsBase_);
  67.177 -    }
  67.178 -};
  67.179 -
  67.180 -class Stack
  67.181 -{
  67.182 -    friend class InvokeArgs;
  67.183 -    friend class NativeArgs;
  67.184 -
  67.185 -  private:
  67.186 -    static const size_t STACK_SIZE = 1024 * 1024;
  67.187 -
  67.188 -  public:
  67.189 -    Stack(Zone *zone);
  67.190 -    ~Stack();
  67.191 -
  67.192 -    bool initialize();
  67.193 -
  67.194 -  public:
  67.195 -    Frame *pushInlineFrame(Handle<Function> fun);
  67.196 -    Frame *popInlineFrame();
  67.197 -
  67.198 -    bool pushInvokeFrame(Handle<Function> fun, InvokeArgs &args);
  67.199 -    bool pushModuleFrame(Handle<Module> module, InvokeArgs &args);
  67.200 -    bool pushNativeFrame(Handle<Native> native, NativeArgs &args, unsigned argc);
  67.201 -
  67.202 -    Top *top() {
  67.203 -        return &top_;
  67.204 -    }
  67.205 -    bool isInCallStack(Handle<Module> module);
  67.206 -    void accept(VirtualObjectVisitor *visitor);
  67.207 -
  67.208 -  private:
  67.209 -    void popInvokeFrame(InvokeArgs &args);
  67.210 -    void popNativeFrame(NativeArgs &args);
  67.211 -
  67.212 -  private:
  67.213 -    Zone *zone_;
  67.214 -    char *buffer_;
  67.215 -    char *end_;
  67.216 -    Top top_;
  67.217 -};
  67.218 -
  67.219 -class StackIter
  67.220 -{
  67.221 -    bytecode *pc_;
  67.222 -    Frame *fp_;
  67.223 -
  67.224 -  public:
  67.225 -    StackIter(Zone *zone);
  67.226 -
  67.227 -    bool done() const;
  67.228 -    const char *function() const;
  67.229 -    unsigned lineNumber() const;
  67.230 -    const char *source() const;
  67.231 -    void prev();
  67.232 -};
  67.233 -
  67.234 -}
  67.235 -
  67.236 -#endif // _include_jc_stack_h_
    68.1 --- a/jitcraft/StringPool.cpp	Tue Jul 24 23:53:34 2012 -0700
    68.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    68.3 @@ -1,69 +0,0 @@
    68.4 -/*
    68.5 - * Copyright (C) 2012 David Anderson
    68.6 - *
    68.7 - * This file is part of JITCraft.
    68.8 - *
    68.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   68.10 - * the terms of the GNU General Public License as published by the Free
   68.11 - * Software Foundation, either version 3 of the License, or (at your option)
   68.12 - * any later version.
   68.13 - * 
   68.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   68.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   68.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   68.17 - *
   68.18 - * You should have received a copy of the GNU General Public License along with
   68.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   68.20 - */
   68.21 -#include "StringPool.h"
   68.22 -#include "Strings.h"
   68.23 -#include "Spaces.h"
   68.24 -
   68.25 -using namespace ke;
   68.26 -
   68.27 -StringPool::StringPool(Zone *zone)
   68.28 -  : zone_(zone),
   68.29 -    set_(ZoneAllocatorPolicy())
   68.30 -{
   68.31 -}
   68.32 -
   68.33 -StringPool::~StringPool()
   68.34 -{
   68.35 -}
   68.36 -
   68.37 -bool
   68.38 -StringPool::initialize()
   68.39 -{
   68.40 -    if (!set_.init(32))
   68.41 -        return false;
   68.42 -    return true;
   68.43 -}
   68.44 -
   68.45 -String *
   68.46 -StringPool::add(const char *str, size_t length)
   68.47 -{
   68.48 -    StringSet::Insert i = set_.findForAdd(CharsAndLength(str, length));
   68.49 -    if (i.found())
   68.50 -        return *i;
   68.51 -
   68.52 -    Local<String> obj(zone_, String::New(zone_, str, length, Heap::Tenure_Old));
   68.53 -    if (!obj)
   68.54 -        return NULL;
   68.55 -
   68.56 -    set_.add(i, obj);
   68.57 -    return obj;
   68.58 -}
   68.59 -
   68.60 -void
   68.61 -StringPool::sweep()
   68.62 -{
   68.63 -    for (StringSet::iterator i(&set_); !i.empty(); i.next()) {
   68.64 -        String *obj = *i;
   68.65 -        MarkBit bits = HeapChunk::GetMarkBit(obj);
   68.66 -        if (HeapChunk::IsWhite(bits))
   68.67 -            i.erase();
   68.68 -        else
   68.69 -            assert(HeapChunk::IsBlack(bits));
   68.70 -    }
   68.71 -    set_.checkDensity();
   68.72 -}
    69.1 --- a/jitcraft/StringPool.h	Tue Jul 24 23:53:34 2012 -0700
    69.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    69.3 @@ -1,85 +0,0 @@
    69.4 -/*
    69.5 - * Copyright (C) 2012 David Anderson
    69.6 - *
    69.7 - * This file is part of JITCraft.
    69.8 - *
    69.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   69.10 - * the terms of the GNU General Public License as published by the Free
   69.11 - * Software Foundation, either version 3 of the License, or (at your option)
   69.12 - * any later version.
   69.13 - * 
   69.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   69.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   69.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   69.17 - *
   69.18 - * You should have received a copy of the GNU General Public License along with
   69.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   69.20 - */
   69.21 -#ifndef _include_jitcraft_string_pool_h_
   69.22 -#define _include_jitcraft_string_pool_h_
   69.23 -
   69.24 -#include "AllocatorPolicies.h"
   69.25 -#include "HashTable.h"
   69.26 -#include "Strings.h"
   69.27 -
   69.28 -namespace ke {
   69.29 -
   69.30 -class Zone;
   69.31 -class String;
   69.32 -
   69.33 -// Guarantee that strings with the same contents will map to one pointer. 
   69.34 -class StringPool
   69.35 -{
   69.36 -    class CharsAndLength {
   69.37 -        const char *str_;
   69.38 -        size_t length_;
   69.39 -
   69.40 -      public:
   69.41 -        CharsAndLength(const char *str, size_t length)
   69.42 -          : str_(str),
   69.43 -            length_(length)
   69.44 -        {
   69.45 -        }
   69.46 -
   69.47 -        const char *str() const {
   69.48 -            return str_;
   69.49 -        }
   69.50 -        size_t length() const {
   69.51 -            return length_;
   69.52 -        }
   69.53 -    };
   69.54 -
   69.55 -    struct Policy
   69.56 -    {
   69.57 -        typedef String * Payload;
   69.58 -
   69.59 -        static uint32 hash(const CharsAndLength &key) {
   69.60 -            return HashCharSequence(key.str(), key.length());
   69.61 -        }
   69.62 -        
   69.63 -        static bool matches(const CharsAndLength &key, String *string) {
   69.64 -            if (string->length() != key.length())
   69.65 -                return false;
   69.66 -            return memcmp(string->chars(), key.str(), key.length() * sizeof(char)) == 0;
   69.67 -        }
   69.68 -    };
   69.69 -
   69.70 -    typedef HashTable<Policy, ZoneAllocatorPolicy> StringSet;
   69.71 -
   69.72 -  public:
   69.73 -    StringPool(Zone *zone);
   69.74 -    ~StringPool();
   69.75 -    bool initialize();
   69.76 -
   69.77 -  public:
   69.78 -    String *add(const char *str, size_t len);
   69.79 -    void sweep();
   69.80 -
   69.81 -  private:
   69.82 -    Zone *zone_;
   69.83 -    StringSet set_;
   69.84 -};
   69.85 -
   69.86 -}
   69.87 -
   69.88 -#endif // _include_jitcraft_string_pool_h_
    70.1 --- a/jitcraft/Strings.cpp	Tue Jul 24 23:53:34 2012 -0700
    70.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    70.3 @@ -1,43 +0,0 @@
    70.4 -/* vim: set ts=4 sw=4 tw=99 et:
    70.5 - *
    70.6 - * Copyright (C) 2012 David Anderson
    70.7 - *
    70.8 - * This file is part of JITCraft.
    70.9 - *
   70.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   70.11 - * the terms of the GNU General Public License as published by the Free
   70.12 - * Software Foundation, either version 3 of the License, or (at your option)
   70.13 - * any later version.
   70.14 - * 
   70.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   70.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   70.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   70.18 - *
   70.19 - * You should have received a copy of the GNU General Public License along with
   70.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   70.21 - */
   70.22 -#include "Strings.h"
   70.23 -#include "Zone.h"
   70.24 -#include "Heap-inl.h"
   70.25 -
   70.26 -using namespace ke;
   70.27 -
   70.28 -String *
   70.29 -String::New(Zone *zone, const char *from, Heap::Tenure tenure)
   70.30 -{
   70.31 -    return New(zone, from, strlen(from), tenure);
   70.32 -}
   70.33 -
   70.34 -String *
   70.35 -String::New(Zone *zone, const char *from, size_t length, Heap::Tenure tenure)
   70.36 -{
   70.37 -    size_t bytes = SizeFor(length);
   70.38 -    Local<String> string(zone, String::cast(zone->allocate(MapKind_String, bytes, tenure)));
   70.39 -    if (!string)
   70.40 -        return NULL;
   70.41 -
   70.42 -    string->length_ = length;
   70.43 -    memcpy(string->chars(), from, length + 1);
   70.44 -
   70.45 -    return string;
   70.46 -}
    71.1 --- a/jitcraft/Strings.h	Tue Jul 24 23:53:34 2012 -0700
    71.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    71.3 @@ -1,54 +0,0 @@
    71.4 -/* vim: set ts=4 sw=4 tw=99 et:
    71.5 - *
    71.6 - * Copyright (C) 2012 David Anderson
    71.7 - *
    71.8 - * This file is part of JITCraft.
    71.9 - *
   71.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   71.11 - * the terms of the GNU General Public License as published by the Free
   71.12 - * Software Foundation, either version 3 of the License, or (at your option)
   71.13 - * any later version.
   71.14 - * 
   71.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   71.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   71.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   71.18 - *
   71.19 - * You should have received a copy of the GNU General Public License along with
   71.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   71.21 - */
   71.22 -#ifndef _include_jitcraft_string_h_
   71.23 -#define _include_jitcraft_string_h_
   71.24 -
   71.25 -#include "Heap.h"
   71.26 -
   71.27 -namespace ke {
   71.28 -
   71.29 -// A fixed-length string containing UTF-8 characters.
   71.30 -class String : public Object
   71.31 -{
   71.32 -    uint32 length_;
   71.33 -    
   71.34 -  public:
   71.35 -    static String *New(Zone *zone, const char *from, Heap::Tenure tenure = Heap::Tenure_Default);
   71.36 -    static String *New(Zone *zone, const char *from, size_t length, Heap::Tenure tenure = Heap::Tenure_Default);
   71.37 -
   71.38 -    unsigned length() {
   71.39 -        return length_;
   71.40 -    }
   71.41 -    char *chars() {
   71.42 -        return reinterpret_cast<char *>(this + 1);
   71.43 -    }
   71.44 -
   71.45 -    static size_t SizeFor(unsigned length) {
   71.46 -        return Align(sizeof(String) + sizeof(char) * (length + 1), kObjectAlignment);
   71.47 -    }
   71.48 -
   71.49 -    static inline String *cast(Object *obj) {
   71.50 -        assert(!obj || obj->is(MapKind_String));
   71.51 -        return reinterpret_cast<String *>(obj);
   71.52 -    }
   71.53 -};
   71.54 -
   71.55 -}
   71.56 -
   71.57 -#endif // _include_jitcraft_string_h_
    72.1 --- a/jitcraft/Structures.cpp	Tue Jul 24 23:53:34 2012 -0700
    72.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    72.3 @@ -1,46 +0,0 @@
    72.4 -/* vim: set ts=4 sw=4 tw=99 et
    72.5 - *
    72.6 - * Copyright (C) 2012 David Anderson
    72.7 - *
    72.8 - * This file is part of JITCraft.
    72.9 - *
   72.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   72.11 - * the terms of the GNU General Public License as published by the Free
   72.12 - * Software Foundation, either version 3 of the License, or (at your option)
   72.13 - * any later version.
   72.14 - * 
   72.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   72.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   72.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   72.18 - *
   72.19 - * You should have received a copy of the GNU General Public License along with
   72.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   72.21 - */
   72.22 -#include "Structures.h"
   72.23 -#include "Types.h"
   72.24 -
   72.25 -using namespace ke;
   72.26 -
   72.27 -StructureBufferBuilder::StructureBufferBuilder()
   72.28 -  : size_(0)
   72.29 -{
   72.30 -}
   72.31 -
   72.32 -bool
   72.33 -StructureBufferBuilder::add(Handle<Type> type, unsigned *offset)
   72.34 -{
   72.35 -    *offset = size_;
   72.36 -
   72.37 -    if (!type->isTraceable()) {
   72.38 -        // For now, assume the size of primitives is 4-byte.
   72.39 -        assert(type->isInt32() || type->isFloat());
   72.40 -        size_ += 4;
   72.41 -        return true;
   72.42 -    }
   72.43 -
   72.44 -    if (!offsets_.append(size_))
   72.45 -        return false;
   72.46 -
   72.47 -    size_ += sizeof(Object *);
   72.48 -    return true;
   72.49 -}
    73.1 --- a/jitcraft/Structures.h	Tue Jul 24 23:53:34 2012 -0700
    73.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    73.3 @@ -1,60 +0,0 @@
    73.4 -/* vim: set ts=4 sw=4 tw=99 et
    73.5 - *
    73.6 - * Copyright (C) 2012 David Anderson
    73.7 - *
    73.8 - * This file is part of JITCraft.
    73.9 - *
   73.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   73.11 - * the terms of the GNU General Public License as published by the Free
   73.12 - * Software Foundation, either version 3 of the License, or (at your option)
   73.13 - * any later version.
   73.14 - * 
   73.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   73.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   73.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   73.18 - *
   73.19 - * You should have received a copy of the GNU General Public License along with
   73.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   73.21 - */
   73.22 -#ifndef _include_jc_structure_h_
   73.23 -#define _include_jc_structure_h_
   73.24 -
   73.25 -#include "Objects.h"
   73.26 -#include "Handles.h"
   73.27 -#include "Vector.h"
   73.28 -
   73.29 -namespace ke {
   73.30 -
   73.31 -class Type;
   73.32 -class String;
   73.33 -class FixedArray;
   73.34 -
   73.35 -// When describing composite structures, the GC must be able to trace interior
   73.36 -// references to Objects. To make this possible, maps that describe composite
   73.37 -// structures must provide a list of offsets into their objects that are
   73.38 -// traceable. StructureBufferBuilder assists with this.
   73.39 -class StructureBufferBuilder
   73.40 -{
   73.41 -  public:
   73.42 -    StructureBufferBuilder();
   73.43 -
   73.44 -    bool add(Handle<Type> type, unsigned *offset);
   73.45 -
   73.46 -    unsigned structureSize() const {
   73.47 -        return size_;
   73.48 -    }
   73.49 -    unsigned traceableOffsetCount() const {
   73.50 -        return offsets_.length();
   73.51 -    }
   73.52 -    const unsigned *offsets() {
   73.53 -        return offsets_.buffer();
   73.54 -    }
   73.55 -
   73.56 -  private:
   73.57 -    Vector<unsigned> offsets_;
   73.58 -    unsigned size_;
   73.59 -};
   73.60 -
   73.61 -}
   73.62 -
   73.63 -#endif // _include_jc_structure_h_
    74.1 --- a/jitcraft/Token.h	Tue Jul 24 23:53:34 2012 -0700
    74.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    74.3 @@ -1,128 +0,0 @@
    74.4 -/*
    74.5 - * Copyright (C) 2012 David Anderson
    74.6 - *
    74.7 - * This file is part of JITCraft.
    74.8 - *
    74.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   74.10 - * the terms of the GNU General Public License as published by the Free
   74.11 - * Software Foundation, either version 3 of the License, or (at your option)
   74.12 - * any later version.
   74.13 - * 
   74.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   74.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   74.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   74.17 - *
   74.18 - * You should have received a copy of the GNU General Public License along with
   74.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   74.20 - */
   74.21 -#ifndef _include_jitcraft_token_h_
   74.22 -#define _include_jitcraft_token_h_
   74.23 -
   74.24 -namespace ke {
   74.25 -
   74.26 -struct SourcePosition
   74.27 -{
   74.28 -    int line;
   74.29 -    int col;
   74.30 -
   74.31 -    SourcePosition()
   74.32 -      : line(-1),
   74.33 -        col(-1)
   74.34 -    {
   74.35 -    }
   74.36 -
   74.37 -    SourcePosition(unsigned line, unsigned col)
   74.38 -      : line(line),
   74.39 -        col(col)
   74.40 -    {
   74.41 -    }
   74.42 -};
   74.43 -
   74.44 -// List of tokens the scanner can recognize.
   74.45 -//
   74.46 -// Some restrictions:
   74.47 -//   * (ASSIGN_ADD - TOK_PLUS) must be the delta between an operator and its
   74.48 -//     op-and-assign equivalent.
   74.49 -#define TOKENMAP(_)                                     \
   74.50 -    _(ERROR,              "<error>")                    \
   74.51 -    _(NEW,                "'new'")                      \
   74.52 -    _(FOR,                "'for'")                      \
   74.53 -    _(RETURN,             "'return'")                   \
   74.54 -    _(NAME,               "<name>")                     \
   74.55 -    _(INTEGER_LITERAL,    "<integer>")                  \
   74.56 -    _(FLOAT_LITERAL,      "<float>")                    \
   74.57 -    _(STRING_LITERAL,     "<string>")                   \
   74.58 -    _(IF,                 "<if>")                       \
   74.59 -    _(ELSE,               "<else>")                     \
   74.60 -    _(ENUM,               "<enum>")                     \
   74.61 -    _(LABEL,              "<label>")                    \
   74.62 -    _(WHILE,              "<while>")                    \
   74.63 -    _(DO,                 "<do>")                       \
   74.64 -    _(BREAK,              "<break>")                    \
   74.65 -    _(CONTINUE,           "<continue>")                 \
   74.66 -    _(FORWARD,            "<forward>")                  \
   74.67 -    _(PUBLIC,             "<public>")                   \
   74.68 -    _(CONST,              "<const>")                    \
   74.69 -    _(NATIVE,             "<native>")                   \
   74.70 -    _(ELLIPSES,           "...")                        \
   74.71 -    _(PLUS,               "+")                          \
   74.72 -    _(MINUS,              "-")                          \
   74.73 -    _(STAR,               "*")                          \
   74.74 -    _(SLASH,              "/")                          \
   74.75 -    _(PERCENT,            "%")                          \
   74.76 -    _(AMPERSAND,          "&")                          \
   74.77 -    _(BITOR,              "|")                          \
   74.78 -    _(BITXOR,             "^")                          \
   74.79 -    _(SHR,                ">>")                         \
   74.80 -    _(USHR,               ">>>")                        \
   74.81 -    _(SHL,                "<<")                         \
   74.82 -    _(ASSIGN,             "=")                          \
   74.83 -    _(SEMICOLON,          ";")                          \
   74.84 -    _(LBRACE,             "{")                          \
   74.85 -    _(RBRACE,             "}")                          \
   74.86 -    _(LPAREN,             "(")                          \
   74.87 -    _(RPAREN,             ")")                          \
   74.88 -    _(LBRACKET,           "[")                          \
   74.89 -    _(RBRACKET,           "]")                          \
   74.90 -    _(ASSIGN_ADD,         "+=")                         \
   74.91 -    _(ASSIGN_SUB,         "-=")                         \
   74.92 -    _(ASSIGN_MUL,         "*=")                         \
   74.93 -    _(ASSIGN_DIV,         "/=")                         \
   74.94 -    _(ASSIGN_MOD,         "%=")                         \
   74.95 -    _(ASSIGN_BITAND,      "&=")                         \
   74.96 -    _(ASSIGN_BITOR,       "|=")                         \
   74.97 -    _(ASSIGN_BITXOR,      "^=")                         \
   74.98 -    _(ASSIGN_SHR,         ">>=")                        \
   74.99 -    _(ASSIGN_USHR,        ">>>=")                       \
  74.100 -    _(ASSIGN_SHL,         "<<=")                        \
  74.101 -    _(INCREMENT,          "++")                         \
  74.102 -    _(DECREMENT,          "--")                         \
  74.103 -    _(EQUALS,             "==")                         \
  74.104 -    _(NOTEQUALS,          "!=")                         \
  74.105 -    _(LT,                 "<")                          \
  74.106 -    _(LE,                 "<=")                         \
  74.107 -    _(GT,                 ">")                          \
  74.108 -    _(GE,                 ">=")                         \
  74.109 -    _(AND,                "&&")                         \
  74.110 -    _(OR,                 "||")                         \
  74.111 -    _(COMMA,              ",")                          \
  74.112 -    _(NOT,                "!")                          \
  74.113 -    _(TILDE,              "~")                          \
  74.114 -    _(QMARK,              "?")                          \
  74.115 -    _(COLON,              ":")                          \
  74.116 -    _(EOF,                "<end-of-file>")
  74.117 -
  74.118 -enum TokenKind
  74.119 -{
  74.120 -#   define _(name, str) TOK_##name,
  74.121 -    TOKENMAP(_)
  74.122 -#   undef _
  74.123 -    TOK_BITAND = TOK_AMPERSAND,
  74.124 -    TOKENS_TOTAL
  74.125 -};
  74.126 -
  74.127 -extern const char *TokenNames[];
  74.128 -
  74.129 -} // namespace ke
  74.130 -
  74.131 -#endif //_include_jitcraft_token_h_
    75.1 --- a/jitcraft/TypeManager.cpp	Tue Jul 24 23:53:34 2012 -0700
    75.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    75.3 @@ -1,119 +0,0 @@
    75.4 -/* vim: set ts=4 sw=4 tw=99 et:
    75.5 - *
    75.6 - * Copyright (C) 2012 David Anderson
    75.7 - *
    75.8 - * This file is part of JITCraft.
    75.9 - *
   75.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   75.11 - * the terms of the GNU General Public License as published by the Free
   75.12 - * Software Foundation, either version 3 of the License, or (at your option)
   75.13 - * any later version.
   75.14 - * 
   75.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   75.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   75.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   75.18 - *
   75.19 - * You should have received a copy of the GNU General Public License along with
   75.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   75.21 - */
   75.22 -#include "Types.h"
   75.23 -#include "TypeManager.h"
   75.24 -#include "Zone.h"
   75.25 -#include "Strings.h"
   75.26 -
   75.27 -using namespace ke;
   75.28 -
   75.29 -
   75.30 -TypeManager::TypeManager(Zone *zone)
   75.31 -  : zone_(zone)
   75.32 -{
   75.33 -}
   75.34 -
   75.35 -bool
   75.36 -TypeManager::initialize()
   75.37 -{
   75.38 -    voidType_ = Type::NewVoid(zone_);
   75.39 -    if (!voidType_)
   75.40 -        return false;
   75.41 -
   75.42 -    Local<String> floatTag(zone_, zone_->makeSymbol("Float"));
   75.43 -    if (!floatTag)
   75.44 -        return false;
   75.45 -
   75.46 -    Local<String> stringTag(zone_, zone_->makeSymbol("String"));
   75.47 -    if (!stringTag)
   75.48 -        return false;
   75.49 -
   75.50 -    Local<String> nullTag(zone_);
   75.51 -
   75.52 -    if ((primitiveTypes_[PrimitiveType_Int32] = Type::NewPrimitive(zone_, nullTag)) == NULL)
   75.53 -        return false;
   75.54 -    if ((primitiveTypes_[PrimitiveType_Float] = Type::NewPrimitive(zone_, floatTag)) == NULL)
   75.55 -        return false;
   75.56 -    if ((primitiveTypes_[PrimitiveType_Native] = Type::NewPrimitive(zone_, PrimitiveType_Native)) == NULL)
   75.57 -        return false;
   75.58 -    if ((primitiveTypes_[PrimitiveType_Char] = Type::NewPrimitive(zone_, stringTag)) == NULL)
   75.59 -        return false;
   75.60 -
   75.61 -    Local<Type> type(zone_);
   75.62 -    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
   75.63 -        type = primitiveTypes_[i];
   75.64 -        if ((referenceTypes_[i] = Type::NewReference(zone_, type, false)) == NULL)
   75.65 -            return false;
   75.66 -    }
   75.67 -
   75.68 -    return true;
   75.69 -}
   75.70 -
   75.71 -Type *
   75.72 -TypeManager::getPrimitiveForTag(Handle<String> tag)
   75.73 -{
   75.74 -    if (!tag)
   75.75 -        return getPrimitive(PrimitiveType_Int32);
   75.76 -    if (strcmp(tag->chars(), "Float") == 0)
   75.77 -        return getPrimitive(PrimitiveType_Float);
   75.78 -    if (strcmp(tag->chars(), "String") == 0)
   75.79 -        return getPrimitive(PrimitiveType_Char);
   75.80 -    return NULL;
   75.81 -}
   75.82 -
   75.83 -Type *
   75.84 -TypeManager::unsafeArray(Handle<Type> contained, int elements, bool isConst)
   75.85 -{
   75.86 -    // :TODO: cache this.
   75.87 -    return Type::NewArray(zone_, contained, elements, isConst);
   75.88 -}
   75.89 -
   75.90 -Type *
   75.91 -TypeManager::getReference(Handle<Type> type, bool isConst)
   75.92 -{
   75.93 -    if (!isConst && (type->isFloat() || (type->isInt32() && !type->tag())))
   75.94 -        return referenceTypes_[type->primitive()];
   75.95 -
   75.96 -    // :TODO: cache this.
   75.97 -    return Type::NewReference(zone_, type, isConst);
   75.98 -}
   75.99 -
  75.100 -Type *
  75.101 -TypeManager::newFunction(Handle<Type> returnType, Handle<FixedArray> args)
  75.102 -{
  75.103 -    // :TODO: cache this.
  75.104 -    return Type::NewFunction(zone_, returnType, args);
  75.105 -}
  75.106 -
  75.107 -Type *
  75.108 -TypeManager::newNative(Handle<Type> returnType, Handle<FixedArray> args, bool variadic)
  75.109 -{
  75.110 -    // :TODO: cache this.
  75.111 -    return Type::NewNative(zone_, returnType, args, variadic);
  75.112 -}
  75.113 -
  75.114 -void
  75.115 -TypeManager::accept(VirtualObjectVisitor *visitor)
  75.116 -{
  75.117 -    visitor->visit(voidType_.address());
  75.118 -    for (unsigned i = 0; i < PrimitiveTypes_Total; i++) {
  75.119 -        visitor->visit(primitiveTypes_[i].address());
  75.120 -        visitor->visit(referenceTypes_[i].address());
  75.121 -    }
  75.122 -}
    76.1 --- a/jitcraft/TypeManager.h	Tue Jul 24 23:53:34 2012 -0700
    76.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    76.3 @@ -1,61 +0,0 @@
    76.4 -/*
    76.5 - * Copyright (C) 2012 David Anderson
    76.6 - *
    76.7 - * This file is part of JITCraft.
    76.8 - *
    76.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   76.10 - * the terms of the GNU General Public License as published by the Free
   76.11 - * Software Foundation, either version 3 of the License, or (at your option)
   76.12 - * any later version.
   76.13 - * 
   76.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   76.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   76.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   76.17 - *
   76.18 - * You should have received a copy of the GNU General Public License along with
   76.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   76.20 - */
   76.21 -#ifndef _include_jitcraft_type_manager_h_
   76.22 -#define _include_jitcraft_type_manager_h_
   76.23 -
   76.24 -#include "Barriers.h"
   76.25 -#include "Types.h"
   76.26 -#include "VirtualObjectVisitor.h"
   76.27 -
   76.28 -namespace ke {
   76.29 -
   76.30 -class String;
   76.31 -
   76.32 -class TypeManager
   76.33 -{
   76.34 -    Zone *zone_;
   76.35 -
   76.36 -    // Primitive type cache.
   76.37 -    Unbarriered<Type> voidType_;
   76.38 -    Unbarriered<Type> primitiveTypes_[PrimitiveTypes_Total];
   76.39 -    Unbarriered<Type> referenceTypes_[PrimitiveTypes_Total];
   76.40 -
   76.41 -  public:
   76.42 -    TypeManager(Zone *zone);
   76.43 -
   76.44 -    bool initialize();
   76.45 -
   76.46 -    Type *getPrimitiveForTag(Handle<String>);
   76.47 -    Type *getPrimitive(PrimitiveType type) {
   76.48 -        return primitiveTypes_[type];
   76.49 -    }
   76.50 -
   76.51 -    Type *getVoid() {
   76.52 -        return voidType_;
   76.53 -    }
   76.54 -    Type *getReference(Handle<Type> type, bool isConst);
   76.55 -    Type *unsafeArray(Handle<Type> contained, int elements, bool isConst);
   76.56 -    Type *newFunction(Handle<Type> returnType, Handle<FixedArray> args);
   76.57 -    Type *newNative(Handle<Type> returnType, Handle<FixedArray> args, bool variadic);
   76.58 -    
   76.59 -    void accept(VirtualObjectVisitor *visitor);
   76.60 -};
   76.61 -
   76.62 -}
   76.63 -
   76.64 -#endif // _include_jitcraft_type_manager_h_
    77.1 --- a/jitcraft/Types.cpp	Tue Jul 24 23:53:34 2012 -0700
    77.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    77.3 @@ -1,187 +0,0 @@
    77.4 -/*
    77.5 - * Copyright (C) 2012 David Anderson
    77.6 - *
    77.7 - * This file is part of JITCraft.
    77.8 - *
    77.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   77.10 - * the terms of the GNU General Public License as published by the Free
   77.11 - * Software Foundation, either version 3 of the License, or (at your option)
   77.12 - * any later version.
   77.13 - * 
   77.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   77.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   77.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   77.17 - *
   77.18 - * You should have received a copy of the GNU General Public License along with
   77.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   77.20 - */
   77.21 -#include "Types.h"
   77.22 -#include "Zone.h"
   77.23 -#include "Strings.h"
   77.24 -#include "Heap-inl.h"
   77.25 -
   77.26 -using namespace ke;
   77.27 -
   77.28 -Type *
   77.29 -Type::NewVoid(Zone *zone)
   77.30 -{
   77.31 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   77.32 -    if (!type)
   77.33 -        return NULL;
   77.34 -
   77.35 -    type->kind_ = VOID;
   77.36 -    type->tag_ = NULL;
   77.37 -    type->contained_ = NULL;
   77.38 -    type->returnType_ = NULL;
   77.39 -    type->parameters_ = NULL;
   77.40 -    return type;
   77.41 -}
   77.42 -
   77.43 -Type *
   77.44 -Type::NewPrimitive(Zone *zone, Handle<String> tag)
   77.45 -{
   77.46 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   77.47 -    if (!type)
   77.48 -        return NULL;
   77.49 -
   77.50 -    type->kind_ = PRIMITIVE;
   77.51 -    type->tag_ = tag;
   77.52 -    type->contained_ = NULL;
   77.53 -    type->returnType_ = NULL;
   77.54 -    type->parameters_ = NULL;
   77.55 -
   77.56 -    if (tag && strcmp(tag->chars(), "Float") == 0)
   77.57 -        type->primitive_ = PrimitiveType_Float;
   77.58 -    else if (tag && strcmp(tag->chars(), "String") == 0)
   77.59 -        type->primitive_ = PrimitiveType_Char;
   77.60 -    else
   77.61 -        type->primitive_ = PrimitiveType_Int32;
   77.62 -    return type;
   77.63 -}
   77.64 -
   77.65 -Type *
   77.66 -Type::NewPrimitive(Zone *zone, PrimitiveType prim)
   77.67 -{
   77.68 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   77.69 -    if (!type)
   77.70 -        return NULL;
   77.71 -
   77.72 -    type->kind_ = PRIMITIVE;
   77.73 -    type->tag_ = NULL;
   77.74 -    type->contained_ = NULL;
   77.75 -    type->returnType_ = NULL;
   77.76 -    type->parameters_ = NULL;
   77.77 -    type->primitive_ = prim;
   77.78 -    return type;
   77.79 -}
   77.80 -
   77.81 -Type *
   77.82 -Type::NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst)
   77.83 -{
   77.84 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
   77.85 -    if (!type)
   77.86 -        return NULL;
   77.87 -
   77.88 -    type->kind_ = ARRAY;
   77.89 -    type->tag_ = NULL;
   77.90 -    type->contained_ = contained;
   77.91 -    type->returnType_ = NULL;
   77.92 -    type->parameters_ = NULL;
   77.93 -    type->elements_ = elements;
   77.94 -    if (contained->isPrimitive())
   77.95 -        type->levels_ = 1;
   77.96 -    else
   77.97 -        type->levels_ = contained->levels() + 1;
   77.98 -    type->const_ = isConst;
   77.99 -    return type;
  77.100 -}
  77.101 -
  77.102 -Type *
  77.103 -Type::NewReference(Zone *zone, Handle<Type> contained, bool isConst)
  77.104 -{
  77.105 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
  77.106 -    if (!type)
  77.107 -        return NULL;
  77.108 -
  77.109 -    type->kind_ = REFERENCE;
  77.110 -    type->tag_ = NULL;
  77.111 -    type->contained_ = contained;
  77.112 -    type->returnType_ = NULL;
  77.113 -    type->parameters_ = NULL;
  77.114 -    type->const_ = isConst;
  77.115 -    return type;
  77.116 -}
  77.117 -
  77.118 -Type *
  77.119 -Type::NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters)
  77.120 -{
  77.121 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
  77.122 -    if (!type)
  77.123 -        return NULL;
  77.124 -
  77.125 -    type->kind_ = FUNCTION;
  77.126 -    type->contained_ = NULL;
  77.127 -    type->returnType_ = returnType;
  77.128 -    type->parameters_ = parameters;
  77.129 -    return type;
  77.130 -}
  77.131 -
  77.132 -Type *
  77.133 -Type::NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool variadic)
  77.134 -{
  77.135 -    Local<Type> type(zone, Type::cast(zone->allocate(MapKind_Type, sizeof(Type), Heap::Tenure_Old)));
  77.136 -    if (!type)
  77.137 -        return NULL;
  77.138 -
  77.139 -    type->kind_ = NATIVE;
  77.140 -    type->contained_ = NULL;
  77.141 -    type->returnType_ = returnType;
  77.142 -    type->parameters_ = parameters;
  77.143 -    type->variadicNative_ = variadic;
  77.144 -    return type;
  77.145 -}
  77.146 -
  77.147 -bool
  77.148 -Type::Compare(Type *left, Type *right)
  77.149 -{
  77.150 -    if (left->kind() != right->kind())
  77.151 -        return false;
  77.152 -
  77.153 -    switch (left->kind()) {
  77.154 -      case Type::PRIMITIVE:
  77.155 -        return (left->primitive() == right->primitive() &&
  77.156 -                left->tag() == right->tag());
  77.157 -
  77.158 -      case Type::ARRAY:
  77.159 -      {
  77.160 -        if (left->levels() != right->levels())
  77.161 -          return false;
  77.162 -        if (left->elements() != right->elements())
  77.163 -          return false;
  77.164 -        return Compare(left->contained(), right->contained());
  77.165 -      }
  77.166 -
  77.167 -      case Type::FUNCTION:
  77.168 -      {
  77.169 -        if (!Compare(left->returnType(), right->returnType()))
  77.170 -            return false;
  77.171 -        if (left->parameters()->length() != right->parameters()->length())
  77.172 -            return false;
  77.173 -        if (left->isNative() != right->isNative())
  77.174 -            return false;
  77.175 -        if (left->isNative() && (left->isNativeVariadic() != right->isNativeVariadic()))
  77.176 -            return false;
  77.177 -        for (unsigned i = 0; i < left->parameters()->length(); i++) {
  77.178 -            Type *leftparam = left->parameterAt(i);
  77.179 -            Type *rightparam = right->parameterAt(i);
  77.180 -            if (!Compare(leftparam, rightparam))
  77.181 -                return false;
  77.182 -        }
  77.183 -        return true;
  77.184 -      }
  77.185 -
  77.186 -      default:
  77.187 -        assert(left->kind() == Type::REFERENCE);
  77.188 -        return Compare(left->contained(), right->contained());
  77.189 -    }
  77.190 -}
    78.1 --- a/jitcraft/Types.h	Tue Jul 24 23:53:34 2012 -0700
    78.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    78.3 @@ -1,215 +0,0 @@
    78.4 -/* vim: set ts=4 sw=4 tw=99 et:
    78.5 - *
    78.6 - * Copyright (C) 2012 David Anderson
    78.7 - *
    78.8 - * This file is part of JITCraft.
    78.9 - *
   78.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   78.11 - * the terms of the GNU General Public License as published by the Free
   78.12 - * Software Foundation, either version 3 of the License, or (at your option)
   78.13 - * any later version.
   78.14 - * 
   78.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   78.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   78.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   78.18 - *
   78.19 - * You should have received a copy of the GNU General Public License along with
   78.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   78.21 - */
   78.22 -#ifndef _include_jc_types_h_
   78.23 -#define _include_jc_types_h_
   78.24 -
   78.25 -#include "Heap.h"
   78.26 -#include "Barriers.h"
   78.27 -#include "FixedArray.h"
   78.28 -
   78.29 -namespace ke {
   78.30 -
   78.31 -class String;
   78.32 -
   78.33 -enum PrimitiveType
   78.34 -{
   78.35 -    PrimitiveType_Char,         // signed, 8-bit character
   78.36 -    PrimitiveType_Int32,        // signed, 32-bit integer
   78.37 -    PrimitiveType_Float,        // 32-bit IEEE-754 float
   78.38 -    PrimitiveType_Native,       // native-sized word
   78.39 -    PrimitiveTypes_Total
   78.40 -};
   78.41 -
   78.42 -class Type : public Object
   78.43 -{
   78.44 -    enum Kind {
   78.45 -        PRIMITIVE,
   78.46 -        ARRAY,
   78.47 -        REFERENCE,
   78.48 -        FUNCTION,
   78.49 -        NATIVE,
   78.50 -        VOID
   78.51 -    };
   78.52 -
   78.53 -  private:
   78.54 -    Kind kind() {
   78.55 -        return kind_;
   78.56 -    }
   78.57 -
   78.58 -  public:
   78.59 -    static const int UNKNOWN_SIZE = -1;
   78.60 -    static const size_t MAX_UNSAFE_ARRAY_DEPTH = 5;
   78.61 -    
   78.62 -    static Type *NewVoid(Zone *zone);
   78.63 -    static Type *NewPrimitive(Zone *zone, Handle<String> tag);
   78.64 -    static Type *NewPrimitive(Zone *zone, PrimitiveType type);
   78.65 -    static Type *NewArray(Zone *zone, Handle<Type> contained, int elements, bool isConst);
   78.66 -    static Type *NewReference(Zone *zone, Handle<Type> contained, bool isConst);
   78.67 -    static Type *NewFunction(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters);
   78.68 -    static Type *NewNative(Zone *zone, Handle<Type> returnType, Handle<FixedArray> parameters, bool isVariadic);
   78.69 -
   78.70 -    static bool Compare(Type *left, Type *right);
   78.71 -
   78.72 -    static Type *cast(Object *obj) {
   78.73 -        assert(!obj || obj->is(MapKind_Type));
   78.74 -        return (Type *)obj;
   78.75 -    }
   78.76 -
   78.77 -    bool isPrimitive() {
   78.78 -        return kind() == PRIMITIVE;
   78.79 -    }
   78.80 -    bool isArray() {
   78.81 -        return kind() == ARRAY;
   78.82 -    }
   78.83 -    bool isReference() {
   78.84 -        return kind() == REFERENCE;
   78.85 -    }
   78.86 -    bool isFunction() {
   78.87 -        return kind() == FUNCTION || kind() == NATIVE;
   78.88 -    }
   78.89 -    bool isNative() {
   78.90 -        return kind() == NATIVE;
   78.91 -    }
   78.92 -    bool isVoid() {
   78.93 -        return kind() == VOID;
   78.94 -    }
   78.95 -    bool isNativeVariadic() {
   78.96 -        assert(isNative());
   78.97 -        return variadicNative_;
   78.98 -    }
   78.99 -    PrimitiveType primitive() {
  78.100 -        assert(isPrimitive());
  78.101 -        return primitive_;
  78.102 -    }
  78.103 -    Type *contained() {
  78.104 -        assert(isArray() || isReference());
  78.105 -        return Type::cast(contained_);
  78.106 -    }
  78.107 -    int elements() {
  78.108 -        assert(isArray());
  78.109 -        return elements_;
  78.110 -    }
  78.111 -    unsigned levels() {
  78.112 -        assert(isArray());
  78.113 -        return levels_;
  78.114 -    }
  78.115 -    String *tag() {
  78.116 -        assert(isPrimitive());
  78.117 -        return tag_;
  78.118 -    }
  78.119 -    Type *innermost() {
  78.120 -        assert(isArray());
  78.121 -        Type *temp = contained();
  78.122 -        while (temp->isArray())
  78.123 -            temp = temp->contained();
  78.124 -        return temp;
  78.125 -    }
  78.126 -    bool isFloat() {
  78.127 -        return isPrimitive() && primitive() == PrimitiveType_Float;
  78.128 -    }
  78.129 -    bool isInt32() {
  78.130 -        return isPrimitive() && primitive() == PrimitiveType_Int32;
  78.131 -    }
  78.132 -    bool isCharArray() {
  78.133 -        return isArray() &&
  78.134 -               contained()->isPrimitive() &&
  78.135 -               contained()->primitive() == PrimitiveType_Char;
  78.136 -    }
  78.137 -    Type *returnType() {
  78.138 -        assert(isFunction());
  78.139 -        return returnType_;
  78.140 -    }
  78.141 -    FixedArray *parameters() {
  78.142 -        assert(isFunction());
  78.143 -        return parameters_;
  78.144 -    }
  78.145 -    Type *parameterAt(size_t i) {
  78.146 -        return Type::cast(parameters()->at(i));
  78.147 -    }
  78.148 -    bool isTraceable() {
  78.149 -        return !isPrimitive();
  78.150 -    }
  78.151 -    bool isConst() {
  78.152 -        assert(kind() == PRIMITIVE || kind() == ARRAY || kind() == REFERENCE);
  78.153 -        return const_;
  78.154 -    }
  78.155 -
  78.156 -    // GC Descriptor.
  78.157 -    static inline size_t offsetOfContained() {
  78.158 -        return offsetof(Type, contained_);
  78.159 -    }
  78.160 -    static inline size_t offsetOfReturnType() {
  78.161 -        return offsetof(Type, returnType_);
  78.162 -    }
  78.163 -    static inline size_t offsetOfParameters() {
  78.164 -        return offsetof(Type, parameters_);
  78.165 -    }
  78.166 -    static inline size_t offsetOfTag() {
  78.167 -        return offsetof(Type, tag_);
  78.168 -    }
  78.169 -    // End GC Descriptor.
  78.170 -
  78.171 -  private:
  78.172 -    Kind kind_;
  78.173 -    PrimitiveType primitive_;
  78.174 -    Barriered<String> tag_;
  78.175 -
  78.176 -    // Primitives, arrays, and references.
  78.177 -    bool const_;
  78.178 -
  78.179 -    // Arrays only.
  78.180 -    int32 elements_;
  78.181 -    unsigned levels_;
  78.182 -
  78.183 -    // Arrays and references only.
  78.184 -    Barriered<Type> contained_;
  78.185 -
  78.186 -    // Functions only.
  78.187 -    Barriered<Type> returnType_;
  78.188 -    Barriered<FixedArray> parameters_;
  78.189 -    bool variadicNative_;
  78.190 -};
  78.191 -
  78.192 -class BoxedPrimitive
  78.193 -{
  78.194 -    PrimitiveType type_;
  78.195 -    union {
  78.196 -        int i_;
  78.197 -    };
  78.198 -
  78.199 -  public:
  78.200 -    static BoxedPrimitive Int(int i) {
  78.201 -        BoxedPrimitive b;
  78.202 -        b.type_ = PrimitiveType_Int32;
  78.203 -        b.i_ = i;
  78.204 -        return b;
  78.205 -    }
  78.206 -
  78.207 -    PrimitiveType type() const {
  78.208 -        return type_;
  78.209 -    }
  78.210 -    int toInt() const {
  78.211 -        assert(type() == PrimitiveType_Int32);
  78.212 -        return i_;
  78.213 -    }
  78.214 -};
  78.215 -
  78.216 -}
  78.217 -
  78.218 -#endif // _include_jc_types_h_
    79.1 --- a/jitcraft/Utility.h	Tue Jul 24 23:53:34 2012 -0700
    79.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    79.3 @@ -1,235 +0,0 @@
    79.4 -/* vim: set ts=4 sw=4 tw=99 et:
    79.5 - *
    79.6 - * Copyright (C) 2012 David Anderson
    79.7 - *
    79.8 - * This file is part of JITCraft.
    79.9 - *
   79.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   79.11 - * the terms of the GNU General Public License as published by the Free
   79.12 - * Software Foundation, either version 3 of the License, or (at your option)
   79.13 - * any later version.
   79.14 - * 
   79.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   79.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   79.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   79.18 - *
   79.19 - * You should have received a copy of the GNU General Public License along with
   79.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   79.21 - */
   79.22 -#ifndef _include_jitcraft_utility_h_
   79.23 -#define _include_jitcraft_utility_h_
   79.24 -
   79.25 -#include <assert.h>
   79.26 -#include <stdint.h>
   79.27 -#ifdef _MSC_VER
   79.28 -# include <intrin.h>
   79.29 -#endif
   79.30 -
   79.31 -#ifdef _MSC_VER
   79.32 -# pragma warning(disable:4355)
   79.33 -#endif
   79.34 -
   79.35 -namespace ke {
   79.36 -
   79.37 -static const size_t kMallocAlignment = sizeof(void *) * 2;
   79.38 -
   79.39 -typedef uint8_t uint8;
   79.40 -typedef int32_t int32;
   79.41 -typedef uint32_t uint32;
   79.42 -
   79.43 -typedef uint8 * Address;
   79.44 -
   79.45 -static const size_t kKB = 1024;
   79.46 -static const size_t kMB = 1024 * kKB;
   79.47 -static const size_t kGB = 1024 * kMB;
   79.48 -
   79.49 -template <typename T>
   79.50 -class AutoVec
   79.51 -{
   79.52 -    T *t_;
   79.53 -
   79.54 -  public:
   79.55 -    AutoVec()
   79.56 -      : t_(NULL)
   79.57 -    {
   79.58 -    }
   79.59 -    AutoVec(T *t)
   79.60 -      : t_(t)
   79.61 -    {
   79.62 -    }
   79.63 -    ~AutoVec() {
   79.64 -        delete [] t_;
   79.65 -    }
   79.66 -    operator T *() {
   79.67 -        return t_;
   79.68 -    }
   79.69 -    void operator =(T *t) {
   79.70 -        if (t_)
   79.71 -            delete [] t_;
   79.72 -        t_ = t;
   79.73 -    }
   79.74 -};
   79.75 -
   79.76 -// Bob Jenkin's one-at-a-time hash function[1].
   79.77 -//
   79.78 -// [1] http://burtleburtle.net/bob/hash/doobs.html
   79.79 -class CharacterStreamHasher
   79.80 -{
   79.81 -    uint32 hash;
   79.82 -
   79.83 -  public:
   79.84 -    CharacterStreamHasher()
   79.85 -      : hash(0)
   79.86 -    { }
   79.87 -
   79.88 -    void add(char c) {
   79.89 -        hash += c;
   79.90 -        hash += (hash << 10);
   79.91 -        hash ^= (hash >> 6);
   79.92 -    }
   79.93 -
   79.94 -    void add(const char *s, size_t length) {
   79.95 -        for (size_t i = 0; i < length; i++)
   79.96 -            add(s[i]);
   79.97 -    }
   79.98 -
   79.99 -    uint32 result() {
  79.100 -        hash += (hash << 3);
  79.101 -        hash ^= (hash >> 11);
  79.102 -        hash += (hash << 15);
  79.103 -        return hash;
  79.104 -    }
  79.105 -};
  79.106 -
  79.107 -static inline uint32
  79.108 -HashCharSequence(const char *s, size_t length)
  79.109 -{
  79.110 -    CharacterStreamHasher hasher;
  79.111 -    hasher.add(s, length);
  79.112 -    return hasher.result();
  79.113 -}
  79.114 -
  79.115 -static inline size_t
  79.116 -Log2(size_t number)
  79.117 -{
  79.118 -    assert(number != 0);
  79.119 -
  79.120 -#ifdef _MSC_VER
  79.121 -    unsigned long rval;
  79.122 -    _BitScanReverse(&rval, number);
  79.123 -    return rval;
  79.124 -#else
  79.125 -	size_t bit;
  79.126 -	asm("bsr %1, %0\n"
  79.127 -		: "=r" (bit)
  79.128 -		: "rm" (number));
  79.129 -	return bit;
  79.130 -#endif
  79.131 -}
  79.132 -
  79.133 -static inline size_t
  79.134 -FindRightmostBit(size_t number)
  79.135 -{
  79.136 -    assert(number != 0);
  79.137 -
  79.138 -#ifdef _MSC_VER
  79.139 -    unsigned long rval;
  79.140 -    _BitScanForward(&rval, number);
  79.141 -    return rval;
  79.142 -#else
  79.143 -	size_t bit;
  79.144 -	asm("bsf %1, %0\n"
  79.145 -		: "=r" (bit)
  79.146 -		: "rm" (number));
  79.147 -	return bit;
  79.148 -#endif
  79.149 -}
  79.150 -
  79.151 -static inline bool
  79.152 -IsPowerOfTwo(size_t value)
  79.153 -{
  79.154 -    if (value == 0)
  79.155 -        return false;
  79.156 -    return !(value & (value - 1));
  79.157 -}
  79.158 -
  79.159 -static inline size_t
  79.160 -Align(size_t count, size_t alignment)
  79.161 -{
  79.162 -    assert(IsPowerOfTwo(alignment));
  79.163 -    return count + (alignment - (count % alignment)) % alignment;
  79.164 -}
  79.165 -
  79.166 -static inline bool
  79.167 -IsUint32AddSafe(unsigned a, unsigned b)
  79.168 -{
  79.169 -    if (!a || !b)
  79.170 -        return true;
  79.171 -    unsigned log2_a = Log2(a);
  79.172 -    unsigned log2_b = Log2(b);
  79.173 -    return (log2_a < sizeof(unsigned) * 8) &&
  79.174 -           (log2_b < sizeof(unsigned) * 8);
  79.175 -}
  79.176 -
  79.177 -static inline bool
  79.178 -IsUintPtrAddSafe(size_t a, size_t b)
  79.179 -{
  79.180 -    if (!a || !b)
  79.181 -        return true;
  79.182 -    size_t log2_a = Log2(a);
  79.183 -    size_t log2_b = Log2(b);
  79.184 -    return (log2_a < sizeof(size_t) * 8) &&
  79.185 -           (log2_b < sizeof(size_t) * 8);
  79.186 -}
  79.187 -
  79.188 -static inline bool
  79.189 -IsUint32MultiplySafe(unsigned a, unsigned b)
  79.190 -{
  79.191 -    if (a <= 1 || b <= 1)
  79.192 -        return true;
  79.193 -
  79.194 -    unsigned log2_a = Log2(a);
  79.195 -    unsigned log2_b = Log2(b);
  79.196 -    return log2_a + log2_b <= sizeof(unsigned) * 8;
  79.197 -}
  79.198 -
  79.199 -static inline bool
  79.200 -IsUintPtrMultiplySafe(size_t a, size_t b)
  79.201 -{
  79.202 -    if (a <= 1 || b <= 1)
  79.203 -        return true;
  79.204 -
  79.205 -    size_t log2_a = Log2(a);
  79.206 -    size_t log2_b = Log2(b);
  79.207 -    return log2_a + log2_b <= sizeof(size_t) * 8;
  79.208 -}
  79.209 -
  79.210 -#define ARRAY_LENGTH(array) (sizeof(array) / sizeof(array[0]))
  79.211 -#define STATIC_ASSERT(cond) extern int static_assert_f(int a[(cond) ? 1 : -1])
  79.212 -
  79.213 -#define IS_ALIGNED(addr, alignment)	(!(uintptr_t(addr) & ((alignment) - 1)))
  79.214 -
  79.215 -template <typename T>
  79.216 -static inline bool
  79.217 -IsAligned(T addr, size_t alignment)
  79.218 -{
  79.219 -    assert(IsPowerOfTwo(alignment));
  79.220 -    return !(uintptr_t(addr) & (alignment - 1));
  79.221 -}
  79.222 -
  79.223 -static inline Address
  79.224 -AlignedBase(Address addr, size_t alignment)
  79.225 -{
  79.226 -    assert(IsPowerOfTwo(alignment));
  79.227 -    return Address(uintptr_t(addr) & ~(alignment - 1));
  79.228 -}
  79.229 -
  79.230 -template <typename T> static inline T
  79.231 -Min(const T &t1, const T &t2)
  79.232 -{
  79.233 -    return t1 < t2 ? t1 : t2;
  79.234 -}
  79.235 -
  79.236 -}
  79.237 -
  79.238 -#endif // _include_jitcraft_utility_h_
    80.1 --- a/jitcraft/Vector.h	Tue Jul 24 23:53:34 2012 -0700
    80.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    80.3 @@ -1,119 +0,0 @@
    80.4 -/* vim: set ts=4 sw=4 tw=99 et:
    80.5 - *
    80.6 - * Copyright (C) 2012 David Anderson
    80.7 - *
    80.8 - * This file is part of JITCraft.
    80.9 - *
   80.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   80.11 - * the terms of the GNU General Public License as published by the Free
   80.12 - * Software Foundation, either version 3 of the License, or (at your option)
   80.13 - * any later version.
   80.14 - * 
   80.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   80.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   80.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   80.18 - *
   80.19 - * You should have received a copy of the GNU General Public License along with
   80.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   80.21 - */
   80.22 -#ifndef _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   80.23 -#define _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_
   80.24 -
   80.25 -#include <new>
   80.26 -#include <stdlib.h>
   80.27 -#include "AllocatorPolicies.h"
   80.28 -#include "Utility.h"
   80.29 -
   80.30 -namespace ke {
   80.31 -
   80.32 -template <typename T, typename AllocPolicy = ZoneAllocatorPolicy>
   80.33 -class Vector : public AllocPolicy
   80.34 -{
   80.35 -  public:
   80.36 -    Vector(AllocPolicy = AllocPolicy())
   80.37 -      : data(NULL),
   80.38 -        nitems(0),
   80.39 -        maxsize(0)
   80.40 -    { }
   80.41 -    ~Vector() {
   80.42 -        for (size_t i = 0; i < nitems; i++)
   80.43 -            data[i].~T();
   80.44 -        this->free(data);
   80.45 -    }
   80.46 -    bool append(const T& item) {
   80.47 -        if (!GrowIfNeeded(1))
   80.48 -            return false;
   80.49 -        new (&data[nitems]) T(item);
   80.50 -        nitems++;
   80.51 -        return true;
   80.52 -    }
   80.53 -    void pop() {
   80.54 -        assert(nitems);
   80.55 -        data[nitems - 1].~T();
   80.56 -        nitems--;
   80.57 -    }
   80.58 -    size_t length() const {
   80.59 -        return nitems;
   80.60 -    }
   80.61 -    T& at(size_t i) {
   80.62 -        assert(i < length());
   80.63 -        return data[i];
   80.64 -    }
   80.65 -    const T& at(size_t i) const {
   80.66 -        assert(i < length());
   80.67 -        return data[i];
   80.68 -    }
   80.69 -    T& operator [](size_t i) {
   80.70 -        return at(i);
   80.71 -    }
   80.72 -    const T& operator [](size_t i) const {
   80.73 -        return at(i);
   80.74 -    }
   80.75 -    void clear() {
   80.76 -        nitems = 0;
   80.77 -    }
   80.78 -
   80.79 -    T *buffer() const {
   80.80 -        return data;
   80.81 -    }
   80.82 -
   80.83 -  private:
   80.84 -    bool GrowIfNeeded(size_t needed)
   80.85 -    {
   80.86 -        if (!IsUintPtrAddSafe(nitems, needed)) {
   80.87 -            this->reportAllocationOverflow();
   80.88 -            return false;
   80.89 -        }
   80.90 -        if (maxsize == 0)
   80.91 -            maxsize = 8;
   80.92 -        while (nitems + needed > maxsize)
   80.93 -        {
   80.94 -            if (!IsUintPtrMultiplySafe(maxsize, 2)) {
   80.95 -                this->reportAllocationOverflow();
   80.96 -                return false;
   80.97 -            }
   80.98 -            maxsize *= 2;
   80.99 -        }
  80.100 -        T* newdata = (T*)this->malloc(sizeof(T) * maxsize);
  80.101 -        if (newdata == NULL)
  80.102 -            return false;
  80.103 -        for (size_t i = 0; i < nitems; i++)
  80.104 -        {
  80.105 -            new (&newdata[i]) T(data[i]);
  80.106 -            data[i].~T();
  80.107 -        }
  80.108 -        this->free(data);
  80.109 -        data = newdata;
  80.110 -        return true;
  80.111 -    }
  80.112 -
  80.113 -  private:
  80.114 -    T* data;
  80.115 -    size_t nitems;
  80.116 -    size_t maxsize;
  80.117 -};
  80.118 -
  80.119 -}
  80.120 -
  80.121 -#endif /* _INCLUDE_KEIMA_TPL_CPP_VECTOR_H_ */
  80.122 -
    81.1 --- a/jitcraft/VirtualObjectVisitor.h	Tue Jul 24 23:53:34 2012 -0700
    81.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    81.3 @@ -1,34 +0,0 @@
    81.4 -/* vim: set ts=4 sw=4 tw=99 et:
    81.5 - *
    81.6 - * Copyright (C) 2012 David Anderson
    81.7 - *
    81.8 - * This file is part of JITCraft.
    81.9 - *
   81.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   81.11 - * the terms of the GNU General Public License as published by the Free
   81.12 - * Software Foundation, either version 3 of the License, or (at your option)
   81.13 - * any later version.
   81.14 - * 
   81.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   81.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   81.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   81.18 - *
   81.19 - * You should have received a copy of the GNU General Public License along with
   81.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   81.21 - */
   81.22 -#ifndef _include_jc_virtual_object_visitor_h_
   81.23 -#define _include_jc_virtual_object_visitor_h_
   81.24 -
   81.25 -namespace ke {
   81.26 -
   81.27 -class Object;
   81.28 -
   81.29 -class VirtualObjectVisitor
   81.30 -{
   81.31 -  public:
   81.32 -    virtual void visit(Object **ptr) = 0;
   81.33 -};
   81.34 -
   81.35 -}
   81.36 -
   81.37 -#endif // _include_jc_virtual_object_visitor_h_
    82.1 --- a/jitcraft/Zone.cpp	Tue Jul 24 23:53:34 2012 -0700
    82.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    82.3 @@ -1,312 +0,0 @@
    82.4 -/* vim: set ts=4 sw=4 tw=99 et:
    82.5 - *
    82.6 - * Copyright (C) 2012 David Anderson
    82.7 - *
    82.8 - * This file is part of JITCraft.
    82.9 - *
   82.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   82.11 - * the terms of the GNU General Public License as published by the Free
   82.12 - * Software Foundation, either version 3 of the License, or (at your option)
   82.13 - * any later version.
   82.14 - * 
   82.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   82.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   82.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   82.18 - *
   82.19 - * You should have received a copy of the GNU General Public License along with
   82.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   82.21 - */
   82.22 -#include <stdlib.h>
   82.23 -#include "Zone.h"
   82.24 -#include "StringPool.h"
   82.25 -#include "TypeManager.h"
   82.26 -#include "GlobalRoots.h"
   82.27 -#include "AllocatorPolicies.h"
   82.28 -#include "Array.h"
   82.29 -
   82.30 -using namespace ke;
   82.31 -
   82.32 -Zone *ke::SingleThreadedZone;
   82.33 -
   82.34 -Zone::Zone()
   82.35 -  : stack_(thisFromCtor()),
   82.36 -    heap_(thisFromCtor()),
   82.37 -    types_(NULL),
   82.38 -    symbols_(NULL),
   82.39 -    globalRoots_(NULL),
   82.40 -    lastLocalRoot_(NULL),
   82.41 -    hasPendingException_(false),
   82.42 -    reporter_(NULL)
   82.43 -{
   82.44 -}
   82.45 -
   82.46 -Zone::~Zone()
   82.47 -{
   82.48 -    delete types_;
   82.49 -    delete symbols_;
   82.50 -    delete globalRoots_;
   82.51 -}
   82.52 -
   82.53 -bool
   82.54 -Zone::initialize()
   82.55 -{
   82.56 -    if (!stack_.initialize())
   82.57 -        return false;
   82.58 -    if (!heap_.initialize())
   82.59 -        return false;
   82.60 -
   82.61 -    symbols_ = new StringPool(this);
   82.62 -    if (!symbols_ || !symbols_->initialize())
   82.63 -        return false;
   82.64 -
   82.65 -    globalRoots_ = new GlobalRoots(this);
   82.66 -    if (!globalRoots_ || !globalRoots_->initialize())
   82.67 -        return false;
   82.68 -
   82.69 -    maps_[MapKind_Meta] = heap_.metaMap();
   82.70 -    if ((maps_[MapKind_Type] = allocateMap(MapKind_Type, sizeof(Map))) == NULL)
   82.71 -        return false;
   82.72 -    if ((maps_[MapKind_FixedArray] = allocateMap(MapKind_FixedArray, sizeof(Map))) == NULL)
   82.73 -        return false;
   82.74 -    if ((maps_[MapKind_ByteArray] = allocateMap(MapKind_ByteArray, sizeof(Map))) == NULL)
   82.75 -        return false;
   82.76 -    if ((maps_[MapKind_Code] = allocateMap(MapKind_Code, sizeof(Map))) == NULL)
   82.77 -        return false;
   82.78 -    if ((maps_[MapKind_Reference] = allocateMap(MapKind_Reference, sizeof(Map))) == NULL)
   82.79 -        return false;
   82.80 -    if ((maps_[MapKind_MetaArray] = allocateMap(MapKind_MetaArray, sizeof(Map))) == NULL)
   82.81 -        return false;
   82.82 -    if ((maps_[MapKind_MetaEnvironment] = allocateMap(MapKind_MetaEnvironment, sizeof(Map))) == NULL)
   82.83 -        return false;
   82.84 -    if ((maps_[MapKind_Module] = allocateMap(MapKind_Module, sizeof(Map))) == NULL)
   82.85 -        return false;
   82.86 -    if ((maps_[MapKind_Function] = allocateMap(MapKind_Function, sizeof(Map))) == NULL)
   82.87 -        return false;
   82.88 -    if ((maps_[MapKind_String] = allocateMap(MapKind_String, sizeof(Map))) == NULL)
   82.89 -        return false;
   82.90 -    if ((maps_[MapKind_Native] = allocateMap(MapKind_Native, sizeof(Map))) == NULL)
   82.91 -        return false;
   82.92 -    if ((maps_[MapKind_FreeRegion] = allocateMap(MapKind_FreeRegion, sizeof(Map))) == NULL)
   82.93 -        return false;
   82.94 -    if ((maps_[MapKind_EnvironmentSlotDescriptorArray] =
   82.95 -         allocateMap(MapKind_EnvironmentSlotDescriptorArray, sizeof(Map))) == NULL)
   82.96 -    {
   82.97 -        return false;
   82.98 -    }
   82.99 -
  82.100 -    types_ = new TypeManager(this);
  82.101 -    if (!types_ || !types_->initialize())
  82.102 -        return false;
  82.103 -
  82.104 -    // Create the cached array maps for generic arrays. This is for the API
  82.105 -    // version of Invoke(), which needs to make arrays very quickly from C++.
  82.106 -    {
  82.107 -        // Generic "cell" array (contents do not matter, just non-gc things).
  82.108 -        Local<Type> type(this, types_->getPrimitive(PrimitiveType_Int32));
  82.109 -        if (!type)
  82.110 -            return false;
  82.111 -
  82.112 -        type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
  82.113 -        if (!type)
  82.114 -            return false;
  82.115 -
  82.116 -        Local<ArrayMap> contained(this);
  82.117 -        genericArrayMap_ = ArrayMap::New(this, type, contained);
  82.118 -        if (!genericArrayMap_)
  82.119 -            return false;
  82.120 -
  82.121 -        type = types_->getPrimitive(PrimitiveType_Char);
  82.122 -        if (!type)
  82.123 -            return false;
  82.124 -
  82.125 -        type = types_->unsafeArray(type, Type::UNKNOWN_SIZE, false);
  82.126 -        if (!type)
  82.127 -            return false;
  82.128 -
  82.129 -        charArrayMap_ = ArrayMap::New(this, type, contained);
  82.130 -        if (!charArrayMap_)
  82.131 -            return false;
  82.132 -    }
  82.133 -
  82.134 -    return true;
  82.135 -}
  82.136 -
  82.137 -Map *
  82.138 -Zone::allocateMap(MapKind kind, size_t bytes, MapKind parent)
  82.139 -{
  82.140 -    assert(maps_[parent]);
  82.141 -    Map *map = heap_.allocateMap(kind, bytes);
  82.142 -    if (!map)
  82.143 -        return NULL;
  82.144 -    map->init(maps_[parent]);
  82.145 -    return map;
  82.146 -}
  82.147 -
  82.148 -void
  82.149 -Zone::accept(VirtualObjectVisitor *visitor)
  82.150 -{
  82.151 -    for (unsigned i = 0; i < MapKinds_Total; i++)
  82.152 -        visitor->visit(maps_[i].address());
  82.153 -    visitor->visit(charArrayMap_.address());
  82.154 -    visitor->visit(genericArrayMap_.address());
  82.155 -    types()->accept(visitor);
  82.156 -
  82.157 -    Local<Object> *local = lastLocalRoot_;
  82.158 -    while (local) {
  82.159 -        visitor->visit(local->address());
  82.160 -        local = local->prev();
  82.161 -    }
  82.162 -
  82.163 -    globalRoots_->accept(visitor);
  82.164 -    rootScopes_.accept(visitor);
  82.165 -
  82.166 -    stack_.accept(visitor);
  82.167 -}
  82.168 -
  82.169 -String *
  82.170 -Zone::makeSymbol(const char *str, size_t length)
  82.171 -{
  82.172 -    return symbols_->add(str, length);
  82.173 -}
  82.174 -
  82.175 -String *
  82.176 -Zone::makeSymbol(const char *str)
  82.177 -{
  82.178 -    return makeSymbol(str, strlen(str));
  82.179 -}
  82.180 -
  82.181 -bool
  82.182 -Zone::hasPendingException()
  82.183 -{
  82.184 -    return hasPendingException_;
  82.185 -}
  82.186 -
  82.187 -void
  82.188 -Zone::reportOutOfMemory()
  82.189 -{
  82.190 -    
  82.191 -}
  82.192 -
  82.193 -void
  82.194 -Zone::reportError(Message message, ...)
  82.195 -{
  82.196 -    va_list ap;
  82.197 -    va_start(ap, message);
  82.198 -    reportErrorVA(message, ap);
  82.199 -    va_end(ap);
  82.200 -}
  82.201 -
  82.202 -#if defined(_MSC_VER)
  82.203 -# define VA_COPY(to, from)  to = from
  82.204 -#else
  82.205 -# define VA_COPY(to, from)  va_copy(to, from)
  82.206 -#endif
  82.207 -
  82.208 -static char *
  82.209 -BuildErrorMessage(const char *format, va_list ap)
  82.210 -{
  82.211 -    va_list use;
  82.212 -    VA_COPY(use, ap);
  82.213 -
  82.214 -    // We over-allocate and zero terminate ahead of time, since LIBCRT's
  82.215 -    // version of vsnprintf is screwy.
  82.216 -    size_t size = 255;
  82.217 -    char *buffer = (char *)calloc(size + 1, 1);
  82.218 -    if (!buffer)
  82.219 -        return NULL;
  82.220 -
  82.221 -    for (;;) {
  82.222 -        int r = vsnprintf(buffer, size, format, use);
  82.223 -
  82.224 -        if (r > -1 && size_t(r) < size)
  82.225 -            return buffer;
  82.226 -       
  82.227 -#if defined(_MSC_VER)
  82.228 -        if (r < 0)
  82.229 -            size *= 2;
  82.230 -#else
  82.231 -        if (r > -1)
  82.232 -            size = size_t(r) + 1;
  82.233 -        else
  82.234 -            size *= 2;
  82.235 -#endif
  82.236 -
  82.237 -        free(buffer);
  82.238 -        if ((buffer = (char *)calloc(size + 1, 1)) == NULL)
  82.239 -            return NULL;
  82.240 -
  82.241 -        VA_COPY(use, ap);
  82.242 -    }
  82.243 -}
  82.244 -
  82.245 -void
  82.246 -Zone::reportErrorVA(Message message, va_list ap)
  82.247 -{
  82.248 -    char *report = BuildErrorMessage(Messages[message].format, ap);
  82.249 -    if (!report) {
  82.250 -        reportOutOfMemory();
  82.251 -        return;
  82.252 -    }
  82.253 -
  82.254 -    if (reporter_) {
  82.255 -        // Reporters can re-enter. When we start having actual exception
  82.256 -        // objects that can be caught and inspected, this code will have to
  82.257 -        // save and restore the exception state.
  82.258 -        reporter_->onUncaughtException(report);
  82.259 -    }
  82.260 -
  82.261 -    hasPendingException_ = true;
  82.262 -
  82.263 -    free(report);
  82.264 -}
  82.265 -
  82.266 -void
  82.267 -Zone::beginCompilationErrors(const char *file)
  82.268 -{
  82.269 -    if (reporter_)
  82.270 -        reporter_->beginCompilationErrors(file);
  82.271 -}
  82.272 -
  82.273 -void
  82.274 -Zone::reportCompilationError(Message message, unsigned line, unsigned col, va_list ap)
  82.275 -{
  82.276 -    char *report = BuildErrorMessage(Messages[message].format, ap);
  82.277 -    if (!report) {
  82.278 -        reportOutOfMemory();
  82.279 -        return;
  82.280 -    }
  82.281 -
  82.282 -    if (reporter_) {
  82.283 -        // Reporters can re-enter. When we start having actual exception
  82.284 -        // objects that can be caught and inspected, this code will have to
  82.285 -        // save and restore the exception state.
  82.286 -        reporter_->reportCompilationError(report, line, col);
  82.287 -    }
  82.288 -
  82.289 -    free(report);
  82.290 -}
  82.291 -
  82.292 -void
  82.293 -Zone::endCompilationErrors()
  82.294 -{
  82.295 -    if (reporter_)
  82.296 -        reporter_->endCompilationErrors();
  82.297 -}
  82.298 -
  82.299 -void
  82.300 -Zone::installErrorReporter(Ke::IMessageReporter *reporter)
  82.301 -{
  82.302 -    reporter_ = reporter;
  82.303 -}
  82.304 -
  82.305 -void
  82.306 -ZoneAllocatorPolicy::reportOutOfMemory()
  82.307 -{
  82.308 -    ZONE()->reportOutOfMemory();
  82.309 -}
  82.310 -
  82.311 -void
  82.312 -ZoneAllocatorPolicy::reportAllocationOverflow()
  82.313 -{
  82.314 -    ZONE()->reportError(Message_AllocationOverflow);
  82.315 -}
    83.1 --- a/jitcraft/Zone.h	Tue Jul 24 23:53:34 2012 -0700
    83.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    83.3 @@ -1,189 +0,0 @@
    83.4 -/* vim: set ts=4 sw=4 tw=99 et:
    83.5 - *
    83.6 - * Copyright (C) 2012 David Anderson
    83.7 - *
    83.8 - * This file is part of JITCraft.
    83.9 - *
   83.10 - * JITCraft is free software: you can redistribute it and/or modify it under
   83.11 - * the terms of the GNU General Public License as published by the Free
   83.12 - * Software Foundation, either version 3 of the License, or (at your option)
   83.13 - * any later version.
   83.14 - * 
   83.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   83.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   83.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   83.18 - *
   83.19 - * You should have received a copy of the GNU General Public License along with
   83.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   83.21 - */
   83.22 -#ifndef _include_jitcraft_thread_h_
   83.23 -#define _include_jitcraft_thread_h_
   83.24 -
   83.25 -#include <stdarg.h>
   83.26 -#include "PoolAllocator.h"
   83.27 -#include "Stack.h"
   83.28 -#include "Heap.h"
   83.29 -#include "Barriers.h"
   83.30 -#include "Handles.h"
   83.31 -#include "Messages.h"
   83.32 -#include "RootScopes.h"
   83.33 -#include "VirtualObjectVisitor.h"
   83.34 -
   83.35 -namespace ke {
   83.36 -
   83.37 -class TypeManager;
   83.38 -class String;
   83.39 -class StringPool;
   83.40 -class GlobalRoots;
   83.41 -class ArrayMap;
   83.42 -class Exception;
   83.43 -
   83.44 -class Zone
   83.45 -{
   83.46 -    PoolAllocator pool_;
   83.47 -    Stack stack_;
   83.48 -    Heap heap_;
   83.49 -
   83.50 -    // Map cache.
   83.51 -    Unbarriered<Map> maps_[MapKinds_Total];
   83.52 -    Unbarriered<ArrayMap> genericArrayMap_;
   83.53 -    Unbarriered<ArrayMap> charArrayMap_;
   83.54 -
   83.55 -    TypeManager *types_;
   83.56 -    StringPool *symbols_;
   83.57 -    GlobalRoots *globalRoots_;
   83.58 -
   83.59 -    // Root list.
   83.60 -    Local<Object> *lastLocalRoot_;
   83.61 -    RootScopeManager rootScopes_;
   83.62 -
   83.63 -    // Exception stuff.
   83.64 -    bool hasPendingException_;
   83.65 -    Ke::IMessageReporter *reporter_;
   83.66 -
   83.67 -  private:
   83.68 -    Zone *thisFromCtor() {
   83.69 -        return this;
   83.70 -    }
   83.71 -
   83.72 -  public:
   83.73 -    Zone();
   83.74 -    ~Zone();
   83.75 -    bool initialize();
   83.76 -
   83.77 -    PoolAllocator &pool() {
   83.78 -        return pool_;
   83.79 -    }
   83.80 -    Stack &stack() {
   83.81 -        return stack_;
   83.82 -    }
   83.83 -    Heap &heap() {
   83.84 -        return heap_;
   83.85 -    }
   83.86 -    Object *allocate(MapKind kind, size_t bytes, Heap::Tenure tenure = Heap::Tenure_Default) {
   83.87 -        assert(maps_[kind]);
   83.88 -        Local<Map> map(this, maps_[kind]);
   83.89 -        return allocate(map, bytes, tenure);
   83.90 -    }
   83.91 -    Object *allocate(Handle<Map> map, size_t bytes, Heap::Tenure tenure = Heap::Tenure_Default) {
   83.92 -        return heap_.allocate(map, bytes, tenure);
   83.93 -    }
   83.94 -    Map *getMap(MapKind kind) {
   83.95 -        return maps_[kind];
   83.96 -    }
   83.97 -    Map *allocateMap(MapKind kind, size_t bytes, MapKind parent = MapKind_Meta);
   83.98 -
   83.99 -    ArrayMap *genericArrayMap() {
  83.100 -        return genericArrayMap_;
  83.101 -    }
  83.102 -    ArrayMap *charArrayMap() {
  83.103 -        return charArrayMap_;
  83.104 -    }
  83.105 -
  83.106 -    TypeManager *types() const {
  83.107 -        return types_;
  83.108 -    }
  83.109 -    Local<Object> **lastLocalRoot() {
  83.110 -        return &lastLocalRoot_;
  83.111 -    }
  83.112 -    Object **makeScopedRoot(Object *ptr) {
  83.113 -        return rootScopes_.make(ptr);
  83.114 -    }
  83.115 -    RootScopeManager &rootScopes() {
  83.116 -        return rootScopes_;
  83.117 -    }
  83.118 -    StringPool *symbols() {
  83.119 -        return symbols_;
  83.120 -    }
  83.121 -    GlobalRoots *globalRoots() {
  83.122 -        return globalRoots_;
  83.123 -    }
  83.124 -
  83.125 -    String *makeSymbol(const char *string, size_t length);
  83.126 -    String *makeSymbol(const char *string);
  83.127 -
  83.128 -    void reportOutOfMemory();
  83.129 -    void reportError(Message message, ...);
  83.130 -    void reportErrorVA(Message message, va_list ap);
  83.131 -    bool hasPendingException();
  83.132 -    void installErrorReporter(Ke::IMessageReporter *reporter);
  83.133 -    void beginCompilationErrors(const char *file);
  83.134 -    void reportCompilationError(Message message, unsigned line, unsigned col, va_list ap);
  83.135 -    void endCompilationErrors();
  83.136 -
  83.137 -    void accept(VirtualObjectVisitor *visitor);
  83.138 -};
  83.139 -
  83.140 -// In a multi-threaded system, this would be a TLS variable.
  83.141 -// In the interest of simplicity, we are single-threaded for now.
  83.142 -extern Zone *SingleThreadedZone;
  83.143 -
  83.144 -static inline Zone *ZONE()
  83.145 -{
  83.146 -    return SingleThreadedZone;
  83.147 -}
  83.148 -
  83.149 -template <typename T>
  83.150 -Local<T>::Local(Zone *zone, T *thing)
  83.151 -  : zone_(zone),
  83.152 -    thing_(thing),
  83.153 -    prev_(*zone->lastLocalRoot())
  83.154 -{
  83.155 -    *zone->lastLocalRoot() = toRaw();
  83.156 -}
  83.157 -
  83.158 -template <typename T>
  83.159 -Local<T>::~Local()
  83.160 -{
  83.161 -    assert(*zone_->lastLocalRoot() == toRaw());
  83.162 -    *zone_->lastLocalRoot() = prev_;
  83.163 -}
  83.164 -
  83.165 -template <typename T>
  83.166 -ScopedRoot<T>::ScopedRoot()
  83.167 -  : thingp_(make(NULL))
  83.168 -{
  83.169 -}
  83.170 -
  83.171 -template <typename T>
  83.172 -ScopedRoot<T>::ScopedRoot(T *thing)
  83.173 -  : thingp_(make(thing))
  83.174 -{
  83.175 -    // Type check that T is an Object.
  83.176 -    (void)static_cast<Object *>(thing);
  83.177 -}
  83.178 -
  83.179 -template <typename T> T **
  83.180 -ScopedRoot<T>::make(T *other)
  83.181 -{
  83.182 -    return reinterpret_cast<T **>(ZONE()->makeScopedRoot(other));
  83.183 -}
  83.184 -
  83.185 -RootScope::RootScope(Zone *zone)
  83.186 -  : Ke::HandleScope(zone, zone->rootScopes().position(), *zone->rootScopes().scope())
  83.187 -{
  83.188 -}
  83.189 -
  83.190 -}
  83.191 -
  83.192 -#endif // _include_jitcraft_thread_h_
    84.1 --- a/jitcraft/configure.in	Tue Jul 24 23:53:34 2012 -0700
    84.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    84.3 @@ -1,47 +0,0 @@
    84.4 -#                                               -*- Autoconf -*-
    84.5 -# Process this file with autoconf to produce a configure script.
    84.6 -
    84.7 -AC_PREREQ([2.61])
    84.8 -AC_INIT(foobar, 0.1, https://bugs.alliedmods.net/)
    84.9 -AC_CONFIG_AUX_DIR(${srcdir}/build/autoconf)
   84.10 -AC_CONFIG_SRCDIR([Heap.cpp])
   84.11 -AC_LANG(C++)
   84.12 -AC_CANONICAL_HOST
   84.13 -
   84.14 -# Checks for programs.
   84.15 -AC_PROG_CXX
   84.16 -
   84.17 -# Checks for libraries.
   84.18 -
   84.19 -# Checks for header files.
   84.20 -AC_CHECK_HEADERS([limits.h stddef.h stdint.h stdlib.h string.h sys/time.h unistd.h])
   84.21 -
   84.22 -# Checks for typedefs, structures, and compiler characteristics.
   84.23 -AC_C_INLINE
   84.24 -
   84.25 -# Checks for library functions.
   84.26 -AC_FUNC_MALLOC
   84.27 -AC_FUNC_REALLOC
   84.28 -AC_CHECK_FUNCS([gettimeofday memset strchr])
   84.29 -
   84.30 -mkdir -p .deps
   84.31 -touch .deps/
   84.32 -
   84.33 -#AX_COMPILER_VENDOR
   84.34 -
   84.35 -CXXVENDOR=$ax_cv_cxx_compiler_vendor
   84.36 -AC_SUBST(CXXVENDOR)
   84.37 -
   84.38 -case "$host" in
   84.39 -    *-linux*)
   84.40 -        PLATFORM="linux"
   84.41 -        ;;
   84.42 -    *-darwin*)
   84.43 -        PLATFORM="darwin"
   84.44 -        ;;
   84.45 -esac
   84.46 -
   84.47 -AC_SUBST(PLATFORM)
   84.48 -
   84.49 -AC_OUTPUT(Makefile)
   84.50 -
    85.1 --- a/jitcraft/jitcraft.vcxproj	Tue Jul 24 23:53:34 2012 -0700
    85.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    85.3 @@ -1,188 +0,0 @@
    85.4 -<?xml version="1.0" encoding="utf-8"?>
    85.5 -<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
    85.6 -  <ItemGroup Label="ProjectConfigurations">
    85.7 -    <ProjectConfiguration Include="Debug - Library|Win32">
    85.8 -      <Configuration>Debug - Library</Configuration>
    85.9 -      <Platform>Win32</Platform>
   85.10 -    </ProjectConfiguration>
   85.11 -    <ProjectConfiguration Include="Debug|Win32">
   85.12 -      <Configuration>Debug</Configuration>
   85.13 -      <Platform>Win32</Platform>
   85.14 -    </ProjectConfiguration>
   85.15 -    <ProjectConfiguration Include="Release|Win32">
   85.16 -      <Configuration>Release</Configuration>
   85.17 -      <Platform>Win32</Platform>
   85.18 -    </ProjectConfiguration>
   85.19 -  </ItemGroup>
   85.20 -  <PropertyGroup Label="Globals">
   85.21 -    <ProjectGuid>{E12034DC-E8CB-4B49-AC0A-0D27CDED9A50}</ProjectGuid>
   85.22 -    <Keyword>Win32Proj</Keyword>
   85.23 -    <RootNamespace>jitcraft</RootNamespace>
   85.24 -  </PropertyGroup>
   85.25 -  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
   85.26 -  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'" Label="Configuration">
   85.27 -    <ConfigurationType>Application</ConfigurationType>
   85.28 -    <UseDebugLibraries>true</UseDebugLibraries>
   85.29 -    <CharacterSet>Unicode</CharacterSet>
   85.30 -  </PropertyGroup>
   85.31 -  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
   85.32 -    <ConfigurationType>Application</ConfigurationType>
   85.33 -    <UseDebugLibraries>false</UseDebugLibraries>
   85.34 -    <WholeProgramOptimization>true</WholeProgramOptimization>
   85.35 -    <CharacterSet>Unicode</CharacterSet>
   85.36 -  </PropertyGroup>
   85.37 -  <PropertyGroup Label="Configuration" Condition="'$(Configuration)|$(Platform)'=='Debug - Library|Win32'">
   85.38 -    <ConfigurationType>StaticLibrary</ConfigurationType>
   85.39 -  </PropertyGroup>
   85.40 -  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
   85.41 -  <ImportGroup Label="ExtensionSettings">
   85.42 -  </ImportGroup>
   85.43 -  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   85.44 -    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   85.45 -  </ImportGroup>
   85.46 -  <ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   85.47 -    <Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
   85.48 -  </ImportGroup>
   85.49 -  <PropertyGroup Label="UserMacros" />
   85.50 -  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   85.51 -    <LinkIncremental>true</LinkIncremental>
   85.52 -  </PropertyGroup>
   85.53 -  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   85.54 -    <LinkIncremental>false</LinkIncremental>
   85.55 -  </PropertyGroup>
   85.56 -  <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Library|Win32'">
   85.57 -    <TargetExt>.lib</TargetExt>
   85.58 -    <TargetName>keima</TargetName>
   85.59 -  </PropertyGroup>
   85.60 -  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
   85.61 -    <ClCompile>
   85.62 -      <PrecompiledHeader>
   85.63 -      </PrecompiledHeader>
   85.64 -      <WarningLevel>Level3</WarningLevel>
   85.65 -      <Optimization>Disabled</Optimization>
   85.66 -      <PreprocessorDefinitions>WIN32;_DEBUG;_CONSOLE;%(PreprocessorDefinitions); _CRT_SECURE_NO_WARNINGS;KE_EXPORTING</PreprocessorDefinitions>
   85.67 -    </ClCompile>
   85.68 -    <Link>
   85.69 -      <SubSystem>Console</SubSystem>
   85.70 -      <GenerateDebugInformation>true</GenerateDebugInformation>
   85.71 -      <RandomizedBaseAddress>false</RandomizedBaseAddress>
   85.72 -    </Link>
   85.73 -  </ItemDefinitionGroup>
   85.74 -  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
   85.75 -    <ClCompile>
   85.76 -      <WarningLevel>Level3</WarningLevel>
   85.77 -      <PrecompiledHeader>
   85.78 -      </PrecompiledHeader>
   85.79 -      <Optimization>MaxSpeed</Optimization>
   85.80 -      <FunctionLevelLinking>true</FunctionLevelLinking>
   85.81 -      <IntrinsicFunctions>true</IntrinsicFunctions>
   85.82 -      <PreprocessorDefinitions>WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions)</PreprocessorDefinitions>
   85.83 -    </ClCompile>
   85.84 -    <Link>
   85.85 -      <SubSystem>Console</SubSystem>
   85.86 -      <GenerateDebugInformation>true</GenerateDebugInformation>
   85.87 -      <EnableCOMDATFolding>true</EnableCOMDATFolding>
   85.88 -      <OptimizeReferences>true</OptimizeReferences>
   85.89 -    </Link>
   85.90 -  </ItemDefinitionGroup>
   85.91 -  <ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug - Library|Win32'">
   85.92 -    <ClCompile>
   85.93 -      <RuntimeLibrary>MultiThreadedDebug</RuntimeLibrary>
   85.94 -      <ExceptionHandling>false</ExceptionHandling>
   85.95 -      <RuntimeTypeInfo>false</RuntimeTypeInfo>
   85.96 -      <Optimization>Disabled</Optimization>
   85.97 -    </ClCompile>
   85.98 -  </ItemDefinitionGroup>
   85.99 -  <ItemGroup>
  85.100 -    <ClCompile Include="API.cpp" />
  85.101 -    <ClCompile Include="Array.cpp" />
  85.102 -    <ClCompile Include="BytecodeCompiler.cpp" />
  85.103 -    <ClCompile Include="BytecodeEmitter.cpp" />
  85.104 -    <ClCompile Include="CompileContext.cpp" />
  85.105 -    <ClCompile Include="Environments.cpp" />
  85.106 -    <ClCompile Include="Exception.cpp" />
  85.107 -    <ClCompile Include="FixedArray.cpp" />
  85.108 -    <ClCompile Include="Functions.cpp" />
  85.109 -    <ClCompile Include="GlobalRoots.cpp" />
  85.110 -    <ClCompile Include="Heap.cpp" />
  85.111 -    <ClCompile Include="Interpreter.cpp" />
  85.112 -    <ClCompile Include="main.cpp" />
  85.113 -    <ClCompile Include="Modules.cpp" />
  85.114 -    <ClCompile Include="NameBinding.cpp" />
  85.115 -    <ClCompile Include="Opcodes.cpp" />
  85.116 -    <ClCompile Include="Parser.cpp" />
  85.117 -    <ClCompile Include="Platform-Windows.cpp" />
  85.118 -    <ClCompile Include="PoolAllocator.cpp" />
  85.119 -    <ClCompile Include="Reference.cpp" />
  85.120 -    <ClCompile Include="RootScopes.cpp" />
  85.121 -    <ClCompile Include="Scanner.cpp" />
  85.122 -    <ClCompile Include="Scopes.cpp" />
  85.123 -    <ClCompile Include="SemanticAnalysis.cpp" />
  85.124 -    <ClCompile Include="Spaces.cpp" />
  85.125 -    <ClCompile Include="Stack.cpp" />
  85.126 -    <ClCompile Include="StringPool.cpp" />
  85.127 -    <ClCompile Include="Strings.cpp" />
  85.128 -    <ClCompile Include="Structures.cpp" />
  85.129 -    <ClCompile Include="TypeManager.cpp" />
  85.130 -    <ClCompile Include="Types.cpp" />
  85.131 -    <ClCompile Include="Zone.cpp" />
  85.132 -  </ItemGroup>
  85.133 -  <ItemGroup>
  85.134 -    <ClInclude Include="..\include\keima.h" />
  85.135 -    <ClInclude Include="..\include\keima_util.h" />
  85.136 -    <ClInclude Include="AllocatorPolicies.h" />
  85.137 -    <ClInclude Include="Array.h" />
  85.138 -    <ClInclude Include="AST.h" />
  85.139 -    <ClInclude Include="Barriers.h" />
  85.140 -    <ClInclude Include="BytecodeEmitter.h" />
  85.141 -    <ClInclude Include="BytecodeCompiler.h" />
  85.142 -    <ClInclude Include="CompactBuffer.h" />
  85.143 -    <ClInclude Include="CompileContext.h" />
  85.144 -    <ClInclude Include="Environments.h" />
  85.145 -    <ClInclude Include="FixedArray.h" />
  85.146 -    <ClInclude Include="Functions.h" />
  85.147 -    <ClInclude Include="GlobalRoots.h" />
  85.148 -    <ClInclude Include="Handles-inl.h" />
  85.149 -    <ClInclude Include="HashTable.h" />
  85.150 -    <ClInclude Include="Heap-inl.h" />
  85.151 -    <ClInclude Include="InlineList.h" />
  85.152 -    <ClInclude Include="Interpreter.h" />
  85.153 -    <ClInclude Include="Messages.h" />
  85.154 -    <ClInclude Include="Modules.h" />
  85.155 -    <ClInclude Include="NameBinding.h" />
  85.156 -    <ClInclude Include="Heap.h" />
  85.157 -    <ClInclude Include="Objects.h" />
  85.158 -    <ClInclude Include="ObjectVisitor.h" />
  85.159 -    <ClInclude Include="Opcodes.h" />
  85.160 -    <ClInclude Include="Parser.h" />
  85.161 -    <ClInclude Include="Platform.h" />
  85.162 -    <ClInclude Include="PoolAllocator.h" />
  85.163 -    <ClInclude Include="Handles.h" />
  85.164 -    <ClInclude Include="Reference.h" />
  85.165 -    <ClInclude Include="RootScopes.h" />
  85.166 -    <ClInclude Include="Scanner.h" />
  85.167 -    <ClInclude Include="Scopes.h" />
  85.168 -    <ClInclude Include="Code.h" />
  85.169 -    <ClInclude Include="SemanticAnalysis.h" />
  85.170 -    <ClInclude Include="Spaces-inl.h" />
  85.171 -    <ClInclude Include="Spaces.h" />
  85.172 -    <ClInclude Include="Stack.h" />
  85.173 -    <ClInclude Include="Strings.h" />
  85.174 -    <ClInclude Include="StringPool.h" />
  85.175 -    <ClInclude Include="Structures.h" />
  85.176 -    <ClInclude Include="TypeManager.h" />
  85.177 -    <ClInclude Include="Types.h" />
  85.178 -    <ClInclude Include="Vector.h" />
  85.179 -    <ClInclude Include="VirtualObjectVisitor.h" />
  85.180 -    <ClInclude Include="Zone.h" />
  85.181 -    <ClInclude Include="Token.h" />
  85.182 -    <ClInclude Include="Utility.h" />
  85.183 -  </ItemGroup>
  85.184 -  <ItemGroup>
  85.185 -    <None Include="Messages.tbl" />
  85.186 -    <None Include="Opcodes.tbl" />
  85.187 -  </ItemGroup>
  85.188 -  <Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
  85.189 -  <ImportGroup Label="ExtensionTargets">
  85.190 -  </ImportGroup>
  85.191 -</Project>
  85.192 \ No newline at end of file
    86.1 --- a/jitcraft/main.cpp	Tue Jul 24 23:53:34 2012 -0700
    86.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
    86.3 @@ -1,132 +0,0 @@
    86.4 -/*
    86.5 - * Copyright (C) 2012 David Anderson
    86.6 - *
    86.7 - * This file is part of JITCraft.
    86.8 - *
    86.9 - * JITCraft is free software: you can redistribute it and/or modify it under
   86.10 - * the terms of the GNU General Public License as published by the Free
   86.11 - * Software Foundation, either version 3 of the License, or (at your option)
   86.12 - * any later version.
   86.13 - * 
   86.14 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
   86.15 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
   86.16 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
   86.17 - *
   86.18 - * You should have received a copy of the GNU General Public License along with
   86.19 - * JITCraft. If not, see http://www.gnu.org/licenses/.
   86.20 - */
   86.21 -#include <stdio.h>
   86.22 -#include "Utility.h"
   86.23 -#include "Scanner.h"
   86.24 -#include "Parser.h"
   86.25 -#include "SemanticAnalysis.h"
   86.26 -#include "Zone.h"
   86.27 -#include "BytecodeCompiler.h"
   86.28 -#include "Code.h"
   86.29 -#include "Interpreter.h"
   86.30 -#include "Modules.h"
   86.31 -#include "RootScopes.h"
   86.32 -#include "../include/keima.h"
   86.33 -
   86.34 -using namespace ke;
   86.35 -
   86.36 -class MessageReporter : public Ke::IMessageReporter
   86.37 -{
   86.38 -  public:
   86.39 -    void onOutOfMemory() {
   86.40 -        fprintf(stderr, "Out of memory!\n");
   86.41 -    }
   86.42 -    void onUncaughtException(const char *message) {
   86.43 -        fprintf(stderr, "Uncaught exception: %s\n", message);
   86.44 -
   86.45 -        Ke::IStackFrameIterator *iter = Ke::Keima::NewStackFrameIterator();
   86.46 -        unsigned index = 0;
   86.47 -        while (!iter->done()) {
   86.48 -            fprintf(stderr, "[%d] %s (%s line %d)\n",
   86.49 -                    index,
   86.50 -                    iter->function(),
   86.51 -                    iter->source(),
   86.52 -                    iter->lineNumber());
   86.53 -            iter->prev();
   86.54 -            index++;
   86.55 -        }
   86.56 -    }
   86.57 -    virtual void beginCompilationErrors(const char *file) {
   86.58 -        fprintf(stderr, "\nDisplaying compilation errors for \"%s\"\n", file);
   86.59 -    }
   86.60 -    virtual void reportCompilationError(const char *message, unsigned line, unsigned col) {
   86.61 -        fprintf(stderr, "  line %d, col %d: %s\n", line, col, message);
   86.62 -    }
   86.63 -    virtual void endCompilationErrors() {
   86.64 -    }
   86.65 -} s_Reporter;
   86.66 -
   86.67 -#if 0
   86.68 -static bool
   86.69 -Compile(const char *stream, size_t length)
   86.70 -{
   86.71 -
   86.72 -    printf("\n ------------ \n\n");
   86.73 -
   86.74 -    Disassemble(module->getFunction(1)->code(), stdout);
   86.75 -    //Disassemble(module->getFunction(1), stdout);
   86.76 -
   86.77 -    printf("\n ------------ \n\n");
   86.78 -
   86.79 -    Function *main = module->getFunction(1);
   86.80 -
   86.81 -    Top top = ZONE()->stack().begin();
   86.82 -    LocalTop localTop(top);
   86.83 -
   86.84 -    Frame *frame = ZONE()->stack().pushFrame(main);
   86.85 -    if (!frame)
   86.86 -        return false;
   86.87 -
   86.88 -    LocalSlot result;
   86.89 -    if (!Interpret(ZONE(), frame, &result))
   86.90 -        return false;
   86.91 -
   86.92 -    printf("Result: %d\n", result.i32);
   86.93 -
   86.94 -    return true;
   86.95 -}
   86.96 -#endif
   86.97 -
   86.98 -intptr_t PrintToServer(void *blah, intptr_t *params)
   86.99 -{
  86.100 -    assert(params[0] == 3);
  86.101 -    const char *fmt = reinterpret_cast<const char *>(params[1]);
  86.102 -    const char *str = reinterpret_cast<const char *>(params[2]);
  86.103 -    int *d = reinterpret_cast<int *>(params[3]);
  86.104 -    printf(fmt, str, *d);
  86.105 -    return 16;
  86.106 -}
  86.107 -
  86.108 -int main(int argc, char **argv)
  86.109 -{
  86.110 -    if (argc < 2) {
  86.111 -        fprintf(stderr, "Usage: <file>\n");
  86.112 -        return 1;
  86.113 -    }
  86.114 -
  86.115 -    if (!Ke::Keima::Initialize())
  86.116 -        return 1;
  86.117 -    Ke::Keima::InstallMessageReporter(&s_Reporter);
  86.118 -    {
  86.119 -        Ke::HandleScope scope;
  86.120 -        Ke::Local<Ke::Module> module = Ke::Compile(argv[1]);
  86.121 -        if (!module)
  86.122 -            return 1;
  86.123 -
  86.124 -        //Ke::Local<Ke::Native> native = module->getNative(0);
  86.125 -        //native->bind(reinterpret_cast<void *>(PrintToServer));
  86.126 -        //module->setNativeIdentity(reinterpret_cast<void *>(5));
  86.127 -
  86.128 -        int result;
  86.129 -        Ke::Local<Ke::Function> fun = module->getPublic(0);
  86.130 -        if (Ke::Keima::Invoke(fun, NULL, 0, &result))
  86.131 -            printf("%d\n", result);
  86.132 -    }
  86.133 -
  86.134 -    Ke::Keima::Shutdown();
  86.135 -}
    87.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    87.2 +++ b/src/AMBuild.library	Tue Jul 24 23:54:14 2012 -0700
    87.3 @@ -0,0 +1,49 @@
    87.4 +# vim: set ts=2 sw=2 tw=99 noet ft=python: 
    87.5 +import os
    87.6 +
    87.7 +compiler = KE.DefaultCompiler()
    87.8 +base = AMBuild.sourceFolder
    87.9 +
   87.10 +compiler['CXXINCLUDES'].append(os.path.join(base, 'include'))
   87.11 +
   87.12 +job = AMBuild.AddJob('libkeima')
   87.13 +library = Cpp.StaticLibraryBuilder('libkeima', AMBuild, job, compiler)
   87.14 +files = [
   87.15 +	'API.cpp',
   87.16 +	'Array.cpp',
   87.17 +	'BytecodeCompiler.cpp',
   87.18 +	'BytecodeEmitter.cpp',
   87.19 +	'CompileContext.cpp',
   87.20 +	'Environments.cpp',
   87.21 +	'Exception.cpp',
   87.22 +	'FixedArray.cpp',
   87.23 +	'Functions.cpp',
   87.24 +	'GlobalRoots.cpp',
   87.25 +	'Heap.cpp',
   87.26 +	'Interpreter.cpp',
   87.27 +	'Modules.cpp',
   87.28 +	'NameBinding.cpp',
   87.29 +	'Opcodes.cpp',
   87.30 +	'Parser.cpp',
   87.31 +	'PoolAllocator.cpp',
   87.32 +	'Reference.cpp',
   87.33 +	'RootScopes.cpp',
   87.34 +	'Scanner.cpp',
   87.35 +	'Scopes.cpp',
   87.36 +	'SemanticAnalysis.cpp',
   87.37 +	'Spaces.cpp',
   87.38 +	'Stack.cpp',
   87.39 +	'StringPool.cpp',
   87.40 +	'Strings.cpp',
   87.41 +	'Structures.cpp',
   87.42 +	'TypeManager.cpp',
   87.43 +	'Types.cpp',
   87.44 +	'Zone.cpp'
   87.45 +]
   87.46 +if AMBuild.target['platform'] == 'windows':
   87.47 +	files.append('Platform-Windows.cpp')
   87.48 +else:
   87.49 +	files.append('Platform-Posix.cpp')
   87.50 +library.AddSourceFiles('src', files)
   87.51 +library.SendToJob()
   87.52 +