src/compiler/NameBinding.cpp
author Michael Busby <prodigysim@gmail.com>
Mon Jun 10 01:50:18 2013 +0100 (2013-06-10)
changeset 264 70b8f318c379
parent 263 ba85a47ee414
child 265 3a903b89a514
permissions -rw-r--r--
Parse assignment RTL instead of LTR, fixes multiple assignment (bug 5420).
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of SourcePawn.
     6  *
     7  * SourcePawn is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * SourcePawn is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * SourcePawn. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include "../Strings.h"
    20 #include "../Zone.h"
    21 #include "../TypeManager.h"
    22 #include "NameBinding.h"
    23 #include "Scopes.h"
    24 #include "ConstantEvaluator.h"
    25 #include "../Spaces-inl.h"
    26 #include "../Heap-inl.h"
    27 
    28 using namespace ke;
    29 
    30 // Create symbol tables and symbols for every scope and declaration. For type
    31 // declarations and methods, we also pre-allocate a Type object, so that
    32 // circular dependencies between types will work.
    33 class NamePopulator : public AstVisitor
    34 {
    35   private:
    36     // This class is analagous to a Scope, however, it allows us to create
    37     // scopes lazily. If a scope is requested, and the current environment
    38     // has no scope, then a scope is created. If no scope is ever requested,
    39     // a scope does not need to be created.
    40     class SymbolEnv
    41     {
    42       public:
    43         SymbolEnv(SymbolEnv **prevp, Scope *scope = NULL)
    44           : envp_(prevp),
    45             prev_(*prevp),
    46             scope_(scope)
    47         {
    48             *envp_ = this;
    49         }
    50         ~SymbolEnv() {
    51             *envp_ = prev_;
    52         }
    53 
    54         Scope *scope() {
    55             return scope_;
    56         }
    57         void setScope(Scope *scope) {
    58             assert(!scope_);
    59             scope_ = scope;
    60         }
    61         SymbolEnv *prev() const {
    62             return prev_;
    63         }
    64 
    65       private:
    66         SymbolEnv **envp_;
    67         SymbolEnv *prev_;
    68         Scope *scope_;
    69     };
    70 
    71     enum ReturnStatus {
    72         NoReturn,
    73         VoidReturn,
    74         ValueReturn
    75     };
    76 
    77     class FunctionScope
    78     {
    79       public:
    80         FunctionScope(FunctionScope **prevp)
    81           : prevp_(prevp),
    82             prev_(*prevp),
    83             status_(NoReturn)
    84         {
    85             *prevp_ = this;
    86         }
    87         ~FunctionScope() {
    88             *prevp_ = prev_;
    89         }
    90         ReturnStatus returns() const {
    91             return status_;
    92         }
    93         void returns(ReturnStatus status) {
    94             if (status > status_)
    95                 status_ = status;
    96         }
    97       private:
    98         FunctionScope **prevp_;
    99         FunctionScope *prev_;
   100         ReturnStatus status_;
   101     };
   102 
   103   public:
   104     NamePopulator(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   105       : zone_(zone),
   106         pool_(zone->pool()),
   107         cc_(cc),
   108         unit_(unit),
   109         env_(NULL),
   110         fun_(NULL)
   111     {
   112     }
   113 
   114     void analyze() {
   115         ImportScope *importScope = ImportScope::New(pool_);
   116         if (!importScope)
   117             return;
   118 
   119         // At the import level, we declare system types.
   120         if (!declareSystemTypes(importScope))
   121             return;
   122 
   123         GlobalScope *globalScope = GlobalScope::New(pool_, importScope);
   124         if (!globalScope)
   125             return;
   126 
   127         unit_->setImportScope(importScope);
   128         unit_->setGlobalScope(globalScope);
   129 
   130         SymbolEnv env(&env_, globalScope);
   131 
   132         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   133             Statement *stmt = unit_->tree()->statements()->at(i);
   134             stmt->accept(this);
   135         }
   136 
   137         return;
   138     }
   139 
   140     bool declareSystemType(ImportScope *scope, const char *name, Handle<Type> effective) {
   141         Local<String> tag(zone_, zone_->makeSymbol(name));
   142         if (!tag)
   143             return false;
   144 
   145         Local<Type> type(zone_, zone_->types()->getType());
   146 
   147         TypeSymbol *sym = new (pool_) TypeSymbol(scope, tag, type, effective);
   148         return scope->addSymbol(sym);
   149     }
   150 
   151     bool declareSystemType(ImportScope *scope, const char *name, PrimitiveType prim) {
   152         Local<Type> primitive(zone_, zone_->types()->getPrimitive(prim));
   153         assert(primitive);
   154         return declareSystemType(scope, name, primitive);
   155     }
   156 
   157     bool declareSystemTypes(ImportScope *scope) {
   158         if (!declareSystemType(scope, "float", PrimitiveType_Float))
   159             return false;
   160         if (!declareSystemType(scope, "_", PrimitiveType_Int32))
   161             return false;
   162         if (!declareSystemType(scope, "int", PrimitiveType_Int32))
   163             return false;
   164         if (!declareSystemType(scope, "bool", PrimitiveType_Bool))
   165             return false;
   166         if (!declareSystemType(scope, "char", PrimitiveType_Char))
   167             return false;
   168 
   169         Local<Type> voidType(zone_, zone_->types()->getVoid());
   170         if (!declareSystemType(scope, "void", voidType))
   171             return false;
   172 
   173         return true;
   174     }
   175 
   176     void visitVariableDeclaration(VariableDeclaration *node) {
   177         Scope *scope = env_->scope();
   178         if (!scope || scope->kind() != Scope::GLOBAL) {
   179             if ((scope = getOrCreateBlockScope()) == NULL)
   180                 return;
   181         }
   182 
   183         if (scope->kind() == Scope::GLOBAL) {
   184             // The symbol must be added now, since it could be an export.
   185             VariableSymbol *sym = new (pool_) VariableSymbol(scope, node->name(), node->pos());
   186             node->setSymbol(sym);
   187 
   188             if (!registerName(scope, sym))
   189                 return;
   190         } else {
   191             // We ensure the scope will exist at the name binding phase, but
   192             // we don't actually register the variable symbol yet. Otherwise,
   193             // when binding the initializer, we could encounter:
   194             //    new x = x;
   195             //
   196             // And we don't necessarily want this to bind.
   197         }
   198 
   199         if (node->initialization())
   200             node->initialization()->accept(this);
   201     }
   202 
   203     void visitEnumStatement(EnumStatement *node) {
   204         Local<String> name(zone_, node->name());
   205         Local<Type> type(zone_);
   206         if (name)
   207             type = zone_->types()->newEnum(name);
   208         else
   209             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   210 
   211         if (!type)
   212             return;
   213 
   214         Scope *scope = getGlobalOrCreateBlockScope();
   215         if (!scope)
   216             return;
   217 
   218         if (name) {
   219             Local<Type> symType(zone_, zone_->types()->getType());
   220             TypeSymbol *sym = new (pool_) TypeSymbol(scope, name, symType, type);
   221             if (!registerName(scope, sym))
   222                 return;
   223 
   224             if (scope->kind() == Scope::GLOBAL) {
   225                 if (!unit_->globalScope()->exported()->append(sym))
   226                     return;
   227             }
   228         }
   229 
   230         // We want each field of the expression to qualify as a constant expression.
   231         if ((type = zone_->types()->qualify(type, TypeQual_ConstExpr)) == NULL)
   232             return;
   233         
   234         int value = 0;
   235         for (size_t i = 0; i < node->entries()->length(); i++) {
   236             EnumStatement::Entry &entry = node->entries()->at(i);
   237             BoxedPrimitive box = BoxedPrimitive::Int(value);
   238             if (entry.expr) {
   239                 if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
   240                     cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
   241                     return;
   242                 }
   243 
   244                 assert(box.type() == PrimitiveType_Int32);
   245                 value = box.toInt();
   246             }
   247          
   248             ConstantSymbol *sym = new (pool_) ConstantSymbol(scope, entry.name, entry.pos, type, box);
   249             if (!registerName(scope, sym))
   250                 return;
   251             if (scope->kind() == Scope::GLOBAL) {
   252                 if (!unit_->globalScope()->exported()->append(sym))
   253                     return;
   254             }
   255 
   256             entry.sym = sym;
   257             value++;
   258         }
   259     }
   260 
   261     void visitFunctionStatement(FunctionStatement *node) {
   262         // We create function types ahead of time, not for any particular
   263         // reason. It makes things consistent with FunctionTypeStatement,
   264         // which actually does produce a type.
   265         Local<FunctionType> type(zone_, FunctionType::New(zone_, node->name(), node->token()));
   266         if (!type)
   267             return;
   268 
   269         assert(env_->scope());
   270 
   271         // Function statements are always named, so add the name to the outer scope.
   272         FunctionSymbol *sym = new (pool_) FunctionSymbol(env_->scope(), node->name(), node->pos(), type);
   273         if (!registerName(env_->scope(), sym))
   274             return;
   275 
   276         if (node->token() == TOK_PUBLIC ||
   277             node->token() == TOK_FORWARD ||
   278             node->token() == TOK_NATIVE)
   279         {
   280             // We're in the global scope, for sure.
   281             assert(env_->scope()->kind() == Scope::GLOBAL);
   282 
   283             if (!unit_->globalScope()->exported()->append(sym))
   284                 return;
   285         }
   286 
   287         node->setSymbol(sym);
   288 
   289         // Scope for the function's arguments.
   290         SymbolEnv argEnv(&env_);
   291         if (!registerArguments(node->signature()))
   292             return;
   293 
   294         // Scope for function body.
   295         SymbolEnv localEnv(&env_);
   296         FunctionScope fun(&fun_);
   297         if (node->body())
   298             node->body()->accept(this);
   299 
   300         // Function statements have quirky semantics around their return
   301         // type. For reasonable compatibility with SP1, we use the following
   302         // heuristics for when no explicit type is declared.
   303         if (!node->signature().returnType()) {
   304             Local<Type> type(zone_);
   305             if (node->token() == TOK_FORWARD || node->token() == TOK_NATIVE) {
   306                 // If the function type is a native or forward, we always
   307                 // assume it returns an int32.
   308                 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   309             } else if (fun.returns() != ValueReturn) {
   310                 // This function never returns a value, so mark it as
   311                 // returning void.
   312                 type = zone_->types()->getVoid();
   313             }
   314             // No need to NULL check here, we'll catch OOM later.
   315             node->sym()->type()->setReturnType(type);
   316         }
   317 
   318         node->setScopes(argEnv.scope(), localEnv.scope());
   319     }
   320 
   321     void visitStructureStatement(StructureStatement *node) {
   322         assert(false);
   323     }
   324 
   325     void visiFunctionTypeStatementt(FunctionTypeStatement *node) {
   326         assert(false);
   327     }
   328 
   329     void visitNameProxy(NameProxy *name) {
   330     }
   331     void visitAssignment(Assignment *node) {
   332         node->lvalue()->accept(this);
   333         node->expression()->accept(this);
   334     }
   335     void visitBinaryExpression(BinaryExpression *node) {
   336         node->left()->accept(this);
   337         node->right()->accept(this);
   338     }
   339     void visitReturnStatement(ReturnStatement *node) {
   340         if (node->expression())
   341             fun_->returns(ValueReturn);
   342         else
   343             fun_->returns(VoidReturn);
   344     }
   345     void visitForStatement(ForStatement *node) {
   346         SymbolEnv env(&env_);
   347 
   348         if (node->initialization())
   349             node->initialization()->accept(this);
   350         if (node->condition())
   351             node->condition()->accept(this);
   352         if (node->update())
   353             node->update()->accept(this);
   354         node->body()->accept(this);
   355 
   356         node->setScope(env.scope());
   357     }
   358     void visitBlockStatement(BlockStatement *node) {
   359         if (node->type() == TOK_NEW) {
   360             // Don't create a symbol environment for this block, since it
   361             // was created solely to house multiple variable decls.
   362             for (size_t i = 0; i < node->statements()->length(); i++)
   363                 node->statements()->at(i)->accept(this);
   364         } else {
   365             assert(node->type() == TOK_LBRACE);
   366 
   367             SymbolEnv env(&env_);
   368 
   369             for (size_t i = 0; i < node->statements()->length(); i++)
   370                 node->statements()->at(i)->accept(this);
   371         
   372             if (node->type() == TOK_NEW) {
   373                 assert(!env.scope());
   374                 return;
   375             }
   376 
   377             node->setScope(env.scope());
   378         }
   379     }
   380     void visitIntegerLiteral(IntegerLiteral *node) {
   381     }
   382     void visitExpressionStatement(ExpressionStatement *node) {
   383         node->expression()->accept(this);
   384     }
   385     void visitCallExpression(CallExpression *node) {
   386         node->callee()->accept(this);
   387         for (size_t i = 0; i < node->arguments()->length(); i++)
   388             node->arguments()->at(i)->accept(this);
   389     }
   390     void visitIfStatement(IfStatement *node) {
   391         node->ifTrue()->accept(this);
   392         if (node->ifFalse())
   393             node->ifFalse()->accept(this);
   394     }
   395     void visitIndexExpression(IndexExpression *node) {
   396         node->left()->accept(this);
   397         node->right()->accept(this);
   398     }
   399     void visitFloatLiteral(FloatLiteral *node) {
   400     }
   401     void visitWhileStatement(WhileStatement *node) {
   402         node->condition()->accept(this);
   403         node->body()->accept(this);
   404     }
   405     void visitBreakStatement(BreakStatement *node) {
   406     }
   407     void visitContinueStatement(ContinueStatement *node) {
   408     }
   409     void visitStringLiteral(StringLiteral *node) {
   410     }
   411     void visitIncDecExpression(IncDecExpression *node) {
   412         node->expression()->accept(this);
   413     }
   414     void visitUnaryExpression(UnaryExpression *node) {
   415         node->expression()->accept(this);
   416     }
   417     void visitTernaryExpression(TernaryExpression *node) {
   418         assert(false);
   419     }
   420     void visitBooleanLiteral(BooleanLiteral *node) {
   421     }
   422     void visitFieldExpression(FieldExpression *node) {
   423     }
   424     void visitSwitchStatement(SwitchStatement *node) {
   425         if (node->defaultCase())
   426             node->defaultCase()->accept(this);
   427 
   428         for (size_t i = 0; i < node->cases()->length(); i++)
   429             node->cases()->at(i)->statement()->accept(this);
   430     }
   431     void visitArrayLiteral(ArrayLiteral *node) {
   432     }
   433     void visitImportStatement(ImportStatement *node) {
   434     }
   435 
   436   private:
   437     Scope *getGlobalOrCreateBlockScope() {
   438         if (env_->scope()) {
   439             assert(env_->scope()->kind() == Scope::BLOCK ||
   440                    env_->scope()->kind() == Scope::GLOBAL);
   441             return env_->scope();
   442         }
   443         return getOrCreateBlockScope();
   444     }
   445     Scope *getOrCreateBlockScope() {
   446         if (env_->scope()) {
   447             assert(env_->scope()->kind() == Scope::BLOCK);
   448             return env_->scope();
   449         }
   450         
   451         LocalScope *scope = LocalScope::New(pool_);
   452         if (!scope)
   453             return NULL;
   454 
   455         env_->setScope(scope);
   456         return scope;
   457     }
   458 
   459     bool registerName(Scope *scope, Symbol *sym) {
   460         if (!scope)
   461             return false;
   462 
   463         if (Symbol *other = scope->localLookup(sym->name())) {
   464             // Report, but allow errors to continue.
   465             cc_.reportError(sym->pos(), Message_RedeclaredName,
   466                             sym->name()->chars(),
   467                             other->pos().line,
   468                             other->pos().col);
   469             return true;
   470         }
   471 
   472         return scope->addSymbol(sym);
   473     }
   474 
   475     bool registerArguments(const FunctionSignature &sig) {
   476         if (!sig.parameters()->length())
   477             return true;
   478 
   479         ArgumentScope *argScope = ArgumentScope::New(pool_);
   480         if (!argScope)
   481             return false;
   482         env_->setScope(argScope);
   483 
   484         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   485             Parameter *param = sig.parameters()->at(i);
   486             VariableSymbol *sym = new (pool_) VariableSymbol(argScope, param->name(), param->pos());
   487             if (!registerName(env_->scope(), sym))
   488                 return false;
   489             param->setSymbol(sym);
   490         }
   491 
   492         return true;
   493     }
   494 
   495   private:
   496     Zone *zone_;
   497     PoolAllocator &pool_;
   498     CompileContext &cc_;
   499     TranslationUnit *unit_;
   500     SymbolEnv *env_;
   501     FunctionScope *fun_;
   502 };
   503 
   504 void
   505 ke::PopulateNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   506 {
   507     AutoEnterCompileContext enter(cc, unit);
   508     NamePopulator populator(zone, cc, unit);
   509     populator.analyze();
   510 }
   511 
   512 static const int INFER_ARRAY_SIZE = 0;
   513 static const int EVAL_ARRAY_SIZE = -1;
   514 static const int DYNAMIC_ARRAY_SIZE = -2;
   515 
   516 class NameBinderBase : public AstVisitor
   517 {
   518   public:
   519     NameBinderBase(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   520       : zone_(zone),
   521         pool_(zone->pool()),
   522         cc_(cc),
   523         unit_(unit)
   524     {
   525     }
   526 
   527   protected:
   528     Type *buildVariableType(VariableDeclaration *node) {
   529         Local<Type> type(zone_, bindType(node->type(), node->quals()));
   530         if (!type)
   531             return NULL;
   532 
   533         // We don't allow array typedefs yet.
   534         assert(!type->isArray());
   535 
   536         if (node->dims()) {
   537             int dims[MAX_ARRAY_DEPTH];
   538             int levels = evaluateDimensions(node->pos(), type, node->dims(), dims);
   539             if (levels < 0)
   540                 return NULL;
   541 
   542             // Do some extra inference based on the initializer, if present.
   543             Expression *init = node->initialization();
   544             if (init) {
   545                 if (init->isArrayLiteral() && init->toArrayLiteral()->isFixed()) {
   546                     Local<Type> contained(zone_, type->isArray()
   547                                                  ? ArrayType::cast(type)->contained()
   548                                                  : type);
   549                     if (!inferFixedArrayDimensions(init->toArrayLiteral(), contained, dims, levels))
   550                         return NULL;
   551                 } else if (init->isStringLiteral()) {
   552                     dims[levels - 1] = init->toStringLiteral()->string()->length() + 1;
   553                 }
   554             }
   555 
   556             // If we got extra dimensions, we need to build a new type.
   557             if (node->dims()) {
   558                 if ((type = buildArrayType(type, node->quals(), dims, node->dims()->length())) == NULL)
   559                     return NULL;
   560             }
   561         }
   562 
   563         return type;
   564     }
   565 
   566     int evaluateDimensions(const SourcePosition &pos, Handle<Type> typeArg, ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH]) {
   567         unsigned level = 0;
   568         Local<Type> type(zone_, typeArg);
   569         while (type->isArray()) {
   570             ArrayType *atype = ArrayType::cast(type);
   571             dims[level] = atype->isFixedLength()
   572                           ? atype->fixedLength()
   573                           : DYNAMIC_ARRAY_SIZE;
   574             type = atype->contained();
   575             level++;
   576         }
   577 
   578         if (!exprs)
   579             return level;
   580 
   581         if (level + exprs->length() > MAX_ARRAY_DEPTH) {
   582             cc_.reportError(pos, Message_MaximumArrayDepth);
   583             return -1;
   584         }
   585 
   586         bool hadEmptySize = false;
   587         for (size_t i = 0; i < exprs->length(); i++) {
   588             Expression *expr = exprs->at(i);
   589             if (!expr) {
   590                 dims[i] = INFER_ARRAY_SIZE;
   591                 hadEmptySize = true;
   592                 continue;
   593             }
   594 
   595             BoxedPrimitive box;
   596             if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   597                 int size = box.toInt();
   598                 if (size <= 0) {
   599                     cc_.reportError(expr->pos(), Message_BadArraySize);
   600                     return false;
   601                 }
   602 
   603                 dims[i] = size;
   604                 continue;
   605             }
   606 
   607             if (hadEmptySize) {
   608                 cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   609                 return false;
   610             }
   611 
   612             dims[i] = EVAL_ARRAY_SIZE;
   613         }
   614 
   615         return level + exprs->length();
   616     }
   617 
   618     // This function computes missing dimension sizes based on a literal
   619     // initializer. We don't really handle any size rules here; we just
   620     // do a really dumb inference.
   621     bool inferFixedArrayDimensions(ArrayLiteral *lit, Handle<Type> contained, int dims[MAX_ARRAY_DEPTH], int levels) {
   622         for (int i = 0; i < levels; i++) {
   623             if (dims[i] == EVAL_ARRAY_SIZE || dims[i] == DYNAMIC_ARRAY_SIZE) {
   624                 // The following are invalid:
   625                 //   new x[<expr>] = {...}
   626                 //   new Type:x = {...}  // where Type is a non-fixed array type
   627                 cc_.reportError(lit->pos(), Message_CannotInitializeEvalArray);
   628                 return false;
   629             }
   630 
   631             if (dims[i] == INFER_ARRAY_SIZE) {
   632                 // Character arrays are always dynamic when inferred from string literals.
   633                 if (i == levels - 1 && contained->isChar())
   634                     dims[i] = DYNAMIC_ARRAY_SIZE;
   635                 else
   636                     dims[i] = lit->expressions()->length();
   637             }
   638 
   639             if (i != levels - 1) {
   640                 // Fixed array literals are guaranteed to have at least one expression.
   641                 Expression *next = lit->expressions()->at(0);
   642                 if (!next->isArrayLiteral()) {
   643                     // Whelp... this array is just malformed. Not the best error message
   644                     // but whatever.
   645                     cc_.reportError(next->pos(), Message_ArraySizeCannotBeDetermined);
   646                     return false;
   647                 }
   648                 lit = next->toArrayLiteral();
   649             }
   650         }
   651 
   652         return true;
   653     }
   654 
   655     ArrayType *buildArrayType(Handle<Type> contained, TypeQualifiers quals, int dims[MAX_ARRAY_DEPTH], size_t postlevels) {
   656         Local<Type> type(zone_, contained);
   657 
   658         for (size_t i = postlevels - 1; i < postlevels; i--) {
   659             int size = dims[i] > 0
   660                        ? dims[i]
   661                        : ArrayType::DYNAMIC_ARRAY_SIZE;
   662             
   663             if ((type = zone_->types()->newArray(contained, size)) == NULL)
   664                 return NULL;
   665             if ((type = zone_->types()->qualify(type, quals)) == NULL)
   666                 return NULL;
   667         }
   668         return ArrayType::cast(type);
   669     }
   670 
   671     bool fillFunctionType(Handle<FunctionType> fun, const FunctionSignature &sig) {
   672         Local<Type> type(zone_);
   673         if (!fun->returnType()) {
   674             if ((type = bindType(sig.returnType(), TypeQual_None)) == NULL)
   675                 return false;
   676             fun->setReturnType(type);
   677         }
   678 
   679         if (sig.variadic())
   680             fun->setVariadic();
   681 
   682         Local<FixedArray> params(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   683         if (!params)
   684             return false;
   685 
   686         for (size_t i = 0; i < sig.parameters()->length(); i++) {
   687             Parameter *param = sig.parameters()->at(i);
   688             if ((type = bindType(param->type(), param->quals())) == NULL)
   689                 return false;
   690 
   691             assert(!type->isArray());
   692 
   693             if (param->dims()) {
   694                 int dims[MAX_ARRAY_DEPTH];
   695                 int levels = evaluateDimensions(param->pos(), type, param->dims(), dims);
   696                 if (levels < 0)
   697                     return false;
   698 
   699                 // If we got extra dimensions, we need to build a new type.
   700                 // Unlike variables, we do not infer anything about array
   701                 // sizes from its default initializer.
   702                 if (param->dims()) {
   703                     if ((type = buildArrayType(type, param->quals(), dims, param->dims()->length())) == NULL)
   704                         return false;
   705                 }
   706 
   707                 if (ArrayType::cast(type)->innermost()->isVoid()) {
   708                     cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   709                     return false;
   710                 }
   711             }
   712 
   713             if (param->reference()) {
   714                 if (!type->isPod()) {
   715                     cc_.reportError(param->pos(), Message_ArrayCantBeReference);
   716                     return false;
   717                 }
   718                 if (param->quals() & TypeQual_Const) {
   719                     cc_.reportError(param->pos(), Message_CannotConstReference);
   720                     return false;
   721                 }
   722                 if ((type = zone_->types()->getReference(type, false)) == NULL)
   723                     return false;
   724             }
   725             if (param->quals() & TypeQual_Const) {
   726                 if (!type->isArray() && !type->isStruct()) {
   727                     cc_.reportError(param->pos(), Message_InvalidConstOnFormal);
   728                     return false;
   729                 }
   730             }
   731 
   732             if (type->isVoid()) {
   733                 cc_.reportError(param->type()->pos(), Message_CannotDeclareVoid);
   734                 return false;
   735             }
   736 
   737             params->set(zone_, i, type);
   738             param->sym()->setType(type);
   739         }
   740 
   741         fun->setParameterTypes(params);
   742 
   743         return true;
   744     }
   745 
   746     Type *bindType(Expression *expr, TypeQualifiers quals) {
   747         Local<Type> type(zone_);
   748 
   749         if (!expr) {
   750             // If no type was declared, we return int32.
   751             type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   752         } else {
   753             expr->accept(this);
   754 
   755             NameProxy *proxy = expr->asNameProxy();
   756             assert(proxy);
   757 
   758             Symbol *sym = proxy->sym();
   759             if (!sym)
   760                 return NULL;
   761 
   762             if (!sym->isType()) {
   763                 cc_.reportError(expr->pos(), Message_IdentifierIsNotAType, sym->name()->chars());
   764                 return NULL;
   765             }
   766 
   767             type = sym->toType()->effective();
   768         }
   769 
   770         return zone_->types()->qualify(type, quals);
   771     }
   772 
   773   protected:
   774     Zone *zone_;
   775     PoolAllocator &pool_;
   776     CompileContext &cc_;
   777     TranslationUnit *unit_;
   778 };
   779 
   780 class GlobalBuilder : public NameBinderBase
   781 {
   782     typedef ScopedRoot<Descriptor> ScopedDescriptor;
   783     struct PrimitiveFill {
   784         ScopedDescriptor *desc;
   785         BoxedPrimitive prim;
   786 
   787         PrimitiveFill(ScopedDescriptor *desc, BoxedPrimitive prim)
   788           : desc(desc),
   789             prim(prim)
   790         {
   791         }
   792     };
   793 
   794   public:
   795     GlobalBuilder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
   796       : NameBinderBase(zone, cc, unit),
   797         globalScope_(unit->globalScope())
   798     {
   799     }
   800 
   801     Struct *build() {
   802         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
   803             unit_->tree()->imports()->at(i)->accept(this);
   804 
   805         // Next, enter the global scope and walk all statements.
   806         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
   807             Statement *stmt = unit_->tree()->statements()->at(i);
   808             stmt->accept(this);
   809         }
   810 
   811         Local<Struct> globals(zone_, createGlobals());
   812         if (!globals)
   813             return NULL;
   814 
   815         populate(globals);
   816 
   817         return globals;
   818     }
   819 
   820   private:
   821     Struct *createGlobals() {
   822         Local<FixedArray> descs(zone_, FixedArray::New(zone_, descriptors_.length(), Heap::Tenure_Old));
   823         if (!descs)
   824             return NULL;
   825 
   826         for (unsigned i = 0; i < descriptors_.length(); i++)
   827             descs->set(zone_, i, *descriptors_[i]);
   828 
   829         Local<String> name(zone_, unit_->module()->name());
   830         Local<StructType> type(zone_, StructType::New(zone_, name, descs));
   831         if (!type)
   832             return NULL;
   833 
   834         Local<StructMap> map(zone_, type->newMap());
   835         return Struct::New(zone_, map, Heap::Tenure_Old);
   836     }
   837 
   838     void populate(Handle<Struct> globals) {
   839         // This is a huge hack, but it's probably better than a full extra
   840         // pass. The problem is that until we have all the descriptors, we
   841         // can't start setting constexprs in the struct, and we need to set
   842         // them now so they're available during full semantic analysis. To
   843         // work around this, we build up the list of values we need to set
   844         // as we build up descriptors, and then populate the global struct
   845         // with this set.
   846         //
   847         // Note, this code is also kind of dead until we support linking. We
   848         // handle constexprs explicitly in importFrom(), by sniffing out the
   849         // symbol type. That code will go away later.
   850         for (size_t i = 0; i < primitiveFills_.length(); i++) {
   851             const PrimitiveFill &fill = primitiveFills_[i];
   852             assert(fill.prim.type() == PrimitiveType_Int32);
   853             globals->set(*fill.desc, fill.prim.toInt());
   854         }
   855     }
   856 
   857   public:
   858     void visitEnumStatement(EnumStatement *stmt) {
   859         if (stmt->visibility() != TOK_PUBLIC || !stmt->name())
   860             return;
   861 
   862         Local<Type> type(zone_, zone_->types()->getType());
   863         Descriptor *desc = Descriptor::New(zone_, stmt->name(), type, Descriptor::Public);
   864         if (!desc)
   865             return;
   866         if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
   867             return;
   868 
   869         for (size_t i = 0; i < stmt->entries()->length(); i++) {
   870             EnumStatement::Entry &e = stmt->entries()->at(i);
   871             ScopedDescriptor *desc = new (pool_) ScopedDescriptor(Descriptor::New(zone_, e.name, e.sym->type(), Descriptor::Public));
   872             if (!desc || !descriptors_.append(desc))
   873                 return;
   874 
   875             // Save the value so we can export it immediately.
   876             if (!primitiveFills_.append(PrimitiveFill(desc, e.sym->value())))
   877                 return;
   878         }
   879     }
   880 
   881     void visitNameProxy(NameProxy *proxy) {
   882         Scope *scope = unit_->globalScope();
   883         Symbol *sym = scope->lookup(proxy->name());
   884         if (!sym)
   885             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
   886         proxy->bind(sym);
   887     }
   888 
   889     void visitFunctionStatement(FunctionStatement *node) {
   890         Local<FunctionType> type(zone_, node->sym()->type());
   891         if (!fillFunctionType(type, node->signature()))
   892             return;
   893 
   894         unsigned offset;
   895         if (!builder_.add(type, &offset))
   896             return;
   897 
   898         Descriptor::Visibility visibility = (node->token() == TOK_NATIVE || node->token() == TOK_FORWARD)
   899                                             ? Descriptor::Public
   900                                             : Descriptor::Private;
   901 
   902         Descriptor *desc = Descriptor::New(zone_, node->name(), type, visibility);
   903         if (!desc)
   904             return;
   905         if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
   906             return;
   907     }
   908 
   909     void visitVariableDeclaration(VariableDeclaration *node) {
   910         Local<Type> type(zone_, buildVariableType(node));
   911         if (!type)
   912             return;
   913 
   914         // If we're in global scope, and we received a |const| qualifier, then
   915         // we extend this to array references as well. This is to sort of mimic
   916         // SP1 functionality, but also means that you cannot have changeable
   917         // const pointers in global scope.
   918         if ((node->quals() & TypeQual_Const) && type->isArray()) {
   919             if ((type = zone_->types()->qualify(type, TypeQual_Const)) == NULL)
   920                 return;
   921         }
   922 
   923         node->sym()->setType(type);
   924 
   925         unsigned offset;
   926         if (!builder_.add(type, &offset))
   927             return;
   928 
   929         Descriptor *desc = Descriptor::New(zone_, node->name(), type, Descriptor::Private);
   930         if (!desc)
   931             return;
   932         if (!descriptors_.append(new (pool_) ScopedRoot<Descriptor>(desc)))
   933             return;
   934     }
   935 
   936     void visitImportStatement(ImportStatement *node) {
   937         if (!node->names()) {
   938             PathComponent *path = node->path();
   939             while (path->next)
   940                 path = path->next;
   941 
   942             // Imports automatically go into the importScope. For now, we
   943             // error if there are any duplicate symbols entered into the
   944             // importScope.
   945             if (unit_->importScope()->localLookup(path->name)) {
   946                 cc_.reportError(node->pos(), Message_DuplicateImport, path->name->chars());
   947                 return;
   948             }
   949 
   950             Local<Type> type(zone_, zone_->types()->getImportable());
   951             ImportSymbol *sym = new (pool_) ImportSymbol(unit_->importScope(), path->name, node->pos(), type, node->importIndex());
   952             if (!unit_->importScope()->addSymbol(sym))
   953                 return;
   954         } else if (node->importAllNames()) {
   955             Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
   956             if (importable->isPackage()) {
   957                 assert(false);
   958             } else {
   959                 Local<Module> module(zone_, Module::cast(importable));
   960                 if (!module->globals())
   961                     importAllFromTranslationUnit(node, module->translationUnit());
   962                 else
   963                     assert(false);
   964             }
   965         } else {
   966             Local<Importable> importable(zone_, unit_->module()->getImportAt(node->importIndex()));
   967             if (importable->isPackage()) {
   968                 assert(false);
   969             } else {
   970                 Local<Module> module(zone_, Module::cast(importable));
   971 
   972                 // Always grab from the translation unit if we can, for now.
   973                 if (module->translationUnit())
   974                     importFromTranslationUnit(node, module->translationUnit());
   975                 else
   976                     assert(false);
   977             }
   978         }
   979     }
   980 
   981   private:
   982     bool importFrom(ImportStatement *node, Symbol *import) {
   983         assert(import->type());
   984 
   985         // Check for duplicate import names.
   986         if (unit_->importScope()->localLookup(import->name())) {
   987             cc_.reportError(node->pos(), Message_DuplicateImport, import->name()->chars());
   988             return false;
   989         }
   990 
   991         Symbol *sym;
   992         if (import->isType()) {
   993             // Fuck it, make a TypeSymbol instead of an ImplicitSymbol. This
   994             // makes bindType() much simpler. We may run into problems
   995             // implementing linking, but it seems unlikely, as long as we are
   996             // exporting Types in module structs.
   997             Local<Type> type(zone_, zone_->types()->getType());
   998             sym = new (pool_) TypeSymbol(unit_->importScope(),
   999                                          import->name(),
  1000                                          type,
  1001                                          import->toType()->effective());
  1002         } else if (import->isConstant()) {
  1003             // Same deal. No reason to lookup in the module globals if we
  1004             // already have a symbol.
  1005             sym = new (pool_) ConstantSymbol(unit_->importScope(),
  1006                                              import->name(),
  1007                                              node->pos(),
  1008                                              import->type(),
  1009                                              import->toConstant()->value());
  1010         } else {
  1011             sym = new (pool_) ImplicitSymbol(unit_->importScope(),
  1012                                              import->name(),
  1013                                              node->pos(),
  1014                                              import->type(),
  1015                                              node->importIndex());
  1016         }
  1017 
  1018         if (!unit_->importScope()->addSymbol(sym))
  1019             return false;
  1020 
  1021         return true;
  1022     }
  1023 
  1024     void importFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
  1025         assert(!other->failed());
  1026 
  1027         for (size_t i = 0; i < node->names()->length(); i++) {
  1028             Handle<String> name = *node->names()->at(i);
  1029 
  1030             // See if the name exists in the other translation unit.
  1031             Symbol *import = other->globalScope()->findExported(name);
  1032             if (!import) {
  1033                 FixedArray *path = unit_->module()->importPathAt(node->importIndex());
  1034                 cc_.reportError(node->pos(), Message_NotFoundInImportable,
  1035                                 name->chars(),
  1036                                 String::cast(path->at(path->length() - 1))->chars());
  1037                 return;
  1038             }
  1039 
  1040             if (!importFrom(node, import))
  1041                 return;
  1042         }
  1043     }
  1044 
  1045     void importAllFromTranslationUnit(ImportStatement *node, TranslationUnit *other) {
  1046         assert(!other->failed());
  1047 
  1048         for (size_t i = 0; i < other->globalScope()->exported()->length(); i++) {
  1049             Symbol *import = other->globalScope()->exported()->at(i);
  1050             if (!importFrom(node, import))
  1051                 return;
  1052         }
  1053     }
  1054 
  1055   private:
  1056     StructureBufferBuilder builder_;
  1057     Vector<ScopedRoot<Descriptor> *> descriptors_;
  1058     GlobalScope *globalScope_;
  1059     Vector<PrimitiveFill> primitiveFills_;
  1060 };
  1061     
  1062 class NameBinder : public NameBinderBase
  1063 {
  1064   public:
  1065     class AutoLinkScope
  1066     {
  1067       public:
  1068         AutoLinkScope(AutoLinkScope **prevp, Scope *scope)
  1069           : prevp_(prevp),
  1070             prev_(*prevp),
  1071             scope_(scope)
  1072         {
  1073             if (scope_) {
  1074                 *prevp_ = this;
  1075                 if (prev_)
  1076                     scope_->setParent(prev_->scope());
  1077             }
  1078         }
  1079         ~AutoLinkScope() {
  1080             if (scope_) {
  1081                 assert(*prevp_ == this);
  1082                 *prevp_ = prev_;
  1083             }
  1084         }
  1085         Scope *scope() const {
  1086             return scope_;
  1087         }
  1088 
  1089       private:
  1090         AutoLinkScope **prevp_;
  1091         AutoLinkScope *prev_;
  1092         Scope *scope_;
  1093     };
  1094 
  1095   public:
  1096     NameBinder(Zone *zone, CompileContext &cc, TranslationUnit *unit)
  1097       : NameBinderBase(zone, cc, unit),
  1098         link_(NULL)
  1099     {
  1100     }
  1101 
  1102     void bind() {
  1103         // Start with the import scope, and collect all imported names.
  1104         AutoLinkScope importScope(&link_, unit_->importScope());
  1105 
  1106         for (size_t i = 0; i < unit_->tree()->imports()->length(); i++)
  1107             unit_->tree()->imports()->at(i)->accept(this);
  1108 
  1109         // Next, enter the global scope and walk all statements.
  1110         AutoLinkScope globalScope(&link_, unit_->globalScope());
  1111         for (size_t i = 0; i < unit_->tree()->statements()->length(); i++) {
  1112             Statement *stmt = unit_->tree()->statements()->at(i);
  1113             stmt->accept(this);
  1114         }
  1115     }
  1116 
  1117     void visitVariableDeclaration(VariableDeclaration *node) {
  1118         // Bind the initializer before registering the declaration, so that we
  1119         // can error on bogus initializers (new x = x).
  1120         if (node->initialization())
  1121             node->initialization()->accept(this);
  1122 
  1123         // If the node already has a symbol (meaning it was a global), then
  1124         // we don't have to do anything more.
  1125         if (node->sym())
  1126             return;
  1127 
  1128         Local<Type> type(zone_, buildVariableType(node));
  1129         if (!type)
  1130             return;
  1131 
  1132         VariableSymbol *sym = new (pool_) VariableSymbol(link_->scope(), node->name(), node->pos(), type);
  1133         node->setSymbol(sym);
  1134        
  1135         if (Symbol *other = link_->scope()->localLookup(sym->name())) {
  1136             // Report, but allow errors to continue.
  1137             cc_.reportError(sym->pos(), Message_RedeclaredName,
  1138                             sym->name()->chars(),
  1139                             other->pos().line,
  1140                             other->pos().col);
  1141             return;
  1142         }
  1143         
  1144         link_->scope()->addSymbol(sym);
  1145     }
  1146     void visitEnumStatement(EnumStatement *node) {
  1147     }
  1148     void visitFunctionStatement(FunctionStatement *node) {
  1149         AutoLinkScope argScope(&link_, node->argScope());
  1150         AutoLinkScope varScope(&link_, node->varScope());
  1151 
  1152         // If the function is in the global scope, we've already computed its
  1153         // type.
  1154         if (node->sym()->scope()->kind() != Scope::GLOBAL) {
  1155             Local<FunctionType> type(zone_, node->sym()->type());
  1156             if (!fillFunctionType(type, node->signature()))
  1157                 return;
  1158         }
  1159 
  1160         if (node->body())
  1161             node->body()->accept(this);
  1162     }
  1163     void visitStructureStatement(StructureStatement *node) {
  1164         assert(false);
  1165     }
  1166     void visitFunctionTypeStatement(FunctionTypeStatement *node) {
  1167         assert(false);
  1168     }
  1169 
  1170     void visitNameProxy(NameProxy *proxy) {
  1171         // We could have already bound globals.
  1172         if (proxy->sym())
  1173             return;
  1174 
  1175         Scope *scope = link_->scope();
  1176         Symbol *sym = scope->lookup(proxy->name());
  1177         if (!sym)
  1178             cc_.reportError(proxy->pos(), Message_IdentifierNotFound, proxy->name()->chars());
  1179         proxy->bind(sym);
  1180     }
  1181     void visitAssignment(Assignment *node) {
  1182         node->lvalue()->accept(this);
  1183         node->expression()->accept(this);
  1184     }
  1185     void visitBinaryExpression(BinaryExpression *node) {
  1186         node->left()->accept(this);
  1187         node->right()->accept(this);
  1188     }
  1189     void visitReturnStatement(ReturnStatement *node) {
  1190         node->expression()->accept(this);
  1191     }
  1192     void visitForStatement(ForStatement *node) {
  1193         AutoLinkScope scope(&link_, node->scope());
  1194 
  1195         if (node->initialization())
  1196             node->initialization()->accept(this);
  1197         if (node->condition())
  1198             node->condition()->accept(this);
  1199         if (node->update())
  1200             node->update()->accept(this);
  1201         node->body()->accept(this);
  1202     }
  1203     void visitBlockStatement(BlockStatement *node) {
  1204         AutoLinkScope scope(&link_, node->scope());
  1205         for (size_t i = 0; i < node->statements()->length(); i++)
  1206             node->statements()->at(i)->accept(this);
  1207     }
  1208     void visitIntegerLiteral(IntegerLiteral *node) {
  1209     }
  1210     void visitExpressionStatement(ExpressionStatement *node) {
  1211         node->expression()->accept(this);
  1212     }
  1213     void visitCallExpression(CallExpression *node) {
  1214         node->callee()->accept(this);
  1215         for (size_t i = 0; i < node->arguments()->length(); i++)
  1216             node->arguments()->at(i)->accept(this);
  1217     }
  1218     void visitIfStatement(IfStatement *node) {
  1219         node->condition()->accept(this);
  1220         node->ifTrue()->accept(this);
  1221         if (node->ifFalse())
  1222             node->ifFalse()->accept(this);
  1223     }
  1224     void visitIndexExpression(IndexExpression *node) {
  1225         node->left()->accept(this);
  1226         node->right()->accept(this);
  1227     }
  1228     void visitFloatLiteral(FloatLiteral *node) {
  1229     }
  1230     void visitWhileStatement(WhileStatement *node) {
  1231         node->condition()->accept(this);
  1232         node->body()->accept(this);
  1233     }
  1234     void visitBreakStatement(BreakStatement *node) {
  1235     }
  1236     void visitContinueStatement(ContinueStatement *node) {
  1237     }
  1238     void visitStringLiteral(StringLiteral *node) {
  1239     }
  1240     void visitIncDecExpression(IncDecExpression *node) {
  1241         node->expression()->accept(this);
  1242     }
  1243     void visitUnaryExpression(UnaryExpression *node) {
  1244         if (node->tag())
  1245             node->tag()->accept(this);
  1246         node->expression()->accept(this);
  1247     }
  1248     void visitTernaryExpression(TernaryExpression *node) {
  1249         node->condition()->accept(this);
  1250         node->left()->accept(this);
  1251         node->right()->accept(this);
  1252     }
  1253     void visitBooleanLiteral(BooleanLiteral *node) {
  1254     }
  1255     void visitFieldExpression(FieldExpression *node) {
  1256         node->left()->accept(this);
  1257     }
  1258     void visitSwitchStatement(SwitchStatement *node) {
  1259         node->expression()->accept(this);
  1260         node->defaultCase()->accept(this);
  1261         for (size_t i = 0; i < node->cases()->length(); i++) {
  1262             // We don't test case expressions because they are literals.
  1263             Case *c = node->cases()->at(i);
  1264             c->statement()->accept(this);
  1265         }
  1266     }
  1267     void visitArrayLiteral(ArrayLiteral *node) {
  1268         for (size_t i = 0; i < node->expressions()->length(); i++)
  1269             node->expressions()->at(i)->accept(this);
  1270     }
  1271     void visitImportStatement(ImportStatement *node) {
  1272     }
  1273 
  1274   private:
  1275     AutoLinkScope *link_;
  1276 };
  1277 
  1278 void
  1279 ke::BindGlobals(Zone *zone, CompileContext &cc, TranslationUnit *unit)
  1280 {
  1281     AutoEnterCompileContext enter(cc, unit);
  1282 
  1283     GlobalBuilder builder(zone, cc, unit);
  1284     Local<Struct> globals(zone, builder.build());
  1285     if (!globals || unit->failed())
  1286         return;
  1287 
  1288     unit->module()->setGlobals(globals);
  1289 }
  1290 
  1291 void
  1292 ke::BindNamesAndTypes(Zone *zone, CompileContext &cc, TranslationUnit *unit)
  1293 {
  1294     AutoEnterCompileContext enter(cc, unit);
  1295     NameBinder binder(zone, cc, unit);
  1296     binder.bind();
  1297 }