Add some more API.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
19 #include "../include/keima.h"
21 #include "RootScopes.h"
22 #include "CompileContext.h"
25 #include "SemanticAnalysis.h"
26 #include "BytecodeCompiler.h"
28 #include "GlobalRoots.h"
33 Ke::Keima::Initialize()
35 SingleThreadedZone = new Zone();
36 if (!SingleThreadedZone || !SingleThreadedZone->initialize())
44 delete SingleThreadedZone;
45 SingleThreadedZone = NULL;
48 Ke::HandleScope::HandleScope()
50 position_(zone_->rootScopes().position()),
51 prev_(*zone_->rootScopes().scope())
53 *zone_->rootScopes().scope() = this;
56 Ke::HandleScope::~HandleScope()
58 zone_->rootScopes().unwind(position_);
59 *zone_->rootScopes().scope() = prev_;
63 Ke::HandleScope::CreateHandle(ke::Object *obj)
68 return ZONE()->rootScopes().make(obj);
71 template <typename From, typename To> static inline To *
72 Open(Ke::Handle<From> from)
74 return *reinterpret_cast<To **>(*from);
77 template <typename From, typename To> static inline Ke::Local<To>
78 ToLocal(Handle<From> from)
80 return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
84 CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
86 Parser parser(ZONE(), cc, stream, length);
87 ParseTree *tree = parser.parse();
92 if (!Scope::Bind(tree))
95 SemanticAnalysis semantics(ZONE(), cc, tree);
96 if (!semantics.analyze())
99 Scope::Allocate(tree);
101 BytecodeCompiler compiler(ZONE(), tree, NULL);
102 return compiler.compile();
105 Ke::Local<Ke::Module>
106 Ke::Compile(const char *path)
108 RootScope roots(ZONE());
109 CompileContext cc(ZONE());
114 FILE *fp = fopen(path, "rb");
116 cc.reportError(SourcePosition(), Message_CantOpenFile);
117 return Ke::Local<Ke::Module>();
120 if (fseek(fp, 0, SEEK_END)) {
121 cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
123 return Ke::Local<Ke::Module>();;
125 long size = ftell(fp);
127 cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
129 return Ke::Local<Ke::Module>();;
132 length = size_t(size);
133 bytes = new char[length + 1];
134 if (fread(bytes, 1, length, fp) != length) {
135 cc.reportError(SourcePosition(), Message_ErrorReadingFile);
138 return Ke::Local<Ke::Module>();;
143 ke::Local<ke::Module> module(ZONE(), CompileFromSource(cc, path, bytes, length));
146 return Ke::Local<Ke::Module>();
148 return ToLocal<ke::Module, Ke::Module>(module);
151 static inline ke::HeapRoot *
152 FromAPI(ke::HeapRoot *from)
154 ke::Address address = reinterpret_cast<ke::Address>(from);
155 address -= offsetof(ke::HeapRoot, obj);
156 return reinterpret_cast<ke::HeapRoot *>(address);
160 Ke::Internals::NewHeapRoot(ke::Object **ptr)
162 ke::Local<ke::Object> obj(ZONE(), *ptr);
163 ke::HeapRoot *root = ke::ZONE()->globalRoots()->create(obj);
167 // Compute an interior pointer, so it looks like a Handle to an object.
168 return reinterpret_cast<ke::HeapRoot *>(&root->obj);
172 Ke::Internals::IncRef(ke::HeapRoot *root)
174 ZONE()->globalRoots()->incref(FromAPI(root));
178 Ke::Internals::DecRef(ke::HeapRoot *root)
180 ZONE()->globalRoots()->decref(FromAPI(root));
184 Ke::Keima::IsInCallStack(Handle<Module> argModule)
186 ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(argModule));
187 return ZONE()->stack().isInCallStack(module);
191 Ke::Keima::CollectGarbage()
193 ke::ZONE()->heap().reclaim();