jitcraft/SemanticAnalysis.cpp
author David Anderson <dvander@alliedmods.net>
Tue Jul 17 23:05:38 2012 -0700 (2012-07-17)
changeset 80 c58dff4e560c
parent 79 0206df35882c
child 83 79265b56316e
permissions -rw-r--r--
Added support for negate operator.
     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 "SemanticAnalysis.h"
    20 #include "Types.h"
    21 #include "Zone.h"
    22 #include "TypeManager.h"
    23 #include "Scopes.h"
    24 #include "Heap-inl.h"
    25 #include "Strings.h"
    26 
    27 using namespace ke;
    28 
    29 static inline bool
    30 IsPrimitiveType(Type *type, PrimitiveType primitive)
    31 {
    32     if (!type)
    33         return false;
    34 
    35     if (!type->isPrimitive())
    36         return false;
    37 
    38     return primitive == type->primitive();
    39 }
    40 
    41 static inline bool
    42 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    43                         BoxedPrimitive *out)
    44 {
    45     switch (kind) {
    46       case TOK_PLUS:
    47         *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    48         return true;
    49 
    50       case TOK_SHL:
    51         *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    52         return true;
    53 
    54       default:
    55         return false;
    56     }
    57 }
    58 
    59 static bool
    60 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
    61 {
    62     switch (expression->kind()) {
    63       case AstNode::kBinaryExpression:
    64       {
    65         BoxedPrimitive left;
    66         BoxedPrimitive right;
    67         BinaryExpression *b = expression->toBinaryExpression();
    68         if (!EvaluateForConstant(b->left(), &left) ||
    69             !EvaluateForConstant(b->right(), &right))
    70         {
    71             return false;
    72         }
    73         return EvaluateBinaryOperation(b->token(), left, right, out);
    74       }
    75 
    76       case AstNode::kNameProxy:
    77       {
    78         NameProxy *proxy = expression->toNameProxy();
    79         if (proxy->binding()->kind() != BoundName::CONSTANT)
    80             return false;
    81 
    82         NamedConstant *c = proxy->binding()->toNamedConstant();
    83         if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
    84             return false;
    85 
    86         *out = c->value();
    87         return true;
    88       }
    89 
    90       case AstNode::kIntegerLiteral:
    91         *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
    92         return true;
    93 
    94       default:
    95         return false;
    96     }
    97 }
    98 
    99 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
   100   : zone_(zone),
   101     cc_(cc),
   102     tree_(tree),
   103     scope_(NULL),
   104     loop_(NULL)
   105 {
   106 }
   107 
   108 bool
   109 SemanticAnalysis::analyze()
   110 {
   111     if (cc_.failures())
   112         return false;
   113 
   114     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   115         Statement *statement = tree_->statements()->at(i);
   116         if (statement->isFunctionStatement()) {
   117             FunctionStatement *funstmt = statement->toFunctionStatement();
   118             if (!preanalyze(funstmt))
   119                 return false;
   120         }
   121     }
   122 
   123     for (size_t i = 0; i < tree_->statements()->length(); i++) {
   124         Statement *statement = tree_->statements()->at(i);
   125         statement->accept(this);
   126     }
   127 
   128     return !cc_.failures();
   129 }
   130 
   131 Type *
   132 SemanticAnalysis::visitAndApplyType(Expression *expression)
   133 {
   134     expression->accept(this);
   135     return expression->type();
   136 }
   137 
   138 Type *
   139 SemanticAnalysis::visitForLoad(Expression *expression)
   140 {
   141     Local<Type> type(zone_, visitAndApplyType(expression));
   142     if (!type)
   143         return NULL;
   144 
   145     if (type->isReference()) {
   146         expression->setType(type->contained());
   147     } else if (expression->isIndexExpression()) {
   148         if (type->isArray())
   149             expression->setType(type->contained());
   150     } else if (expression->isCallExpression()) {
   151         if (type->isVoid()) {
   152             CallExpression *call = expression->toCallExpression();
   153             cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
   154             return NULL;
   155         }
   156     }
   157 
   158     return expression->type();
   159 }
   160 
   161 // :TODO: this leaks an interior pointer.
   162 static inline const char *
   163 GetTypeName(Type *type)
   164 {
   165     if (type->isArray())
   166         return "array";
   167     if (type->isFunction())
   168         return "function";
   169     if (type->isReference())
   170         type = type->contained();
   171     if (type->tag())
   172         return type->tag()->chars();
   173     return "int";
   174 }
   175 
   176 void
   177 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
   178 {
   179     const char *op = TokenNames[token];
   180     const char *name = GetTypeName(type);
   181 
   182     cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   183 }
   184 
   185 void
   186 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   187 {
   188     const char *op = TokenNames[token];
   189     const char *leftName = GetTypeName(left);
   190     const char *rightName = GetTypeName(right);
   191 
   192     cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   193 }
   194 
   195 Type *
   196 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   197 {
   198     if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   199         (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   200     {
   201         // If either side is a float, the other side must be a float or int.
   202         if (left->isFloat() || right->isFloat()) {
   203             Type *floatType = left->isFloat() ? left : right;
   204             Type *other = left->isFloat() ? right : left;
   205             if (other->isFloat() || (other->isInt32() && !other->tag()))
   206                 return floatType;
   207         }
   208     }
   209 
   210     if (token == TOK_OR || token == TOK_AND) {
   211         if (!canTest(node, left) || !canTest(node, right))
   212             return NULL;
   213         return zone_->types()->getPrimitive(PrimitiveType_Int32);
   214     }
   215 
   216     if (token >= TOK_EQUALS && token <= TOK_GE) {
   217         if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
   218             (right->isFloat() || (right->isInt32() && !right->tag())))
   219         {
   220             return zone_->types()->getPrimitive(PrimitiveType_Int32);
   221         }
   222         binaryTypeError(node, token, left, right);
   223         return NULL;
   224     }
   225 
   226     if ((!left->isInt32() || left->tag()) ||
   227         (!right->isInt32() || right->tag()))
   228     {
   229         binaryTypeError(node, token, left, right);
   230         return NULL;
   231     }
   232 
   233     return left;
   234 }
   235 
   236 bool
   237 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
   238 {
   239     if (type->isArray() || (type->isInt32() && type->tag())) {
   240         cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   241         return false;
   242     }
   243     return true;
   244 }
   245 
   246 Type *
   247 SemanticAnalysis::visitForLValue(Expression *expression)
   248 {
   249     if (expression->isIndexExpression()) {
   250         Type *type = visitAndApplyType(expression);
   251         if (!type)
   252             return NULL;
   253 
   254         if (type->isConst()) {
   255             cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   256             return NULL;
   257         }
   258 
   259         return type->contained();
   260     }
   261 
   262     if (!expression->isNameProxy()) {
   263         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   264         return NULL;
   265     }
   266 
   267     NameProxy *proxy = expression->toNameProxy();
   268     if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   269         cc_.reportError(expression->pos(), Message_ExpectedLValue);
   270         return NULL;
   271     }
   272 
   273     Variable *var = proxy->binding()->toVariable();
   274     if (!var->type())
   275         return NULL;
   276 
   277     if  (var->type()->isReference()) {
   278         if (var->type()->isConst()) {
   279             cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   280             return NULL;
   281         }
   282         return var->type()->contained();
   283     }
   284     return var->type();
   285 }
   286 
   287 SemanticAnalysis::ControlStatus
   288 SemanticAnalysis::visitForControl(Statement *statement)
   289 {
   290     ControlScope scope(&control_);
   291     statement->accept(this);
   292     return scope.status();
   293 }
   294 
   295 void
   296 SemanticAnalysis::visit(NameProxy *name)
   297 {
   298     name->setType(name->binding()->type());
   299 }
   300 
   301 void
   302 SemanticAnalysis::visit(Assignment *node)
   303 {
   304     Local<Type> exprType(zone_, visitForLoad(node->expression()));
   305     if (!exprType)
   306         return ;
   307 
   308     Local<Type> type(zone_, visitForLValue(node->lvalue()));
   309     if (!type)
   310         return;
   311 
   312     if (node->token() != TOK_ASSIGN) {
   313         if (!typeCheckBinary(node, node->token(), type, exprType))
   314             return;
   315     }
   316 
   317     if (!typeCheckAssignment(node, exprType, type, true))
   318         return;
   319 
   320     node->setType(type);
   321 }
   322 
   323 void
   324 SemanticAnalysis::visit(IncDecExpression *node)
   325 {
   326     Local<Type> type(zone_, visitForLValue(node->expression()));
   327     if (!type)
   328         return;
   329 
   330     assert(!type->isReference());
   331 
   332     if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
   333         unaryTypeError(node, node->token(), type);
   334         return;
   335     }
   336 
   337     node->setType(type);
   338 }
   339 
   340 void
   341 SemanticAnalysis::visit(UnaryExpression *node)
   342 {
   343     Local<Type> type(zone_, visitForLoad(node->expression()));
   344     if (!type)
   345         return;
   346 
   347     switch (node->token())
   348     {
   349       case TOK_NOT:
   350         if (!canTest(node->expression(), type))
   351             return;
   352         type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   353         if (!type)
   354             return;
   355         node->setType(type);
   356         break;
   357 
   358       case TOK_MINUS:
   359         if (!type->isFloat() && (!type->isInt32() || type->tag())) {
   360             unaryTypeError(node, node->token(), type);
   361             return;
   362         }
   363         node->setType(type);
   364         break;
   365 
   366       default:
   367         assert(node->token() == TOK_TILDE);
   368         if (!type->isInt32() || type->tag()) {
   369             unaryTypeError(node, node->token(), type);
   370             return;
   371         }
   372         node->setType(type);
   373         break;
   374     }
   375 }
   376 
   377 void
   378 SemanticAnalysis::visit(BinaryExpression *node)
   379 {
   380     Local<Type> left(zone_, visitForLoad(node->left()));
   381     Local<Type> right(zone_, visitForLoad(node->right()));
   382     if (!left || !right)
   383         return;
   384 
   385     Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
   386     if (!result)
   387         return;
   388 
   389     node->setType(result);
   390 }
   391 
   392 void
   393 SemanticAnalysis::visit(ReturnStatement *node)
   394 {
   395     // Set this early, so if we error we don't get more errors.
   396     control_->returns(Returns_Always);
   397 
   398     if (!node->expression()) {
   399         if (!function_->returnType()->isVoid())
   400             cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
   401         return;
   402     }
   403 
   404     Local<Type> type(zone_, visitForLoad(node->expression()));
   405     if (!type)
   406         return;
   407 
   408     Local<Type> returnType(zone_, function_->returnType());
   409     if (!typeCheckAssignment(node, type, returnType, true))
   410         return;
   411 }
   412 
   413 void
   414 SemanticAnalysis::visit(ForStatement *node)
   415 {
   416     LoopScope loop(&loop_);
   417 
   418     if (node->scope())
   419         scope_ = node->scope();
   420 
   421     if (node->initialization())
   422         node->initialization()->accept(this);
   423 
   424     if (node->condition()) {
   425         Local<Type> type(zone_, visitForLoad(node->condition()));
   426         if (!type || !canTest(node->condition(), type)) {
   427             return;
   428         }
   429     }
   430 
   431     if (node->update())
   432         node->update()->accept(this);
   433 
   434     ControlStatus status = visitForControl(node->body());
   435 
   436     // If there is a condition, we treat this like a while loop. Otherwise,
   437     // join point is only reachable if the loop contains a break. The
   438     // termination status doesn't tell us anything yet.
   439     if (node->condition() || loop.breaks())
   440         control_->merge(status, ControlStatus(false, Returns_Never));
   441     else
   442         control_->terminate(status.returns());
   443 
   444     if (node->scope())
   445         scope_ = scope_->enclosing();
   446 }
   447 
   448 void 
   449 SemanticAnalysis::visit(WhileStatement *node)
   450 {
   451     LoopScope loop(&loop_);
   452 
   453     Local<Type> type(zone_, visitForLoad(node->condition()));
   454     if (!type || !canTest(node->condition(), type)) {
   455         return;
   456     }
   457 
   458     ControlStatus status = visitForControl(node->body());
   459 
   460     // Detect loops that will always have a fork in the control-flow graph.
   461     // This will be a |while| loop, or a |do-while| loop whose body does
   462     // not terminate.
   463     //
   464     // For now, we treat these as an |if| regardless of the direction the
   465     // branch can take. That means the control-flow is always conditional.
   466     if (node->token() == TOK_WHILE ||
   467         !status.terminates() ||
   468         loop.breaks())
   469     {
   470         control_->merge(status, ControlStatus(false, Returns_Never));
   471     } else {
   472         // At this point, we've got a do-while loop with a |return| or
   473         // |continue|, meaning that the rest of the block is unreachable.
   474         control_->terminate(status.returns());
   475     }
   476 }
   477 
   478 void
   479 SemanticAnalysis::visit(BlockStatement *node)
   480 {
   481     if (node->scope())
   482         scope_ = node->scope();
   483     for (size_t i = 0; i < node->statements()->length(); i++) {
   484         Statement *statement = node->statements()->at(i);
   485         statement->accept(this);
   486     }
   487     if (node->scope())
   488         scope_ = scope_->enclosing();
   489 }
   490 
   491 void
   492 SemanticAnalysis::visit(VariableDeclaration *node)
   493 {
   494     Local<String> tag(zone_, node->tag());
   495     Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
   496     if (!type)
   497         return;
   498 
   499     if (node->postDimensions()) {
   500         Local<Type> init(zone_);
   501         if (node->initialization()) {
   502             if ((init = visitForLoad(node->initialization())) == NULL)
   503                 return;
   504         }
   505 
   506         if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   507             cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   508             return;
   509         }
   510 
   511         // If we have an initializer, make sure it's the same type.
   512         if (init && node->postDimensions()->length() != init->levels()) {
   513             cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
   514             return;
   515         }
   516 
   517         Local<Type> check(zone_, init);
   518         for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
   519             Expression *expr = node->postDimensions()->at(i);
   520             int size = -1;
   521 
   522             if (expr) {
   523                 Local<Type> exprType(zone_, visitForLoad(expr));
   524                 if (!exprType)
   525                     return;
   526 
   527                 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   528                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   529                     return;
   530                 }
   531 
   532                 BoxedPrimitive box;
   533                 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   534                     size = box.toInt();
   535                     if (size <= 0) {
   536                         cc_.reportError(expr->pos(), Message_BadArraySize);
   537                         return;
   538                     }
   539                     if (size >= INT_MAX / sizeof(int)) {
   540                         cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
   541                         return;
   542                     }
   543 
   544                     if (check) {
   545                         if (check->elements() == -1) {
   546                             cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
   547                             return;
   548                         }
   549 
   550                         if (check->isCharArray()) {
   551                             if (check->elements() > size) {
   552                                 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   553                                 return;
   554                             }
   555                         } else if (check->elements() != size) {
   556                             cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
   557                             return;
   558                         }
   559                     }
   560                 } else {
   561                     if (init) {
   562                         cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
   563                         return;
   564                     }
   565 
   566                     // here until we get dynamic array support.
   567                     cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   568                     return;
   569                 }
   570             } else {
   571                 // Infer the size from the initializer.
   572                 if (!init) {
   573                     cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
   574                     return;
   575                 }
   576                 if (init->elements() == -1) {
   577                     cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
   578                     return;
   579                 }
   580                 size = init->elements();
   581             }
   582 
   583             type = zone_->types()->unsafeArray(type, size, false);
   584             if (!type)
   585                 return;
   586 
   587             if (check)
   588                 check = check->contained();
   589         }
   590 
   591         // Right now, any array is allowed on the LIFO heap. In case the
   592         // runtime actually decides to use the LIFO heap, we must reserve
   593         // a slot so we can unwind the heap when the current scope leaves.
   594         scope_->setUsesLifoHeap();
   595     } else {
   596         if (node->initialization()) {
   597             Local<Type> right(zone_, visitForLoad(node->initialization()));
   598             if (!right)
   599                 return;
   600             if (!typeCheckAssignment(node, type, right, true))
   601                 return;
   602         }
   603         if (type->primitive() == PrimitiveType_Char) {
   604             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   605             return;
   606         }
   607     }
   608 
   609     node->variable()->setType(type);
   610 }
   611 
   612 void
   613 SemanticAnalysis::visit(IntegerLiteral *node)
   614 {
   615     node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   616 }
   617 
   618 void
   619 SemanticAnalysis::visit(ExpressionStatement *node)
   620 {
   621     visitAndApplyType(node->expression());
   622 }
   623 
   624 bool
   625 SemanticAnalysis::preanalyze(FunctionStatement *node)
   626 {
   627     Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
   628     if (!args)
   629         return false;
   630 
   631     // Apply types to arguments.
   632     for (size_t i = 0; i < node->parameters()->length(); i++) {
   633         Parameter *parameter = node->parameters()->at(i);
   634         
   635         Local<String> tag(zone_, parameter->tag());
   636         Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
   637         if (!type)
   638             return false;
   639 
   640         if (parameter->reference()) {
   641             if (parameter->dimensions()) {
   642                 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
   643                 return NULL;
   644             }
   645 
   646             type = zone_->types()->getReference(type, parameter->isConst());
   647             if (!type)
   648                 return false;
   649         } else if (parameter->dimensions()) {
   650             if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
   651                 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
   652                 return false;
   653             }
   654 
   655             if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
   656                 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
   657                 return false;
   658             }
   659 
   660             for (size_t i = parameter->dimensions()->length() - 1;
   661                  i < parameter->dimensions()->length();
   662                  i++)
   663             {
   664                 int size = Type::UNKNOWN_SIZE;
   665                 if (Expression *expr = parameter->dimensions()->at(i)) {
   666                     BoxedPrimitive box;
   667                     if (!EvaluateForConstant(expr, &box)) {
   668                         cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
   669                         return false;
   670                     }
   671                     size = box.toInt();
   672                 }
   673 
   674                 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
   675                 if (!type)
   676                     return false;
   677             }
   678         }
   679 
   680         if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
   681             (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
   682         {
   683             cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   684             return false;
   685         }
   686 
   687         args->set(zone_, i, type);
   688         parameter->variable()->setType(type);
   689     }
   690 
   691     Local<Type> returnType(zone_);
   692     if (node->hasExplicitReturn() || node->fun()->isNative())
   693         returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
   694     else
   695         returnType = zone_->types()->getVoid();
   696     if (!returnType)
   697         return false;
   698 
   699     Local<Type> funtype(zone_);
   700     if (node->fun()->isNative())
   701         funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
   702     else
   703         funtype = zone_->types()->newFunction(returnType, args);
   704     if (!funtype)
   705         return false;
   706     
   707     // If the function already has a type, it was forward declared before, and
   708     // now this is our chance to type check the second declaration.
   709     if (node->fun()->type()) {
   710         Local<Type> forward(zone_, node->fun()->type());
   711         if (!Type::Compare(funtype, forward)) {
   712             cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
   713             return false;
   714         }
   715         node->fun()->setForwardType(forward);
   716     }
   717 
   718     node->fun()->setType(funtype);
   719 
   720     return true;
   721 }
   722 
   723 void
   724 SemanticAnalysis::visit(FunctionStatement *node)
   725 {
   726     function_ = node->fun()->type();
   727     scope_ = node->scope();
   728 
   729     ControlScope control(&control_);
   730     if (node->body()) {
   731         node->body()->accept(this);
   732 
   733         ControlStatus status = control.status();
   734         if (status.returns() == Returns_Sometimes) {
   735             cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
   736         } else if (status.returns() == Returns_Never) {
   737             if (!function_->returnType()->isVoid())
   738                 cc_.reportError(node->pos(), Message_MissingReturnValue);
   739         }
   740     }
   741 
   742     scope_ = NULL;
   743     function_ = NULL;
   744 }
   745 
   746 bool
   747 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
   748 {
   749     Local<Type> actual(zone_, argActual);
   750     Local<Type> given(zone_, argGiven);
   751 
   752     if (!given->isArray()) {
   753         cc_.reportError(node->pos(), Message_ExpectedArray);
   754         return false;
   755     }
   756     if (given->levels() != actual->levels()) {
   757         cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
   758         return false;
   759     }
   760 
   761     unsigned level = 0;
   762     while (given->isArray()) {
   763         if (actual->elements() != -1) {
   764             if (forAssign) {
   765                 if (given->elements() == -1 || actual->elements() == -1) {
   766                     cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
   767                     return false;
   768                 }
   769 
   770                 if (actual->isCharArray()) {
   771                     // String assignment can have a truncated |given|.
   772                     if (given->elements() > actual->elements()) {
   773                         cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
   774                         return false;
   775                     }
   776                 } else {
   777                     if (given->elements() != actual->elements()) {
   778                         cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   779                         return false;
   780                     }
   781                 }
   782             } else {
   783                 if (actual->elements() != -1 && given->elements() != actual->elements()) {
   784                     cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
   785                     return false;
   786                 }
   787             }
   788         }
   789         given = given->contained();
   790         actual = actual->contained();
   791     }
   792 
   793     if (given->primitive() != actual->primitive()) {
   794         // :TODO: leaks an interior pointer.
   795         const char *givenTag = given->tag() ? given->tag()->chars() : "_";
   796         const char *actualTag = given->tag() ? given->tag()->chars() : "_";
   797         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   798         return false;
   799     }
   800 
   801     return true;
   802 }
   803 
   804 bool
   805 SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
   806 {
   807     Local<Type> actual(zone_, argActual);
   808     Local<Type> given(zone_, argGiven);
   809 
   810     if (actual->isArray())
   811         return typeCheckArrayAssignment(node, given, actual, forAssign);
   812 
   813     if (given->isArray()) {
   814         cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
   815         return false;
   816     }
   817 
   818     // The given type may not have been dereferenced.
   819     if (given->isReference())
   820         given = given->contained();
   821     if (actual->isReference())
   822         actual = actual->contained();
   823 
   824     if (!given->isPrimitive() || !actual->isPrimitive()) {
   825         cc_.reportError(node->pos(), Message_UnsupportedType);
   826         return false;
   827     }
   828     
   829     if (given->primitive() != actual->primitive()) {
   830         // :TODO: leaks an interior pointer
   831         const char *givenTag = given->tag() ? given->tag()->chars() : "_";
   832         const char *actualTag = given->tag() ? given->tag()->chars() : "_";
   833         cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
   834         return false;
   835     }
   836 
   837     return true;
   838 }
   839 
   840 bool
   841 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
   842 {
   843     return typeCheckAssignment(node, given, actual, false);
   844 }
   845 
   846 void
   847 SemanticAnalysis::visit(CallExpression *node)
   848 {
   849     Local<Type> type(zone_, visitForLoad(node->callee()));
   850     if (!type)
   851         return;
   852 
   853     if (!type->isFunction()) {
   854         cc_.reportError(node->pos(), Message_CalleeNotFunction);
   855         return;
   856     }
   857     if (node->arguments()->length() != type->parameters()->length()) {
   858         if (!type->isNative() ||
   859             !type->isNativeVariadic() ||
   860             node->arguments()->length() < type->parameters()->length())
   861         {
   862             cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
   863             return;
   864         }
   865     }
   866 
   867     // Currently, only calls from a NameProxy are possible.
   868     NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
   869     if (fun->isForward()) {
   870         cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
   871         return;
   872     }
   873 
   874     for (unsigned i = 0; i < node->arguments()->length(); i++) {
   875         // Note: we don't compute references unless the callee needs a
   876         // reference type.
   877         Expression *expression = node->arguments()->at(i);
   878         Local<Type> given(zone_, visitAndApplyType(expression));
   879         if (!given)
   880             return;
   881 
   882         // Since we skip a load, check for a call expression that returns void.
   883         if (given->isVoid()) {
   884             assert(expression->isCallExpression());
   885             CallExpression *call = expression->toCallExpression();
   886             cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
   887             return;
   888         }
   889         
   890         // If it's an IndexExpression, we special case the ability to compute
   891         // a reference.
   892         if (expression->isIndexExpression())
   893             given = given->contained();
   894 
   895         bool mustComputeReference;
   896         if (i >= type->parameters()->length()) {
   897             // Special handling for natives. Arguments past the formal must
   898             // always have references computed. However, arrays are already
   899             // references for natives.  
   900             assert(type->isNative() && type->isNativeVariadic());
   901             mustComputeReference = !given->isReference() && !given->isArray();
   902         } else {
   903             Local<Type> actual(zone_, type->parameterAt(i));
   904             if (!typeCheckParameter(expression, given, actual))
   905                 return;
   906             mustComputeReference = actual->isReference() && !given->isReference();
   907         }
   908 
   909         // If the actual is a reference, and the given is not, we'll need to
   910         // compute a reference, which may be allocated on the stack.
   911         if (mustComputeReference)
   912             scope_->setUsesLifoHeap();
   913     }
   914 
   915     node->setType(fun->type()->returnType());
   916 }
   917 
   918 void
   919 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
   920 {
   921     // If both sides terminate in a return, we consider this a return as well.
   922     if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
   923         terminate(Returns_Always);
   924         return;
   925     }
   926 
   927     ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
   928                           ? Returns_Never
   929                           : Returns_Sometimes;
   930 
   931     if (left.terminates() && right.terminates())
   932         terminate(status);
   933     else
   934         returns(status);
   935 }
   936 
   937 void
   938 SemanticAnalysis::visit(IfStatement *node)
   939 {
   940     Local<Type> type(zone_, visitForLoad(node->condition()));
   941     if (!type)
   942         return;
   943 
   944     if (!canTest(node, type))
   945         return;
   946 
   947     ControlStatus trueBranch = visitForControl(node->ifTrue());
   948     ControlStatus falseBranch = ControlStatus(false, Returns_Never);
   949 
   950     if (node->ifFalse())
   951         falseBranch = visitForControl(node->ifFalse());
   952 
   953     control_->merge(trueBranch, falseBranch);
   954 }
   955 
   956 void
   957 SemanticAnalysis::visit(IndexExpression *node)
   958 {
   959     Local<Type> left(zone_, visitForLoad(node->left()));
   960     Local<Type> right(zone_, visitForLoad(node->right()));
   961 
   962     if (!left || !right)
   963         return;
   964 
   965     if (!right->isInt32()) {
   966         cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
   967         return;
   968     }
   969     if (!left->isArray()) {
   970         cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
   971         return;
   972     }
   973     node->setType(left);
   974 }
   975 
   976 void
   977 SemanticAnalysis::visit(EnumStatement *node)
   978 {
   979     // Forbid the blessed types.
   980     Local<String> tag(zone_, node->name());
   981     if (!strcmp(tag->chars(), "Float") ||
   982         !strcmp(tag->chars(), "String") ||
   983         !strcmp(tag->chars(), "any") ||
   984         !strcmp(tag->chars(), "bool"))
   985     {
   986         cc_.reportError(node->pos(), Message_InvalidEnumName);
   987         return;
   988     }
   989 
   990     Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
   991     if (!type)
   992         return;
   993 
   994     int value = 0;
   995     for (size_t i = 0; i < node->entries()->length(); i++) {
   996         EnumStatement::Entry &entry = node->entries()->at(i);
   997 
   998         BoxedPrimitive box = BoxedPrimitive::Int(value);
   999         if (entry.expr) {
  1000             entry.expr->accept(this);
  1001             if (!EvaluateForConstant(entry.expr, &box)) {
  1002                 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1003                 return;
  1004             }
  1005 
  1006             assert(box.type() == PrimitiveType_Int32);
  1007             value = box.toInt();
  1008         }
  1009 
  1010         entry.name->set(type, box);
  1011         value++;
  1012     }
  1013 }
  1014 
  1015 void
  1016 SemanticAnalysis::visit(StringLiteral *node)
  1017 {
  1018     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1019     if (!type)
  1020         return;
  1021 
  1022     type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1023     if (!type)
  1024         return;
  1025 
  1026     node->setType(type);
  1027 }
  1028 
  1029 void
  1030 SemanticAnalysis::visit(FloatLiteral *node)
  1031 {
  1032     Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1033     if (!type)
  1034         return;
  1035 
  1036     node->setType(type);
  1037 }
  1038 
  1039 void
  1040 SemanticAnalysis::visit(BreakStatement *node)
  1041 {
  1042     if (!loop_) {
  1043         cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1044         return;
  1045     }
  1046 
  1047     // Note: ignore breaks that occur in unreachable control-flow.
  1048     if (!control_->status().terminates())
  1049         loop_->addBreak();
  1050 
  1051     control_->terminate(Returns_Never);
  1052 }
  1053 
  1054 void
  1055 SemanticAnalysis::visit(ContinueStatement *node)
  1056 {
  1057     if (!loop_) {
  1058         cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1059         return;
  1060     }
  1061 
  1062     // Note: ignore continues that occur in unreachable control-flow.
  1063     if (!control_->status().terminates())
  1064         loop_->addContinue();
  1065 
  1066     control_->terminate(Returns_Never);
  1067 }