src/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Sat Sep 01 16:36:20 2012 -0700 (2012-09-01)
changeset 174 e718b56aba78
parent 172 48cffae8c9e0
child 183 05571208642f
permissions -rw-r--r--
Implemented callbacks.
     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 void
   707 SemanticAnalysis::visit(VariableDeclaration *node)
   708 {
   709     Local<Type> type(zone_, bindType(node->pos(), node->type()));
   710     if (!type)
   711         return;
   712 
   713     if (node->postDimensions()) {
   714         Local<Type> init(zone_);
   715         if (node->initialization()) {
   716             if ((init = visitForLoad(node->initialization())) == NULL)
   717                 return;
   718         }
   719 
   720         if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   721             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   722             return;
   723         }
   724 
   725         // If we have an initializer, make sure it's the same type.
   726         if (init && node->postDimensions()->length() != init->levels()) {
   727             cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
   728             return;
   729         }
   730 
   731         Local<Type> check(zone_, init);
   732         for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
   733             Expression *expr = node->postDimensions()->at(i);
   734             int size = -1;
   735 
   736             if (expr) {
   737                 Local<Type> exprType(zone_, visitForLoad(expr));
   738                 if (!exprType)
   739                     return;
   740 
   741                 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   742                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   743                     return;
   744                 }
   745 
   746                 BoxedPrimitive box;
   747                 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   748                     size = box.toInt();
   749                     if (size <= 0) {
   750                         cc_.reportError(expr->pos(), Message_BadArraySize);
   751                         return;
   752                     }
   753                     if (size >= int(INT_MAX / sizeof(int))) {
   754                         cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
   755                         return;
   756                     }
   757 
   758                     if (check) {
   759                         if (check->elements() == -1) {
   760                             cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
   761                             return;
   762                         }
   763 
   764                         if (check->isCharArray()) {
   765                             if (check->elements() > size) {
   766                                 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   767                                 return;
   768                             }
   769                         } else if (check->elements() != size) {
   770                             cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
   771                             return;
   772                         }
   773                     }
   774                 } else {
   775                     if (init) {
   776                         cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
   777                         return;
   778                     }
   779 
   780                     // here until we get dynamic array support.
   781                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   782                     return;
   783                 }
   784             } else {
   785                 // Infer the size from the initializer.
   786                 if (!init) {
   787                     cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
   788                     return;
   789                 }
   790                 if (init->elements() == -1) {
   791                     cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
   792                     return;
   793                 }
   794                 size = init->elements();
   795             }
   796 
   797             type = zone_->types()->unsafeArray(type, size, false);
   798             if (!type)
   799                 return;
   800 
   801             if (check)
   802                 check = check->contained();
   803         }
   804     } else {
   805         if (node->initialization()) {
   806             Local<Type> right(zone_, visitForLoad(node->initialization()));
   807             if (!right)
   808                 return;
   809             if (!typeCheckAssignment(node->pos(), type, right, true))
   810                 return;
   811         }
   812 
   813         if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
   814             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   815             return;
   816         }
   817     }
   818 
   819     // If this variable is stack allocated, we could use the LIFO heap
   820     // to allocate it. If that's the case, make sure to reserve a slot
   821     // so we can unwind the LIFO heap at the end of this scope.
   822     if (!node->variable()->needsHeapAllocation()) {
   823         if (type->isArray() || type->isStruct())
   824             scope_->setUsesLifoHeap();
   825     }
   826 
   827     node->variable()->setType(type);
   828 }
   829 
   830 void
   831 SemanticAnalysis::visit(IntegerLiteral *node)
   832 {
   833     node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   834 }
   835 
   836 void
   837 SemanticAnalysis::visit(BooleanLiteral *node)
   838 {
   839     node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
   840 }
   841 
   842 void
   843 SemanticAnalysis::visit(ExpressionStatement *node)
   844 {
   845     visitAndApplyType(node->expression());
   846 }
   847 
   848 Box *
   849 SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
   850 {
   851     Local<Type> given(zone_, visitForLoad(parameter->initializer()));
   852 
   853     BoxedPrimitive prim;
   854     if (EvaluateForConstant(parameter->initializer(), &prim)) {
   855         if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   856             return NULL;
   857 
   858         if (prim.type() == PrimitiveType_Int32)
   859             return Box::New(zone_, given, prim.toInt());
   860         return Box::New(zone_, given, prim.toFloat());
   861     } else if (parameter->initializer()->isStringLiteral()) {
   862         StringLiteral *literal = parameter->initializer()->toStringLiteral();
   863 
   864         if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   865             return NULL;
   866 
   867         Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
   868         if (!map)
   869             return NULL;
   870 
   871         Local<Array> array(zone_,
   872             Array::NewString(zone_,
   873                              map,
   874                              literal->string()->raw(),
   875                              literal->string()->length(),
   876                              Heap::Tenure_Old));
   877         if (!array)
   878             return NULL;
   879 
   880         return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
   881     }
   882 
   883     cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
   884     return NULL;
   885 }
   886 
   887 bool
   888 SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
   889                                     FixedArray **argsp, FixedArray **defaultsp)
   890 {
   891     Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
   892     if (!args)
   893         return false;
   894 
   895     Local<FixedArray> defaults(zone_);
   896 
   897     // Apply types to arguments.
   898     for (size_t i = 0; i < sig.parameters()->length(); i++) {
   899         Parameter *parameter = sig.parameters()->at(i);
   900         
   901         Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
   902         if (!type)
   903             return false;
   904 
   905         if (parameter->reference()) {
   906             if (parameter->dimensions()) {
   907                 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
   908                 return false;
   909             }
   910 
   911             if (type->isStruct()) {
   912                 cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
   913                 return false;
   914             }
   915 
   916             type = zone_->types()->getReference(type, parameter->isConst());
   917             if (!type)
   918                 return false;
   919         } else if (parameter->dimensions()) {
   920             if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   921                 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
   922                 return false;
   923             }
   924 
   925             if (kind == TOK_NATIVE && parameter->dimensions()->length() > 1) {
   926                 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
   927                 return false;
   928             }
   929 
   930             for (size_t i = parameter->dimensions()->length() - 1;
   931                  i < parameter->dimensions()->length();
   932                  i++)
   933             {
   934                 int size = Type::UNKNOWN_SIZE;
   935                 if (Expression *expr = parameter->dimensions()->at(i)) {
   936                     BoxedPrimitive box;
   937                     if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
   938                         cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
   939                         return false;
   940                     }
   941                     size = box.toInt();
   942                 }
   943 
   944                 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
   945                 if (!type)
   946                     return false;
   947             }
   948         }
   949 
   950         if (IsScalarString(type)) {
   951             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   952             return false;
   953         }
   954 
   955         args->set(zone_, i, type);
   956         parameter->variable()->setType(type);
   957 
   958         if (parameter->initializer()) {
   959             if (!defaults) {
   960                 defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
   961                 if (!defaults)
   962                     return false;
   963             }
   964 
   965             Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
   966             if (!box)
   967                 return false;
   968 
   969             defaults->set(zone_, i, box);
   970         }
   971     }
   972 
   973     *argsp = args;
   974     *defaultsp = defaults;
   975 
   976     return true;
   977 }
   978 
   979 void
   980 SemanticAnalysis::visit(FunctionTypeStatement *node)
   981 {
   982     if (node->decl()->type())
   983         return;
   984 
   985     Local<FixedArray> args(zone_);
   986     Local<FixedArray> defaults(zone_);
   987 
   988     const FunctionSignature &sig= node->signature();
   989     if (!buildFunctionArgs(node,
   990                            TOK_STOCK,
   991                            sig,
   992                            args.address(),
   993                            defaults.address()))
   994     {
   995         return;
   996     }
   997 
   998     Local<Type> returnType(zone_);
   999     if (sig.returnType())
  1000         returnType = bindType(node->pos(), sig.returnType());
  1001     else
  1002         returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1003 
  1004     if (!returnType)
  1005         return;
  1006 
  1007     Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
  1008     if (!funtype)
  1009         return;
  1010 
  1011     node->decl()->setType(funtype);
  1012 }
  1013 
  1014 bool
  1015 SemanticAnalysis::preanalyze(FunctionStatement *node)
  1016 {
  1017     Local<FixedArray> args(zone_);
  1018     Local<FixedArray> defaults(zone_);
  1019 
  1020     const FunctionSignature &sig = node->signature();
  1021     if (!buildFunctionArgs(node,
  1022                            node->fun()->token(),
  1023                            sig,
  1024                            args.address(),
  1025                            defaults.address()))
  1026     {
  1027         return false;
  1028     }
  1029 
  1030     Local<Type> returnType(zone_);
  1031     if (sig.returnType() ||
  1032         node->hasExplicitReturn() ||
  1033         node->fun()->isNative())
  1034     {
  1035         returnType = bindType(node->pos(), sig.returnType());
  1036     } else {
  1037         returnType = zone_->types()->getVoid();
  1038     }
  1039     if (!returnType)
  1040         return false;
  1041 
  1042     Local<Type> funtype(zone_);
  1043     if (node->fun()->isNative())
  1044         funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
  1045     else
  1046         funtype = zone_->types()->newFunction(returnType, args, defaults);
  1047     if (!funtype)
  1048         return false;
  1049     
  1050     // If the function already has a type, it was forward declared before, and
  1051     // now this is our chance to type check the second declaration.
  1052     if (node->fun()->type()) {
  1053         Local<Type> forward(zone_, node->fun()->type());
  1054         if (!Type::Compare(funtype, forward)) {
  1055             cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  1056             return false;
  1057         }
  1058         node->fun()->setForwardType(forward);
  1059     }
  1060 
  1061     node->fun()->setType(funtype);
  1062 
  1063     return true;
  1064 }
  1065 
  1066 void
  1067 SemanticAnalysis::visit(FunctionStatement *node)
  1068 {
  1069     function_ = node->fun();
  1070     scope_ = node->scope();
  1071 
  1072     ControlScope control(&control_);
  1073     if (node->body()) {
  1074         node->body()->accept(this);
  1075 
  1076         ControlStatus status = control.status();
  1077         if (status.returns() == Returns_Sometimes) {
  1078             cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1079         } else if (status.returns() == Returns_Never) {
  1080             if (!function_->type()->returnType()->isVoid())
  1081                 cc_.reportError(node->pos(), Message_MissingReturnValue);
  1082         }
  1083     }
  1084 
  1085     scope_ = NULL;
  1086     function_ = NULL;
  1087 }
  1088 
  1089 void
  1090 SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
  1091 {
  1092     cc_.reportError(pos, Message_TypeMismatch,
  1093                     GetTypeName(actual),
  1094                     GetTypeName(given));
  1095 }
  1096 
  1097 bool
  1098 SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1099                                            Handle<Type> argActual, bool forAssign)
  1100 {
  1101     Local<Type> actual(zone_, argActual);
  1102     Local<Type> given(zone_, argGiven);
  1103 
  1104     if (!given->isArray()) {
  1105         cc_.reportError(pos, Message_ExpectedArray);
  1106         return false;
  1107     }
  1108     if (given->levels() != actual->levels()) {
  1109         cc_.reportError(pos, Message_ArrayDimensionsMismatch);
  1110         return false;
  1111     }
  1112 
  1113     unsigned level = 0;
  1114     while (given->isArray()) {
  1115         if (actual->elements() != -1) {
  1116             if (forAssign) {
  1117                 if (given->elements() == -1 || actual->elements() == -1) {
  1118                     cc_.reportError(pos, Message_ArraySizeNotKnown);
  1119                     return false;
  1120                 }
  1121 
  1122                 if (actual->isCharArray()) {
  1123                     // String assignment can have a truncated |given|.
  1124                     if (given->elements() > actual->elements()) {
  1125                         cc_.reportError(pos, Message_ArrayAssignmentTooBig);
  1126                         return false;
  1127                     }
  1128                 } else {
  1129                     if (given->elements() != actual->elements()) {
  1130                         cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1131                         return false;
  1132                     }
  1133                 }
  1134             } else {
  1135                 if (actual->elements() != -1 && given->elements() != actual->elements()) {
  1136                     cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1137                     return false;
  1138                 }
  1139             }
  1140         }
  1141         given = given->contained();
  1142         actual = actual->contained();
  1143     }
  1144 
  1145     return typeCheckAssignment(pos, given, actual, forAssign);
  1146 }
  1147 
  1148 bool
  1149 SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1150                                       Handle<Type> argActual, bool forAssign)
  1151 {
  1152     Local<Type> actual(zone_, argActual);
  1153     Local<Type> given(zone_, argGiven);
  1154 
  1155     if (actual->isArray())
  1156         return typeCheckArrayAssignment(pos, given, actual, forAssign);
  1157 
  1158     if (given->isArray()) {
  1159         cc_.reportError(pos, Message_CannotAssignArrayToScalar);
  1160         return false;
  1161     }
  1162 
  1163     // The given type may not have been dereferenced.
  1164     if (given->isReference())
  1165         given = given->contained();
  1166     if (actual->isReference())
  1167         actual = actual->contained();
  1168 
  1169     // We coerce unchecked to a few things.
  1170     if (actual->isUnchecked() || given->isUnchecked()) {
  1171         Type *check = actual->isUnchecked() ? given : actual;
  1172         if (check->isUnchecked() ||
  1173             check->isEnum() ||
  1174             check->isInt32() ||
  1175             check->isBool() ||
  1176             check->isFloat())
  1177         {
  1178             return true;
  1179         }
  1180         typeMismatch(pos, actual, given);
  1181         return false;
  1182     }
  1183 
  1184     if (given->isFunction() && actual->isFunction()) {
  1185         if (!Type::Compare(given, actual)) {
  1186             typeMismatch(pos, actual, given);
  1187             return false;
  1188         }
  1189         return true;
  1190     }
  1191 
  1192     if (actual->isEnum()) {
  1193         if (!given->isEnum() || actual != given) {
  1194             typeMismatch(pos, actual, given);
  1195             return false;
  1196         }
  1197         return true;
  1198     }
  1199 
  1200     if (actual->isStruct()) {
  1201         if (!given->isStruct() || actual != given) {
  1202             typeMismatch(pos, actual, given);
  1203             return false;
  1204         }
  1205         return true;
  1206     }
  1207 
  1208     if (given->isEnum() || given->isFunction() || given->isStruct()) {
  1209         typeMismatch(pos, actual, given);
  1210         return false;
  1211     }
  1212 
  1213     // This coercion is trivial.
  1214     if (given->isBool() && actual->isInt32())
  1215         return true;
  1216 
  1217     if (given->primitive() != actual->primitive()) {
  1218         typeMismatch(pos, actual, given);
  1219         return false;
  1220     }
  1221 
  1222     return true;
  1223 }
  1224 
  1225 bool
  1226 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  1227 {
  1228     return typeCheckAssignment(node->pos(), given, actual, false);
  1229 }
  1230 
  1231 bool
  1232 SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
  1233 {
  1234     if (type->parameters()->length() == actual)
  1235         return true;
  1236 
  1237     if (actual > type->parameters()->length()) {
  1238         if (!type->isNative() || !type->isNativeVariadic())
  1239             return false;
  1240         return true;
  1241     }
  1242 
  1243     if (!type->defaults())
  1244         return false;
  1245 
  1246     // Missing arguments. See if there's a default argument for each missing
  1247     // actual.
  1248     for (unsigned i = actual; i < type->parameters()->length(); i++) {
  1249         if (!type->defaults()->at(i))
  1250             return false;
  1251     }
  1252 
  1253     return true;
  1254 }
  1255 
  1256 void
  1257 SemanticAnalysis::visit(CallExpression *node)
  1258 {
  1259     Local<Type> type(zone_, visitForLoad(node->callee()));
  1260     if (!type)
  1261         return;
  1262 
  1263     if (!type->isFunction()) {
  1264         cc_.reportError(node->pos(), Message_CalleeNotFunction);
  1265         return;
  1266     }
  1267 
  1268     if (!checkArgumentCount(type, node->arguments()->length())) {
  1269         cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  1270         return;
  1271     }
  1272 
  1273     // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  1274     // if (fun->isForward()) {
  1275     //     cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  1276     //     return;
  1277     // }
  1278 
  1279     for (unsigned i = 0; i < node->arguments()->length(); i++) {
  1280         // Note: we don't compute references unless the callee needs a
  1281         // reference type.
  1282         Expression *expression = node->arguments()->at(i);
  1283         Local<Type> given(zone_, visitAndApplyType(expression));
  1284         if (!given)
  1285             return;
  1286 
  1287         // Since we skip a load, check for a call expression that returns void.
  1288         if (given->isVoid()) {
  1289             assert(expression->isCallExpression());
  1290             CallExpression *call = expression->toCallExpression();
  1291             cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1292             return;
  1293         }
  1294         
  1295         bool mustComputeReference;
  1296         if (i >= type->parameters()->length()) {
  1297             // Special handling for natives. Arguments past the formal must
  1298             // always have references computed. However, arrays are already
  1299             // references for natives.  
  1300             assert(type->isNative() && type->isNativeVariadic());
  1301             mustComputeReference = !given->isReference() && !given->isArray();
  1302         } else {
  1303             Local<Type> actual(zone_, type->parameterAt(i));
  1304 
  1305             if (expression->isIndexExpression() && actual->isArray()) {
  1306                 // We special case the ability to pass x[y] into x[], which
  1307                 // creates an array slice. We only do this if we know the
  1308                 // assignment would otherwise not type-check.
  1309                 IndexExpression *index = expression->toIndexExpression();
  1310                 if (index->left()->type()->levels() == actual->levels())
  1311                     given = index->left()->type();
  1312             }
  1313 
  1314             if (!typeCheckParameter(expression, given, actual))
  1315                 return;
  1316             mustComputeReference = actual->isReference() && !given->isReference();
  1317         }
  1318 
  1319         // If the actual is a reference, and the given is not, we'll need to
  1320         // compute a reference, which may be allocated on the stack.
  1321         if (mustComputeReference)
  1322             scope_->setUsesLifoHeap();
  1323     }
  1324 
  1325     node->setType(type->returnType());
  1326 }
  1327 
  1328 void
  1329 SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
  1330 {
  1331     if (other.returns() < status().returns())
  1332         return;
  1333 
  1334     if (other.terminates())
  1335         terminate(other.returns());
  1336     else
  1337         returns(other.returns());
  1338 }
  1339 
  1340 void
  1341 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  1342 {
  1343     // If both sides terminate in a return, we consider this a return as well.
  1344     if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  1345         terminate(Returns_Always);
  1346         return;
  1347     }
  1348 
  1349     ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  1350                           ? Returns_Never
  1351                           : Returns_Sometimes;
  1352 
  1353     if (left.terminates() && right.terminates())
  1354         terminate(status);
  1355     else
  1356         returns(status);
  1357 }
  1358 
  1359 void
  1360 SemanticAnalysis::visit(IfStatement *node)
  1361 {
  1362     Local<Type> type(zone_, visitForLoad(node->condition()));
  1363     if (!type)
  1364         return;
  1365 
  1366     if (!canTest(node, type))
  1367         return;
  1368 
  1369     ControlStatus trueBranch = visitForControl(node->ifTrue());
  1370     ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  1371 
  1372     if (node->ifFalse())
  1373         falseBranch = visitForControl(node->ifFalse());
  1374 
  1375     control_->merge(trueBranch, falseBranch);
  1376 }
  1377 
  1378 void
  1379 SemanticAnalysis::visit(IndexExpression *node)
  1380 {
  1381     Local<Type> left(zone_, visitForLoad(node->left()));
  1382     Local<Type> right(zone_, visitForLoad(node->right()));
  1383 
  1384     if (!left || !right)
  1385         return;
  1386 
  1387     if (!right->isInt32() && !right->isEnum()) {
  1388         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  1389         return;
  1390     }
  1391     if (!left->isArray()) {
  1392         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  1393         return;
  1394     }
  1395 
  1396     // Note: char arrays are automatically up-casted to return an int32.
  1397     if (left->isCharArray())
  1398         node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1399     else
  1400         node->setType(left->contained());
  1401 }
  1402 
  1403 void
  1404 SemanticAnalysis::visit(FieldExpression *node)
  1405 {
  1406     Local<Type> left(zone_, visitForLoad(node->left()));
  1407     if (!left)
  1408         return;
  1409 
  1410     if (!left->isStruct()) {
  1411         cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1412                         GetTypeName(left));
  1413         return;
  1414     }
  1415 
  1416     Local<String> field(zone_, node->field());
  1417 
  1418     unsigned offset;
  1419     Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
  1420     if (!desc) {
  1421         cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1422                         GetTypeName(left));
  1423         return;
  1424     }
  1425 
  1426     node->setFieldIndex(offset);
  1427     node->setType(desc->type());
  1428 }
  1429 
  1430 void
  1431 SemanticAnalysis::visit(EnumStatement *node)
  1432 {
  1433     Local<String> name(zone_, node->name());
  1434     Local<Type> type(zone_);
  1435     if (name)
  1436         type = zone_->types()->newEnum(name);
  1437     else
  1438         type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1439 
  1440     if (!type)
  1441         return;
  1442 
  1443     if (node->decl())
  1444         node->decl()->setType(type);
  1445 
  1446     int value = 0;
  1447     for (size_t i = 0; i < node->entries()->length(); i++) {
  1448         EnumStatement::Entry &entry = node->entries()->at(i);
  1449 
  1450         BoxedPrimitive box = BoxedPrimitive::Int(value);
  1451         if (entry.expr) {
  1452             entry.expr->accept(this);
  1453             if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
  1454                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1455                 return;
  1456             }
  1457 
  1458             assert(box.type() == PrimitiveType_Int32);
  1459             value = box.toInt();
  1460         }
  1461 
  1462         entry.name->set(type, box);
  1463         value++;
  1464     }
  1465 }
  1466 
  1467 static int
  1468 SortCaseIntValues(const void *p1, const void *p2)
  1469 {
  1470     CaseValue *v1 = (CaseValue *)p1;
  1471     CaseValue *v2 = (CaseValue *)p2;
  1472 
  1473     return v1->box.toInt() - v2->box.toInt();
  1474 }
  1475 
  1476 void
  1477 SemanticAnalysis::visit(SwitchStatement *node)
  1478 {
  1479     Local<Type> caseType(zone_, visitForLoad(node->expression()));
  1480     if (!caseType)
  1481         return;
  1482 
  1483     if (!caseType->isEnum() && !caseType->isInt32()) {
  1484         cc_.reportError(node->pos(), Message_CaseMustBeInteger);
  1485         return;
  1486     }
  1487 
  1488     PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
  1489     ControlStatus status = ControlStatus(false, Returns_Never);
  1490 
  1491     Local<Type> check(zone_);
  1492     for (size_t i = 0; i < node->cases()->length(); i++) {
  1493         Case *c = node->cases()->at(i);
  1494 
  1495         check = visitForLoad(c->expression());
  1496         if (!check)
  1497             return;
  1498 
  1499         if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
  1500             return;
  1501 
  1502         CaseValue v(i);
  1503         if (!EvaluateForConstant(c->expression(), &v.box)) {
  1504             cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
  1505             return;
  1506         }
  1507         if (!values->append(v))
  1508             return;
  1509 
  1510         if (c->others()) {
  1511             for (size_t j = 0; j < c->others()->length(); j++) {
  1512                 Expression *expr = c->others()->at(j);
  1513                 check = visitForLoad(expr);
  1514                 if (!check)
  1515                     return;
  1516 
  1517                 if (!typeCheckAssignment(expr->pos(), check, caseType, false))
  1518                     return;
  1519 
  1520                 CaseValue v(i);
  1521                 if (!EvaluateForConstant(expr, &v.box)) {
  1522                     cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
  1523                     return;
  1524                 }
  1525                 if (!values->append(v))
  1526                     return;
  1527             }
  1528         }
  1529 
  1530         ControlStatus latest = visitForControl(c->statement());
  1531 
  1532         if (i != 0)
  1533             control_->merge(status, latest);
  1534 
  1535         status = latest;
  1536     }
  1537 
  1538     if (node->defaultCase()) {
  1539         ControlStatus latest = visitForControl(node->defaultCase());
  1540 
  1541         if (node->cases()->length()) {
  1542             // If we had any other cases, we must merge.
  1543             control_->merge(status, latest);
  1544         } else {
  1545             // Otherwise, control-flow always flows through here.
  1546             control_->inherit(latest);
  1547         }
  1548     } else if (node->cases()->length()) {
  1549         control_->merge(status, ControlStatus(false, Returns_Never));
  1550     }
  1551 
  1552     if (values->length() > 1) {
  1553         qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
  1554 
  1555         for (size_t i = 1; i < values->length(); i++) {
  1556             CaseValue &prev = values->at(i - 1);
  1557             CaseValue &cur = values->at(i);
  1558             if (prev.box.toInt() == cur.box.toInt()) {
  1559                 cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
  1560                 return;
  1561             }
  1562         }
  1563     }
  1564 
  1565     node->setCaseValueList(values);
  1566 }
  1567 
  1568 void
  1569 SemanticAnalysis::visit(StructureStatement *node)
  1570 {
  1571     // If this node already has a type, it was pre-analyzed, so skip it.
  1572     if (node->decl()->type())
  1573         return;
  1574 
  1575     FieldList *fields = node->fields();
  1576     Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
  1577     if (!desctable)
  1578         return;
  1579 
  1580     Vector<unsigned> composedList;
  1581     StructureBufferBuilder builder;
  1582 
  1583     Local<Type> type(zone_);
  1584     Local<String> name(zone_);
  1585     Local<Descriptor> desc(zone_);
  1586     for (size_t i = 0; i < fields->length(); i++) {
  1587         StructureStatement::Field *field = fields->at(i);
  1588 
  1589         type = bindType(field->pos(), field->type());
  1590         if (!type)
  1591             return;
  1592 
  1593         if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
  1594             cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
  1595             return;
  1596         }
  1597 
  1598         unsigned offset;
  1599         if (!builder.add(type, &offset))
  1600             return;
  1601 
  1602         name = field->name();
  1603         desc = Descriptor::New(zone_, name, type, offset);
  1604         if (!desc)
  1605             return;
  1606 
  1607         desctable->set(zone_, i, desc);
  1608 
  1609         if (type->isStruct() || type->isArray()) {
  1610             if (!composedList.append(i))
  1611                 return;
  1612         }
  1613     }
  1614 
  1615     Local<FixedArray> composed(zone_);
  1616     if (composedList.length()) {
  1617         composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
  1618         if (!composed)
  1619             return;
  1620 
  1621         for (unsigned i = 0; i < composedList.length(); i++)
  1622             composed->set(zone_, i, desctable->at(i));
  1623     }
  1624 
  1625     Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
  1626     if (!map)
  1627         return;
  1628 
  1629     name = node->decl()->name();
  1630     type = zone_->types()->newStruct(name, desctable, map);
  1631     if (!type)
  1632         return;
  1633 
  1634     map->setType(type);
  1635     node->decl()->setType(type);
  1636 }
  1637 
  1638 void
  1639 SemanticAnalysis::visit(StringLiteral *node)
  1640 {
  1641     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1642     if (!type)
  1643         return;
  1644 
  1645     type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1646     if (!type)
  1647         return;
  1648 
  1649     node->setType(type);
  1650 }
  1651 
  1652 void
  1653 SemanticAnalysis::visit(FloatLiteral *node)
  1654 {
  1655     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1656     if (!type)
  1657         return;
  1658 
  1659     node->setType(type);
  1660 }
  1661 
  1662 void
  1663 SemanticAnalysis::visit(BreakStatement *node)
  1664 {
  1665     if (!loop_) {
  1666         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1667         return;
  1668     }
  1669 
  1670     // Note: ignore breaks that occur in unreachable control-flow.
  1671     if (!control_->status().terminates())
  1672         loop_->addBreak();
  1673 
  1674     control_->terminate(Returns_Never);
  1675 }
  1676 
  1677 void
  1678 SemanticAnalysis::visit(ContinueStatement *node)
  1679 {
  1680     if (!loop_) {
  1681         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1682         return;
  1683     }
  1684 
  1685     // Note: ignore continues that occur in unreachable control-flow.
  1686     if (!control_->status().terminates())
  1687         loop_->addContinue();
  1688 
  1689     control_->terminate(Returns_Never);
  1690 }