1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
1.2 +++ b/jitcraft/API.cpp Sun Jul 08 01:54:08 2012 -0700
1.3 @@ -0,0 +1,142 @@
1.4 +/* vim: set ts=4 sw=4 tw=99 et:
1.5 + *
1.6 + * Copyright (C) 2012 David Anderson
1.7 + *
1.8 + * This file is part of JITCraft.
1.9 + *
1.10 + * JITCraft is free software: you can redistribute it and/or modify it under
1.11 + * the terms of the GNU General Public License as published by the Free
1.12 + * Software Foundation, either version 3 of the License, or (at your option)
1.13 + * any later version.
1.14 + *
1.15 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
1.16 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.17 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.18 + *
1.19 + * You should have received a copy of the GNU General Public License along with
1.20 + * JITCraft. If not, see http://www.gnu.org/licenses/.
1.21 + */
1.22 +#include "../include/keima.h"
1.23 +#include "Zone.h"
1.24 +#include "RootScopes.h"
1.25 +#include "CompileContext.h"
1.26 +#include "Parser.h"
1.27 +#include "Scopes.h"
1.28 +#include "SemanticAnalysis.h"
1.29 +#include "BytecodeCompiler.h"
1.30 +#include "Modules.h"
1.31 +
1.32 +using namespace ke;
1.33 +
1.34 +bool
1.35 +Ke::Initialize()
1.36 +{
1.37 + SingleThreadedZone = new Zone();
1.38 + if (!SingleThreadedZone || !SingleThreadedZone->initialize())
1.39 + return false;
1.40 + return true;
1.41 +}
1.42 +
1.43 +void
1.44 +Ke::Shutdown()
1.45 +{
1.46 + delete SingleThreadedZone;
1.47 + SingleThreadedZone = NULL;
1.48 +}
1.49 +
1.50 +Ke::HandleScope::HandleScope()
1.51 + : zone_(ke::ZONE()),
1.52 + position_(zone_->rootScopes().position()),
1.53 + prev_(*zone_->rootScopes().scope())
1.54 +{
1.55 + *zone_->rootScopes().scope() = this;
1.56 +}
1.57 +
1.58 +Ke::HandleScope::~HandleScope()
1.59 +{
1.60 + zone_->rootScopes().unwind(position_);
1.61 + *zone_->rootScopes().scope() = prev_;
1.62 +}
1.63 +
1.64 +ke::Object **
1.65 +Ke::HandleScope::CreateHandle(ke::Object *obj)
1.66 +{
1.67 + if (!obj)
1.68 + return NULL;
1.69 +
1.70 + return ZONE()->rootScopes().make(obj);
1.71 +}
1.72 +
1.73 +template <typename From, typename To> static inline Ke::Local<To>
1.74 +ToLocal(Handle<From> from)
1.75 +{
1.76 + return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
1.77 +}
1.78 +
1.79 +static ke::Module *
1.80 +CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
1.81 +{
1.82 + Parser parser(ZONE(), cc, stream, length);
1.83 + ParseTree *tree = parser.parse();
1.84 + if (!tree)
1.85 + return NULL;
1.86 + tree->dump(stdout);
1.87 +
1.88 + if (!Scope::Bind(tree))
1.89 + return NULL;
1.90 +
1.91 + SemanticAnalysis semantics(ZONE(), cc, tree);
1.92 + if (!semantics.analyze())
1.93 + return NULL;
1.94 +
1.95 + Scope::Allocate(tree);
1.96 +
1.97 + BytecodeCompiler compiler(ZONE(), tree, NULL);
1.98 + return compiler.compile();
1.99 +}
1.100 +
1.101 +Ke::Local<Ke::Module>
1.102 +Ke::Compile(const char *path)
1.103 +{
1.104 + RootScope roots(ZONE());
1.105 + CompileContext cc(ZONE());
1.106 +
1.107 + char *bytes = NULL;
1.108 + size_t length;
1.109 + {
1.110 + FILE *fp = fopen(path, "rb");
1.111 + if (!fp) {
1.112 + cc.reportError(SourcePosition(), Message_CantOpenFile);
1.113 + return Ke::Local<Ke::Module>();
1.114 + }
1.115 +
1.116 + if (fseek(fp, 0, SEEK_END)) {
1.117 + cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
1.118 + fclose(fp);
1.119 + return Ke::Local<Ke::Module>();;
1.120 + }
1.121 + long size = ftell(fp);
1.122 + if (size < 0) {
1.123 + cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
1.124 + fclose(fp);
1.125 + return Ke::Local<Ke::Module>();;
1.126 + }
1.127 + rewind(fp);
1.128 + length = size_t(size);
1.129 + bytes = new char[length + 1];
1.130 + if (fread(bytes, 1, length, fp) != length) {
1.131 + cc.reportError(SourcePosition(), Message_ErrorReadingFile);
1.132 + fclose(fp);
1.133 + delete [] bytes;
1.134 + return Ke::Local<Ke::Module>();;
1.135 + }
1.136 + fclose(fp);
1.137 + }
1.138 +
1.139 + ke::Local<ke::Module> module(ZONE(), CompileFromSource(cc, path, bytes, length));
1.140 + delete [] bytes;
1.141 + if (!module)
1.142 + return Ke::Local<Ke::Module>();
1.143 +
1.144 + return ToLocal<ke::Module, Ke::Module>(module);
1.145 +}