1.1 --- a/src/Scopes.cpp Mon Sep 17 00:10:01 2012 -0700
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,289 +0,0 @@
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 "Scopes.h"
1.23 -#include "Zone.h"
1.24 -#include "Types.h"
1.25 -#include "TypeManager.h"
1.26 -#include "Strings.h"
1.27 -#include "CompileContext.h"
1.28 -#include "Environments.h"
1.29 -#include "Spaces-inl.h"
1.30 -#include "Heap-inl.h"
1.31 -
1.32 -using namespace ke;
1.33 -
1.34 -Scope::Scope(PoolAllocator &pool, Kind kind, Scope *enclosing)
1.35 - : pool_(pool),
1.36 - locals_(0),
1.37 - maxContainedLocals_(0),
1.38 - numFunctions_(0),
1.39 - numNatives_(0),
1.40 - lifoSlot_(NULL),
1.41 - kind_(kind),
1.42 - enclosing_(enclosing)
1.43 -{
1.44 -}
1.45 -
1.46 -bool
1.47 -Scope::initialize()
1.48 -{
1.49 - if (enclosing_ && !enclosing_->children_.append(this))
1.50 - return false;
1.51 - return true;
1.52 -}
1.53 -
1.54 -void
1.55 -Scope::unlink()
1.56 -{
1.57 - assert(empty());
1.58 -
1.59 - assert(enclosing_->children_[enclosing_->children_.length() - 1] == this);
1.60 - enclosing_->children_.pop();
1.61 -
1.62 - // OOM here is swallowed and checked after compilation.
1.63 - // :TODO: make the above true.
1.64 - for (size_t i = 0; i < children_.length(); i++)
1.65 - enclosing_->children_.append(children_[i]);
1.66 -}
1.67 -
1.68 -Scope *
1.69 -Scope::unlinkIfEmpty()
1.70 -{
1.71 - if (empty()) {
1.72 - unlink();
1.73 - return NULL;
1.74 - }
1.75 - return this;
1.76 -}
1.77 -
1.78 -BoundName *
1.79 -Scope::localLookup(Handle<String> name)
1.80 -{
1.81 - for (size_t i = 0; i < names_.length(); i++) {
1.82 - if (names_[i]->name() == name)
1.83 - return names_[i];
1.84 - }
1.85 - return NULL;
1.86 -}
1.87 -
1.88 -BoundName *
1.89 -Scope::lookup(Handle<String> name)
1.90 -{
1.91 - for (Scope *scope = this; scope; scope = scope->enclosing()) {
1.92 - if (BoundName *bound = scope->localLookup(name))
1.93 - return bound;
1.94 - }
1.95 - return NULL;
1.96 -}
1.97 -
1.98 -Variable *
1.99 -Scope::declareVariable(Handle<String> name, const SourcePosition &pos)
1.100 -{
1.101 - assert(!localLookup(name));
1.102 -
1.103 - Variable *var = new (pool_) Variable(this, name, pos);
1.104 - if (!names_.append(var))
1.105 - return NULL;
1.106 - return var;
1.107 -}
1.108 -
1.109 -Variable *
1.110 -Scope::declareArgument(Handle<String> name, const SourcePosition &pos)
1.111 -{
1.112 - assert(kind() == FUNCTION);
1.113 - Variable *var = declareVariable(name, pos);
1.114 - if (!names_.append(var))
1.115 - return NULL;
1.116 - if (!parameters_.append(var))
1.117 - return NULL;
1.118 - return var;
1.119 -}
1.120 -
1.121 -NamedFunction *
1.122 -Scope::declareFunction(Handle<String> name, const SourcePosition &pos, TokenKind token)
1.123 -{
1.124 - assert(!localLookup(name));
1.125 - assert(kind() == GLOBAL);
1.126 -
1.127 - NamedFunction *fun = new (pool_) NamedFunction(this, name, pos, token);
1.128 - if (!names_.append(fun))
1.129 - return NULL;
1.130 - return fun;
1.131 -}
1.132 -
1.133 -NamedConstant *
1.134 -Scope::declareConstant(Handle<String> name, const SourcePosition &pos)
1.135 -{
1.136 - NamedConstant *constant = new (pool_) NamedConstant(this, name, pos);
1.137 - if (!names_.append(constant))
1.138 - return NULL;
1.139 - return constant;
1.140 -}
1.141 -
1.142 -NamedType *
1.143 -Scope::declareType(Handle<String> name, const SourcePosition &pos)
1.144 -{
1.145 - NamedType *decl = new (pool_) NamedType(this, name, pos);
1.146 - if (!names_.append(decl))
1.147 - return NULL;
1.148 - return decl;
1.149 -}
1.150 -
1.151 -NamedType *
1.152 -Scope::declareType(Handle<String> name, Handle<Type> type)
1.153 -{
1.154 - NamedType *decl = new (pool_) NamedType(this, name, type);
1.155 - if (!names_.append(decl))
1.156 - return NULL;
1.157 - return decl;
1.158 -}
1.159 -
1.160 -void
1.161 -Scope::allocateGlobals()
1.162 -{
1.163 - assert(kind() == GLOBAL);
1.164 -
1.165 - for (size_t i = 0; i < children_.length(); i++) {
1.166 - assert(children_[i]->kind() == FUNCTION);
1.167 - children_[i]->allocate();
1.168 - }
1.169 -
1.170 - Local<Type> type(ZONE());
1.171 - for (size_t i = 0; i < names_.length(); i++) {
1.172 - BoundName *name = names_[i];
1.173 -
1.174 - if (name->kind() == BoundName::FUNCTION) {
1.175 - NamedFunction *fun = name->toNamedFunction();
1.176 - if (!fun->used())
1.177 - continue;
1.178 -
1.179 - if (fun->isNative())
1.180 - fun->allocate(numNatives_++);
1.181 - else
1.182 - fun->allocate(numFunctions_++);
1.183 - } else if (name->kind() == BoundName::VARIABLE) {
1.184 - allocate(name->toVariable());
1.185 - }
1.186 - }
1.187 -}
1.188 -
1.189 -void
1.190 -Scope::allocate(Variable *var)
1.191 -{
1.192 - if (!var->unallocated())
1.193 - return;
1.194 -
1.195 - if (kind() == GLOBAL) {
1.196 - var->allocate(Variable::ENVIRONMENT, envVars_.length());
1.197 - envVars_.append(var);
1.198 - } else {
1.199 - var->allocate(Variable::STACK, maxContainedLocals_ + locals_);
1.200 - locals_++;
1.201 - }
1.202 -}
1.203 -
1.204 -void
1.205 -Scope::allocate()
1.206 -{
1.207 - maxContainedLocals_ = 0;
1.208 - for (size_t i = 0; i < children_.length(); i++) {
1.209 - Scope *scope = children_[i];
1.210 - scope->allocate();
1.211 - if (scope->maxContainedLocals() > maxContainedLocals_)
1.212 - maxContainedLocals_ = scope->maxContainedLocals();
1.213 - }
1.214 -
1.215 - for (size_t i = 0; i < parameters_.length(); i++)
1.216 - parameters_[i]->allocate(Variable::PARAMETER, i);
1.217 -
1.218 - if (lifoSlot_)
1.219 - allocate(lifoSlot_);
1.220 - for (size_t i = 0; i < names_.length(); i++) {
1.221 - if (names_[i]->kind() != BoundName::VARIABLE)
1.222 - continue;
1.223 -
1.224 - allocate(names_[i]->toVariable());
1.225 - }
1.226 -
1.227 - maxContainedLocals_ += locals_;
1.228 -}
1.229 -
1.230 -bool
1.231 -Scope::Bind(CompileContext &cc, ParseTree *tree)
1.232 -{
1.233 - Local<String> name(ZONE());
1.234 - for (size_t i = 0; i < tree->unbound()->length(); i++) {
1.235 - NameProxy *proxy = tree->unbound()->at(i);
1.236 - name = proxy->name();
1.237 - BoundName *binding = tree->scope()->lookup(name);
1.238 -
1.239 - if (!binding) {
1.240 - cc.reportError(proxy->pos(), Message_IdentifierNotFound, name->chars());
1.241 - return false;
1.242 - }
1.243 -
1.244 - // We only allow global functions to be late-bound.
1.245 - if (binding->kind() != BoundName::FUNCTION ||
1.246 - binding->scope()->kind() != Scope::GLOBAL)
1.247 - {
1.248 - cc.reportError(proxy->pos(), Message_IdentifierNotFound, name->chars());
1.249 - return false;
1.250 - }
1.251 -
1.252 - proxy->bind(binding);
1.253 -
1.254 - // Find the function the proxy is defined in.
1.255 - }
1.256 - return true;
1.257 -}
1.258 -
1.259 -void
1.260 -Scope::Allocate(ParseTree *tree)
1.261 -{
1.262 - tree->scope()->allocateGlobals();
1.263 -}
1.264 -
1.265 -void
1.266 -Scope::setUsesLifoHeap()
1.267 -{
1.268 - // Only one lifo slot is needed per scope.
1.269 - if (lifoSlot_)
1.270 - return;
1.271 -
1.272 - // If the parent of this scope is the function scope, then this is the
1.273 - // function's block scope, and the lifo slot is part of the Frame instead.
1.274 - // Note we can get a function scope here if we're making a temporary in a
1.275 - // function with no local variables.
1.276 - if (kind() == FUNCTION || enclosing()->kind() == FUNCTION)
1.277 - return;
1.278 -
1.279 - Local<Type> type(ZONE(), ZONE()->types()->getPrimitive(PrimitiveType_Native));
1.280 - if (!type)
1.281 - return;
1.282 -
1.283 - Local<String> name(ZONE());
1.284 - lifoSlot_ = new (pool_) Variable(this, name, SourcePosition());
1.285 - lifoSlot_->setType(type);
1.286 -}
1.287 -
1.288 -EnvironmentMap *
1.289 -Scope::createEnvironmentMap(Zone *zone)
1.290 -{
1.291 - return EnvironmentMap::New(zone, envVars_.length(), envVars_.buffer());
1.292 -}