Added API for looking at module public functions.
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 To *
80 return *reinterpret_cast<To **>(from);
83 template <typename From, typename To> static inline Ke::Local<To>
86 return Ke::Local<To>(reinterpret_cast<To *>(Ke::HandleScope::CreateHandle(from)));
90 CompileFromSource(CompileContext &cc, const char *path, const char *stream, size_t length)
92 Parser parser(ZONE(), cc, stream, length);
93 ParseTree *tree = parser.parse();
98 if (!Scope::Bind(tree))
101 SemanticAnalysis semantics(ZONE(), cc, tree);
102 if (!semantics.analyze())
105 Scope::Allocate(tree);
107 BytecodeCompiler compiler(ZONE(), tree, NULL);
108 return compiler.compile();
111 Ke::Local<Ke::Module>
112 Ke::Compile(const char *path)
114 RootScope roots(ZONE());
115 CompileContext cc(ZONE());
120 FILE *fp = fopen(path, "rb");
122 cc.reportError(SourcePosition(), Message_CantOpenFile);
123 return Ke::Local<Ke::Module>();
126 if (fseek(fp, 0, SEEK_END)) {
127 cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
129 return Ke::Local<Ke::Module>();;
131 long size = ftell(fp);
133 cc.reportError(SourcePosition(), Message_ErrorSeekingFile);
135 return Ke::Local<Ke::Module>();;
138 length = size_t(size);
139 bytes = new char[length + 1];
140 if (fread(bytes, 1, length, fp) != length) {
141 cc.reportError(SourcePosition(), Message_ErrorReadingFile);
144 return Ke::Local<Ke::Module>();;
149 ke::Local<ke::Module> module(ZONE(), CompileFromSource(cc, path, bytes, length));
152 return Ke::Local<Ke::Module>();
154 return ToLocal<ke::Module, Ke::Module>(module);
157 static inline ke::HeapRoot *
158 FromAPI(ke::HeapRoot *from)
160 ke::Address address = reinterpret_cast<ke::Address>(from);
161 address -= offsetof(ke::HeapRoot, obj);
162 return reinterpret_cast<ke::HeapRoot *>(address);
166 Ke::Internals::NewHeapRoot(ke::Object **ptr)
168 ke::Local<ke::Object> obj(ZONE(), *ptr);
169 ke::HeapRoot *root = ke::ZONE()->globalRoots()->create(obj);
173 // Compute an interior pointer, so it looks like a Handle to an object.
174 return reinterpret_cast<ke::HeapRoot *>(&root->obj);
178 Ke::Internals::IncRef(ke::HeapRoot *root)
180 ZONE()->globalRoots()->incref(FromAPI(root));
184 Ke::Internals::DecRef(ke::HeapRoot *root)
186 ZONE()->globalRoots()->decref(FromAPI(root));
190 Ke::Keima::IsInCallStack(Handle<Module> argModule)
192 ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(argModule));
193 return ZONE()->stack().isInCallStack(module);
197 Ke::Keima::CollectGarbage()
199 ke::ZONE()->heap().reclaim();
203 Ke::Module::numPublics()
205 ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
206 return module->publics()->length();
209 Ke::Local<Ke::Function>
210 Ke::Module::getPublic(unsigned index)
212 ke::Local<ke::Module> module(ke::ZONE(), Open<Ke::Module, ke::Module>(this));
213 ke::Local<ke::Function> fun(ke::ZONE(), ke::Function::cast(module->publics()->at(index)));
214 return ToLocal<ke::Function, Ke::Function>(fun);
220 ke::Local<ke::String> obj(ke::ZONE(), Open<Ke::String, ke::String>(this));
221 return obj->length();
227 ke::Local<ke::String> obj(ke::ZONE(), Open<Ke::String, ke::String>(this));
231 Ke::Local<Ke::String>
234 ke::Local<ke::Function> fun(ke::ZONE(), Open<Ke::Function, ke::Function>(this));
235 return ToLocal<ke::String, Ke::String>(fun->name());