1.1 --- a/src/compiler/NameBinding.cpp Mon Jun 10 00:46:29 2013 +0100
1.2 +++ b/src/compiler/NameBinding.cpp Mon Jun 10 01:04:43 2013 +0100
1.3 @@ -1,1297 +1,1297 @@
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 SourcePawn.
1.9 - *
1.10 - * SourcePawn 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 - * SourcePawn 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 - * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.21 - */
1.22 -#include "../Strings.h"
1.23 -#include "../Zone.h"
1.24 -#include "../TypeManager.h"
1.25 -#include "NameBinding.h"
1.26 -#include "Scopes.h"
1.27 -#include "ConstantEvaluator.h"
1.28 -#include "../Spaces-inl.h"
1.29 -#include "../Heap-inl.h"
1.30 -
1.31 -using namespace ke;
1.32 -
1.33 -// Create symbol tables and symbols for every scope and declaration. For type
1.34 -// declarations and methods, we also pre-allocate a Type object, so that
1.35 -// circular dependencies between types will work.
1.36 -class NamePopulator : public AstVisitor
1.37 -{
1.38 - private:
1.39 - // This class is analagous to a Scope, however, it allows us to create
1.40 - // scopes lazily. If a scope is requested, and the current environment
1.41 - // has no scope, then a scope is created. If no scope is ever requested,
1.42 - // a scope does not need to be created.
1.43 - class SymbolEnv
1.44 - {
1.45 - public:
1.46 - SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
1.47 - : envp_(prevp),
1.48 - prev_(*prevp),
1.49 - scope_(scope)
1.50 - {
1.51 - *envp_ = this;
1.52 - }
1.53 - ~SymbolEnv() {
1.54 - *envp_ = prev_;
1.55 - }
1.56 -
1.57 - Scope *scope() {
1.58 - return scope_;
1.59 - }
1.60 - void setScope(Scope *scope) {
1.61 - assert(!scope_);
1.62 - scope_ = scope;
1.63 - }
1.64 - SymbolEnv *prev() const {
1.65 - return prev_;
1.66 - }
1.67 -
1.68 - private:
1.69 - SymbolEnv **envp_;
1.70 - SymbolEnv *prev_;
1.71 - Scope *scope_;
1.72 - };
1.73 -
1.74 - enum ReturnStatus {
1.75 - NoReturn,
1.76 - VoidReturn,
1.77 - ValueReturn
1.78 - };
1.79 -
1.80 - class FunctionScope
1.81 - {
1.82 - public:
1.83 - FunctionScope(FunctionScope **prevp)
1.84 - : prevp_(prevp),
1.85 - prev_(*prevp),
1.86 - status_(NoReturn)
1.87 - {
1.88 - *prevp_ = this;
1.89 - }
1.90 - ~FunctionScope() {
1.91 - *prevp_ = prev_;
1.92 - }
1.93 - ReturnStatus returns() const {
1.94 - return status_;
1.95 - }
1.96 - void returns(ReturnStatus status) {
1.97 - if (status > status_)
1.98 - status_ = status;
1.99 - }
1.100 - private:
1.101 - FunctionScope **prevp_;
1.102 - FunctionScope *prev_;
1.103 - ReturnStatus status_;
1.104 - };
1.105 -
1.106 - public:
1.107 - NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.108 - : zone_(zone),
1.109 - pool_(zone->pool()),
1.110 - cc_(cc),
1.111 - unit_(unit),
1.112 - env_(NULL),
1.113 - fun_(NULL)
1.114 - {
1.115 - }
1.116 -
1.117 - void analyze() {
1.118 - ImportScope *importScope = ImportScope::New(pool_);
1.119 - if (!importScope)
1.120 - return;
1.121 -
1.122 - // At the import level, we declare system types.
1.123 - if (!declareSystemTypes(importScope))
1.124 - return;
1.125 -
1.126 - GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
1.127 - if (!globalScope)
1.128 - return;
1.129 -
1.130 - unit_->setImportScope(importScope);
1.131 - unit_->setGlobalScope(globalScope);
1.132 -
1.133 - SymbolEnv env(&env_, globalScope);
1.134 -
1.135 - for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.136 - Statement *stmt = unit_->tree()->statements()->at(i);
1.137 - stmt->accept(this);
1.138 - }
1.139 -
1.140 - return;
1.141 - }
1.142 -
1.143 - bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> effective) {
1.144 - Local<String> tag(zone_, zone_->makeSymbol(name));
1.145 - if (!tag)
1.146 - return false;
1.147 -
1.148 - Local<Type> type(zone_, zone_->types()->getType());
1.149 -
1.150 - TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type, effective);
1.151 - return scope->addSymbol(sym);
1.152 - }
1.153 -
1.154 - bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
1.155 - Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
1.156 - assert(primitive);
1.157 - return declareSystemType(scope, name, primitive);
1.158 - }
1.159 -
1.160 - bool declareSystemTypes(ImportScope *scope) {
1.161 - if (!declareSystemType(scope, "float", PrimitiveType_Float))
1.162 - return false;
1.163 - if (!declareSystemType(scope, "_", PrimitiveType_Int32))
1.164 - return false;
1.165 - if (!declareSystemType(scope, "int", PrimitiveType_Int32))
1.166 - return false;
1.167 - if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
1.168 - return false;
1.169 - if (!declareSystemType(scope, "char", PrimitiveType_Char))
1.170 - return false;
1.171 -
1.172 - Local<Type> voidType(zone_, zone_->types()->getVoid());
1.173 - if (!declareSystemType(scope, "void", voidType))
1.174 - return false;
1.175 -
1.176 - return true;
1.177 - }
1.178 -
1.179 - void visitVariableDeclaration(VariableDeclaration *node) {
1.180 - Scope *scope = env_->scope();
1.181 - if (!scope || scope->kind() != Scope::GLOBAL) {
1.182 - if ((scope = getOrCreateBlockScope()) == NULL)
1.183 - return;
1.184 - }
1.185 -
1.186 - if (scope->kind() == Scope::GLOBAL) {
1.187 - // The symbol must be added now, since it could be an export.
1.188 - VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
1.189 - node->setSymbol(sym);
1.190 -
1.191 - if (!registerName(scope, sym))
1.192 - return;
1.193 - } else {
1.194 - // We ensure the scope will exist at the name binding phase, but
1.195 - // we don't actually register the variable symbol yet. Otherwise,
1.196 - // when binding the initializer, we could encounter:
1.197 - // new x = x;
1.198 - //
1.199 - // And we don't necessarily want this to bind.
1.200 - }
1.201 -
1.202 - if (node->initialization())
1.203 - node->initialization()->accept(this);
1.204 - }
1.205 -
1.206 - void visitEnumStatement(EnumStatement *node) {
1.207 - Local<String> name(zone_, node->name());
1.208 - Local<Type> type(zone_);
1.209 - if (name)
1.210 - type = zone_->types()->newEnum(name);
1.211 - else
1.212 - type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.213 -
1.214 - if (!type)
1.215 - return;
1.216 -
1.217 - Scope *scope = getGlobalOrCreateBlockScope();
1.218 - if (!scope)
1.219 - return;
1.220 -
1.221 - if (name) {
1.222 - Local<Type> symType(zone_, zone_->types()->getType());
1.223 - TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, symType, type);
1.224 - if (!registerName(scope, sym))
1.225 - return;
1.226 -
1.227 - if (scope->kind() == Scope::GLOBAL) {
1.228 - if (!unit_->globalScope()->exported()->append(sym))
1.229 - return;
1.230 - }
1.231 - }
1.232 -
1.233 - // We want each field of the expression to qualify as a constant expression.
1.234 - if ((type = zone_->types()->qualify(type, TypeQual_ConstExpr)) == NULL)
1.235 - return;
1.236 -
1.237 - int value = 0;
1.238 - for (size_t i = 0; i < node->entries()->length(); i++) {
1.239 - EnumStatement::Entry &entry = node->entries()->at(i);
1.240 - BoxedPrimitive box = BoxedPrimitive::Int(value);
1.241 - if (entry.expr) {
1.242 - if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
1.243 - cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1.244 - return;
1.245 - }
1.246 -
1.247 - assert(box.type() == PrimitiveType_Int32);
1.248 - value = box.toInt();
1.249 - }
1.250 -
1.251 - ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
1.252 - if (!registerName(scope, sym))
1.253 - return;
1.254 - if (scope->kind() == Scope::GLOBAL) {
1.255 - if (!unit_->globalScope()->exported()->append(sym))
1.256 - return;
1.257 - }
1.258 -
1.259 - entry.sym = sym;
1.260 - value++;
1.261 - }
1.262 - }
1.263 -
1.264 - void visitFunctionStatement(FunctionStatement *node) {
1.265 - // We create function types ahead of time, not for any particular
1.266 - // reason. It makes things consistent with FunctionTypeStatement,
1.267 - // which actually does produce a type.
1.268 - Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
1.269 - if (!type)
1.270 - return;
1.271 -
1.272 - assert(env_->scope());
1.273 -
1.274 - // Function statements are always named, so add the name to the outer scope.
1.275 - FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
1.276 - if (!registerName(env_->scope(), sym))
1.277 - return;
1.278 -
1.279 - if (node->token() == TOK_PUBLIC ||
1.280 - node->token() == TOK_FORWARD ||
1.281 - node->token() == TOK_NATIVE)
1.282 - {
1.283 - // We're in the global scope, for sure.
1.284 - assert(env_->scope()->kind() == Scope::GLOBAL);
1.285 -
1.286 - if (!unit_->globalScope()->exported()->append(sym))
1.287 - return;
1.288 - }
1.289 -
1.290 - node->setSymbol(sym);
1.291 -
1.292 - // Scope for the function's arguments.
1.293 - SymbolEnv argEnv(&env_);
1.294 - if (!registerArguments(node->signature()))
1.295 - return;
1.296 -
1.297 - // Scope for function body.
1.298 - SymbolEnv localEnv(&env_);
1.299 - FunctionScope fun(&fun_);
1.300 - if (node->body())
1.301 - node->body()->accept(this);
1.302 -
1.303 - // Function statements have quirky semantics around their return
1.304 - // type. For reasonable compatibility with SP1, we use the following
1.305 - // heuristics for when no explicit type is declared.
1.306 - if (!node->signature().returnType()) {
1.307 - Local<Type> type(zone_);
1.308 - if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
1.309 - // If the function type is a native or forward, we always
1.310 - // assume it returns an int32.
1.311 - type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.312 - } else if (fun.returns() != ValueReturn) {
1.313 - // This function never returns a value, so mark it as
1.314 - // returning void.
1.315 - type = zone_->types()->getVoid();
1.316 - }
1.317 - // No need to NULL check here, we'll catch OOM later.
1.318 - node->sym()->type()->setReturnType(type);
1.319 - }
1.320 -
1.321 - node->setScopes(argEnv.scope(), localEnv.scope());
1.322 - }
1.323 -
1.324 - void visitStructureStatement(StructureStatement *node) {
1.325 - assert(false);
1.326 - }
1.327 -
1.328 - void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
1.329 - assert(false);
1.330 - }
1.331 -
1.332 - void visitNameProxy(NameProxy *name) {
1.333 - }
1.334 - void visitAssignment(Assignment *node) {
1.335 - node->lvalue()->accept(this);
1.336 - node->expression()->accept(this);
1.337 - }
1.338 - void visitBinaryExpression(BinaryExpression *node) {
1.339 - node->left()->accept(this);
1.340 - node->right()->accept(this);
1.341 - }
1.342 - void visitReturnStatement(ReturnStatement *node) {
1.343 - if (node->expression())
1.344 - fun_->returns(ValueReturn);
1.345 - else
1.346 - fun_->returns(VoidReturn);
1.347 - }
1.348 - void visitForStatement(ForStatement *node) {
1.349 - SymbolEnv env(&env_);
1.350 -
1.351 - if (node->initialization())
1.352 - node->initialization()->accept(this);
1.353 - if (node->condition())
1.354 - node->condition()->accept(this);
1.355 - if (node->update())
1.356 - node->update()->accept(this);
1.357 - node->body()->accept(this);
1.358 -
1.359 - node->setScope(env.scope());
1.360 - }
1.361 - void visitBlockStatement(BlockStatement *node) {
1.362 - if (node->type() == TOK_NEW) {
1.363 - // Don't create a symbol environment for this block, since it
1.364 - // was created solely to house multiple variable decls.
1.365 - for (size_t i = 0; i < node->statements()->length(); i++)
1.366 - node->statements()->at(i)->accept(this);
1.367 - } else {
1.368 - assert(node->type() == TOK_LBRACE);
1.369 -
1.370 - SymbolEnv env(&env_);
1.371 -
1.372 - for (size_t i = 0; i < node->statements()->length(); i++)
1.373 - node->statements()->at(i)->accept(this);
1.374 -
1.375 - if (node->type() == TOK_NEW) {
1.376 - assert(!env.scope());
1.377 - return;
1.378 - }
1.379 -
1.380 - node->setScope(env.scope());
1.381 - }
1.382 - }
1.383 - void visitIntegerLiteral(IntegerLiteral *node) {
1.384 - }
1.385 - void visitExpressionStatement(ExpressionStatement *node) {
1.386 - node->expression()->accept(this);
1.387 - }
1.388 - void visitCallExpression(CallExpression *node) {
1.389 - node->callee()->accept(this);
1.390 - for (size_t i = 0; i < node->arguments()->length(); i++)
1.391 - node->arguments()->at(i)->accept(this);
1.392 - }
1.393 - void visitIfStatement(IfStatement *node) {
1.394 - node->ifTrue()->accept(this);
1.395 - if (node->ifFalse())
1.396 - node->ifFalse()->accept(this);
1.397 - }
1.398 - void visitIndexExpression(IndexExpression *node) {
1.399 - node->left()->accept(this);
1.400 - node->right()->accept(this);
1.401 - }
1.402 - void visitFloatLiteral(FloatLiteral *node) {
1.403 - }
1.404 - void visitWhileStatement(WhileStatement *node) {
1.405 - node->condition()->accept(this);
1.406 - node->body()->accept(this);
1.407 - }
1.408 - void visitBreakStatement(BreakStatement *node) {
1.409 - }
1.410 - void visitContinueStatement(ContinueStatement *node) {
1.411 - }
1.412 - void visitStringLiteral(StringLiteral *node) {
1.413 - }
1.414 - void visitIncDecExpression(IncDecExpression *node) {
1.415 - node->expression()->accept(this);
1.416 - }
1.417 - void visitUnaryExpression(UnaryExpression *node) {
1.418 - node->expression()->accept(this);
1.419 - }
1.420 - void visitTernaryExpression(TernaryExpression *node) {
1.421 - assert(false);
1.422 - }
1.423 - void visitBooleanLiteral(BooleanLiteral *node) {
1.424 - }
1.425 - void visitFieldExpression(FieldExpression *node) {
1.426 - }
1.427 - void visitSwitchStatement(SwitchStatement *node) {
1.428 - if (node->defaultCase())
1.429 - node->defaultCase()->accept(this);
1.430 -
1.431 - for (size_t i = 0; i < node->cases()->length(); i++)
1.432 - node->cases()->at(i)->statement()->accept(this);
1.433 - }
1.434 - void visitArrayLiteral(ArrayLiteral *node) {
1.435 - }
1.436 - void visitImportStatement(ImportStatement *node) {
1.437 - }
1.438 -
1.439 - private:
1.440 - Scope *getGlobalOrCreateBlockScope() {
1.441 - if (env_->scope()) {
1.442 - assert(env_->scope()->kind() == Scope::BLOCK ||
1.443 - env_->scope()->kind() == Scope::GLOBAL);
1.444 - return env_->scope();
1.445 - }
1.446 - return getOrCreateBlockScope();
1.447 - }
1.448 - Scope *getOrCreateBlockScope() {
1.449 - if (env_->scope()) {
1.450 - assert(env_->scope()->kind() == Scope::BLOCK);
1.451 - return env_->scope();
1.452 - }
1.453 -
1.454 - LocalScope *scope = LocalScope::New(pool_);
1.455 - if (!scope)
1.456 - return NULL;
1.457 -
1.458 - env_->setScope(scope);
1.459 - return scope;
1.460 - }
1.461 -
1.462 - bool registerName(Scope *scope, Symbol *sym) {
1.463 - if (!scope)
1.464 - return false;
1.465 -
1.466 - if (Symbol *other = scope->localLookup(sym->name())) {
1.467 - // Report, but allow errors to continue.
1.468 - cc_.reportError(sym->pos(), Message_RedeclaredName,
1.469 - sym->name()->chars(),
1.470 - other->pos().line,
1.471 - other->pos().col);
1.472 - return true;
1.473 - }
1.474 -
1.475 - return scope->addSymbol(sym);
1.476 - }
1.477 -
1.478 - bool registerArguments(const FunctionSignature &sig) {
1.479 - if (!sig.parameters()->length())
1.480 - return true;
1.481 -
1.482 - ArgumentScope *argScope = ArgumentScope::New(pool_);
1.483 - if (!argScope)
1.484 - return false;
1.485 - env_->setScope(argScope);
1.486 -
1.487 - for (size_t i = 0; i < sig.parameters()->length(); i++) {
1.488 - Parameter *param = sig.parameters()->at(i);
1.489 - VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
1.490 - if (!registerName(env_->scope(), sym))
1.491 - return false;
1.492 - param->setSymbol(sym);
1.493 - }
1.494 -
1.495 - return true;
1.496 - }
1.497 -
1.498 - private:
1.499 - Zone *zone_;
1.500 - PoolAllocator &pool_;
1.501 - CompileContext &cc_;
1.502 - TranslationUnit *unit_;
1.503 - SymbolEnv *env_;
1.504 - FunctionScope *fun_;
1.505 -};
1.506 -
1.507 -void
1.508 -ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.509 -{
1.510 - AutoEnterCompileContext enter(cc, unit);
1.511 - NamePopulator populator(zone, cc, unit);
1.512 - populator.analyze();
1.513 -}
1.514 -
1.515 -static const int INFER_ARRAY_SIZE = 0;
1.516 -static const int EVAL_ARRAY_SIZE = -1;
1.517 -static const int DYNAMIC_ARRAY_SIZE = -2;
1.518 -
1.519 -class NameBinderBase : public AstVisitor
1.520 -{
1.521 - public:
1.522 - NameBinderBase(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.523 - : zone_(zone),
1.524 - pool_(zone->pool()),
1.525 - cc_(cc),
1.526 - unit_(unit)
1.527 - {
1.528 - }
1.529 -
1.530 - protected:
1.531 - Type *buildVariableType(VariableDeclaration *node) {
1.532 - Local<Type> type(zone_, bindType(node->type(), node->quals()));
1.533 - if (!type)
1.534 - return NULL;
1.535 -
1.536 - // We don't allow array typedefs yet.
1.537 - assert(!type->isArray());
1.538 -
1.539 - if (node->dims()) {
1.540 - int dims[MAX_ARRAY_DEPTH];
1.541 - int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
1.542 - if (levels < 0)
1.543 - return NULL;
1.544 -
1.545 - // Do some extra inference based on the initializer, if present.
1.546 - Expression *init = node->initialization();
1.547 - if (init) {
1.548 - if (init->isArrayLiteral() && init->toArrayLiteral()->isFixed()) {
1.549 - Local<Type> contained(zone_, type->isArray()
1.550 - ? ArrayType::cast(type)->contained()
1.551 - : type);
1.552 - if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
1.553 - return NULL;
1.554 - } else if (init->isStringLiteral()) {
1.555 - dims[levels - 1] = init->toStringLiteral()->string()->length() + 1;
1.556 - }
1.557 - }
1.558 -
1.559 - // If we got extra dimensions, we need to build a new type.
1.560 - if (node->dims()) {
1.561 - if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
1.562 - return NULL;
1.563 - }
1.564 - }
1.565 -
1.566 - return type;
1.567 - }
1.568 -
1.569 - int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
1.570 - unsigned level = 0;
1.571 - Local<Type> type(zone_, typeArg);
1.572 - while (type->isArray()) {
1.573 - ArrayType *atype = ArrayType::cast(type);
1.574 - dims[level] = atype->isFixedLength()
1.575 - ? atype->fixedLength()
1.576 - : DYNAMIC_ARRAY_SIZE;
1.577 - type = atype->contained();
1.578 - level++;
1.579 - }
1.580 -
1.581 - if (!exprs)
1.582 - return level;
1.583 -
1.584 - if (level + exprs->length() > MAX_ARRAY_DEPTH) {
1.585 - cc_.reportError(pos, Message_MaximumArrayDepth);
1.586 - return -1;
1.587 - }
1.588 -
1.589 - bool hadEmptySize = false;
1.590 - for (size_t i = 0; i < exprs->length(); i++) {
1.591 - Expression *expr = exprs->at(i);
1.592 - if (!expr) {
1.593 - dims[i] = INFER_ARRAY_SIZE;
1.594 - hadEmptySize = true;
1.595 - continue;
1.596 - }
1.597 -
1.598 - BoxedPrimitive box;
1.599 - if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
1.600 - int size = box.toInt();
1.601 - if (size <= 0) {
1.602 - cc_.reportError(expr->pos(), Message_BadArraySize);
1.603 - return false;
1.604 - }
1.605 -
1.606 - dims[i] = size;
1.607 - continue;
1.608 - }
1.609 -
1.610 - if (hadEmptySize) {
1.611 - cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
1.612 - return false;
1.613 - }
1.614 -
1.615 - dims[i] = EVAL_ARRAY_SIZE;
1.616 - }
1.617 -
1.618 - return level + exprs->length();
1.619 - }
1.620 -
1.621 - // This function computes missing dimension sizes based on a literal
1.622 - // initializer. We don't really handle any size rules here; we just
1.623 - // do a really dumb inference.
1.624 - bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
1.625 - for (int i = 0; i < levels; i++) {
1.626 - if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
1.627 - // The following are invalid:
1.628 - // new x[<expr>] = {...}
1.629 - // new Type:x = {...} // where Type is a non-fixed array type
1.630 - cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
1.631 - return false;
1.632 - }
1.633 -
1.634 - if (dims[i] == INFER_ARRAY_SIZE) {
1.635 - // Character arrays are always dynamic when inferred from string literals.
1.636 - if (i == levels - 1 && contained->isChar())
1.637 - dims[i] = DYNAMIC_ARRAY_SIZE;
1.638 - else
1.639 - dims[i] = lit->expressions()->length();
1.640 - }
1.641 -
1.642 - if (i != levels - 1) {
1.643 - // Fixed array literals are guaranteed to have at least one expression.
1.644 - Expression *next = lit->expressions()->at(0);
1.645 - if (!next->isArrayLiteral()) {
1.646 - // Whelp... this array is just malformed. Not the best error message
1.647 - // but whatever.
1.648 - cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
1.649 - return false;
1.650 - }
1.651 - lit = next->toArrayLiteral();
1.652 - }
1.653 - }
1.654 -
1.655 - return true;
1.656 - }
1.657 -
1.658 - ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
1.659 - Local<Type> type(zone_, contained);
1.660 -
1.661 - for (size_t i = postlevels - 1; i < postlevels; i--) {
1.662 - int size = dims[i] > 0
1.663 - ? dims[i]
1.664 - : ArrayType::DYNAMIC_ARRAY_SIZE;
1.665 -
1.666 - if ((type = zone_->types()->newArray(contained, size)) == NULL)
1.667 - return NULL;
1.668 - if ((type = zone_->types()->qualify(type, quals)) == NULL)
1.669 - return NULL;
1.670 - }
1.671 - return ArrayType::cast(type);
1.672 - }
1.673 -
1.674 - bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
1.675 - Local<Type> type(zone_);
1.676 - if (!fun->returnType()) {
1.677 - if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
1.678 - return false;
1.679 - fun->setReturnType(type);
1.680 - }
1.681 -
1.682 - if (sig.variadic())
1.683 - fun->setVariadic();
1.684 -
1.685 - Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
1.686 - if (!params)
1.687 - return false;
1.688 -
1.689 - for (size_t i = 0; i < sig.parameters()->length(); i++) {
1.690 - Parameter *param = sig.parameters()->at(i);
1.691 - if ((type = bindType(param->type(), param->quals())) == NULL)
1.692 - return false;
1.693 -
1.694 - assert(!type->isArray());
1.695 -
1.696 - if (param->dims()) {
1.697 - int dims[MAX_ARRAY_DEPTH];
1.698 - int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
1.699 - if (levels < 0)
1.700 - return false;
1.701 -
1.702 - // If we got extra dimensions, we need to build a new type.
1.703 - // Unlike variables, we do not infer anything about array
1.704 - // sizes from its default initializer.
1.705 - if (param->dims()) {
1.706 - if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
1.707 - return false;
1.708 - }
1.709 -
1.710 - if (ArrayType::cast(type)->innermost()->isVoid()) {
1.711 - cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
1.712 - return false;
1.713 - }
1.714 - }
1.715 -
1.716 - if (param->reference()) {
1.717 - if (!type->isPod()) {
1.718 - cc_.reportError(param->pos(), Message_ArrayCantBeReference);
1.719 - return false;
1.720 - }
1.721 - if (param->quals() & TypeQual_Const) {
1.722 - cc_.reportError(param->pos(), Message_CannotConstReference);
1.723 - return false;
1.724 - }
1.725 - if ((type = zone_->types()->getReference(type, false)) == NULL)
1.726 - return false;
1.727 - }
1.728 - if (param->quals() & TypeQual_Const) {
1.729 - if (!type->isArray() && !type->isStruct()) {
1.730 - cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
1.731 - return false;
1.732 - }
1.733 - }
1.734 -
1.735 - if (type->isVoid()) {
1.736 - cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
1.737 - return false;
1.738 - }
1.739 -
1.740 - params->set(zone_, i, type);
1.741 - param->sym()->setType(type);
1.742 - }
1.743 -
1.744 - fun->setParameterTypes(params);
1.745 -
1.746 - return true;
1.747 - }
1.748 -
1.749 - Type *bindType(Expression *expr, TypeQualifiers quals) {
1.750 - Local<Type> type(zone_);
1.751 -
1.752 - if (!expr) {
1.753 - // If no type was declared, we return int32.
1.754 - type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.755 - } else {
1.756 - expr->accept(this);
1.757 -
1.758 - NameProxy *proxy = expr->asNameProxy();
1.759 - assert(proxy);
1.760 -
1.761 - Symbol *sym = proxy->sym();
1.762 - if (!sym)
1.763 - return NULL;
1.764 -
1.765 - if (!sym->isType()) {
1.766 - cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
1.767 - return NULL;
1.768 - }
1.769 -
1.770 - type = sym->toType()->effective();
1.771 - }
1.772 -
1.773 - return zone_->types()->qualify(type, quals);
1.774 - }
1.775 -
1.776 - protected:
1.777 - Zone *zone_;
1.778 - PoolAllocator &pool_;
1.779 - CompileContext &cc_;
1.780 - TranslationUnit *unit_;
1.781 -};
1.782 -
1.783 -class GlobalBuilder : public NameBinderBase
1.784 -{
1.785 - typedef ScopedRoot<Descriptor> ScopedDescriptor;
1.786 - struct PrimitiveFill {
1.787 - ScopedDescriptor *desc;
1.788 - BoxedPrimitive prim;
1.789 -
1.790 - PrimitiveFill(ScopedDescriptor *desc, BoxedPrimitive prim)
1.791 - : desc(desc),
1.792 - prim(prim)
1.793 - {
1.794 - }
1.795 - };
1.796 -
1.797 - public:
1.798 - GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.799 - : NameBinderBase(zone, cc, unit),
1.800 - globalScope_(unit->globalScope())
1.801 - {
1.802 - }
1.803 -
1.804 - Struct *build() {
1.805 - for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
1.806 - unit_->tree()->imports()->at(i)->accept(this);
1.807 -
1.808 - // Next, enter the global scope and walk all statements.
1.809 - for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.810 - Statement *stmt = unit_->tree()->statements()->at(i);
1.811 - stmt->accept(this);
1.812 - }
1.813 -
1.814 - Local<Struct> globals(zone_, createGlobals());
1.815 - if (!globals)
1.816 - return NULL;
1.817 -
1.818 - populate(globals);
1.819 -
1.820 - return globals;
1.821 - }
1.822 -
1.823 - private:
1.824 - Struct *createGlobals() {
1.825 - Local<FixedArray> descs(zone_, FixedArray::New(zone_, descriptors_.length(), Heap::Tenure_Old));
1.826 - if (!descs)
1.827 - return NULL;
1.828 -
1.829 - for (unsigned i = 0; i < descriptors_.length(); i++)
1.830 - descs->set(zone_, i, *descriptors_[i]);
1.831 -
1.832 - Local<String> name(zone_, unit_->module()->name());
1.833 - Local<StructType> type(zone_, StructType::New(zone_, name, descs));
1.834 - if (!type)
1.835 - return NULL;
1.836 -
1.837 - Local<StructMap> map(zone_, type->newMap());
1.838 - return Struct::New(zone_, map, Heap::Tenure_Old);
1.839 - }
1.840 -
1.841 - void populate(Handle<Struct> globals) {
1.842 - // This is a huge hack, but it's probably better than a full extra
1.843 - // pass. The problem is that until we have all the descriptors, we
1.844 - // can't start setting constexprs in the struct, and we need to set
1.845 - // them now so they're available during full semantic analysis. To
1.846 - // work around this, we build up the list of values we need to set
1.847 - // as we build up descriptors, and then populate the global struct
1.848 - // with this set.
1.849 - //
1.850 - // Note, this code is also kind of dead until we support linking. We
1.851 - // handle constexprs explicitly in importFrom(), by sniffing out the
1.852 - // symbol type. That code will go away later.
1.853 - for (size_t i = 0; i < primitiveFills_.length(); i++) {
1.854 - const PrimitiveFill &fill = primitiveFills_[i];
1.855 - assert(fill.prim.type() == PrimitiveType_Int32);
1.856 - globals->set(*fill.desc, fill.prim.toInt());
1.857 - }
1.858 - }
1.859 -
1.860 - public:
1.861 - void visitEnumStatement(EnumStatement *stmt) {
1.862 - if (stmt->visibility() != TOK_PUBLIC || !stmt->name())
1.863 - return;
1.864 -
1.865 - Local<Type> type(zone_, zone_->types()->getType());
1.866 - Descriptor *desc = Descriptor::New(zone_, stmt->name(), type, Descriptor::Public);
1.867 - if (!desc)
1.868 - return;
1.869 - if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.870 - return;
1.871 -
1.872 - for (size_t i = 0; i < stmt->entries()->length(); i++) {
1.873 - EnumStatement::Entry &e = stmt->entries()->at(i);
1.874 - ScopedDescriptor *desc = new (pool_) ScopedDescriptor(Descriptor::New(zone_, e.name, e.sym->type(), Descriptor::Public));
1.875 - if (!desc || !descriptors_.append(desc))
1.876 - return;
1.877 -
1.878 - // Save the value so we can export it immediately.
1.879 - if (!primitiveFills_.append(PrimitiveFill(desc, e.sym->value())))
1.880 - return;
1.881 - }
1.882 - }
1.883 -
1.884 - void visitNameProxy(NameProxy *proxy) {
1.885 - Scope *scope = unit_->globalScope();
1.886 - Symbol *sym = scope->lookup(proxy->name());
1.887 - if (!sym)
1.888 - cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
1.889 - proxy->bind(sym);
1.890 - }
1.891 -
1.892 - void visitFunctionStatement(FunctionStatement *node) {
1.893 - Local<FunctionType> type(zone_, node->sym()->type());
1.894 - if (!fillFunctionType(type, node->signature()))
1.895 - return;
1.896 -
1.897 - unsigned offset;
1.898 - if (!builder_.add(type, &offset))
1.899 - return;
1.900 -
1.901 - Descriptor::Visibility visibility = (node->token() == TOK_NATIVE || node->token() == TOK_FORWARD)
1.902 - ? Descriptor::Public
1.903 - : Descriptor::Private;
1.904 -
1.905 - Descriptor *desc = Descriptor::New(zone_, node->name(), type, visibility);
1.906 - if (!desc)
1.907 - return;
1.908 - if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.909 - return;
1.910 - }
1.911 -
1.912 - void visitVariableDeclaration(VariableDeclaration *node) {
1.913 - Local<Type> type(zone_, buildVariableType(node));
1.914 - if (!type)
1.915 - return;
1.916 -
1.917 - // If we're in global scope, and we received a |const| qualifier, then
1.918 - // we extend this to array references as well. This is to sort of mimic
1.919 - // SP1 functionality, but also means that you cannot have changeable
1.920 - // const pointers in global scope.
1.921 - if ((node->quals() & TypeQual_Const) && type->isArray()) {
1.922 - if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
1.923 - return;
1.924 - }
1.925 -
1.926 - node->sym()->setType(type);
1.927 -
1.928 - unsigned offset;
1.929 - if (!builder_.add(type, &offset))
1.930 - return;
1.931 -
1.932 - Descriptor *desc = Descriptor::New(zone_, node->name(), type, Descriptor::Private);
1.933 - if (!desc)
1.934 - return;
1.935 - if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.936 - return;
1.937 - }
1.938 -
1.939 - void visitImportStatement(ImportStatement *node) {
1.940 - if (!node->names()) {
1.941 - PathComponent *path = node->path();
1.942 - while (path->next)
1.943 - path = path->next;
1.944 -
1.945 - // Imports automatically go into the importScope. For now, we
1.946 - // error if there are any duplicate symbols entered into the
1.947 - // importScope.
1.948 - if (unit_->importScope()->localLookup(path->name)) {
1.949 - cc_.reportError(node->pos(), Message_DuplicateImport, path->name->chars());
1.950 - return;
1.951 - }
1.952 -
1.953 - Local<Type> type(zone_, zone_->types()->getImportable());
1.954 - ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
1.955 - if (!unit_->importScope()->addSymbol(sym))
1.956 - return;
1.957 - } else if (node->importAllNames()) {
1.958 - Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
1.959 - if (importable->isPackage()) {
1.960 - assert(false);
1.961 - } else {
1.962 - Local<Module> module(zone_, Module::cast(importable));
1.963 - if (!module->globals())
1.964 - importAllFromTranslationUnit(node, module->translationUnit());
1.965 - else
1.966 - assert(false);
1.967 - }
1.968 - } else {
1.969 - Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
1.970 - if (importable->isPackage()) {
1.971 - assert(false);
1.972 - } else {
1.973 - Local<Module> module(zone_, Module::cast(importable));
1.974 -
1.975 - // Always grab from the translation unit if we can, for now.
1.976 - if (module->translationUnit())
1.977 - importFromTranslationUnit(node, module->translationUnit());
1.978 - else
1.979 - assert(false);
1.980 - }
1.981 - }
1.982 - }
1.983 -
1.984 - private:
1.985 - bool importFrom(ImportStatement *node, Symbol *import) {
1.986 - assert(import->type());
1.987 -
1.988 - // Check for duplicate import names.
1.989 - if (unit_->importScope()->localLookup(import->name())) {
1.990 - cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
1.991 - return false;
1.992 - }
1.993 -
1.994 - Symbol *sym;
1.995 - if (import->isType()) {
1.996 - // Fuck it, make a TypeSymbol instead of an ImplicitSymbol. This
1.997 - // makes bindType() much simpler. We may run into problems
1.998 - // implementing linking, but it seems unlikely, as long as we are
1.999 - // exporting Types in module structs.
1.1000 - Local<Type> type(zone_, zone_->types()->getType());
1.1001 - sym = new (pool_) TypeSymbol(unit_->importScope(),
1.1002 - import->name(),
1.1003 - type,
1.1004 - import->toType()->effective());
1.1005 - } else if (import->isConstant()) {
1.1006 - // Same deal. No reason to lookup in the module globals if we
1.1007 - // already have a symbol.
1.1008 - sym = new (pool_) ConstantSymbol(unit_->importScope(),
1.1009 - import->name(),
1.1010 - node->pos(),
1.1011 - import->type(),
1.1012 - import->toConstant()->value());
1.1013 - } else {
1.1014 - sym = new (pool_) ImplicitSymbol(unit_->importScope(),
1.1015 - import->name(),
1.1016 - node->pos(),
1.1017 - import->type(),
1.1018 - node->importIndex());
1.1019 - }
1.1020 -
1.1021 - if (!unit_->importScope()->addSymbol(sym))
1.1022 - return false;
1.1023 -
1.1024 - return true;
1.1025 - }
1.1026 -
1.1027 - void importFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
1.1028 - assert(!other->failed());
1.1029 -
1.1030 - for (size_t i = 0; i < node->names()->length(); i++) {
1.1031 - Handle<String> name = *node->names()->at(i);
1.1032 -
1.1033 - // See if the name exists in the other translation unit.
1.1034 - Symbol *import = other->globalScope()->findExported(name);
1.1035 - if (!import) {
1.1036 - FixedArray *path = unit_->module()->importPathAt(node->importIndex());
1.1037 - cc_.reportError(node->pos(), Message_NotFoundInImportable,
1.1038 - name->chars(),
1.1039 - String::cast(path->at(path->length() - 1))->chars());
1.1040 - return;
1.1041 - }
1.1042 -
1.1043 - if (!importFrom(node, import))
1.1044 - return;
1.1045 - }
1.1046 - }
1.1047 -
1.1048 - void importAllFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
1.1049 - assert(!other->failed());
1.1050 -
1.1051 - for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
1.1052 - Symbol *import = other->globalScope()->exported()->at(i);
1.1053 - if (!importFrom(node, import))
1.1054 - return;
1.1055 - }
1.1056 - }
1.1057 -
1.1058 - private:
1.1059 - StructureBufferBuilder builder_;
1.1060 - Vector<ScopedRoot<Descriptor> *> descriptors_;
1.1061 - GlobalScope *globalScope_;
1.1062 - Vector<PrimitiveFill> primitiveFills_;
1.1063 -};
1.1064 -
1.1065 -class NameBinder : public NameBinderBase
1.1066 -{
1.1067 - public:
1.1068 - class AutoLinkScope
1.1069 - {
1.1070 - public:
1.1071 - AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
1.1072 - : prevp_(prevp),
1.1073 - prev_(*prevp),
1.1074 - scope_(scope)
1.1075 - {
1.1076 - if (scope_) {
1.1077 - *prevp_ = this;
1.1078 - if (prev_)
1.1079 - scope_->setParent(prev_->scope());
1.1080 - }
1.1081 - }
1.1082 - ~AutoLinkScope() {
1.1083 - if (scope_) {
1.1084 - assert(*prevp_ == this);
1.1085 - *prevp_ = prev_;
1.1086 - }
1.1087 - }
1.1088 - Scope *scope() const {
1.1089 - return scope_;
1.1090 - }
1.1091 -
1.1092 - private:
1.1093 - AutoLinkScope **prevp_;
1.1094 - AutoLinkScope *prev_;
1.1095 - Scope *scope_;
1.1096 - };
1.1097 -
1.1098 - public:
1.1099 - NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1100 - : NameBinderBase(zone, cc, unit),
1.1101 - link_(NULL)
1.1102 - {
1.1103 - }
1.1104 -
1.1105 - void bind() {
1.1106 - // Start with the import scope, and collect all imported names.
1.1107 - AutoLinkScope importScope(&link_, unit_->importScope());
1.1108 -
1.1109 - for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
1.1110 - unit_->tree()->imports()->at(i)->accept(this);
1.1111 -
1.1112 - // Next, enter the global scope and walk all statements.
1.1113 - AutoLinkScope globalScope(&link_, unit_->globalScope());
1.1114 - for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.1115 - Statement *stmt = unit_->tree()->statements()->at(i);
1.1116 - stmt->accept(this);
1.1117 - }
1.1118 - }
1.1119 -
1.1120 - void visitVariableDeclaration(VariableDeclaration *node) {
1.1121 - // Bind the initializer before registering the declaration, so that we
1.1122 - // can error on bogus initializers (new x = x).
1.1123 - if (node->initialization())
1.1124 - node->initialization()->accept(this);
1.1125 -
1.1126 - // If the node already has a symbol (meaning it was a global), then
1.1127 - // we don't have to do anything more.
1.1128 - if (node->sym())
1.1129 - return;
1.1130 -
1.1131 - Local<Type> type(zone_, buildVariableType(node));
1.1132 - if (!type)
1.1133 - return;
1.1134 -
1.1135 - VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
1.1136 - node->setSymbol(sym);
1.1137 -
1.1138 - if (Symbol *other = link_->scope()->localLookup(sym->name())) {
1.1139 - // Report, but allow errors to continue.
1.1140 - cc_.reportError(sym->pos(), Message_RedeclaredName,
1.1141 - sym->name()->chars(),
1.1142 - other->pos().line,
1.1143 - other->pos().col);
1.1144 - return;
1.1145 - }
1.1146 -
1.1147 - link_->scope()->addSymbol(sym);
1.1148 - }
1.1149 - void visitEnumStatement(EnumStatement *node) {
1.1150 - }
1.1151 - void visitFunctionStatement(FunctionStatement *node) {
1.1152 - AutoLinkScope argScope(&link_, node->argScope());
1.1153 - AutoLinkScope varScope(&link_, node->varScope());
1.1154 -
1.1155 - // If the function is in the global scope, we've already computed its
1.1156 - // type.
1.1157 - if (node->sym()->scope()->kind() != Scope::GLOBAL) {
1.1158 - Local<FunctionType> type(zone_, node->sym()->type());
1.1159 - if (!fillFunctionType(type, node->signature()))
1.1160 - return;
1.1161 - }
1.1162 -
1.1163 - if (node->body())
1.1164 - node->body()->accept(this);
1.1165 - }
1.1166 - void visitStructureStatement(StructureStatement *node) {
1.1167 - assert(false);
1.1168 - }
1.1169 - void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1.1170 - assert(false);
1.1171 - }
1.1172 -
1.1173 - void visitNameProxy(NameProxy *proxy) {
1.1174 - // We could have already bound globals.
1.1175 - if (proxy->sym())
1.1176 - return;
1.1177 -
1.1178 - Scope *scope = link_->scope();
1.1179 - Symbol *sym = scope->lookup(proxy->name());
1.1180 - if (!sym)
1.1181 - cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
1.1182 - proxy->bind(sym);
1.1183 - }
1.1184 - void visitAssignment(Assignment *node) {
1.1185 - node->lvalue()->accept(this);
1.1186 - node->expression()->accept(this);
1.1187 - }
1.1188 - void visitBinaryExpression(BinaryExpression *node) {
1.1189 - node->left()->accept(this);
1.1190 - node->right()->accept(this);
1.1191 - }
1.1192 - void visitReturnStatement(ReturnStatement *node) {
1.1193 - node->expression()->accept(this);
1.1194 - }
1.1195 - void visitForStatement(ForStatement *node) {
1.1196 - AutoLinkScope scope(&link_, node->scope());
1.1197 -
1.1198 - if (node->initialization())
1.1199 - node->initialization()->accept(this);
1.1200 - if (node->condition())
1.1201 - node->condition()->accept(this);
1.1202 - if (node->update())
1.1203 - node->update()->accept(this);
1.1204 - node->body()->accept(this);
1.1205 - }
1.1206 - void visitBlockStatement(BlockStatement *node) {
1.1207 - AutoLinkScope scope(&link_, node->scope());
1.1208 - for (size_t i = 0; i < node->statements()->length(); i++)
1.1209 - node->statements()->at(i)->accept(this);
1.1210 - }
1.1211 - void visitIntegerLiteral(IntegerLiteral *node) {
1.1212 - }
1.1213 - void visitExpressionStatement(ExpressionStatement *node) {
1.1214 - node->expression()->accept(this);
1.1215 - }
1.1216 - void visitCallExpression(CallExpression *node) {
1.1217 - node->callee()->accept(this);
1.1218 - for (size_t i = 0; i < node->arguments()->length(); i++)
1.1219 - node->arguments()->at(i)->accept(this);
1.1220 - }
1.1221 - void visitIfStatement(IfStatement *node) {
1.1222 - node->condition()->accept(this);
1.1223 - node->ifTrue()->accept(this);
1.1224 - if (node->ifFalse())
1.1225 - node->ifFalse()->accept(this);
1.1226 - }
1.1227 - void visitIndexExpression(IndexExpression *node) {
1.1228 - node->left()->accept(this);
1.1229 - node->right()->accept(this);
1.1230 - }
1.1231 - void visitFloatLiteral(FloatLiteral *node) {
1.1232 - }
1.1233 - void visitWhileStatement(WhileStatement *node) {
1.1234 - node->condition()->accept(this);
1.1235 - node->body()->accept(this);
1.1236 - }
1.1237 - void visitBreakStatement(BreakStatement *node) {
1.1238 - }
1.1239 - void visitContinueStatement(ContinueStatement *node) {
1.1240 - }
1.1241 - void visitStringLiteral(StringLiteral *node) {
1.1242 - }
1.1243 - void visitIncDecExpression(IncDecExpression *node) {
1.1244 - node->expression()->accept(this);
1.1245 - }
1.1246 - void visitUnaryExpression(UnaryExpression *node) {
1.1247 - if (node->tag())
1.1248 - node->tag()->accept(this);
1.1249 - node->expression()->accept(this);
1.1250 - }
1.1251 - void visitTernaryExpression(TernaryExpression *node) {
1.1252 - node->condition()->accept(this);
1.1253 - node->left()->accept(this);
1.1254 - node->right()->accept(this);
1.1255 - }
1.1256 - void visitBooleanLiteral(BooleanLiteral *node) {
1.1257 - }
1.1258 - void visitFieldExpression(FieldExpression *node) {
1.1259 - node->left()->accept(this);
1.1260 - }
1.1261 - void visitSwitchStatement(SwitchStatement *node) {
1.1262 - node->expression()->accept(this);
1.1263 - node->defaultCase()->accept(this);
1.1264 - for (size_t i = 0; i < node->cases()->length(); i++) {
1.1265 - // We don't test case expressions because they are literals.
1.1266 - Case *c = node->cases()->at(i);
1.1267 - c->statement()->accept(this);
1.1268 - }
1.1269 - }
1.1270 - void visitArrayLiteral(ArrayLiteral *node) {
1.1271 - for (size_t i = 0; i < node->expressions()->length(); i++)
1.1272 - node->expressions()->at(i)->accept(this);
1.1273 - }
1.1274 - void visitImportStatement(ImportStatement *node) {
1.1275 - }
1.1276 -
1.1277 - private:
1.1278 - AutoLinkScope *link_;
1.1279 -};
1.1280 -
1.1281 -void
1.1282 -ke::BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1283 -{
1.1284 - AutoEnterCompileContext enter(cc, unit);
1.1285 -
1.1286 - GlobalBuilder builder(zone, cc, unit);
1.1287 - Local<Struct> globals(zone, builder.build());
1.1288 - if (!globals || unit->failed())
1.1289 - return;
1.1290 -
1.1291 - unit->module()->setGlobals(globals);
1.1292 -}
1.1293 -
1.1294 -void
1.1295 -ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1296 -{
1.1297 - AutoEnterCompileContext enter(cc, unit);
1.1298 - NameBinder binder(zone, cc, unit);
1.1299 - binder.bind();
1.1300 -}
1.1301 +/* vim: set ts=4 sw=4 tw=99 et:
1.1302 + *
1.1303 + * Copyright (C) 2012 David Anderson
1.1304 + *
1.1305 + * This file is part of SourcePawn.
1.1306 + *
1.1307 + * SourcePawn is free software: you can redistribute it and/or modify it under
1.1308 + * the terms of the GNU General Public License as published by the Free
1.1309 + * Software Foundation, either version 3 of the License, or (at your option)
1.1310 + * any later version.
1.1311 + *
1.1312 + * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
1.1313 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
1.1314 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
1.1315 + *
1.1316 + * You should have received a copy of the GNU General Public License along with
1.1317 + * SourcePawn. If not, see http://www.gnu.org/licenses/.
1.1318 + */
1.1319 +#include "../Strings.h"
1.1320 +#include "../Zone.h"
1.1321 +#include "../TypeManager.h"
1.1322 +#include "NameBinding.h"
1.1323 +#include "Scopes.h"
1.1324 +#include "ConstantEvaluator.h"
1.1325 +#include "../Spaces-inl.h"
1.1326 +#include "../Heap-inl.h"
1.1327 +
1.1328 +using namespace ke;
1.1329 +
1.1330 +// Create symbol tables and symbols for every scope and declaration. For type
1.1331 +// declarations and methods, we also pre-allocate a Type object, so that
1.1332 +// circular dependencies between types will work.
1.1333 +class NamePopulator : public AstVisitor
1.1334 +{
1.1335 + private:
1.1336 + // This class is analagous to a Scope, however, it allows us to create
1.1337 + // scopes lazily. If a scope is requested, and the current environment
1.1338 + // has no scope, then a scope is created. If no scope is ever requested,
1.1339 + // a scope does not need to be created.
1.1340 + class SymbolEnv
1.1341 + {
1.1342 + public:
1.1343 + SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
1.1344 + : envp_(prevp),
1.1345 + prev_(*prevp),
1.1346 + scope_(scope)
1.1347 + {
1.1348 + *envp_ = this;
1.1349 + }
1.1350 + ~SymbolEnv() {
1.1351 + *envp_ = prev_;
1.1352 + }
1.1353 +
1.1354 + Scope *scope() {
1.1355 + return scope_;
1.1356 + }
1.1357 + void setScope(Scope *scope) {
1.1358 + assert(!scope_);
1.1359 + scope_ = scope;
1.1360 + }
1.1361 + SymbolEnv *prev() const {
1.1362 + return prev_;
1.1363 + }
1.1364 +
1.1365 + private:
1.1366 + SymbolEnv **envp_;
1.1367 + SymbolEnv *prev_;
1.1368 + Scope *scope_;
1.1369 + };
1.1370 +
1.1371 + enum ReturnStatus {
1.1372 + NoReturn,
1.1373 + VoidReturn,
1.1374 + ValueReturn
1.1375 + };
1.1376 +
1.1377 + class FunctionScope
1.1378 + {
1.1379 + public:
1.1380 + FunctionScope(FunctionScope **prevp)
1.1381 + : prevp_(prevp),
1.1382 + prev_(*prevp),
1.1383 + status_(NoReturn)
1.1384 + {
1.1385 + *prevp_ = this;
1.1386 + }
1.1387 + ~FunctionScope() {
1.1388 + *prevp_ = prev_;
1.1389 + }
1.1390 + ReturnStatus returns() const {
1.1391 + return status_;
1.1392 + }
1.1393 + void returns(ReturnStatus status) {
1.1394 + if (status > status_)
1.1395 + status_ = status;
1.1396 + }
1.1397 + private:
1.1398 + FunctionScope **prevp_;
1.1399 + FunctionScope *prev_;
1.1400 + ReturnStatus status_;
1.1401 + };
1.1402 +
1.1403 + public:
1.1404 + NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1405 + : zone_(zone),
1.1406 + pool_(zone->pool()),
1.1407 + cc_(cc),
1.1408 + unit_(unit),
1.1409 + env_(NULL),
1.1410 + fun_(NULL)
1.1411 + {
1.1412 + }
1.1413 +
1.1414 + void analyze() {
1.1415 + ImportScope *importScope = ImportScope::New(pool_);
1.1416 + if (!importScope)
1.1417 + return;
1.1418 +
1.1419 + // At the import level, we declare system types.
1.1420 + if (!declareSystemTypes(importScope))
1.1421 + return;
1.1422 +
1.1423 + GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
1.1424 + if (!globalScope)
1.1425 + return;
1.1426 +
1.1427 + unit_->setImportScope(importScope);
1.1428 + unit_->setGlobalScope(globalScope);
1.1429 +
1.1430 + SymbolEnv env(&env_, globalScope);
1.1431 +
1.1432 + for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.1433 + Statement *stmt = unit_->tree()->statements()->at(i);
1.1434 + stmt->accept(this);
1.1435 + }
1.1436 +
1.1437 + return;
1.1438 + }
1.1439 +
1.1440 + bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> effective) {
1.1441 + Local<String> tag(zone_, zone_->makeSymbol(name));
1.1442 + if (!tag)
1.1443 + return false;
1.1444 +
1.1445 + Local<Type> type(zone_, zone_->types()->getType());
1.1446 +
1.1447 + TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type, effective);
1.1448 + return scope->addSymbol(sym);
1.1449 + }
1.1450 +
1.1451 + bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
1.1452 + Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
1.1453 + assert(primitive);
1.1454 + return declareSystemType(scope, name, primitive);
1.1455 + }
1.1456 +
1.1457 + bool declareSystemTypes(ImportScope *scope) {
1.1458 + if (!declareSystemType(scope, "float", PrimitiveType_Float))
1.1459 + return false;
1.1460 + if (!declareSystemType(scope, "_", PrimitiveType_Int32))
1.1461 + return false;
1.1462 + if (!declareSystemType(scope, "int", PrimitiveType_Int32))
1.1463 + return false;
1.1464 + if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
1.1465 + return false;
1.1466 + if (!declareSystemType(scope, "char", PrimitiveType_Char))
1.1467 + return false;
1.1468 +
1.1469 + Local<Type> voidType(zone_, zone_->types()->getVoid());
1.1470 + if (!declareSystemType(scope, "void", voidType))
1.1471 + return false;
1.1472 +
1.1473 + return true;
1.1474 + }
1.1475 +
1.1476 + void visitVariableDeclaration(VariableDeclaration *node) {
1.1477 + Scope *scope = env_->scope();
1.1478 + if (!scope || scope->kind() != Scope::GLOBAL) {
1.1479 + if ((scope = getOrCreateBlockScope()) == NULL)
1.1480 + return;
1.1481 + }
1.1482 +
1.1483 + if (scope->kind() == Scope::GLOBAL) {
1.1484 + // The symbol must be added now, since it could be an export.
1.1485 + VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
1.1486 + node->setSymbol(sym);
1.1487 +
1.1488 + if (!registerName(scope, sym))
1.1489 + return;
1.1490 + } else {
1.1491 + // We ensure the scope will exist at the name binding phase, but
1.1492 + // we don't actually register the variable symbol yet. Otherwise,
1.1493 + // when binding the initializer, we could encounter:
1.1494 + // new x = x;
1.1495 + //
1.1496 + // And we don't necessarily want this to bind.
1.1497 + }
1.1498 +
1.1499 + if (node->initialization())
1.1500 + node->initialization()->accept(this);
1.1501 + }
1.1502 +
1.1503 + void visitEnumStatement(EnumStatement *node) {
1.1504 + Local<String> name(zone_, node->name());
1.1505 + Local<Type> type(zone_);
1.1506 + if (name)
1.1507 + type = zone_->types()->newEnum(name);
1.1508 + else
1.1509 + type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.1510 +
1.1511 + if (!type)
1.1512 + return;
1.1513 +
1.1514 + Scope *scope = getGlobalOrCreateBlockScope();
1.1515 + if (!scope)
1.1516 + return;
1.1517 +
1.1518 + if (name) {
1.1519 + Local<Type> symType(zone_, zone_->types()->getType());
1.1520 + TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, symType, type);
1.1521 + if (!registerName(scope, sym))
1.1522 + return;
1.1523 +
1.1524 + if (scope->kind() == Scope::GLOBAL) {
1.1525 + if (!unit_->globalScope()->exported()->append(sym))
1.1526 + return;
1.1527 + }
1.1528 + }
1.1529 +
1.1530 + // We want each field of the expression to qualify as a constant expression.
1.1531 + if ((type = zone_->types()->qualify(type, TypeQual_ConstExpr)) == NULL)
1.1532 + return;
1.1533 +
1.1534 + int value = 0;
1.1535 + for (size_t i = 0; i < node->entries()->length(); i++) {
1.1536 + EnumStatement::Entry &entry = node->entries()->at(i);
1.1537 + BoxedPrimitive box = BoxedPrimitive::Int(value);
1.1538 + if (entry.expr) {
1.1539 + if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
1.1540 + cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1.1541 + return;
1.1542 + }
1.1543 +
1.1544 + assert(box.type() == PrimitiveType_Int32);
1.1545 + value = box.toInt();
1.1546 + }
1.1547 +
1.1548 + ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
1.1549 + if (!registerName(scope, sym))
1.1550 + return;
1.1551 + if (scope->kind() == Scope::GLOBAL) {
1.1552 + if (!unit_->globalScope()->exported()->append(sym))
1.1553 + return;
1.1554 + }
1.1555 +
1.1556 + entry.sym = sym;
1.1557 + value++;
1.1558 + }
1.1559 + }
1.1560 +
1.1561 + void visitFunctionStatement(FunctionStatement *node) {
1.1562 + // We create function types ahead of time, not for any particular
1.1563 + // reason. It makes things consistent with FunctionTypeStatement,
1.1564 + // which actually does produce a type.
1.1565 + Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
1.1566 + if (!type)
1.1567 + return;
1.1568 +
1.1569 + assert(env_->scope());
1.1570 +
1.1571 + // Function statements are always named, so add the name to the outer scope.
1.1572 + FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
1.1573 + if (!registerName(env_->scope(), sym))
1.1574 + return;
1.1575 +
1.1576 + if (node->token() == TOK_PUBLIC ||
1.1577 + node->token() == TOK_FORWARD ||
1.1578 + node->token() == TOK_NATIVE)
1.1579 + {
1.1580 + // We're in the global scope, for sure.
1.1581 + assert(env_->scope()->kind() == Scope::GLOBAL);
1.1582 +
1.1583 + if (!unit_->globalScope()->exported()->append(sym))
1.1584 + return;
1.1585 + }
1.1586 +
1.1587 + node->setSymbol(sym);
1.1588 +
1.1589 + // Scope for the function's arguments.
1.1590 + SymbolEnv argEnv(&env_);
1.1591 + if (!registerArguments(node->signature()))
1.1592 + return;
1.1593 +
1.1594 + // Scope for function body.
1.1595 + SymbolEnv localEnv(&env_);
1.1596 + FunctionScope fun(&fun_);
1.1597 + if (node->body())
1.1598 + node->body()->accept(this);
1.1599 +
1.1600 + // Function statements have quirky semantics around their return
1.1601 + // type. For reasonable compatibility with SP1, we use the following
1.1602 + // heuristics for when no explicit type is declared.
1.1603 + if (!node->signature().returnType()) {
1.1604 + Local<Type> type(zone_);
1.1605 + if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
1.1606 + // If the function type is a native or forward, we always
1.1607 + // assume it returns an int32.
1.1608 + type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.1609 + } else if (fun.returns() != ValueReturn) {
1.1610 + // This function never returns a value, so mark it as
1.1611 + // returning void.
1.1612 + type = zone_->types()->getVoid();
1.1613 + }
1.1614 + // No need to NULL check here, we'll catch OOM later.
1.1615 + node->sym()->type()->setReturnType(type);
1.1616 + }
1.1617 +
1.1618 + node->setScopes(argEnv.scope(), localEnv.scope());
1.1619 + }
1.1620 +
1.1621 + void visitStructureStatement(StructureStatement *node) {
1.1622 + assert(false);
1.1623 + }
1.1624 +
1.1625 + void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
1.1626 + assert(false);
1.1627 + }
1.1628 +
1.1629 + void visitNameProxy(NameProxy *name) {
1.1630 + }
1.1631 + void visitAssignment(Assignment *node) {
1.1632 + node->lvalue()->accept(this);
1.1633 + node->expression()->accept(this);
1.1634 + }
1.1635 + void visitBinaryExpression(BinaryExpression *node) {
1.1636 + node->left()->accept(this);
1.1637 + node->right()->accept(this);
1.1638 + }
1.1639 + void visitReturnStatement(ReturnStatement *node) {
1.1640 + if (node->expression())
1.1641 + fun_->returns(ValueReturn);
1.1642 + else
1.1643 + fun_->returns(VoidReturn);
1.1644 + }
1.1645 + void visitForStatement(ForStatement *node) {
1.1646 + SymbolEnv env(&env_);
1.1647 +
1.1648 + if (node->initialization())
1.1649 + node->initialization()->accept(this);
1.1650 + if (node->condition())
1.1651 + node->condition()->accept(this);
1.1652 + if (node->update())
1.1653 + node->update()->accept(this);
1.1654 + node->body()->accept(this);
1.1655 +
1.1656 + node->setScope(env.scope());
1.1657 + }
1.1658 + void visitBlockStatement(BlockStatement *node) {
1.1659 + if (node->type() == TOK_NEW) {
1.1660 + // Don't create a symbol environment for this block, since it
1.1661 + // was created solely to house multiple variable decls.
1.1662 + for (size_t i = 0; i < node->statements()->length(); i++)
1.1663 + node->statements()->at(i)->accept(this);
1.1664 + } else {
1.1665 + assert(node->type() == TOK_LBRACE);
1.1666 +
1.1667 + SymbolEnv env(&env_);
1.1668 +
1.1669 + for (size_t i = 0; i < node->statements()->length(); i++)
1.1670 + node->statements()->at(i)->accept(this);
1.1671 +
1.1672 + if (node->type() == TOK_NEW) {
1.1673 + assert(!env.scope());
1.1674 + return;
1.1675 + }
1.1676 +
1.1677 + node->setScope(env.scope());
1.1678 + }
1.1679 + }
1.1680 + void visitIntegerLiteral(IntegerLiteral *node) {
1.1681 + }
1.1682 + void visitExpressionStatement(ExpressionStatement *node) {
1.1683 + node->expression()->accept(this);
1.1684 + }
1.1685 + void visitCallExpression(CallExpression *node) {
1.1686 + node->callee()->accept(this);
1.1687 + for (size_t i = 0; i < node->arguments()->length(); i++)
1.1688 + node->arguments()->at(i)->accept(this);
1.1689 + }
1.1690 + void visitIfStatement(IfStatement *node) {
1.1691 + node->ifTrue()->accept(this);
1.1692 + if (node->ifFalse())
1.1693 + node->ifFalse()->accept(this);
1.1694 + }
1.1695 + void visitIndexExpression(IndexExpression *node) {
1.1696 + node->left()->accept(this);
1.1697 + node->right()->accept(this);
1.1698 + }
1.1699 + void visitFloatLiteral(FloatLiteral *node) {
1.1700 + }
1.1701 + void visitWhileStatement(WhileStatement *node) {
1.1702 + node->condition()->accept(this);
1.1703 + node->body()->accept(this);
1.1704 + }
1.1705 + void visitBreakStatement(BreakStatement *node) {
1.1706 + }
1.1707 + void visitContinueStatement(ContinueStatement *node) {
1.1708 + }
1.1709 + void visitStringLiteral(StringLiteral *node) {
1.1710 + }
1.1711 + void visitIncDecExpression(IncDecExpression *node) {
1.1712 + node->expression()->accept(this);
1.1713 + }
1.1714 + void visitUnaryExpression(UnaryExpression *node) {
1.1715 + node->expression()->accept(this);
1.1716 + }
1.1717 + void visitTernaryExpression(TernaryExpression *node) {
1.1718 + assert(false);
1.1719 + }
1.1720 + void visitBooleanLiteral(BooleanLiteral *node) {
1.1721 + }
1.1722 + void visitFieldExpression(FieldExpression *node) {
1.1723 + }
1.1724 + void visitSwitchStatement(SwitchStatement *node) {
1.1725 + if (node->defaultCase())
1.1726 + node->defaultCase()->accept(this);
1.1727 +
1.1728 + for (size_t i = 0; i < node->cases()->length(); i++)
1.1729 + node->cases()->at(i)->statement()->accept(this);
1.1730 + }
1.1731 + void visitArrayLiteral(ArrayLiteral *node) {
1.1732 + }
1.1733 + void visitImportStatement(ImportStatement *node) {
1.1734 + }
1.1735 +
1.1736 + private:
1.1737 + Scope *getGlobalOrCreateBlockScope() {
1.1738 + if (env_->scope()) {
1.1739 + assert(env_->scope()->kind() == Scope::BLOCK ||
1.1740 + env_->scope()->kind() == Scope::GLOBAL);
1.1741 + return env_->scope();
1.1742 + }
1.1743 + return getOrCreateBlockScope();
1.1744 + }
1.1745 + Scope *getOrCreateBlockScope() {
1.1746 + if (env_->scope()) {
1.1747 + assert(env_->scope()->kind() == Scope::BLOCK);
1.1748 + return env_->scope();
1.1749 + }
1.1750 +
1.1751 + LocalScope *scope = LocalScope::New(pool_);
1.1752 + if (!scope)
1.1753 + return NULL;
1.1754 +
1.1755 + env_->setScope(scope);
1.1756 + return scope;
1.1757 + }
1.1758 +
1.1759 + bool registerName(Scope *scope, Symbol *sym) {
1.1760 + if (!scope)
1.1761 + return false;
1.1762 +
1.1763 + if (Symbol *other = scope->localLookup(sym->name())) {
1.1764 + // Report, but allow errors to continue.
1.1765 + cc_.reportError(sym->pos(), Message_RedeclaredName,
1.1766 + sym->name()->chars(),
1.1767 + other->pos().line,
1.1768 + other->pos().col);
1.1769 + return true;
1.1770 + }
1.1771 +
1.1772 + return scope->addSymbol(sym);
1.1773 + }
1.1774 +
1.1775 + bool registerArguments(const FunctionSignature &sig) {
1.1776 + if (!sig.parameters()->length())
1.1777 + return true;
1.1778 +
1.1779 + ArgumentScope *argScope = ArgumentScope::New(pool_);
1.1780 + if (!argScope)
1.1781 + return false;
1.1782 + env_->setScope(argScope);
1.1783 +
1.1784 + for (size_t i = 0; i < sig.parameters()->length(); i++) {
1.1785 + Parameter *param = sig.parameters()->at(i);
1.1786 + VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
1.1787 + if (!registerName(env_->scope(), sym))
1.1788 + return false;
1.1789 + param->setSymbol(sym);
1.1790 + }
1.1791 +
1.1792 + return true;
1.1793 + }
1.1794 +
1.1795 + private:
1.1796 + Zone *zone_;
1.1797 + PoolAllocator &pool_;
1.1798 + CompileContext &cc_;
1.1799 + TranslationUnit *unit_;
1.1800 + SymbolEnv *env_;
1.1801 + FunctionScope *fun_;
1.1802 +};
1.1803 +
1.1804 +void
1.1805 +ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1806 +{
1.1807 + AutoEnterCompileContext enter(cc, unit);
1.1808 + NamePopulator populator(zone, cc, unit);
1.1809 + populator.analyze();
1.1810 +}
1.1811 +
1.1812 +static const int INFER_ARRAY_SIZE = 0;
1.1813 +static const int EVAL_ARRAY_SIZE = -1;
1.1814 +static const int DYNAMIC_ARRAY_SIZE = -2;
1.1815 +
1.1816 +class NameBinderBase : public AstVisitor
1.1817 +{
1.1818 + public:
1.1819 + NameBinderBase(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.1820 + : zone_(zone),
1.1821 + pool_(zone->pool()),
1.1822 + cc_(cc),
1.1823 + unit_(unit)
1.1824 + {
1.1825 + }
1.1826 +
1.1827 + protected:
1.1828 + Type *buildVariableType(VariableDeclaration *node) {
1.1829 + Local<Type> type(zone_, bindType(node->type(), node->quals()));
1.1830 + if (!type)
1.1831 + return NULL;
1.1832 +
1.1833 + // We don't allow array typedefs yet.
1.1834 + assert(!type->isArray());
1.1835 +
1.1836 + if (node->dims()) {
1.1837 + int dims[MAX_ARRAY_DEPTH];
1.1838 + int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
1.1839 + if (levels < 0)
1.1840 + return NULL;
1.1841 +
1.1842 + // Do some extra inference based on the initializer, if present.
1.1843 + Expression *init = node->initialization();
1.1844 + if (init) {
1.1845 + if (init->isArrayLiteral() && init->toArrayLiteral()->isFixed()) {
1.1846 + Local<Type> contained(zone_, type->isArray()
1.1847 + ? ArrayType::cast(type)->contained()
1.1848 + : type);
1.1849 + if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
1.1850 + return NULL;
1.1851 + } else if (init->isStringLiteral()) {
1.1852 + dims[levels - 1] = init->toStringLiteral()->string()->length() + 1;
1.1853 + }
1.1854 + }
1.1855 +
1.1856 + // If we got extra dimensions, we need to build a new type.
1.1857 + if (node->dims()) {
1.1858 + if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
1.1859 + return NULL;
1.1860 + }
1.1861 + }
1.1862 +
1.1863 + return type;
1.1864 + }
1.1865 +
1.1866 + int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
1.1867 + unsigned level = 0;
1.1868 + Local<Type> type(zone_, typeArg);
1.1869 + while (type->isArray()) {
1.1870 + ArrayType *atype = ArrayType::cast(type);
1.1871 + dims[level] = atype->isFixedLength()
1.1872 + ? atype->fixedLength()
1.1873 + : DYNAMIC_ARRAY_SIZE;
1.1874 + type = atype->contained();
1.1875 + level++;
1.1876 + }
1.1877 +
1.1878 + if (!exprs)
1.1879 + return level;
1.1880 +
1.1881 + if (level + exprs->length() > MAX_ARRAY_DEPTH) {
1.1882 + cc_.reportError(pos, Message_MaximumArrayDepth);
1.1883 + return -1;
1.1884 + }
1.1885 +
1.1886 + bool hadEmptySize = false;
1.1887 + for (size_t i = 0; i < exprs->length(); i++) {
1.1888 + Expression *expr = exprs->at(i);
1.1889 + if (!expr) {
1.1890 + dims[i] = INFER_ARRAY_SIZE;
1.1891 + hadEmptySize = true;
1.1892 + continue;
1.1893 + }
1.1894 +
1.1895 + BoxedPrimitive box;
1.1896 + if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
1.1897 + int size = box.toInt();
1.1898 + if (size <= 0) {
1.1899 + cc_.reportError(expr->pos(), Message_BadArraySize);
1.1900 + return false;
1.1901 + }
1.1902 +
1.1903 + dims[i] = size;
1.1904 + continue;
1.1905 + }
1.1906 +
1.1907 + if (hadEmptySize) {
1.1908 + cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
1.1909 + return false;
1.1910 + }
1.1911 +
1.1912 + dims[i] = EVAL_ARRAY_SIZE;
1.1913 + }
1.1914 +
1.1915 + return level + exprs->length();
1.1916 + }
1.1917 +
1.1918 + // This function computes missing dimension sizes based on a literal
1.1919 + // initializer. We don't really handle any size rules here; we just
1.1920 + // do a really dumb inference.
1.1921 + bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
1.1922 + for (int i = 0; i < levels; i++) {
1.1923 + if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
1.1924 + // The following are invalid:
1.1925 + // new x[<expr>] = {...}
1.1926 + // new Type:x = {...} // where Type is a non-fixed array type
1.1927 + cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
1.1928 + return false;
1.1929 + }
1.1930 +
1.1931 + if (dims[i] == INFER_ARRAY_SIZE) {
1.1932 + // Character arrays are always dynamic when inferred from string literals.
1.1933 + if (i == levels - 1 && contained->isChar())
1.1934 + dims[i] = DYNAMIC_ARRAY_SIZE;
1.1935 + else
1.1936 + dims[i] = lit->expressions()->length();
1.1937 + }
1.1938 +
1.1939 + if (i != levels - 1) {
1.1940 + // Fixed array literals are guaranteed to have at least one expression.
1.1941 + Expression *next = lit->expressions()->at(0);
1.1942 + if (!next->isArrayLiteral()) {
1.1943 + // Whelp... this array is just malformed. Not the best error message
1.1944 + // but whatever.
1.1945 + cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
1.1946 + return false;
1.1947 + }
1.1948 + lit = next->toArrayLiteral();
1.1949 + }
1.1950 + }
1.1951 +
1.1952 + return true;
1.1953 + }
1.1954 +
1.1955 + ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
1.1956 + Local<Type> type(zone_, contained);
1.1957 +
1.1958 + for (size_t i = postlevels - 1; i < postlevels; i--) {
1.1959 + int size = dims[i] > 0
1.1960 + ? dims[i]
1.1961 + : ArrayType::DYNAMIC_ARRAY_SIZE;
1.1962 +
1.1963 + if ((type = zone_->types()->newArray(contained, size)) == NULL)
1.1964 + return NULL;
1.1965 + if ((type = zone_->types()->qualify(type, quals)) == NULL)
1.1966 + return NULL;
1.1967 + }
1.1968 + return ArrayType::cast(type);
1.1969 + }
1.1970 +
1.1971 + bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
1.1972 + Local<Type> type(zone_);
1.1973 + if (!fun->returnType()) {
1.1974 + if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
1.1975 + return false;
1.1976 + fun->setReturnType(type);
1.1977 + }
1.1978 +
1.1979 + if (sig.variadic())
1.1980 + fun->setVariadic();
1.1981 +
1.1982 + Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
1.1983 + if (!params)
1.1984 + return false;
1.1985 +
1.1986 + for (size_t i = 0; i < sig.parameters()->length(); i++) {
1.1987 + Parameter *param = sig.parameters()->at(i);
1.1988 + if ((type = bindType(param->type(), param->quals())) == NULL)
1.1989 + return false;
1.1990 +
1.1991 + assert(!type->isArray());
1.1992 +
1.1993 + if (param->dims()) {
1.1994 + int dims[MAX_ARRAY_DEPTH];
1.1995 + int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
1.1996 + if (levels < 0)
1.1997 + return false;
1.1998 +
1.1999 + // If we got extra dimensions, we need to build a new type.
1.2000 + // Unlike variables, we do not infer anything about array
1.2001 + // sizes from its default initializer.
1.2002 + if (param->dims()) {
1.2003 + if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
1.2004 + return false;
1.2005 + }
1.2006 +
1.2007 + if (ArrayType::cast(type)->innermost()->isVoid()) {
1.2008 + cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
1.2009 + return false;
1.2010 + }
1.2011 + }
1.2012 +
1.2013 + if (param->reference()) {
1.2014 + if (!type->isPod()) {
1.2015 + cc_.reportError(param->pos(), Message_ArrayCantBeReference);
1.2016 + return false;
1.2017 + }
1.2018 + if (param->quals() & TypeQual_Const) {
1.2019 + cc_.reportError(param->pos(), Message_CannotConstReference);
1.2020 + return false;
1.2021 + }
1.2022 + if ((type = zone_->types()->getReference(type, false)) == NULL)
1.2023 + return false;
1.2024 + }
1.2025 + if (param->quals() & TypeQual_Const) {
1.2026 + if (!type->isArray() && !type->isStruct()) {
1.2027 + cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
1.2028 + return false;
1.2029 + }
1.2030 + }
1.2031 +
1.2032 + if (type->isVoid()) {
1.2033 + cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
1.2034 + return false;
1.2035 + }
1.2036 +
1.2037 + params->set(zone_, i, type);
1.2038 + param->sym()->setType(type);
1.2039 + }
1.2040 +
1.2041 + fun->setParameterTypes(params);
1.2042 +
1.2043 + return true;
1.2044 + }
1.2045 +
1.2046 + Type *bindType(Expression *expr, TypeQualifiers quals) {
1.2047 + Local<Type> type(zone_);
1.2048 +
1.2049 + if (!expr) {
1.2050 + // If no type was declared, we return int32.
1.2051 + type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1.2052 + } else {
1.2053 + expr->accept(this);
1.2054 +
1.2055 + NameProxy *proxy = expr->asNameProxy();
1.2056 + assert(proxy);
1.2057 +
1.2058 + Symbol *sym = proxy->sym();
1.2059 + if (!sym)
1.2060 + return NULL;
1.2061 +
1.2062 + if (!sym->isType()) {
1.2063 + cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
1.2064 + return NULL;
1.2065 + }
1.2066 +
1.2067 + type = sym->toType()->effective();
1.2068 + }
1.2069 +
1.2070 + return zone_->types()->qualify(type, quals);
1.2071 + }
1.2072 +
1.2073 + protected:
1.2074 + Zone *zone_;
1.2075 + PoolAllocator &pool_;
1.2076 + CompileContext &cc_;
1.2077 + TranslationUnit *unit_;
1.2078 +};
1.2079 +
1.2080 +class GlobalBuilder : public NameBinderBase
1.2081 +{
1.2082 + typedef ScopedRoot<Descriptor> ScopedDescriptor;
1.2083 + struct PrimitiveFill {
1.2084 + ScopedDescriptor *desc;
1.2085 + BoxedPrimitive prim;
1.2086 +
1.2087 + PrimitiveFill(ScopedDescriptor *desc, BoxedPrimitive prim)
1.2088 + : desc(desc),
1.2089 + prim(prim)
1.2090 + {
1.2091 + }
1.2092 + };
1.2093 +
1.2094 + public:
1.2095 + GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.2096 + : NameBinderBase(zone, cc, unit),
1.2097 + globalScope_(unit->globalScope())
1.2098 + {
1.2099 + }
1.2100 +
1.2101 + Struct *build() {
1.2102 + for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
1.2103 + unit_->tree()->imports()->at(i)->accept(this);
1.2104 +
1.2105 + // Next, enter the global scope and walk all statements.
1.2106 + for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.2107 + Statement *stmt = unit_->tree()->statements()->at(i);
1.2108 + stmt->accept(this);
1.2109 + }
1.2110 +
1.2111 + Local<Struct> globals(zone_, createGlobals());
1.2112 + if (!globals)
1.2113 + return NULL;
1.2114 +
1.2115 + populate(globals);
1.2116 +
1.2117 + return globals;
1.2118 + }
1.2119 +
1.2120 + private:
1.2121 + Struct *createGlobals() {
1.2122 + Local<FixedArray> descs(zone_, FixedArray::New(zone_, descriptors_.length(), Heap::Tenure_Old));
1.2123 + if (!descs)
1.2124 + return NULL;
1.2125 +
1.2126 + for (unsigned i = 0; i < descriptors_.length(); i++)
1.2127 + descs->set(zone_, i, *descriptors_[i]);
1.2128 +
1.2129 + Local<String> name(zone_, unit_->module()->name());
1.2130 + Local<StructType> type(zone_, StructType::New(zone_, name, descs));
1.2131 + if (!type)
1.2132 + return NULL;
1.2133 +
1.2134 + Local<StructMap> map(zone_, type->newMap());
1.2135 + return Struct::New(zone_, map, Heap::Tenure_Old);
1.2136 + }
1.2137 +
1.2138 + void populate(Handle<Struct> globals) {
1.2139 + // This is a huge hack, but it's probably better than a full extra
1.2140 + // pass. The problem is that until we have all the descriptors, we
1.2141 + // can't start setting constexprs in the struct, and we need to set
1.2142 + // them now so they're available during full semantic analysis. To
1.2143 + // work around this, we build up the list of values we need to set
1.2144 + // as we build up descriptors, and then populate the global struct
1.2145 + // with this set.
1.2146 + //
1.2147 + // Note, this code is also kind of dead until we support linking. We
1.2148 + // handle constexprs explicitly in importFrom(), by sniffing out the
1.2149 + // symbol type. That code will go away later.
1.2150 + for (size_t i = 0; i < primitiveFills_.length(); i++) {
1.2151 + const PrimitiveFill &fill = primitiveFills_[i];
1.2152 + assert(fill.prim.type() == PrimitiveType_Int32);
1.2153 + globals->set(*fill.desc, fill.prim.toInt());
1.2154 + }
1.2155 + }
1.2156 +
1.2157 + public:
1.2158 + void visitEnumStatement(EnumStatement *stmt) {
1.2159 + if (stmt->visibility() != TOK_PUBLIC || !stmt->name())
1.2160 + return;
1.2161 +
1.2162 + Local<Type> type(zone_, zone_->types()->getType());
1.2163 + Descriptor *desc = Descriptor::New(zone_, stmt->name(), type, Descriptor::Public);
1.2164 + if (!desc)
1.2165 + return;
1.2166 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.2167 + return;
1.2168 +
1.2169 + for (size_t i = 0; i < stmt->entries()->length(); i++) {
1.2170 + EnumStatement::Entry &e = stmt->entries()->at(i);
1.2171 + ScopedDescriptor *desc = new (pool_) ScopedDescriptor(Descriptor::New(zone_, e.name, e.sym->type(), Descriptor::Public));
1.2172 + if (!desc || !descriptors_.append(desc))
1.2173 + return;
1.2174 +
1.2175 + // Save the value so we can export it immediately.
1.2176 + if (!primitiveFills_.append(PrimitiveFill(desc, e.sym->value())))
1.2177 + return;
1.2178 + }
1.2179 + }
1.2180 +
1.2181 + void visitNameProxy(NameProxy *proxy) {
1.2182 + Scope *scope = unit_->globalScope();
1.2183 + Symbol *sym = scope->lookup(proxy->name());
1.2184 + if (!sym)
1.2185 + cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
1.2186 + proxy->bind(sym);
1.2187 + }
1.2188 +
1.2189 + void visitFunctionStatement(FunctionStatement *node) {
1.2190 + Local<FunctionType> type(zone_, node->sym()->type());
1.2191 + if (!fillFunctionType(type, node->signature()))
1.2192 + return;
1.2193 +
1.2194 + unsigned offset;
1.2195 + if (!builder_.add(type, &offset))
1.2196 + return;
1.2197 +
1.2198 + Descriptor::Visibility visibility = (node->token() == TOK_NATIVE || node->token() == TOK_FORWARD)
1.2199 + ? Descriptor::Public
1.2200 + : Descriptor::Private;
1.2201 +
1.2202 + Descriptor *desc = Descriptor::New(zone_, node->name(), type, visibility);
1.2203 + if (!desc)
1.2204 + return;
1.2205 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.2206 + return;
1.2207 + }
1.2208 +
1.2209 + void visitVariableDeclaration(VariableDeclaration *node) {
1.2210 + Local<Type> type(zone_, buildVariableType(node));
1.2211 + if (!type)
1.2212 + return;
1.2213 +
1.2214 + // If we're in global scope, and we received a |const| qualifier, then
1.2215 + // we extend this to array references as well. This is to sort of mimic
1.2216 + // SP1 functionality, but also means that you cannot have changeable
1.2217 + // const pointers in global scope.
1.2218 + if ((node->quals() & TypeQual_Const) && type->isArray()) {
1.2219 + if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
1.2220 + return;
1.2221 + }
1.2222 +
1.2223 + node->sym()->setType(type);
1.2224 +
1.2225 + unsigned offset;
1.2226 + if (!builder_.add(type, &offset))
1.2227 + return;
1.2228 +
1.2229 + Descriptor *desc = Descriptor::New(zone_, node->name(), type, Descriptor::Private);
1.2230 + if (!desc)
1.2231 + return;
1.2232 + if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
1.2233 + return;
1.2234 + }
1.2235 +
1.2236 + void visitImportStatement(ImportStatement *node) {
1.2237 + if (!node->names()) {
1.2238 + PathComponent *path = node->path();
1.2239 + while (path->next)
1.2240 + path = path->next;
1.2241 +
1.2242 + // Imports automatically go into the importScope. For now, we
1.2243 + // error if there are any duplicate symbols entered into the
1.2244 + // importScope.
1.2245 + if (unit_->importScope()->localLookup(path->name)) {
1.2246 + cc_.reportError(node->pos(), Message_DuplicateImport, path->name->chars());
1.2247 + return;
1.2248 + }
1.2249 +
1.2250 + Local<Type> type(zone_, zone_->types()->getImportable());
1.2251 + ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
1.2252 + if (!unit_->importScope()->addSymbol(sym))
1.2253 + return;
1.2254 + } else if (node->importAllNames()) {
1.2255 + Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
1.2256 + if (importable->isPackage()) {
1.2257 + assert(false);
1.2258 + } else {
1.2259 + Local<Module> module(zone_, Module::cast(importable));
1.2260 + if (!module->globals())
1.2261 + importAllFromTranslationUnit(node, module->translationUnit());
1.2262 + else
1.2263 + assert(false);
1.2264 + }
1.2265 + } else {
1.2266 + Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
1.2267 + if (importable->isPackage()) {
1.2268 + assert(false);
1.2269 + } else {
1.2270 + Local<Module> module(zone_, Module::cast(importable));
1.2271 +
1.2272 + // Always grab from the translation unit if we can, for now.
1.2273 + if (module->translationUnit())
1.2274 + importFromTranslationUnit(node, module->translationUnit());
1.2275 + else
1.2276 + assert(false);
1.2277 + }
1.2278 + }
1.2279 + }
1.2280 +
1.2281 + private:
1.2282 + bool importFrom(ImportStatement *node, Symbol *import) {
1.2283 + assert(import->type());
1.2284 +
1.2285 + // Check for duplicate import names.
1.2286 + if (unit_->importScope()->localLookup(import->name())) {
1.2287 + cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
1.2288 + return false;
1.2289 + }
1.2290 +
1.2291 + Symbol *sym;
1.2292 + if (import->isType()) {
1.2293 + // Fuck it, make a TypeSymbol instead of an ImplicitSymbol. This
1.2294 + // makes bindType() much simpler. We may run into problems
1.2295 + // implementing linking, but it seems unlikely, as long as we are
1.2296 + // exporting Types in module structs.
1.2297 + Local<Type> type(zone_, zone_->types()->getType());
1.2298 + sym = new (pool_) TypeSymbol(unit_->importScope(),
1.2299 + import->name(),
1.2300 + type,
1.2301 + import->toType()->effective());
1.2302 + } else if (import->isConstant()) {
1.2303 + // Same deal. No reason to lookup in the module globals if we
1.2304 + // already have a symbol.
1.2305 + sym = new (pool_) ConstantSymbol(unit_->importScope(),
1.2306 + import->name(),
1.2307 + node->pos(),
1.2308 + import->type(),
1.2309 + import->toConstant()->value());
1.2310 + } else {
1.2311 + sym = new (pool_) ImplicitSymbol(unit_->importScope(),
1.2312 + import->name(),
1.2313 + node->pos(),
1.2314 + import->type(),
1.2315 + node->importIndex());
1.2316 + }
1.2317 +
1.2318 + if (!unit_->importScope()->addSymbol(sym))
1.2319 + return false;
1.2320 +
1.2321 + return true;
1.2322 + }
1.2323 +
1.2324 + void importFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
1.2325 + assert(!other->failed());
1.2326 +
1.2327 + for (size_t i = 0; i < node->names()->length(); i++) {
1.2328 + Handle<String> name = *node->names()->at(i);
1.2329 +
1.2330 + // See if the name exists in the other translation unit.
1.2331 + Symbol *import = other->globalScope()->findExported(name);
1.2332 + if (!import) {
1.2333 + FixedArray *path = unit_->module()->importPathAt(node->importIndex());
1.2334 + cc_.reportError(node->pos(), Message_NotFoundInImportable,
1.2335 + name->chars(),
1.2336 + String::cast(path->at(path->length() - 1))->chars());
1.2337 + return;
1.2338 + }
1.2339 +
1.2340 + if (!importFrom(node, import))
1.2341 + return;
1.2342 + }
1.2343 + }
1.2344 +
1.2345 + void importAllFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
1.2346 + assert(!other->failed());
1.2347 +
1.2348 + for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
1.2349 + Symbol *import = other->globalScope()->exported()->at(i);
1.2350 + if (!importFrom(node, import))
1.2351 + return;
1.2352 + }
1.2353 + }
1.2354 +
1.2355 + private:
1.2356 + StructureBufferBuilder builder_;
1.2357 + Vector<ScopedRoot<Descriptor> *> descriptors_;
1.2358 + GlobalScope *globalScope_;
1.2359 + Vector<PrimitiveFill> primitiveFills_;
1.2360 +};
1.2361 +
1.2362 +class NameBinder : public NameBinderBase
1.2363 +{
1.2364 + public:
1.2365 + class AutoLinkScope
1.2366 + {
1.2367 + public:
1.2368 + AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
1.2369 + : prevp_(prevp),
1.2370 + prev_(*prevp),
1.2371 + scope_(scope)
1.2372 + {
1.2373 + if (scope_) {
1.2374 + *prevp_ = this;
1.2375 + if (prev_)
1.2376 + scope_->setParent(prev_->scope());
1.2377 + }
1.2378 + }
1.2379 + ~AutoLinkScope() {
1.2380 + if (scope_) {
1.2381 + assert(*prevp_ == this);
1.2382 + *prevp_ = prev_;
1.2383 + }
1.2384 + }
1.2385 + Scope *scope() const {
1.2386 + return scope_;
1.2387 + }
1.2388 +
1.2389 + private:
1.2390 + AutoLinkScope **prevp_;
1.2391 + AutoLinkScope *prev_;
1.2392 + Scope *scope_;
1.2393 + };
1.2394 +
1.2395 + public:
1.2396 + NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.2397 + : NameBinderBase(zone, cc, unit),
1.2398 + link_(NULL)
1.2399 + {
1.2400 + }
1.2401 +
1.2402 + void bind() {
1.2403 + // Start with the import scope, and collect all imported names.
1.2404 + AutoLinkScope importScope(&link_, unit_->importScope());
1.2405 +
1.2406 + for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
1.2407 + unit_->tree()->imports()->at(i)->accept(this);
1.2408 +
1.2409 + // Next, enter the global scope and walk all statements.
1.2410 + AutoLinkScope globalScope(&link_, unit_->globalScope());
1.2411 + for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
1.2412 + Statement *stmt = unit_->tree()->statements()->at(i);
1.2413 + stmt->accept(this);
1.2414 + }
1.2415 + }
1.2416 +
1.2417 + void visitVariableDeclaration(VariableDeclaration *node) {
1.2418 + // Bind the initializer before registering the declaration, so that we
1.2419 + // can error on bogus initializers (new x = x).
1.2420 + if (node->initialization())
1.2421 + node->initialization()->accept(this);
1.2422 +
1.2423 + // If the node already has a symbol (meaning it was a global), then
1.2424 + // we don't have to do anything more.
1.2425 + if (node->sym())
1.2426 + return;
1.2427 +
1.2428 + Local<Type> type(zone_, buildVariableType(node));
1.2429 + if (!type)
1.2430 + return;
1.2431 +
1.2432 + VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
1.2433 + node->setSymbol(sym);
1.2434 +
1.2435 + if (Symbol *other = link_->scope()->localLookup(sym->name())) {
1.2436 + // Report, but allow errors to continue.
1.2437 + cc_.reportError(sym->pos(), Message_RedeclaredName,
1.2438 + sym->name()->chars(),
1.2439 + other->pos().line,
1.2440 + other->pos().col);
1.2441 + return;
1.2442 + }
1.2443 +
1.2444 + link_->scope()->addSymbol(sym);
1.2445 + }
1.2446 + void visitEnumStatement(EnumStatement *node) {
1.2447 + }
1.2448 + void visitFunctionStatement(FunctionStatement *node) {
1.2449 + AutoLinkScope argScope(&link_, node->argScope());
1.2450 + AutoLinkScope varScope(&link_, node->varScope());
1.2451 +
1.2452 + // If the function is in the global scope, we've already computed its
1.2453 + // type.
1.2454 + if (node->sym()->scope()->kind() != Scope::GLOBAL) {
1.2455 + Local<FunctionType> type(zone_, node->sym()->type());
1.2456 + if (!fillFunctionType(type, node->signature()))
1.2457 + return;
1.2458 + }
1.2459 +
1.2460 + if (node->body())
1.2461 + node->body()->accept(this);
1.2462 + }
1.2463 + void visitStructureStatement(StructureStatement *node) {
1.2464 + assert(false);
1.2465 + }
1.2466 + void visitFunctionTypeStatement(FunctionTypeStatement *node) {
1.2467 + assert(false);
1.2468 + }
1.2469 +
1.2470 + void visitNameProxy(NameProxy *proxy) {
1.2471 + // We could have already bound globals.
1.2472 + if (proxy->sym())
1.2473 + return;
1.2474 +
1.2475 + Scope *scope = link_->scope();
1.2476 + Symbol *sym = scope->lookup(proxy->name());
1.2477 + if (!sym)
1.2478 + cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
1.2479 + proxy->bind(sym);
1.2480 + }
1.2481 + void visitAssignment(Assignment *node) {
1.2482 + node->lvalue()->accept(this);
1.2483 + node->expression()->accept(this);
1.2484 + }
1.2485 + void visitBinaryExpression(BinaryExpression *node) {
1.2486 + node->left()->accept(this);
1.2487 + node->right()->accept(this);
1.2488 + }
1.2489 + void visitReturnStatement(ReturnStatement *node) {
1.2490 + node->expression()->accept(this);
1.2491 + }
1.2492 + void visitForStatement(ForStatement *node) {
1.2493 + AutoLinkScope scope(&link_, node->scope());
1.2494 +
1.2495 + if (node->initialization())
1.2496 + node->initialization()->accept(this);
1.2497 + if (node->condition())
1.2498 + node->condition()->accept(this);
1.2499 + if (node->update())
1.2500 + node->update()->accept(this);
1.2501 + node->body()->accept(this);
1.2502 + }
1.2503 + void visitBlockStatement(BlockStatement *node) {
1.2504 + AutoLinkScope scope(&link_, node->scope());
1.2505 + for (size_t i = 0; i < node->statements()->length(); i++)
1.2506 + node->statements()->at(i)->accept(this);
1.2507 + }
1.2508 + void visitIntegerLiteral(IntegerLiteral *node) {
1.2509 + }
1.2510 + void visitExpressionStatement(ExpressionStatement *node) {
1.2511 + node->expression()->accept(this);
1.2512 + }
1.2513 + void visitCallExpression(CallExpression *node) {
1.2514 + node->callee()->accept(this);
1.2515 + for (size_t i = 0; i < node->arguments()->length(); i++)
1.2516 + node->arguments()->at(i)->accept(this);
1.2517 + }
1.2518 + void visitIfStatement(IfStatement *node) {
1.2519 + node->condition()->accept(this);
1.2520 + node->ifTrue()->accept(this);
1.2521 + if (node->ifFalse())
1.2522 + node->ifFalse()->accept(this);
1.2523 + }
1.2524 + void visitIndexExpression(IndexExpression *node) {
1.2525 + node->left()->accept(this);
1.2526 + node->right()->accept(this);
1.2527 + }
1.2528 + void visitFloatLiteral(FloatLiteral *node) {
1.2529 + }
1.2530 + void visitWhileStatement(WhileStatement *node) {
1.2531 + node->condition()->accept(this);
1.2532 + node->body()->accept(this);
1.2533 + }
1.2534 + void visitBreakStatement(BreakStatement *node) {
1.2535 + }
1.2536 + void visitContinueStatement(ContinueStatement *node) {
1.2537 + }
1.2538 + void visitStringLiteral(StringLiteral *node) {
1.2539 + }
1.2540 + void visitIncDecExpression(IncDecExpression *node) {
1.2541 + node->expression()->accept(this);
1.2542 + }
1.2543 + void visitUnaryExpression(UnaryExpression *node) {
1.2544 + if (node->tag())
1.2545 + node->tag()->accept(this);
1.2546 + node->expression()->accept(this);
1.2547 + }
1.2548 + void visitTernaryExpression(TernaryExpression *node) {
1.2549 + node->condition()->accept(this);
1.2550 + node->left()->accept(this);
1.2551 + node->right()->accept(this);
1.2552 + }
1.2553 + void visitBooleanLiteral(BooleanLiteral *node) {
1.2554 + }
1.2555 + void visitFieldExpression(FieldExpression *node) {
1.2556 + node->left()->accept(this);
1.2557 + }
1.2558 + void visitSwitchStatement(SwitchStatement *node) {
1.2559 + node->expression()->accept(this);
1.2560 + node->defaultCase()->accept(this);
1.2561 + for (size_t i = 0; i < node->cases()->length(); i++) {
1.2562 + // We don't test case expressions because they are literals.
1.2563 + Case *c = node->cases()->at(i);
1.2564 + c->statement()->accept(this);
1.2565 + }
1.2566 + }
1.2567 + void visitArrayLiteral(ArrayLiteral *node) {
1.2568 + for (size_t i = 0; i < node->expressions()->length(); i++)
1.2569 + node->expressions()->at(i)->accept(this);
1.2570 + }
1.2571 + void visitImportStatement(ImportStatement *node) {
1.2572 + }
1.2573 +
1.2574 + private:
1.2575 + AutoLinkScope *link_;
1.2576 +};
1.2577 +
1.2578 +void
1.2579 +ke::BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.2580 +{
1.2581 + AutoEnterCompileContext enter(cc, unit);
1.2582 +
1.2583 + GlobalBuilder builder(zone, cc, unit);
1.2584 + Local<Struct> globals(zone, builder.build());
1.2585 + if (!globals || unit->failed())
1.2586 + return;
1.2587 +
1.2588 + unit->module()->setGlobals(globals);
1.2589 +}
1.2590 +
1.2591 +void
1.2592 +ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
1.2593 +{
1.2594 + AutoEnterCompileContext enter(cc, unit);
1.2595 + NameBinder binder(zone, cc, unit);
1.2596 + binder.bind();
1.2597 +}