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