Implement |const| keyword.
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/.
21 #include "../TypeManager.h"
22 #include "../Strings.h"
23 #include "../Environments.h"
24 #include "../Structures.h"
25 #include "CompileContext.h"
27 #include "../Spaces-inl.h"
28 #include "../Heap-inl.h"
32 Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
42 if (enclosing_ && !enclosing_->children_.append(this))
52 assert(enclosing_->children_[enclosing_->children_.length() - 1] == this);
53 enclosing_->children_.pop();
55 // OOM here is swallowed and checked after compilation.
56 // :TODO: make the above true.
57 for (size_t i = 0; i < children_.length(); i++)
58 enclosing_->children_.append(children_[i]);
62 Scope::unlinkIfEmpty()
72 Scope::localLookup(Handle<String> name)
74 for (size_t i = 0; i < names_.length(); i++) {
75 if (names_[i]->name() == name)
82 Scope::lookup(Handle<String> name)
84 for (Scope *scope = this; scope; scope = scope->enclosing()) {
85 if (Symbol *bound = scope->localLookup(name))
93 Scope::setUsesLifoHeap()
95 // Only one lifo slot is needed per scope.
101 // If the parent of this scope is the function scope, then this is the
102 // function's block scope, and the lifo slot is part of the Frame instead.
103 // Note we can get a function scope here if we're making a temporary in a
104 // function with no local variables.
105 if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
108 Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
112 Local<String> name(ZONE());
114 lifoSlot_ = new (pool_) Variable(this, name, SourcePosition());
115 lifoSlot_->setType(type);
121 Scope::addSymbol(Symbol *sym)
123 return names_.append(sym);
126 LocalScope::LocalScope(PoolAllocator &pool)
127 : Scope(pool, Scope::BLOCK, NULL)
132 LocalScope::New(PoolAllocator &pool)
134 LocalScope *scope = new (pool) LocalScope(pool);
135 if (!scope->initialize())
141 ArgumentScope::ArgumentScope(PoolAllocator &pool)
142 : Scope(pool, Scope::FUNCTION, NULL)
147 ArgumentScope::New(PoolAllocator &pool)
149 ArgumentScope *scope = new (pool) ArgumentScope(pool);
150 if (!scope->initialize())
156 GlobalScope::GlobalScope(PoolAllocator &pool, ImportScope *parent)
157 : Scope(pool, Scope::GLOBAL, parent)
162 GlobalScope::New(PoolAllocator &pool, ImportScope *parent)
164 GlobalScope *scope = new (pool) GlobalScope(pool, parent);
165 if (!scope->initialize())
172 GlobalScope::addPublic(Symbol *sym)
174 return publics_.append(sym);
178 GlobalScope::findPublic(Handle<String> name)
180 for (size_t i = 0; i < publics_.length(); i++) {
181 if (publics_[i]->name() == name)
188 GlobalScope::build(Zone *zone)
190 Local<FixedArray> descriptors(zone, FixedArray::New(zone, names_.length(), Heap::Tenure_Old));
192 for (size_t i = 0; i < names_.length(); i++) {
193 Handle<String> name = names_[i]->name();
194 Handle<Type> type = names_[i]->type();
197 Local<Descriptor> desc(zone, Descriptor::New(zone, name, type));
201 descriptors->set(zone, i, desc);
204 Local<StructType> type(zone, StructType::New(zone, Handle<String>::Null(), descriptors));
208 Local<StructMap> map(zone, type->newMap());
209 return Struct::New(zone, map, Heap::Tenure_Old);
212 ImportScope::ImportScope(PoolAllocator &pool)
213 : Scope(pool, Scope::IMPORT, NULL)
218 ImportScope::New(PoolAllocator &pool)
220 ImportScope *scope = new (pool) ImportScope(pool);
221 if (!scope->initialize())