src/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Sun Sep 16 19:02:23 2012 -0700 (2012-09-16)
changeset 187 9308d52205a0
parent 185 10936f3a2ba3
child 188 bab29bcec7fe
permissions -rw-r--r--
Add support for SP1-style fixed array initializers.
     1 /* vim: set ts=4 sw=4 tw=99 et:
     2  *
     3  * Copyright (C) 2012 David Anderson
     4  *
     5  * This file is part of JITCraft.
     6  *
     7  * JITCraft is free software: you can redistribute it and/or modify it under
     8  * the terms of the GNU General Public License as published by the Free
     9  * Software Foundation, either version 3 of the License, or (at your option)
    10  * any later version.
    11  * 
    12  * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    14  * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    15  *
    16  * You should have received a copy of the GNU General Public License along with
    17  * JITCraft. If not, see http://www.gnu.org/licenses/.
    18  */
    19 #include <string.h>
    20 #include "SemanticAnalysis.h"
    21 #include "Types.h"
    22 #include "Zone.h"
    23 #include "TypeManager.h"
    24 #include "Scopes.h"
    25 #include "NameBinding.h"
    26 #include "Strings.h"
    27 #include "Box.h"
    28 #include "Array.h"
    29 #include "Heap-inl.h"
    30 
    31 using namespace ke;
    32 
    33 static inline bool
    34 IsPrimitiveType(Type *type, PrimitiveType primitive)
    35 {
    36     if (!type)
    37         return false;
    38 
    39     if (!type->isPrimitive())
    40         return false;
    41 
    42     return primitive == type->primitive();
    43 }
    44 
    45 static inline bool
    46 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    47                         BoxedPrimitive *out)
    48 {
    49     switch (kind) {
    50       case TOK_PLUS:
    51         *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    52         return true;
    53 
    54       case TOK_SHL:
    55         *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    56         return true;
    57 
    58       default:
    59         return false;
    60     }
    61 }
    62 
    63 static inline bool
    64 EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
    65 {
    66   switch (kind) {
    67     case TOK_MINUS:
    68       *out = BoxedPrimitive::Int(-inner.toInt());
    69       return true;
    70 
    71     default:
    72       return false;
    73   }
    74 }
    75 
    76 static bool
    77 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
    78 {
    79     switch (expression->kind()) {
    80       case AstNode::kBinaryExpression:
    81       {
    82         BoxedPrimitive left;
    83         BoxedPrimitive right;
    84         BinaryExpression *b = expression->toBinaryExpression();
    85         if (!EvaluateForConstant(b->left(), &left) ||
    86             !EvaluateForConstant(b->right(), &right))
    87         {
    88             return false;
    89         }
    90         return EvaluateBinaryOperation(b->token(), left, right, out);
    91       }
    92 
    93       case AstNode::kUnaryExpression:
    94       {
    95         BoxedPrimitive inner;
    96         UnaryExpression *u = expression->toUnaryExpression();
    97         if (!EvaluateForConstant(u->expression(), &inner))
    98             return false;
    99         return EvaluateUnaryOperation(u->token(), inner, out);
   100       }
   101 
   102       case AstNode::kNameProxy:
   103       {
   104         NameProxy *proxy = expression->toNameProxy();
   105         if (proxy->binding()->kind() != BoundName::CONSTANT)
   106             return false;
   107 
   108         NamedConstant *c = proxy->binding()->toNamedConstant();
   109         if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
   110             return false;
   111 
   112         *out = c->value();
   113         return true;
   114       }
   115 
   116       case AstNode::kBooleanLiteral:
   117         *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
   118         return true;
   119 
   120       case AstNode::kIntegerLiteral:
   121         *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
   122         return true;
   123 
   124       default:
   125         return false;
   126     }
   127 }
   128 
   129 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
   130   : zone_(zone),
   131     cc_(cc),
   132     tree_(tree),
   133     scope_(NULL),
   134     loop_(NULL)
   135 {
   136 }
   137 
   138 bool
   139 SemanticAnalysis::analyze()
   140 {
   141     if (cc_.failures())
   142         return false;
   143 
   144     scope_ = tree_->scope();
   145 
   146     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   147         Statement *statement = tree_->statements()->at(i);
   148         if (statement->isFunctionStatement()) {
   149             FunctionStatement *funstmt = statement->toFunctionStatement();
   150             if (!preanalyze(funstmt))
   151                 return false;
   152         } else if (statement->isEnumStatement()) {
   153             EnumStatement *enumstmt = statement->toEnumStatement();
   154 
   155             // We pre-fill global enum types, since they may occur in function
   156             // signatures. This should probably be somewhere else...
   157             enumstmt->accept(this);
   158         } else if (statement->isStructureStatement()) {
   159             StructureStatement *node = statement->toStructureStatement();
   160             node->accept(this);
   161             if (!node->decl()->type())
   162                 return false;
   163         } else if (statement->isFunctionTypeStatement()) {
   164             FunctionTypeStatement *node = statement->toFunctionTypeStatement();
   165             node->accept(this);
   166             if (!node->decl()->type())
   167                 return false;
   168         }
   169     }
   170 
   171     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   172         Statement *statement = tree_->statements()->at(i);
   173 
   174         // We can't double-process these. Maybe put this check somewhere else.
   175         if (statement->isEnumStatement())
   176             continue;
   177 
   178         statement->accept(this);
   179     }
   180 
   181     if (!determineLiveFunctions())
   182         return false;
   183 
   184     return !cc_.failures();
   185 }
   186 
   187 bool
   188 SemanticAnalysis::determineLiveFunctions()
   189 {
   190     Vector<NamedFunction *> worklist;
   191 
   192     // Add the root set.
   193     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   194         Statement *statement = tree_->statements()->at(i);
   195         if (!statement->isFunctionStatement())
   196             continue;
   197 
   198         FunctionStatement *stmt = statement->toFunctionStatement();
   199         NamedFunction  *fun = stmt->fun();
   200         if (!fun->used())
   201             continue;
   202 
   203         for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   204             NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   205 
   206             // Names in these lists are always unused, however, we mark them
   207             // as used while inserting into the work queue, to avoid double-
   208             // insertion.
   209             if (name->used())
   210                 continue;
   211 
   212             if (!worklist.append(name))
   213                 return false;
   214 
   215             name->setUsed();
   216         }
   217     }
   218 
   219     while (!worklist.empty()) {
   220         NamedFunction *fun = worklist.popCopy();
   221 
   222         for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   223             NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   224             if (name->used())
   225                 continue;
   226             if (!worklist.append(name))
   227                 return false;
   228             name->setUsed();
   229         }
   230     }
   231 
   232     return true;
   233 }
   234 
   235 Type *
   236 SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
   237 {
   238     if (!name)
   239         return zone_->types()->getPrimitive(PrimitiveType_Int32);
   240 
   241     if (name->kind() == BoundName::UNBOUND) {
   242         cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
   243         return NULL;
   244     }
   245 
   246     if (name->kind() != BoundName::TYPE) {
   247         cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
   248         return NULL;
   249     }
   250 
   251     if (!name->type())
   252         return NULL;
   253 
   254     return name->type();
   255 }
   256 
   257 Type *
   258 SemanticAnalysis::visitAndApplyType(Expression *expression)
   259 {
   260     expression->accept(this);
   261     return expression->type();
   262 }
   263 
   264 Type *
   265 SemanticAnalysis::visitForLoad(Expression *expression)
   266 {
   267     Local<Type> type(zone_, visitAndApplyType(expression));
   268     if (!type)
   269         return NULL;
   270 
   271     if (type->isReference()) {
   272         expression->setType(type->contained());
   273     } else if (expression->isCallExpression()) {
   274         if (type->isVoid()) {
   275             CallExpression *call = expression->toCallExpression();
   276             cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
   277             return NULL;
   278         }
   279     }
   280 
   281     return expression->type();
   282 }
   283 
   284 // :TODO: this leaks an interior pointer.
   285 const char *
   286 ke::GetTypeName(Type *type)
   287 {
   288     if (type->isArray())
   289         return "array";
   290     if (type->isFunction())
   291         return "function";
   292     if (type->isVoid())
   293         return "void";
   294     if (type->isEnum() || type->isStruct())
   295         return type->name()->chars();
   296     if (type->isReference())
   297         type = type->contained();
   298     switch (type->primitive()) {
   299       case PrimitiveType_Bool:
   300         return "bool";
   301       case PrimitiveType_Char:
   302         return "String";
   303       case PrimitiveType_Int32:
   304         return "int";
   305       case PrimitiveType_Float:
   306         return "Float";
   307       default:
   308         return "<unknown>";
   309     }
   310 }
   311 
   312 void
   313 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
   314 {
   315     const char *op = TokenNames[token];
   316     const char *name = GetTypeName(type);
   317 
   318     cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   319 }
   320 
   321 void
   322 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   323 {
   324     const char *op = TokenNames[token];
   325     const char *leftName = GetTypeName(left);
   326     const char *rightName = GetTypeName(right);
   327 
   328     cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   329 }
   330 
   331 Type *
   332 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   333 {
   334     if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   335         (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   336     {
   337         // If either side is a float, the other side must be a float or int.
   338         if (left->isFloat() || right->isFloat()) {
   339             Type *floatType = left->isFloat() ? left : right;
   340             Type *other = left->isFloat() ? right : left;
   341             if (other->isFloat() || other->isInt32())
   342                 return floatType;
   343         }
   344     }
   345 
   346     if (token == TOK_OR || token == TOK_AND) {
   347         if (!canTest(node, left) || !canTest(node, right))
   348             return NULL;
   349         return zone_->types()->getPrimitive(PrimitiveType_Bool);
   350     }
   351 
   352     if (token >= TOK_EQUALS && token <= TOK_GE) {
   353         if ((left->isFloat() || left->isInt32()) &&
   354             (right->isFloat() || right->isInt32()))
   355         {
   356             return zone_->types()->getPrimitive(PrimitiveType_Bool);
   357         }
   358         binaryTypeError(node, token, left, right);
   359         return NULL;
   360     }
   361 
   362     if (!left->isInt32() || !right->isInt32()) {
   363         binaryTypeError(node, token, left, right);
   364         return NULL;
   365     }
   366 
   367     return left;
   368 }
   369 
   370 bool
   371 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
   372 {
   373     if (!type->isPrimitive() && !type->isEnum()) {
   374         cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   375         return false;
   376     }
   377     return true;
   378 }
   379 
   380 Type *
   381 SemanticAnalysis::visitForLValue(Expression *expression)
   382 {
   383     if (expression->isIndexExpression()) {
   384         Type *type = visitAndApplyType(expression);
   385         if (!type)
   386             return NULL;
   387 
   388         // if (type->isConst()) {
   389         //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   390         //     return NULL;
   391         // }
   392 
   393         return type;
   394     }
   395 
   396     if (expression->isFieldExpression()) {
   397         Type *type = visitAndApplyType(expression);
   398         if (!type)
   399             return NULL;
   400 
   401         // if (expression->toFieldExpression()->left()->type()->isConst()) {
   402         //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   403         //     return NULL;
   404         // }
   405 
   406         return type;
   407     }
   408 
   409     if (!expression->isNameProxy()) {
   410         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   411         return NULL;
   412     }
   413 
   414     NameProxy *proxy = expression->toNameProxy();
   415     if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   416         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   417         return NULL;
   418     }
   419 
   420     Variable *var = proxy->binding()->toVariable();
   421     if (!var->type())
   422         return NULL;
   423 
   424     if  (var->type()->isReference()) {
   425         if (var->type()->isConst()) {
   426             cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   427             return NULL;
   428         }
   429         return var->type()->contained();
   430     }
   431     return var->type();
   432 }
   433 
   434 SemanticAnalysis::ControlStatus
   435 SemanticAnalysis::visitForControl(Statement *statement)
   436 {
   437     ControlScope scope(&control_);
   438     statement->accept(this);
   439     return scope.status();
   440 }
   441 
   442 void
   443 SemanticAnalysis::visit(NameProxy *name)
   444 {
   445     BoundName *binding = name->binding();
   446 
   447     if (binding->scope()->kind() == Scope::GLOBAL) {
   448         if (!function_ || function_->isPublic()) {
   449             // Whatever we're referencing must be kept alive no matter what.
   450             // As such, we simply mark it used, and don't do anything special.
   451             binding->setUsed();
   452         } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
   453             // Otherwise, we're inside a normal stock or function. Since we
   454             // don't really know if we've been used yet, we shouldn't
   455             // prematurely references as alive. Instead, we keep a list of
   456             // which names have been used, so we can mark them later if needed.
   457             //
   458             // Note that we skip this step if the binding is already in the
   459             // root set.
   460             if (!function_->addUsedGlobal(binding))
   461                 return;
   462         }
   463     }
   464 
   465     name->setType(binding->type());
   466 }
   467 
   468 void
   469 SemanticAnalysis::visit(Assignment *node)
   470 {
   471     Local<Type> exprType(zone_, visitForLoad(node->expression()));
   472     if (!exprType)
   473         return ;
   474 
   475     Local<Type> type(zone_, visitForLValue(node->lvalue()));
   476     if (!type)
   477         return;
   478 
   479     if (node->token() != TOK_ASSIGN) {
   480         if (!typeCheckBinary(node, node->token(), type, exprType))
   481             return;
   482     }
   483 
   484     if (!typeCheckAssignment(node->pos(), exprType, type, true))
   485         return;
   486 
   487     node->setType(type);
   488 }
   489 
   490 void
   491 SemanticAnalysis::visit(IncDecExpression *node)
   492 {
   493     Local<Type> type(zone_, visitForLValue(node->expression()));
   494     if (!type)
   495         return;
   496 
   497     assert(!type->isReference());
   498 
   499     if (!type->isInt32() && !type->isFloat()) {
   500         unaryTypeError(node, node->token(), type);
   501         return;
   502     }
   503 
   504     node->setType(type);
   505 }
   506 
   507 void
   508 SemanticAnalysis::visit(UnaryExpression *node)
   509 {
   510     Local<Type> type(zone_, visitForLoad(node->expression()));
   511     if (!type)
   512         return;
   513 
   514     switch (node->token())
   515     {
   516       case TOK_NOT:
   517         if (!canTest(node->expression(), type))
   518             return;
   519         type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   520         if (!type)
   521             return;
   522         node->setType(type);
   523         break;
   524 
   525       case TOK_MINUS:
   526         if (!type->isFloat() && !type->isInt32()) {
   527             unaryTypeError(node, node->token(), type);
   528             return;
   529         }
   530         node->setType(type);
   531         break;
   532 
   533       case TOK_LABEL:
   534       {
   535         Local<Type> to(zone_, bindType(node->pos(), node->type()));
   536         if (!to)
   537             return;
   538 
   539         if ((!type->isFloat() && !type->isInt32OrEnum()) ||
   540             (!to->isFloat() && !to->isInt32OrEnum()))
   541         {
   542             unaryTypeError(node, node->token(), type);
   543             return;
   544         }
   545 
   546         node->setType(to);
   547         break;
   548       }
   549 
   550       default:
   551         assert(node->token() == TOK_TILDE);
   552         if (!type->isInt32()) {
   553             unaryTypeError(node, node->token(), type);
   554             return;
   555         }
   556         node->setType(type);
   557         break;
   558     }
   559 }
   560 
   561 void
   562 SemanticAnalysis::visit(TernaryExpression *node)
   563 {
   564     Local<Type> type(zone_, visitForLoad(node->condition()));
   565     if (!type)
   566         return;
   567 
   568     if (!canTest(node->condition(), type))
   569         return;
   570 
   571     Local<Type> left(zone_, visitForLoad(node->left()));
   572     Local<Type> right(zone_, visitForLoad(node->right()));
   573     if (!left || !right)
   574         return;
   575 
   576     if (left != right) {
   577         binaryTypeError(node, TOK_QMARK, left, right);
   578         return;
   579     }
   580 }
   581 
   582 void
   583 SemanticAnalysis::visit(BinaryExpression *node)
   584 {
   585     Local<Type> left(zone_, visitForLoad(node->left()));
   586     Local<Type> right(zone_, visitForLoad(node->right()));
   587     if (!left || !right)
   588         return;
   589 
   590     Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
   591     if (!result)
   592         return;
   593 
   594     node->setType(result);
   595 }
   596 
   597 void
   598 SemanticAnalysis::visit(ReturnStatement *node)
   599 {
   600     // Set this early, so if we error we don't get more errors.
   601     control_->returns(Returns_Always);
   602 
   603     if (!node->expression()) {
   604         if (!function_->type()->returnType()->isVoid())
   605             cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
   606         return;
   607     }
   608 
   609     Local<Type> type(zone_, visitForLoad(node->expression()));
   610     if (!type)
   611         return;
   612 
   613     Local<Type> returnType(zone_, function_->type()->returnType());
   614     if (!typeCheckAssignment(node->pos(), type, returnType, true))
   615         return;
   616 }
   617 
   618 void
   619 SemanticAnalysis::visit(ForStatement *node)
   620 {
   621     LoopScope loop(&loop_);
   622 
   623     if (node->scope())
   624         scope_ = node->scope();
   625 
   626     if (node->initialization())
   627         node->initialization()->accept(this);
   628 
   629     if (node->condition()) {
   630         Local<Type> type(zone_, visitForLoad(node->condition()));
   631         if (!type || !canTest(node->condition(), type)) {
   632             return;
   633         }
   634     }
   635 
   636     if (node->update())
   637         node->update()->accept(this);
   638 
   639     ControlStatus status = visitForControl(node->body());
   640 
   641     // If there is a condition, we treat this like a while loop. Otherwise,
   642     // join point is only reachable if the loop contains a break. The
   643     // termination status doesn't tell us anything yet.
   644     if (node->condition() || loop.breaks())
   645         control_->merge(status, ControlStatus(false, Returns_Never));
   646     else
   647         control_->terminate(status.returns());
   648 
   649     if (node->scope())
   650         scope_ = scope_->enclosing();
   651 }
   652 
   653 void 
   654 SemanticAnalysis::visit(WhileStatement *node)
   655 {
   656     LoopScope loop(&loop_);
   657 
   658     Local<Type> type(zone_, visitForLoad(node->condition()));
   659     if (!type || !canTest(node->condition(), type)) {
   660         return;
   661     }
   662 
   663     ControlStatus status = visitForControl(node->body());
   664 
   665     // Detect loops that will always have a fork in the control-flow graph.
   666     // This will be a |while| loop, or a |do-while| loop whose body does
   667     // not terminate.
   668     //
   669     // For now, we treat these as an |if| regardless of the direction the
   670     // branch can take. That means the control-flow is always conditional.
   671     if (node->token() == TOK_WHILE ||
   672         !status.terminates() ||
   673         loop.breaks())
   674     {
   675         control_->merge(status, ControlStatus(false, Returns_Never));
   676     } else {
   677         // At this point, we've got a do-while loop with a |return| or
   678         // |continue|, meaning that the rest of the block is unreachable.
   679         control_->terminate(status.returns());
   680     }
   681 }
   682 
   683 void
   684 SemanticAnalysis::visit(BlockStatement *node)
   685 {
   686     if (node->scope())
   687         scope_ = node->scope();
   688     for (size_t i = 0; i < node->statements()->length(); i++) {
   689         Statement *statement = node->statements()->at(i);
   690         statement->accept(this);
   691     }
   692     if (node->scope())
   693         scope_ = scope_->enclosing();
   694 }
   695 
   696 static inline bool
   697 IsScalarString(Type *type)
   698 {
   699     if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
   700         return true;
   701     if (type->isReference())
   702         return IsScalarString(type->contained());
   703     return false;
   704 }
   705 
   706 static const int INFER_ARRAY_SIZE = 0;
   707 static const int EVAL_ARRAY_SIZE = -1;
   708 static const int DYNAMIC_ARRAY_SIZE = -2;
   709 
   710 bool
   711 SemanticAnalysis::evaluateDimensions(ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH])
   712 {
   713     for (size_t i = 0; i < exprs->length(); i++) {
   714         Expression *expr = exprs->at(i);
   715         if (!expr) {
   716             dims[i] = INFER_ARRAY_SIZE;
   717             continue;
   718         }
   719 
   720         BoxedPrimitive box;
   721         if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   722             int size = box.toInt();
   723             if (size <= 0) {
   724                 cc_.reportError(expr->pos(), Message_BadArraySize);
   725                 return false;
   726             }
   727 
   728             dims[i] = size;
   729             continue;
   730         }
   731 
   732         Local<Type> exprType(zone_, visitForLoad(expr));
   733         if (!exprType)
   734             return false;
   735 
   736         if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   737             cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   738             return false;
   739         }
   740 
   741         dims[i] = EVAL_ARRAY_SIZE;
   742     }
   743 
   744     return true;
   745 }
   746 
   747 bool
   748 SemanticAnalysis::inferFixedArrayLiteral(ArrayLiteral *literal, Handle<Type> contained,
   749                                          int dims[MAX_ARRAY_DEPTH],
   750                                          unsigned dimcount, unsigned level)
   751 {
   752     if (dims[level] == EVAL_ARRAY_SIZE) {
   753         cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   754         return false;
   755     }
   756 
   757     if (dims[level] == INFER_ARRAY_SIZE) {
   758         // Strings always become dynamic arrays.
   759         if (level != dimcount - 1 || !IsPrimitiveType(contained, PrimitiveType_Char))
   760             dims[level] = literal->expressions()->length();
   761     } else if (dims[level] == DYNAMIC_ARRAY_SIZE) {
   762         cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   763         return false;
   764     } else {
   765         if (literal->expressions()->length() != unsigned(dims[level])) {
   766             cc_.reportError(literal->pos(), Message_ArrayDimensionSizeMismatch, level + 1);
   767             return false;
   768         }
   769     }
   770 
   771     if (level == dimcount - 2 && IsPrimitiveType(contained, PrimitiveType_Char)) {
   772         for (size_t i = 0; i < literal->expressions()->length(); i++) {
   773             Expression *expr = literal->expressions()->at(i);
   774             if (!expr->isStringLiteral()) {
   775                 cc_.reportError(expr->pos(), Message_ExpectedStringLiteral);
   776                 return false;
   777             }
   778 
   779             StringLiteral *lit = expr->toStringLiteral();
   780             if (dims[level + 1] > 0 &&
   781                 unsigned(dims[level]) < lit->string()->length())
   782             {
   783                 cc_.reportError(lit->pos(), Message_ArrayDimensionSizeMismatch, level + 2);
   784                 return false;
   785             }
   786             if (!visitAndApplyType(lit))
   787                 return false;
   788         }
   789     } else if (level == dimcount - 1) {
   790         Local<Type> type(zone_);
   791         for (size_t i = 0; i < literal->expressions()->length(); i++) {
   792             Expression *expr = literal->expressions()->at(i);
   793             if (expr->isArrayLiteral()) {
   794                 cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   795                 return false;
   796             }
   797 
   798             if ((type = visitAndApplyType(expr)) == NULL)
   799                 return false;
   800 
   801             if (!typeCheckAssignment(expr->pos(), type, contained, true))
   802                 return false;
   803         }
   804     } else {
   805         for (size_t i = 0; i < literal->expressions()->length(); i++) {
   806             Expression *expr = literal->expressions()->at(i);
   807             if (!expr->isArrayLiteral()) {
   808                 cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   809                 return false;
   810             }
   811 
   812             assert(expr->toArrayLiteral()->isFixed());
   813 
   814             if (!inferFixedArrayLiteral(expr->toArrayLiteral(),
   815                                         contained,
   816                                         dims,
   817                                         dimcount,
   818                                         level + 1))
   819             {
   820                 return false;
   821             }
   822         }
   823     }
   824 
   825     return true;
   826 }
   827 
   828 void
   829 SemanticAnalysis::visit(VariableDeclaration *node)
   830 {
   831     Local<Type> type(zone_, bindType(node->pos(), node->type()));
   832     if (!type)
   833         return;
   834 
   835     if (node->postDimensions() || type->isArray()) {
   836         // The type could be an array type, so sum the type and postDimensions
   837         // together.
   838         unsigned dimcount = node->postDimensions()->length();
   839         if (type->isArray())
   840             dimcount += type->levels();
   841         if (dimcount > MAX_ARRAY_DEPTH) {
   842             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   843             return;
   844         }
   845 
   846         // Take an initial guess at the array dimension sizes.
   847         int dims[MAX_ARRAY_DEPTH];
   848         if (!evaluateDimensions(node->postDimensions(), dims))
   849             return;
   850 
   851         // Now add in the type's array dimensions.
   852         Local<Type> contained(zone_, type);
   853         for (size_t i = node->postDimensions()->length(); i < dimcount; i++) {
   854             if (type->isFixedLength())
   855                 dims[i] = type->fixedLength();
   856             else
   857                 dims[i] = DYNAMIC_ARRAY_SIZE;
   858             contained = contained->contained();
   859         }
   860 
   861         Expression *initializer = node->initialization();
   862         if (initializer &&
   863             initializer->isArrayLiteral() &&
   864             initializer->toArrayLiteral()->isFixed())
   865         {
   866             // Fixed array initializers are special; we use them to infer any
   867             // missing information in the original array. We do not evaluate
   868             // the array initializer as an expression.
   869             if (!inferFixedArrayLiteral(initializer->toArrayLiteral(),
   870                                         contained,
   871                                         dims,
   872                                         dimcount,
   873                                         0))
   874             {
   875                 return;
   876             }
   877             initializer = NULL;
   878         }
   879 
   880         // We now have enough information to build the actual array type.
   881         // Start from the original dimcount, not the one computed for
   882         // initializers.
   883         for (size_t i = node->postDimensions()->length() - 1;
   884              i < node->postDimensions()->length();
   885              i--)
   886         {
   887             int size = dims[i] > 0
   888                        ? dims[i]
   889                        : Type::DYNAMIC_ARRAY_SIZE;
   890 
   891             type = zone_->types()->newArray(type, size, false);
   892             if (!type)
   893                 return;
   894         }
   895 
   896         // Finally, if we had a non-fixed initializer, make sure it type
   897         // checks. 
   898         if (initializer) {
   899             Local<Type> right(zone_, visitForLoad(initializer));
   900             if (!right)
   901                 return;
   902 
   903             if (!typeCheckAssignment(node->pos(), right, type, true))
   904                 return;
   905         }
   906     } else {
   907         if (node->initialization()) {
   908             Local<Type> right(zone_, visitForLoad(node->initialization()));
   909             if (!right)
   910                 return;
   911             if (!typeCheckAssignment(node->pos(), right, type, true))
   912                 return;
   913         }
   914 
   915         if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
   916             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   917             return;
   918         }
   919     }
   920 
   921     // If this variable is stack allocated, we could use the LIFO heap
   922     // to allocate it. If that's the case, make sure to reserve a slot
   923     // so we can unwind the LIFO heap at the end of this scope.
   924     if (!node->variable()->needsHeapAllocation()) {
   925         if (type->isArray() || type->isStruct())
   926             scope_->setUsesLifoHeap();
   927     }
   928 
   929     node->variable()->setType(type);
   930 }
   931 
   932 void
   933 SemanticAnalysis::visit(IntegerLiteral *node)
   934 {
   935     node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   936 }
   937 
   938 void
   939 SemanticAnalysis::visit(BooleanLiteral *node)
   940 {
   941     node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
   942 }
   943 
   944 void
   945 SemanticAnalysis::visit(ExpressionStatement *node)
   946 {
   947     visitAndApplyType(node->expression());
   948 }
   949 
   950 Box *
   951 SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
   952 {
   953     Local<Type> given(zone_, visitForLoad(parameter->initializer()));
   954 
   955     BoxedPrimitive prim;
   956     if (EvaluateForConstant(parameter->initializer(), &prim)) {
   957         if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   958             return NULL;
   959 
   960         if (prim.type() == PrimitiveType_Int32)
   961             return Box::New(zone_, given, prim.toInt());
   962         return Box::New(zone_, given, prim.toFloat());
   963     } else if (parameter->initializer()->isStringLiteral()) {
   964         StringLiteral *literal = parameter->initializer()->toStringLiteral();
   965 
   966         if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   967             return NULL;
   968 
   969         Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
   970         if (!map)
   971             return NULL;
   972 
   973         Local<Array> array(zone_,
   974             Array::NewString(zone_,
   975                              map,
   976                              literal->string()->raw(),
   977                              literal->string()->length(),
   978                              Heap::Tenure_Old));
   979         if (!array)
   980             return NULL;
   981 
   982         return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
   983     }
   984 
   985     cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
   986     return NULL;
   987 }
   988 
   989 bool
   990 SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
   991                                     FixedArray **argsp, FixedArray **defaultsp)
   992 {
   993     Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   994     if (!args)
   995         return false;
   996 
   997     Local<FixedArray> defaults(zone_);
   998 
   999     // Apply types to arguments.
  1000     for (size_t i = 0; i < sig.parameters()->length(); i++) {
  1001         Parameter *parameter = sig.parameters()->at(i);
  1002         
  1003         Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
  1004         if (!type)
  1005             return false;
  1006 
  1007         if (parameter->reference()) {
  1008             if (parameter->dimensions()) {
  1009                 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
  1010                 return false;
  1011             }
  1012 
  1013             if (type->isStruct()) {
  1014                 cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
  1015                 return false;
  1016             }
  1017 
  1018             type = zone_->types()->getReference(type, parameter->isConst());
  1019             if (!type)
  1020                 return false;
  1021         } else if (parameter->dimensions()) {
  1022             // :TODO: factor in type dimcount
  1023             if (parameter->dimensions()->length() > MAX_ARRAY_DEPTH) {
  1024                 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
  1025                 return false;
  1026             }
  1027 
  1028             if (kind == TOK_NATIVE && parameter->dimensions()->length() > 1) {
  1029                 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
  1030                 return false;
  1031             }
  1032 
  1033             for (size_t i = parameter->dimensions()->length() - 1;
  1034                  i < parameter->dimensions()->length();
  1035                  i--)
  1036             {
  1037                 int size = Type::DYNAMIC_ARRAY_SIZE;
  1038                 if (Expression *expr = parameter->dimensions()->at(i)) {
  1039                     BoxedPrimitive box;
  1040                     if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
  1041                         cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
  1042                         return false;
  1043                     }
  1044                     size = box.toInt();
  1045                 }
  1046 
  1047                 type = zone_->types()->newArray(type, size, parameter->isConst());
  1048                 if (!type)
  1049                     return false;
  1050             }
  1051         }
  1052 
  1053         if (IsScalarString(type)) {
  1054             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1055             return false;
  1056         }
  1057 
  1058         args->set(zone_, i, type);
  1059         parameter->variable()->setType(type);
  1060 
  1061         if (parameter->initializer()) {
  1062             if (!defaults) {
  1063                 defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
  1064                 if (!defaults)
  1065                     return false;
  1066             }
  1067 
  1068             Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
  1069             if (!box)
  1070                 return false;
  1071 
  1072             defaults->set(zone_, i, box);
  1073         }
  1074     }
  1075 
  1076     *argsp = args;
  1077     *defaultsp = defaults;
  1078 
  1079     return true;
  1080 }
  1081 
  1082 void
  1083 SemanticAnalysis::visit(FunctionTypeStatement *node)
  1084 {
  1085     if (node->decl()->type())
  1086         return;
  1087 
  1088     Local<FixedArray> args(zone_);
  1089     Local<FixedArray> defaults(zone_);
  1090 
  1091     const FunctionSignature &sig= node->signature();
  1092     if (!buildFunctionArgs(node,
  1093                            TOK_STOCK,
  1094                            sig,
  1095                            args.address(),
  1096                            defaults.address()))
  1097     {
  1098         return;
  1099     }
  1100 
  1101     Local<Type> returnType(zone_);
  1102     if (sig.returnType())
  1103         returnType = bindType(node->pos(), sig.returnType());
  1104     else
  1105         returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1106 
  1107     if (!returnType)
  1108         return;
  1109 
  1110     Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
  1111     if (!funtype)
  1112         return;
  1113 
  1114     node->decl()->setType(funtype);
  1115 }
  1116 
  1117 bool
  1118 SemanticAnalysis::preanalyze(FunctionStatement *node)
  1119 {
  1120     Local<FixedArray> args(zone_);
  1121     Local<FixedArray> defaults(zone_);
  1122 
  1123     const FunctionSignature &sig = node->signature();
  1124     if (!buildFunctionArgs(node,
  1125                            node->fun()->token(),
  1126                            sig,
  1127                            args.address(),
  1128                            defaults.address()))
  1129     {
  1130         return false;
  1131     }
  1132 
  1133     Local<Type> returnType(zone_);
  1134     if (sig.returnType() ||
  1135         node->hasExplicitReturn() ||
  1136         node->fun()->isNative())
  1137     {
  1138         returnType = bindType(node->pos(), sig.returnType());
  1139     } else {
  1140         returnType = zone_->types()->getVoid();
  1141     }
  1142     if (!returnType)
  1143         return false;
  1144 
  1145     Local<Type> funtype(zone_);
  1146     if (node->fun()->isNative())
  1147         funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
  1148     else
  1149         funtype = zone_->types()->newFunction(returnType, args, defaults);
  1150     if (!funtype)
  1151         return false;
  1152     
  1153     // If the function already has a type, it was forward declared before, and
  1154     // now this is our chance to type check the second declaration.
  1155     if (node->fun()->type()) {
  1156         Local<Type> forward(zone_, node->fun()->type());
  1157         if (!Type::Compare(funtype, forward)) {
  1158             cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  1159             return false;
  1160         }
  1161         node->fun()->setForwardType(forward);
  1162     }
  1163 
  1164     node->fun()->setType(funtype);
  1165 
  1166     return true;
  1167 }
  1168 
  1169 void
  1170 SemanticAnalysis::visit(FunctionStatement *node)
  1171 {
  1172     function_ = node->fun();
  1173     scope_ = node->scope();
  1174 
  1175     ControlScope control(&control_);
  1176     if (node->body()) {
  1177         node->body()->accept(this);
  1178 
  1179         ControlStatus status = control.status();
  1180         if (status.returns() == Returns_Sometimes) {
  1181             cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1182         } else if (status.returns() == Returns_Never) {
  1183             if (!function_->type()->returnType()->isVoid())
  1184                 cc_.reportError(node->pos(), Message_MissingReturnValue);
  1185         }
  1186     }
  1187 
  1188     scope_ = NULL;
  1189     function_ = NULL;
  1190 }
  1191 
  1192 void
  1193 SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
  1194 {
  1195     cc_.reportError(pos, Message_TypeMismatch,
  1196                     GetTypeName(actual),
  1197                     GetTypeName(given));
  1198 }
  1199 
  1200 bool
  1201 SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1202                                            Handle<Type> argActual, bool forAssign)
  1203 {
  1204     Local<Type> actual(zone_, argActual);
  1205     Local<Type> given(zone_, argGiven);
  1206 
  1207     if (!given->isArray()) {
  1208         cc_.reportError(pos, Message_ExpectedArray);
  1209         return false;
  1210     }
  1211     if (given->levels() != actual->levels()) {
  1212         cc_.reportError(pos, Message_ArrayDimensionsMismatch);
  1213         return false;
  1214     }
  1215 
  1216     unsigned level = 1;
  1217     while (given->isArray()) {
  1218         if (actual->isFixedLength()) {
  1219             if (forAssign) {
  1220                 if (!given->isFixedLength()) {
  1221                     cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1222                     return false;
  1223                 }
  1224 
  1225                 if (actual->isCharArray()) {
  1226                     // String assignment can have a truncated |given|.
  1227                     if (given->fixedLength() > actual->fixedLength()) {
  1228                         cc_.reportError(pos, Message_ArrayAssignmentTooBig);
  1229                         return false;
  1230                     }
  1231                 } else {
  1232                     if (given->fixedLength() != actual->fixedLength()) {
  1233                         cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1234                         return false;
  1235                     }
  1236                 }
  1237             }
  1238         } else if (given->isFixedLength()) {
  1239             // We do not allow assignments in the form:
  1240             //    [][] = [][Y]
  1241             //
  1242             // Otherwise, the following code could break the size guarantees
  1243             // of the right-hand side:
  1244             //
  1245             //   new x[][5];
  1246             //   new y[][];
  1247             //   new z[3];
  1248             //
  1249             //   y = x;
  1250             //   y[0] = z;
  1251             //   
  1252             // Now |x[0]| contains a 4-length array.
  1253             if (level > 1) {
  1254                 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1255                 return false;
  1256             }
  1257         }
  1258         given = given->contained();
  1259         actual = actual->contained();
  1260         level++;
  1261     }
  1262 
  1263     return typeCheckAssignment(pos, given, actual, forAssign);
  1264 }
  1265 
  1266 bool
  1267 SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1268                                       Handle<Type> argActual, bool forAssign)
  1269 {
  1270     Local<Type> actual(zone_, argActual);
  1271     Local<Type> given(zone_, argGiven);
  1272 
  1273     if (actual->isArray())
  1274         return typeCheckArrayAssignment(pos, given, actual, forAssign);
  1275 
  1276     if (given->isArray()) {
  1277         cc_.reportError(pos, Message_CannotAssignArrayToScalar);
  1278         return false;
  1279     }
  1280 
  1281     // The given type may not have been dereferenced.
  1282     if (given->isReference())
  1283         given = given->contained();
  1284     if (actual->isReference())
  1285         actual = actual->contained();
  1286 
  1287     // We coerce unchecked to a few things.
  1288     if (actual->isUnchecked() || given->isUnchecked()) {
  1289         Type *check = actual->isUnchecked() ? given : actual;
  1290         if (check->isUnchecked() ||
  1291             check->isEnum() ||
  1292             check->isInt32() ||
  1293             check->isBool() ||
  1294             check->isFloat())
  1295         {
  1296             return true;
  1297         }
  1298         typeMismatch(pos, actual, given);
  1299         return false;
  1300     }
  1301 
  1302     if (given->isFunction() && actual->isFunction()) {
  1303         if (!Type::Compare(given, actual)) {
  1304             typeMismatch(pos, actual, given);
  1305             return false;
  1306         }
  1307         return true;
  1308     }
  1309 
  1310     if (actual->isEnum()) {
  1311         if (!given->isEnum() || actual != given) {
  1312             typeMismatch(pos, actual, given);
  1313             return false;
  1314         }
  1315         return true;
  1316     }
  1317 
  1318     if (actual->isStruct()) {
  1319         if (!given->isStruct() || actual != given) {
  1320             typeMismatch(pos, actual, given);
  1321             return false;
  1322         }
  1323         return true;
  1324     }
  1325 
  1326     if (given->isEnum() || given->isFunction() || given->isStruct()) {
  1327         typeMismatch(pos, actual, given);
  1328         return false;
  1329     }
  1330 
  1331     // This coercion is trivial.
  1332     if (given->isBool() && actual->isInt32())
  1333         return true;
  1334 
  1335     if (given->primitive() != actual->primitive()) {
  1336         typeMismatch(pos, actual, given);
  1337         return false;
  1338     }
  1339 
  1340     return true;
  1341 }
  1342 
  1343 bool
  1344 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  1345 {
  1346     return typeCheckAssignment(node->pos(), given, actual, false);
  1347 }
  1348 
  1349 bool
  1350 SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
  1351 {
  1352     if (type->parameters()->length() == actual)
  1353         return true;
  1354 
  1355     if (actual > type->parameters()->length()) {
  1356         if (!type->isNative() || !type->isNativeVariadic())
  1357             return false;
  1358         return true;
  1359     }
  1360 
  1361     if (!type->defaults())
  1362         return false;
  1363 
  1364     // Missing arguments. See if there's a default argument for each missing
  1365     // actual.
  1366     for (unsigned i = actual; i < type->parameters()->length(); i++) {
  1367         if (!type->defaults()->at(i))
  1368             return false;
  1369     }
  1370 
  1371     return true;
  1372 }
  1373 
  1374 void
  1375 SemanticAnalysis::visit(CallExpression *node)
  1376 {
  1377     Local<Type> type(zone_, visitForLoad(node->callee()));
  1378     if (!type)
  1379         return;
  1380 
  1381     if (!type->isFunction()) {
  1382         cc_.reportError(node->pos(), Message_CalleeNotFunction);
  1383         return;
  1384     }
  1385 
  1386     if (!checkArgumentCount(type, node->arguments()->length())) {
  1387         cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  1388         return;
  1389     }
  1390 
  1391     // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  1392     // if (fun->isForward()) {
  1393     //     cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  1394     //     return;
  1395     // }
  1396 
  1397     for (unsigned i = 0; i < node->arguments()->length(); i++) {
  1398         // Note: we don't compute references unless the callee needs a
  1399         // reference type.
  1400         Expression *expression = node->arguments()->at(i);
  1401         Local<Type> given(zone_, visitAndApplyType(expression));
  1402         if (!given)
  1403             return;
  1404 
  1405         // Since we skip a load, check for a call expression that returns void.
  1406         if (given->isVoid()) {
  1407             assert(expression->isCallExpression());
  1408             CallExpression *call = expression->toCallExpression();
  1409             cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1410             return;
  1411         }
  1412         
  1413         bool mustComputeReference;
  1414         if (i >= type->parameters()->length()) {
  1415             // Special handling for natives. Arguments past the formal must
  1416             // always have references computed. However, arrays are already
  1417             // references for natives.  
  1418             assert(type->isNative() && type->isNativeVariadic());
  1419             mustComputeReference = !given->isReference() && !given->isArray();
  1420         } else {
  1421             Local<Type> actual(zone_, type->parameterAt(i));
  1422 
  1423             if (expression->isIndexExpression() && actual->isArray()) {
  1424                 // We special case the ability to pass x[y] into x[], which
  1425                 // creates an array slice. We only do this if we know the
  1426                 // assignment would otherwise not type-check.
  1427                 IndexExpression *index = expression->toIndexExpression();
  1428                 if (index->left()->type()->levels() == actual->levels())
  1429                     given = index->left()->type();
  1430             }
  1431 
  1432             if (!typeCheckParameter(expression, given, actual))
  1433                 return;
  1434             mustComputeReference = actual->isReference() && !given->isReference();
  1435         }
  1436 
  1437         // If the actual is a reference, and the given is not, we'll need to
  1438         // compute a reference, which may be allocated on the stack.
  1439         if (mustComputeReference)
  1440             scope_->setUsesLifoHeap();
  1441     }
  1442 
  1443     node->setType(type->returnType());
  1444 }
  1445 
  1446 void
  1447 SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
  1448 {
  1449     if (other.returns() < status().returns())
  1450         return;
  1451 
  1452     if (other.terminates())
  1453         terminate(other.returns());
  1454     else
  1455         returns(other.returns());
  1456 }
  1457 
  1458 void
  1459 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  1460 {
  1461     // If both sides terminate in a return, we consider this a return as well.
  1462     if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  1463         terminate(Returns_Always);
  1464         return;
  1465     }
  1466 
  1467     ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  1468                           ? Returns_Never
  1469                           : Returns_Sometimes;
  1470 
  1471     if (left.terminates() && right.terminates())
  1472         terminate(status);
  1473     else
  1474         returns(status);
  1475 }
  1476 
  1477 void
  1478 SemanticAnalysis::visit(IfStatement *node)
  1479 {
  1480     Local<Type> type(zone_, visitForLoad(node->condition()));
  1481     if (!type)
  1482         return;
  1483 
  1484     if (!canTest(node, type))
  1485         return;
  1486 
  1487     ControlStatus trueBranch = visitForControl(node->ifTrue());
  1488     ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  1489 
  1490     if (node->ifFalse())
  1491         falseBranch = visitForControl(node->ifFalse());
  1492 
  1493     control_->merge(trueBranch, falseBranch);
  1494 }
  1495 
  1496 void
  1497 SemanticAnalysis::visit(IndexExpression *node)
  1498 {
  1499     Local<Type> left(zone_, visitForLoad(node->left()));
  1500     Local<Type> right(zone_, visitForLoad(node->right()));
  1501 
  1502     if (!left || !right)
  1503         return;
  1504 
  1505     if (!right->isInt32() && !right->isEnum()) {
  1506         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  1507         return;
  1508     }
  1509     if (!left->isArray()) {
  1510         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  1511         return;
  1512     }
  1513 
  1514     // Note: char arrays are automatically up-casted to return an int32.
  1515     if (left->isCharArray())
  1516         node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1517     else
  1518         node->setType(left->contained());
  1519 }
  1520 
  1521 void
  1522 SemanticAnalysis::visit(FieldExpression *node)
  1523 {
  1524     Local<Type> left(zone_, visitForLoad(node->left()));
  1525     if (!left)
  1526         return;
  1527 
  1528     if (!left->isStruct()) {
  1529         cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1530                         GetTypeName(left));
  1531         return;
  1532     }
  1533 
  1534     Local<String> field(zone_, node->field());
  1535 
  1536     unsigned offset;
  1537     Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
  1538     if (!desc) {
  1539         cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1540                         GetTypeName(left));
  1541         return;
  1542     }
  1543 
  1544     node->setFieldIndex(offset);
  1545     node->setType(desc->type());
  1546 }
  1547 
  1548 void
  1549 SemanticAnalysis::visit(EnumStatement *node)
  1550 {
  1551     Local<String> name(zone_, node->name());
  1552     Local<Type> type(zone_);
  1553     if (name)
  1554         type = zone_->types()->newEnum(name);
  1555     else
  1556         type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1557 
  1558     if (!type)
  1559         return;
  1560 
  1561     if (node->decl())
  1562         node->decl()->setType(type);
  1563 
  1564     int value = 0;
  1565     for (size_t i = 0; i < node->entries()->length(); i++) {
  1566         EnumStatement::Entry &entry = node->entries()->at(i);
  1567 
  1568         BoxedPrimitive box = BoxedPrimitive::Int(value);
  1569         if (entry.expr) {
  1570             entry.expr->accept(this);
  1571             if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
  1572                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1573                 return;
  1574             }
  1575 
  1576             assert(box.type() == PrimitiveType_Int32);
  1577             value = box.toInt();
  1578         }
  1579 
  1580         entry.name->set(type, box);
  1581         value++;
  1582     }
  1583 }
  1584 
  1585 static int
  1586 SortCaseIntValues(const void *p1, const void *p2)
  1587 {
  1588     CaseValue *v1 = (CaseValue *)p1;
  1589     CaseValue *v2 = (CaseValue *)p2;
  1590 
  1591     return v1->box.toInt() - v2->box.toInt();
  1592 }
  1593 
  1594 void
  1595 SemanticAnalysis::visit(SwitchStatement *node)
  1596 {
  1597     Local<Type> caseType(zone_, visitForLoad(node->expression()));
  1598     if (!caseType)
  1599         return;
  1600 
  1601     if (!caseType->isEnum() && !caseType->isInt32()) {
  1602         cc_.reportError(node->pos(), Message_CaseMustBeInteger);
  1603         return;
  1604     }
  1605 
  1606     PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
  1607     ControlStatus status = ControlStatus(false, Returns_Never);
  1608 
  1609     Local<Type> check(zone_);
  1610     for (size_t i = 0; i < node->cases()->length(); i++) {
  1611         Case *c = node->cases()->at(i);
  1612 
  1613         check = visitForLoad(c->expression());
  1614         if (!check)
  1615             return;
  1616 
  1617         if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
  1618             return;
  1619 
  1620         CaseValue v(i);
  1621         if (!EvaluateForConstant(c->expression(), &v.box)) {
  1622             cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
  1623             return;
  1624         }
  1625         if (!values->append(v))
  1626             return;
  1627 
  1628         if (c->others()) {
  1629             for (size_t j = 0; j < c->others()->length(); j++) {
  1630                 Expression *expr = c->others()->at(j);
  1631                 check = visitForLoad(expr);
  1632                 if (!check)
  1633                     return;
  1634 
  1635                 if (!typeCheckAssignment(expr->pos(), check, caseType, false))
  1636                     return;
  1637 
  1638                 CaseValue v(i);
  1639                 if (!EvaluateForConstant(expr, &v.box)) {
  1640                     cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
  1641                     return;
  1642                 }
  1643                 if (!values->append(v))
  1644                     return;
  1645             }
  1646         }
  1647 
  1648         ControlStatus latest = visitForControl(c->statement());
  1649 
  1650         if (i != 0)
  1651             control_->merge(status, latest);
  1652 
  1653         status = latest;
  1654     }
  1655 
  1656     if (node->defaultCase()) {
  1657         ControlStatus latest = visitForControl(node->defaultCase());
  1658 
  1659         if (node->cases()->length()) {
  1660             // If we had any other cases, we must merge.
  1661             control_->merge(status, latest);
  1662         } else {
  1663             // Otherwise, control-flow always flows through here.
  1664             control_->inherit(latest);
  1665         }
  1666     } else if (node->cases()->length()) {
  1667         control_->merge(status, ControlStatus(false, Returns_Never));
  1668     }
  1669 
  1670     if (values->length() > 1) {
  1671         qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
  1672 
  1673         for (size_t i = 1; i < values->length(); i++) {
  1674             CaseValue &prev = values->at(i - 1);
  1675             CaseValue &cur = values->at(i);
  1676             if (prev.box.toInt() == cur.box.toInt()) {
  1677                 cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
  1678                 return;
  1679             }
  1680         }
  1681     }
  1682 
  1683     node->setCaseValueList(values);
  1684 }
  1685 
  1686 void
  1687 SemanticAnalysis::visit(StructureStatement *node)
  1688 {
  1689     // If this node already has a type, it was pre-analyzed, so skip it.
  1690     if (node->decl()->type())
  1691         return;
  1692 
  1693     FieldList *fields = node->fields();
  1694     Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
  1695     if (!desctable)
  1696         return;
  1697 
  1698     Vector<unsigned> composedList;
  1699     StructureBufferBuilder builder;
  1700 
  1701     Local<Type> type(zone_);
  1702     Local<String> name(zone_);
  1703     Local<Descriptor> desc(zone_);
  1704     for (size_t i = 0; i < fields->length(); i++) {
  1705         StructureStatement::Field *field = fields->at(i);
  1706 
  1707         type = bindType(field->pos(), field->type());
  1708         if (!type)
  1709             return;
  1710 
  1711         if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
  1712             cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
  1713             return;
  1714         }
  1715 
  1716         unsigned offset;
  1717         if (!builder.add(type, &offset))
  1718             return;
  1719 
  1720         name = field->name();
  1721         desc = Descriptor::New(zone_, name, type, offset);
  1722         if (!desc)
  1723             return;
  1724 
  1725         desctable->set(zone_, i, desc);
  1726 
  1727         if (type->isStruct() || type->isArray()) {
  1728             if (!composedList.append(i))
  1729                 return;
  1730         }
  1731     }
  1732 
  1733     Local<FixedArray> composed(zone_);
  1734     if (composedList.length()) {
  1735         composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
  1736         if (!composed)
  1737             return;
  1738 
  1739         for (unsigned i = 0; i < composedList.length(); i++)
  1740             composed->set(zone_, i, desctable->at(i));
  1741     }
  1742 
  1743     Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
  1744     if (!map)
  1745         return;
  1746 
  1747     name = node->decl()->name();
  1748     type = zone_->types()->newStruct(name, desctable, map);
  1749     if (!type)
  1750         return;
  1751 
  1752     map->setType(type);
  1753     node->decl()->setType(type);
  1754 }
  1755 
  1756 void
  1757 SemanticAnalysis::visit(StringLiteral *node)
  1758 {
  1759     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1760     if (!type)
  1761         return;
  1762 
  1763     type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1764     if (!type)
  1765         return;
  1766 
  1767     node->setType(type);
  1768 }
  1769 
  1770 void
  1771 SemanticAnalysis::visit(FloatLiteral *node)
  1772 {
  1773     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1774     if (!type)
  1775         return;
  1776 
  1777     node->setType(type);
  1778 }
  1779 
  1780 void
  1781 SemanticAnalysis::visit(BreakStatement *node)
  1782 {
  1783     if (!loop_) {
  1784         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1785         return;
  1786     }
  1787 
  1788     // Note: ignore breaks that occur in unreachable control-flow.
  1789     if (!control_->status().terminates())
  1790         loop_->addBreak();
  1791 
  1792     control_->terminate(Returns_Never);
  1793 }
  1794 
  1795 void
  1796 SemanticAnalysis::visit(ContinueStatement *node)
  1797 {
  1798     if (!loop_) {
  1799         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1800         return;
  1801     }
  1802 
  1803     // Note: ignore continues that occur in unreachable control-flow.
  1804     if (!control_->status().terminates())
  1805         loop_->addContinue();
  1806 
  1807     control_->terminate(Returns_Never);
  1808 }
  1809 
  1810 void
  1811 SemanticAnalysis::visit(ArrayLiteral *node)
  1812 {
  1813     // We should never visit this.
  1814     cc_.reportError(node->pos(), Message_UnexpectedArrayLiteral);
  1815 }
  1816