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