src/SemanticAnalysis.cpp
changeset 195 c1ba166f3fc4
parent 194 b029d63565a2
child 196 9904633b1dfc
     1.1 --- a/src/SemanticAnalysis.cpp	Mon Sep 17 00:10:01 2012 -0700
     1.2 +++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.3 @@ -1,1887 +0,0 @@
     1.4 -/* vim: set ts=4 sw=4 tw=99 et:
     1.5 - *
     1.6 - * Copyright (C) 2012 David Anderson
     1.7 - *
     1.8 - * This file is part of JITCraft.
     1.9 - *
    1.10 - * JITCraft is free software: you can redistribute it and/or modify it under
    1.11 - * the terms of the GNU General Public License as published by the Free
    1.12 - * Software Foundation, either version 3 of the License, or (at your option)
    1.13 - * any later version.
    1.14 - * 
    1.15 - * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
    1.16 - * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
    1.17 - * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
    1.18 - *
    1.19 - * You should have received a copy of the GNU General Public License along with
    1.20 - * JITCraft. If not, see http://www.gnu.org/licenses/.
    1.21 - */
    1.22 -#include <string.h>
    1.23 -#include "SemanticAnalysis.h"
    1.24 -#include "Types.h"
    1.25 -#include "Zone.h"
    1.26 -#include "TypeManager.h"
    1.27 -#include "Scopes.h"
    1.28 -#include "NameBinding.h"
    1.29 -#include "Strings.h"
    1.30 -#include "Box.h"
    1.31 -#include "Array.h"
    1.32 -#include "Heap-inl.h"
    1.33 -
    1.34 -using namespace ke;
    1.35 -
    1.36 -static inline bool
    1.37 -IsPrimitiveType(Type *type, PrimitiveType primitive)
    1.38 -{
    1.39 -    if (!type)
    1.40 -        return false;
    1.41 -
    1.42 -    if (!type->isPrimitive())
    1.43 -        return false;
    1.44 -
    1.45 -    return primitive == type->primitive();
    1.46 -}
    1.47 -
    1.48 -static inline bool
    1.49 -EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    1.50 -                        BoxedPrimitive *out)
    1.51 -{
    1.52 -    switch (kind) {
    1.53 -      case TOK_PLUS:
    1.54 -        *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    1.55 -        return true;
    1.56 -
    1.57 -      case TOK_SHL:
    1.58 -        *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    1.59 -        return true;
    1.60 -
    1.61 -      default:
    1.62 -        return false;
    1.63 -    }
    1.64 -}
    1.65 -
    1.66 -static inline bool
    1.67 -EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
    1.68 -{
    1.69 -  switch (kind) {
    1.70 -    case TOK_MINUS:
    1.71 -      *out = BoxedPrimitive::Int(-inner.toInt());
    1.72 -      return true;
    1.73 -
    1.74 -    default:
    1.75 -      return false;
    1.76 -  }
    1.77 -}
    1.78 -
    1.79 -static bool
    1.80 -EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
    1.81 -{
    1.82 -    switch (expression->kind()) {
    1.83 -      case AstNode::kBinaryExpression:
    1.84 -      {
    1.85 -        BoxedPrimitive left;
    1.86 -        BoxedPrimitive right;
    1.87 -        BinaryExpression *b = expression->toBinaryExpression();
    1.88 -        if (!EvaluateForConstant(b->left(), &left) ||
    1.89 -            !EvaluateForConstant(b->right(), &right))
    1.90 -        {
    1.91 -            return false;
    1.92 -        }
    1.93 -        return EvaluateBinaryOperation(b->token(), left, right, out);
    1.94 -      }
    1.95 -
    1.96 -      case AstNode::kUnaryExpression:
    1.97 -      {
    1.98 -        BoxedPrimitive inner;
    1.99 -        UnaryExpression *u = expression->toUnaryExpression();
   1.100 -        if (!EvaluateForConstant(u->expression(), &inner))
   1.101 -            return false;
   1.102 -        return EvaluateUnaryOperation(u->token(), inner, out);
   1.103 -      }
   1.104 -
   1.105 -      case AstNode::kNameProxy:
   1.106 -      {
   1.107 -        NameProxy *proxy = expression->toNameProxy();
   1.108 -        if (proxy->binding()->kind() != BoundName::CONSTANT)
   1.109 -            return false;
   1.110 -
   1.111 -        NamedConstant *c = proxy->binding()->toNamedConstant();
   1.112 -        if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
   1.113 -            return false;
   1.114 -
   1.115 -        *out = c->value();
   1.116 -        return true;
   1.117 -      }
   1.118 -
   1.119 -      case AstNode::kBooleanLiteral:
   1.120 -        *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
   1.121 -        return true;
   1.122 -
   1.123 -      case AstNode::kIntegerLiteral:
   1.124 -        *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
   1.125 -        return true;
   1.126 -
   1.127 -      default:
   1.128 -        return false;
   1.129 -    }
   1.130 -}
   1.131 -
   1.132 -SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
   1.133 -  : zone_(zone),
   1.134 -    cc_(cc),
   1.135 -    tree_(tree),
   1.136 -    scope_(NULL),
   1.137 -    loop_(NULL)
   1.138 -{
   1.139 -}
   1.140 -
   1.141 -bool
   1.142 -SemanticAnalysis::analyze()
   1.143 -{
   1.144 -    if (cc_.failures())
   1.145 -        return false;
   1.146 -
   1.147 -    scope_ = tree_->scope();
   1.148 -
   1.149 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.150 -        Statement *statement = tree_->statements()->at(i);
   1.151 -        if (statement->isFunctionStatement()) {
   1.152 -            FunctionStatement *funstmt = statement->toFunctionStatement();
   1.153 -            if (!preanalyze(funstmt))
   1.154 -                return false;
   1.155 -        } else if (statement->isEnumStatement()) {
   1.156 -            EnumStatement *enumstmt = statement->toEnumStatement();
   1.157 -
   1.158 -            // We pre-fill global enum types, since they may occur in function
   1.159 -            // signatures. This should probably be somewhere else...
   1.160 -            enumstmt->accept(this);
   1.161 -        } else if (statement->isStructureStatement()) {
   1.162 -            StructureStatement *node = statement->toStructureStatement();
   1.163 -            node->accept(this);
   1.164 -            if (!node->decl()->type())
   1.165 -                return false;
   1.166 -        } else if (statement->isFunctionTypeStatement()) {
   1.167 -            FunctionTypeStatement *node = statement->toFunctionTypeStatement();
   1.168 -            node->accept(this);
   1.169 -            if (!node->decl()->type())
   1.170 -                return false;
   1.171 -        }
   1.172 -    }
   1.173 -
   1.174 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.175 -        Statement *statement = tree_->statements()->at(i);
   1.176 -
   1.177 -        // We can't double-process these. Maybe put this check somewhere else.
   1.178 -        if (statement->isEnumStatement())
   1.179 -            continue;
   1.180 -
   1.181 -        statement->accept(this);
   1.182 -    }
   1.183 -
   1.184 -    if (!determineLiveFunctions())
   1.185 -        return false;
   1.186 -
   1.187 -    return !cc_.failures();
   1.188 -}
   1.189 -
   1.190 -bool
   1.191 -SemanticAnalysis::determineLiveFunctions()
   1.192 -{
   1.193 -    Vector<NamedFunction *> worklist;
   1.194 -
   1.195 -    // Add the root set.
   1.196 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.197 -        Statement *statement = tree_->statements()->at(i);
   1.198 -        if (!statement->isFunctionStatement())
   1.199 -            continue;
   1.200 -
   1.201 -        FunctionStatement *stmt = statement->toFunctionStatement();
   1.202 -        NamedFunction  *fun = stmt->fun();
   1.203 -        if (!fun->used())
   1.204 -            continue;
   1.205 -
   1.206 -        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   1.207 -            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   1.208 -
   1.209 -            // Names in these lists are always unused, however, we mark them
   1.210 -            // as used while inserting into the work queue, to avoid double-
   1.211 -            // insertion.
   1.212 -            if (name->used())
   1.213 -                continue;
   1.214 -
   1.215 -            if (!worklist.append(name))
   1.216 -                return false;
   1.217 -
   1.218 -            name->setUsed();
   1.219 -        }
   1.220 -    }
   1.221 -
   1.222 -    while (!worklist.empty()) {
   1.223 -        NamedFunction *fun = worklist.popCopy();
   1.224 -
   1.225 -        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   1.226 -            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   1.227 -            if (name->used())
   1.228 -                continue;
   1.229 -            if (!worklist.append(name))
   1.230 -                return false;
   1.231 -            name->setUsed();
   1.232 -        }
   1.233 -    }
   1.234 -
   1.235 -    return true;
   1.236 -}
   1.237 -
   1.238 -Type *
   1.239 -SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
   1.240 -{
   1.241 -    if (!name)
   1.242 -        return zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.243 -
   1.244 -    if (name->kind() == BoundName::UNBOUND) {
   1.245 -        cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
   1.246 -        return NULL;
   1.247 -    }
   1.248 -
   1.249 -    if (name->kind() != BoundName::TYPE) {
   1.250 -        cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
   1.251 -        return NULL;
   1.252 -    }
   1.253 -
   1.254 -    if (!name->type())
   1.255 -        return NULL;
   1.256 -
   1.257 -    return name->type();
   1.258 -}
   1.259 -
   1.260 -Type *
   1.261 -SemanticAnalysis::visitAndApplyType(Expression *expression)
   1.262 -{
   1.263 -    expression->accept(this);
   1.264 -    return expression->type();
   1.265 -}
   1.266 -
   1.267 -Type *
   1.268 -SemanticAnalysis::visitForLoad(Expression *expression)
   1.269 -{
   1.270 -    Local<Type> type(zone_, visitAndApplyType(expression));
   1.271 -    if (!type)
   1.272 -        return NULL;
   1.273 -
   1.274 -    if (type->isReference()) {
   1.275 -        expression->setType(type->contained());
   1.276 -    } else if (expression->isCallExpression()) {
   1.277 -        if (type->isVoid()) {
   1.278 -            CallExpression *call = expression->toCallExpression();
   1.279 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
   1.280 -            return NULL;
   1.281 -        }
   1.282 -    }
   1.283 -
   1.284 -    return expression->type();
   1.285 -}
   1.286 -
   1.287 -// :TODO: this leaks an interior pointer.
   1.288 -const char *
   1.289 -ke::GetTypeName(Type *type)
   1.290 -{
   1.291 -    if (type->isArray())
   1.292 -        return "array";
   1.293 -    if (type->isFunction())
   1.294 -        return "function";
   1.295 -    if (type->isVoid())
   1.296 -        return "void";
   1.297 -    if (type->isEnum() || type->isStruct())
   1.298 -        return type->name()->chars();
   1.299 -    if (type->isReference())
   1.300 -        type = type->contained();
   1.301 -    switch (type->primitive()) {
   1.302 -      case PrimitiveType_Bool:
   1.303 -        return "bool";
   1.304 -      case PrimitiveType_Char:
   1.305 -        return "String";
   1.306 -      case PrimitiveType_Int32:
   1.307 -        return "int";
   1.308 -      case PrimitiveType_Float:
   1.309 -        return "Float";
   1.310 -      default:
   1.311 -        return "<unknown>";
   1.312 -    }
   1.313 -}
   1.314 -
   1.315 -void
   1.316 -SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
   1.317 -{
   1.318 -    const char *op = TokenNames[token];
   1.319 -    const char *name = GetTypeName(type);
   1.320 -
   1.321 -    cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   1.322 -}
   1.323 -
   1.324 -void
   1.325 -SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   1.326 -{
   1.327 -    const char *op = TokenNames[token];
   1.328 -    const char *leftName = GetTypeName(left);
   1.329 -    const char *rightName = GetTypeName(right);
   1.330 -
   1.331 -    cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   1.332 -}
   1.333 -
   1.334 -Type *
   1.335 -SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   1.336 -{
   1.337 -    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   1.338 -        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   1.339 -    {
   1.340 -        // If either side is a float, the other side must be a float or int.
   1.341 -        if (left->isFloat() || right->isFloat()) {
   1.342 -            Type *floatType = left->isFloat() ? left : right;
   1.343 -            Type *other = left->isFloat() ? right : left;
   1.344 -            if (other->isFloat() || other->isInt32())
   1.345 -                return floatType;
   1.346 -        }
   1.347 -    }
   1.348 -
   1.349 -    if (token == TOK_OR || token == TOK_AND) {
   1.350 -        if (!canTest(node, left) || !canTest(node, right))
   1.351 -            return NULL;
   1.352 -        return zone_->types()->getPrimitive(PrimitiveType_Bool);
   1.353 -    }
   1.354 -
   1.355 -    if (token >= TOK_EQUALS && token <= TOK_GE) {
   1.356 -        if ((left->isFloat() || left->isInt32()) &&
   1.357 -            (right->isFloat() || right->isInt32()))
   1.358 -        {
   1.359 -            return zone_->types()->getPrimitive(PrimitiveType_Bool);
   1.360 -        }
   1.361 -        binaryTypeError(node, token, left, right);
   1.362 -        return NULL;
   1.363 -    }
   1.364 -
   1.365 -    if (!left->isInt32() || !right->isInt32()) {
   1.366 -        binaryTypeError(node, token, left, right);
   1.367 -        return NULL;
   1.368 -    }
   1.369 -
   1.370 -    return left;
   1.371 -}
   1.372 -
   1.373 -bool
   1.374 -SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
   1.375 -{
   1.376 -    if (!type->isPrimitive() && !type->isEnum()) {
   1.377 -        cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   1.378 -        return false;
   1.379 -    }
   1.380 -    return true;
   1.381 -}
   1.382 -
   1.383 -Type *
   1.384 -SemanticAnalysis::visitForLValue(Expression *expression)
   1.385 -{
   1.386 -    if (expression->isIndexExpression()) {
   1.387 -        Type *type = visitAndApplyType(expression);
   1.388 -        if (!type)
   1.389 -            return NULL;
   1.390 -
   1.391 -        // if (type->isConst()) {
   1.392 -        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.393 -        //     return NULL;
   1.394 -        // }
   1.395 -
   1.396 -        return type;
   1.397 -    }
   1.398 -
   1.399 -    if (expression->isFieldExpression()) {
   1.400 -        Type *type = visitAndApplyType(expression);
   1.401 -        if (!type)
   1.402 -            return NULL;
   1.403 -
   1.404 -        // if (expression->toFieldExpression()->left()->type()->isConst()) {
   1.405 -        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.406 -        //     return NULL;
   1.407 -        // }
   1.408 -
   1.409 -        return type;
   1.410 -    }
   1.411 -
   1.412 -    if (!expression->isNameProxy()) {
   1.413 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
   1.414 -        return NULL;
   1.415 -    }
   1.416 -
   1.417 -    NameProxy *proxy = expression->toNameProxy();
   1.418 -    if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   1.419 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
   1.420 -        return NULL;
   1.421 -    }
   1.422 -
   1.423 -    Variable *var = proxy->binding()->toVariable();
   1.424 -    if (!var->type())
   1.425 -        return NULL;
   1.426 -
   1.427 -    if  (var->type()->isReference()) {
   1.428 -        if (var->type()->isConst()) {
   1.429 -            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.430 -            return NULL;
   1.431 -        }
   1.432 -        return var->type()->contained();
   1.433 -    }
   1.434 -    return var->type();
   1.435 -}
   1.436 -
   1.437 -SemanticAnalysis::ControlStatus
   1.438 -SemanticAnalysis::visitForControl(Statement *statement)
   1.439 -{
   1.440 -    ControlScope scope(&control_);
   1.441 -    statement->accept(this);
   1.442 -    return scope.status();
   1.443 -}
   1.444 -
   1.445 -void
   1.446 -SemanticAnalysis::visit(NameProxy *name)
   1.447 -{
   1.448 -    BoundName *binding = name->binding();
   1.449 -
   1.450 -    if (binding->scope()->kind() == Scope::GLOBAL) {
   1.451 -        if (!function_ || function_->isPublic()) {
   1.452 -            // Whatever we're referencing must be kept alive no matter what.
   1.453 -            // As such, we simply mark it used, and don't do anything special.
   1.454 -            binding->setUsed();
   1.455 -        } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
   1.456 -            // Otherwise, we're inside a normal stock or function. Since we
   1.457 -            // don't really know if we've been used yet, we shouldn't
   1.458 -            // prematurely references as alive. Instead, we keep a list of
   1.459 -            // which names have been used, so we can mark them later if needed.
   1.460 -            //
   1.461 -            // Note that we skip this step if the binding is already in the
   1.462 -            // root set.
   1.463 -            if (!function_->addUsedGlobal(binding))
   1.464 -                return;
   1.465 -        }
   1.466 -    }
   1.467 -
   1.468 -    name->setType(binding->type());
   1.469 -}
   1.470 -
   1.471 -void
   1.472 -SemanticAnalysis::visit(Assignment *node)
   1.473 -{
   1.474 -    Local<Type> exprType(zone_, visitForLoad(node->expression()));
   1.475 -    if (!exprType)
   1.476 -        return ;
   1.477 -
   1.478 -    Local<Type> type(zone_, visitForLValue(node->lvalue()));
   1.479 -    if (!type)
   1.480 -        return;
   1.481 -
   1.482 -    if (node->token() != TOK_ASSIGN) {
   1.483 -        if (!typeCheckBinary(node, node->token(), type, exprType))
   1.484 -            return;
   1.485 -    }
   1.486 -
   1.487 -    if (!typeCheckAssignment(node->pos(), exprType, type, true))
   1.488 -        return;
   1.489 -
   1.490 -    node->setType(type);
   1.491 -}
   1.492 -
   1.493 -void
   1.494 -SemanticAnalysis::visit(IncDecExpression *node)
   1.495 -{
   1.496 -    Local<Type> type(zone_, visitForLValue(node->expression()));
   1.497 -    if (!type)
   1.498 -        return;
   1.499 -
   1.500 -    assert(!type->isReference());
   1.501 -
   1.502 -    if (!type->isInt32() && !type->isFloat()) {
   1.503 -        unaryTypeError(node, node->token(), type);
   1.504 -        return;
   1.505 -    }
   1.506 -
   1.507 -    node->setType(type);
   1.508 -}
   1.509 -
   1.510 -void
   1.511 -SemanticAnalysis::visit(UnaryExpression *node)
   1.512 -{
   1.513 -    Local<Type> type(zone_, visitForLoad(node->expression()));
   1.514 -    if (!type)
   1.515 -        return;
   1.516 -
   1.517 -    switch (node->token())
   1.518 -    {
   1.519 -      case TOK_NOT:
   1.520 -        if (!canTest(node->expression(), type))
   1.521 -            return;
   1.522 -        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.523 -        if (!type)
   1.524 -            return;
   1.525 -        node->setType(type);
   1.526 -        break;
   1.527 -
   1.528 -      case TOK_MINUS:
   1.529 -        if (!type->isFloat() && !type->isInt32()) {
   1.530 -            unaryTypeError(node, node->token(), type);
   1.531 -            return;
   1.532 -        }
   1.533 -        node->setType(type);
   1.534 -        break;
   1.535 -
   1.536 -      case TOK_LABEL:
   1.537 -      {
   1.538 -        Local<Type> to(zone_, bindType(node->pos(), node->type()));
   1.539 -        if (!to)
   1.540 -            return;
   1.541 -
   1.542 -        if ((!type->isFloat() && !type->isInt32OrEnum()) ||
   1.543 -            (!to->isFloat() && !to->isInt32OrEnum()))
   1.544 -        {
   1.545 -            unaryTypeError(node, node->token(), type);
   1.546 -            return;
   1.547 -        }
   1.548 -
   1.549 -        node->setType(to);
   1.550 -        break;
   1.551 -      }
   1.552 -
   1.553 -      case TOK_SIZEOF:
   1.554 -      {
   1.555 -        if (!type->isArray()) {
   1.556 -            cc_.reportError(node->pos(), Message_SizeofNeedsArray);
   1.557 -            return;
   1.558 -        }
   1.559 -        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   1.560 -        break;
   1.561 -      }
   1.562 -
   1.563 -      default:
   1.564 -        assert(node->token() == TOK_TILDE);
   1.565 -        if (!type->isInt32()) {
   1.566 -            unaryTypeError(node, node->token(), type);
   1.567 -            return;
   1.568 -        }
   1.569 -        node->setType(type);
   1.570 -        break;
   1.571 -    }
   1.572 -}
   1.573 -
   1.574 -void
   1.575 -SemanticAnalysis::visit(TernaryExpression *node)
   1.576 -{
   1.577 -    Local<Type> type(zone_, visitForLoad(node->condition()));
   1.578 -    if (!type)
   1.579 -        return;
   1.580 -
   1.581 -    if (!canTest(node->condition(), type))
   1.582 -        return;
   1.583 -
   1.584 -    Local<Type> left(zone_, visitForLoad(node->left()));
   1.585 -    Local<Type> right(zone_, visitForLoad(node->right()));
   1.586 -    if (!left || !right)
   1.587 -        return;
   1.588 -
   1.589 -    if (left != right) {
   1.590 -        binaryTypeError(node, TOK_QMARK, left, right);
   1.591 -        return;
   1.592 -    }
   1.593 -}
   1.594 -
   1.595 -void
   1.596 -SemanticAnalysis::visit(BinaryExpression *node)
   1.597 -{
   1.598 -    Local<Type> left(zone_, visitForLoad(node->left()));
   1.599 -    Local<Type> right(zone_, visitForLoad(node->right()));
   1.600 -    if (!left || !right)
   1.601 -        return;
   1.602 -
   1.603 -    Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
   1.604 -    if (!result)
   1.605 -        return;
   1.606 -
   1.607 -    node->setType(result);
   1.608 -}
   1.609 -
   1.610 -void
   1.611 -SemanticAnalysis::visit(ReturnStatement *node)
   1.612 -{
   1.613 -    // Set this early, so if we error we don't get more errors.
   1.614 -    control_->returns(Returns_Always);
   1.615 -
   1.616 -    if (!node->expression()) {
   1.617 -        if (!function_->type()->returnType()->isVoid())
   1.618 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
   1.619 -        return;
   1.620 -    }
   1.621 -
   1.622 -    Local<Type> type(zone_, visitForLoad(node->expression()));
   1.623 -    if (!type)
   1.624 -        return;
   1.625 -
   1.626 -    Local<Type> returnType(zone_, function_->type()->returnType());
   1.627 -    if (!typeCheckAssignment(node->pos(), type, returnType, true))
   1.628 -        return;
   1.629 -}
   1.630 -
   1.631 -void
   1.632 -SemanticAnalysis::visit(ForStatement *node)
   1.633 -{
   1.634 -    LoopScope loop(&loop_);
   1.635 -
   1.636 -    if (node->scope())
   1.637 -        scope_ = node->scope();
   1.638 -
   1.639 -    if (node->initialization())
   1.640 -        node->initialization()->accept(this);
   1.641 -
   1.642 -    if (node->condition()) {
   1.643 -        Local<Type> type(zone_, visitForLoad(node->condition()));
   1.644 -        if (!type || !canTest(node->condition(), type)) {
   1.645 -            return;
   1.646 -        }
   1.647 -    }
   1.648 -
   1.649 -    if (node->update())
   1.650 -        node->update()->accept(this);
   1.651 -
   1.652 -    ControlStatus status = visitForControl(node->body());
   1.653 -
   1.654 -    // If there is a condition, we treat this like a while loop. Otherwise,
   1.655 -    // join point is only reachable if the loop contains a break. The
   1.656 -    // termination status doesn't tell us anything yet.
   1.657 -    if (node->condition() || loop.breaks())
   1.658 -        control_->merge(status, ControlStatus(false, Returns_Never));
   1.659 -    else
   1.660 -        control_->terminate(status.returns());
   1.661 -
   1.662 -    if (node->scope())
   1.663 -        scope_ = scope_->enclosing();
   1.664 -}
   1.665 -
   1.666 -void 
   1.667 -SemanticAnalysis::visit(WhileStatement *node)
   1.668 -{
   1.669 -    LoopScope loop(&loop_);
   1.670 -
   1.671 -    Local<Type> type(zone_, visitForLoad(node->condition()));
   1.672 -    if (!type || !canTest(node->condition(), type)) {
   1.673 -        return;
   1.674 -    }
   1.675 -
   1.676 -    ControlStatus status = visitForControl(node->body());
   1.677 -
   1.678 -    // Detect loops that will always have a fork in the control-flow graph.
   1.679 -    // This will be a |while| loop, or a |do-while| loop whose body does
   1.680 -    // not terminate.
   1.681 -    //
   1.682 -    // For now, we treat these as an |if| regardless of the direction the
   1.683 -    // branch can take. That means the control-flow is always conditional.
   1.684 -    if (node->token() == TOK_WHILE ||
   1.685 -        !status.terminates() ||
   1.686 -        loop.breaks())
   1.687 -    {
   1.688 -        control_->merge(status, ControlStatus(false, Returns_Never));
   1.689 -    } else {
   1.690 -        // At this point, we've got a do-while loop with a |return| or
   1.691 -        // |continue|, meaning that the rest of the block is unreachable.
   1.692 -        control_->terminate(status.returns());
   1.693 -    }
   1.694 -}
   1.695 -
   1.696 -void
   1.697 -SemanticAnalysis::visit(BlockStatement *node)
   1.698 -{
   1.699 -    if (node->scope())
   1.700 -        scope_ = node->scope();
   1.701 -    for (size_t i = 0; i < node->statements()->length(); i++) {
   1.702 -        Statement *statement = node->statements()->at(i);
   1.703 -        statement->accept(this);
   1.704 -    }
   1.705 -    if (node->scope())
   1.706 -        scope_ = scope_->enclosing();
   1.707 -}
   1.708 -
   1.709 -static inline bool
   1.710 -IsScalarString(Type *type)
   1.711 -{
   1.712 -    if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
   1.713 -        return true;
   1.714 -    if (type->isReference())
   1.715 -        return IsScalarString(type->contained());
   1.716 -    return false;
   1.717 -}
   1.718 -
   1.719 -static const int INFER_ARRAY_SIZE = 0;
   1.720 -static const int EVAL_ARRAY_SIZE = -1;
   1.721 -static const int DYNAMIC_ARRAY_SIZE = -2;
   1.722 -
   1.723 -bool
   1.724 -SemanticAnalysis::evaluateDimensions(ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH])
   1.725 -{
   1.726 -    bool hadEmptySize = false;
   1.727 -
   1.728 -    for (size_t i = 0; i < exprs->length(); i++) {
   1.729 -        Expression *expr = exprs->at(i);
   1.730 -        if (!expr) {
   1.731 -            dims[i] = INFER_ARRAY_SIZE;
   1.732 -            hadEmptySize = true;
   1.733 -            continue;
   1.734 -        }
   1.735 -
   1.736 -        BoxedPrimitive box;
   1.737 -        if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   1.738 -            int size = box.toInt();
   1.739 -            if (size <= 0) {
   1.740 -                cc_.reportError(expr->pos(), Message_BadArraySize);
   1.741 -                return false;
   1.742 -            }
   1.743 -
   1.744 -            dims[i] = size;
   1.745 -            continue;
   1.746 -        }
   1.747 -
   1.748 -        Local<Type> exprType(zone_, visitForLoad(expr));
   1.749 -        if (!exprType)
   1.750 -            return false;
   1.751 -
   1.752 -        if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   1.753 -            cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   1.754 -            return false;
   1.755 -        }
   1.756 -
   1.757 -        if (hadEmptySize) {
   1.758 -            cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   1.759 -            return false;
   1.760 -        }
   1.761 -
   1.762 -        dims[i] = EVAL_ARRAY_SIZE;
   1.763 -    }
   1.764 -
   1.765 -    return true;
   1.766 -}
   1.767 -
   1.768 -bool
   1.769 -SemanticAnalysis::inferFixedArrayLiteral(ArrayLiteral *literal, Handle<Type> contained,
   1.770 -                                         int dims[MAX_ARRAY_DEPTH],
   1.771 -                                         unsigned dimcount, unsigned level)
   1.772 -{
   1.773 -    if (dims[level] == EVAL_ARRAY_SIZE) {
   1.774 -        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   1.775 -        return false;
   1.776 -    }
   1.777 -
   1.778 -    if (dims[level] == INFER_ARRAY_SIZE) {
   1.779 -        // Strings always become dynamic arrays.
   1.780 -        if (level != dimcount - 1 || !IsPrimitiveType(contained, PrimitiveType_Char))
   1.781 -            dims[level] = literal->expressions()->length();
   1.782 -    } else if (dims[level] == DYNAMIC_ARRAY_SIZE) {
   1.783 -        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   1.784 -        return false;
   1.785 -    } else {
   1.786 -        if (literal->expressions()->length() != unsigned(dims[level])) {
   1.787 -            cc_.reportError(literal->pos(), Message_ArrayDimensionSizeMismatch, level + 1);
   1.788 -            return false;
   1.789 -        }
   1.790 -    }
   1.791 -
   1.792 -    if (level == dimcount - 2 && IsPrimitiveType(contained, PrimitiveType_Char)) {
   1.793 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.794 -            Expression *expr = literal->expressions()->at(i);
   1.795 -            if (!expr->isStringLiteral()) {
   1.796 -                cc_.reportError(expr->pos(), Message_ExpectedStringLiteral);
   1.797 -                return false;
   1.798 -            }
   1.799 -
   1.800 -            StringLiteral *lit = expr->toStringLiteral();
   1.801 -            if (dims[level + 1] > 0 &&
   1.802 -                unsigned(dims[level]) < lit->string()->length())
   1.803 -            {
   1.804 -                cc_.reportError(lit->pos(), Message_ArrayDimensionSizeMismatch, level + 2);
   1.805 -                return false;
   1.806 -            }
   1.807 -            if (!visitAndApplyType(lit))
   1.808 -                return false;
   1.809 -        }
   1.810 -    } else if (level == dimcount - 1) {
   1.811 -        Local<Type> type(zone_);
   1.812 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.813 -            Expression *expr = literal->expressions()->at(i);
   1.814 -            if (expr->isArrayLiteral()) {
   1.815 -                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   1.816 -                return false;
   1.817 -            }
   1.818 -
   1.819 -            if ((type = visitAndApplyType(expr)) == NULL)
   1.820 -                return false;
   1.821 -
   1.822 -            if (!typeCheckAssignment(expr->pos(), type, contained, true))
   1.823 -                return false;
   1.824 -        }
   1.825 -    } else {
   1.826 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.827 -            Expression *expr = literal->expressions()->at(i);
   1.828 -            if (!expr->isArrayLiteral()) {
   1.829 -                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   1.830 -                return false;
   1.831 -            }
   1.832 -
   1.833 -            assert(expr->toArrayLiteral()->isFixed());
   1.834 -
   1.835 -            if (!inferFixedArrayLiteral(expr->toArrayLiteral(),
   1.836 -                                        contained,
   1.837 -                                        dims,
   1.838 -                                        dimcount,
   1.839 -                                        level + 1))
   1.840 -            {
   1.841 -                return false;
   1.842 -            }
   1.843 -        }
   1.844 -    }
   1.845 -
   1.846 -    return true;
   1.847 -}
   1.848 -
   1.849 -void
   1.850 -SemanticAnalysis::visit(VariableDeclaration *node)
   1.851 -{
   1.852 -    Local<Type> type(zone_, bindType(node->pos(), node->type()));
   1.853 -    if (!type)
   1.854 -        return;
   1.855 -
   1.856 -    if (node->postDimensions() || type->isArray()) {
   1.857 -        // The type could be an array type, so sum the type and postDimensions
   1.858 -        // together.
   1.859 -        unsigned dimcount = node->postDimensions()->length();
   1.860 -        if (type->isArray())
   1.861 -            dimcount += type->levels();
   1.862 -        if (dimcount > MAX_ARRAY_DEPTH) {
   1.863 -            cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   1.864 -            return;
   1.865 -        }
   1.866 -
   1.867 -        // Take an initial guess at the array dimension sizes.
   1.868 -        int dims[MAX_ARRAY_DEPTH];
   1.869 -        if (!evaluateDimensions(node->postDimensions(), dims))
   1.870 -            return;
   1.871 -
   1.872 -        // Now add in the type's array dimensions.
   1.873 -        Local<Type> contained(zone_, type);
   1.874 -        for (size_t i = node->postDimensions()->length(); i < dimcount; i++) {
   1.875 -            if (type->isFixedLength())
   1.876 -                dims[i] = type->fixedLength();
   1.877 -            else
   1.878 -                dims[i] = DYNAMIC_ARRAY_SIZE;
   1.879 -            contained = contained->contained();
   1.880 -        }
   1.881 -
   1.882 -        Expression *initializer = node->initialization();
   1.883 -        if (initializer &&
   1.884 -            initializer->isArrayLiteral() &&
   1.885 -            initializer->toArrayLiteral()->isFixed())
   1.886 -        {
   1.887 -            // Fixed array initializers are special; we use them to infer any
   1.888 -            // missing information in the original array. We do not evaluate
   1.889 -            // the array initializer as an expression.
   1.890 -            if (!inferFixedArrayLiteral(initializer->toArrayLiteral(),
   1.891 -                                        contained,
   1.892 -                                        dims,
   1.893 -                                        dimcount,
   1.894 -                                        0))
   1.895 -            {
   1.896 -                return;
   1.897 -            }
   1.898 -            initializer = NULL;
   1.899 -        }
   1.900 -
   1.901 -        // We now have enough information to build the actual array type.
   1.902 -        // Start from the original dimcount, not the one computed for
   1.903 -        // initializers.
   1.904 -        for (size_t i = node->postDimensions()->length() - 1;
   1.905 -             i < node->postDimensions()->length();
   1.906 -             i--)
   1.907 -        {
   1.908 -            int size = dims[i] > 0
   1.909 -                       ? dims[i]
   1.910 -                       : Type::DYNAMIC_ARRAY_SIZE;
   1.911 -
   1.912 -            type = zone_->types()->newArray(type, size, false);
   1.913 -            if (!type)
   1.914 -                return;
   1.915 -        }
   1.916 -
   1.917 -        // Finally, if we had a non-fixed initializer, make sure it type
   1.918 -        // checks. 
   1.919 -        if (initializer) {
   1.920 -            Local<Type> right(zone_, visitForLoad(initializer));
   1.921 -            if (!right)
   1.922 -                return;
   1.923 -
   1.924 -            if (!typeCheckAssignment(node->pos(), right, type, true))
   1.925 -                return;
   1.926 -        }
   1.927 -    } else {
   1.928 -        if (node->initialization()) {
   1.929 -            Local<Type> right(zone_, visitForLoad(node->initialization()));
   1.930 -            if (!right)
   1.931 -                return;
   1.932 -            if (!typeCheckAssignment(node->pos(), right, type, true))
   1.933 -                return;
   1.934 -        }
   1.935 -
   1.936 -        if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
   1.937 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   1.938 -            return;
   1.939 -        }
   1.940 -    }
   1.941 -
   1.942 -    // If this variable is stack allocated, we could use the LIFO heap
   1.943 -    // to allocate it. If that's the case, make sure to reserve a slot
   1.944 -    // so we can unwind the LIFO heap at the end of this scope.
   1.945 -    if (!node->variable()->needsHeapAllocation()) {
   1.946 -        if (type->isArray() || type->isStruct())
   1.947 -            scope_->setUsesLifoHeap();
   1.948 -    }
   1.949 -
   1.950 -    node->variable()->setType(type);
   1.951 -}
   1.952 -
   1.953 -void
   1.954 -SemanticAnalysis::visit(IntegerLiteral *node)
   1.955 -{
   1.956 -    node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   1.957 -}
   1.958 -
   1.959 -void
   1.960 -SemanticAnalysis::visit(BooleanLiteral *node)
   1.961 -{
   1.962 -    node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
   1.963 -}
   1.964 -
   1.965 -void
   1.966 -SemanticAnalysis::visit(ExpressionStatement *node)
   1.967 -{
   1.968 -    visitAndApplyType(node->expression());
   1.969 -}
   1.970 -
   1.971 -Box *
   1.972 -SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
   1.973 -{
   1.974 -    Local<Type> given(zone_, visitForLoad(parameter->initializer()));
   1.975 -
   1.976 -    BoxedPrimitive prim;
   1.977 -    if (EvaluateForConstant(parameter->initializer(), &prim)) {
   1.978 -        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   1.979 -            return NULL;
   1.980 -
   1.981 -        if (prim.type() == PrimitiveType_Int32)
   1.982 -            return Box::New(zone_, given, prim.toInt());
   1.983 -        return Box::New(zone_, given, prim.toFloat());
   1.984 -    } else if (parameter->initializer()->isStringLiteral()) {
   1.985 -        StringLiteral *literal = parameter->initializer()->toStringLiteral();
   1.986 -
   1.987 -        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   1.988 -            return NULL;
   1.989 -
   1.990 -        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
   1.991 -        if (!map)
   1.992 -            return NULL;
   1.993 -
   1.994 -        Local<Array> array(zone_,
   1.995 -            Array::NewString(zone_,
   1.996 -                             map,
   1.997 -                             literal->string()->raw(),
   1.998 -                             literal->string()->length(),
   1.999 -                             Heap::Tenure_Old));
  1.1000 -        if (!array)
  1.1001 -            return NULL;
  1.1002 -
  1.1003 -        return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
  1.1004 -    }
  1.1005 -
  1.1006 -    cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
  1.1007 -    return NULL;
  1.1008 -}
  1.1009 -
  1.1010 -bool
  1.1011 -SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
  1.1012 -                                    FixedArray **argsp, FixedArray **defaultsp)
  1.1013 -{
  1.1014 -    Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
  1.1015 -    if (!args)
  1.1016 -        return false;
  1.1017 -
  1.1018 -    Local<FixedArray> defaults(zone_);
  1.1019 -
  1.1020 -    // Apply types to arguments.
  1.1021 -    for (size_t i = 0; i < sig.parameters()->length(); i++) {
  1.1022 -        Parameter *parameter = sig.parameters()->at(i);
  1.1023 -        
  1.1024 -        Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
  1.1025 -        if (!type)
  1.1026 -            return false;
  1.1027 -
  1.1028 -        if (parameter->reference()) {
  1.1029 -            if (parameter->dimensions()) {
  1.1030 -                cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
  1.1031 -                return false;
  1.1032 -            }
  1.1033 -
  1.1034 -            if (type->isStruct()) {
  1.1035 -                cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
  1.1036 -                return false;
  1.1037 -            }
  1.1038 -
  1.1039 -            type = zone_->types()->getReference(type, parameter->isConst());
  1.1040 -            if (!type)
  1.1041 -                return false;
  1.1042 -        } else if (parameter->dimensions()) {
  1.1043 -            type = buildArrayType(type, parameter->dimensions(), parameter->isConst());
  1.1044 -            if (!type)
  1.1045 -                return false;
  1.1046 -
  1.1047 -            if (kind == TOK_NATIVE && type->levels() > 1) {
  1.1048 -                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
  1.1049 -                return false;
  1.1050 -            }
  1.1051 -        }
  1.1052 -
  1.1053 -        if (IsScalarString(type)) {
  1.1054 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.1055 -            return false;
  1.1056 -        }
  1.1057 -
  1.1058 -        args->set(zone_, i, type);
  1.1059 -        parameter->variable()->setType(type);
  1.1060 -
  1.1061 -        if (parameter->initializer()) {
  1.1062 -            if (!defaults) {
  1.1063 -                defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
  1.1064 -                if (!defaults)
  1.1065 -                    return false;
  1.1066 -            }
  1.1067 -
  1.1068 -            Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
  1.1069 -            if (!box)
  1.1070 -                return false;
  1.1071 -
  1.1072 -            defaults->set(zone_, i, box);
  1.1073 -        }
  1.1074 -    }
  1.1075 -
  1.1076 -    *argsp = args;
  1.1077 -    *defaultsp = defaults;
  1.1078 -
  1.1079 -    return true;
  1.1080 -}
  1.1081 -
  1.1082 -void
  1.1083 -SemanticAnalysis::visit(FunctionTypeStatement *node)
  1.1084 -{
  1.1085 -    if (node->decl()->type())
  1.1086 -        return;
  1.1087 -
  1.1088 -    Local<FixedArray> args(zone_);
  1.1089 -    Local<FixedArray> defaults(zone_);
  1.1090 -
  1.1091 -    const FunctionSignature &sig= node->signature();
  1.1092 -    if (!buildFunctionArgs(node,
  1.1093 -                           TOK_STOCK,
  1.1094 -                           sig,
  1.1095 -                           args.address(),
  1.1096 -                           defaults.address()))
  1.1097 -    {
  1.1098 -        return;
  1.1099 -    }
  1.1100 -
  1.1101 -    Local<Type> returnType(zone_);
  1.1102 -    if (sig.returnType())
  1.1103 -        returnType = bindType(node->pos(), sig.returnType());
  1.1104 -    else
  1.1105 -        returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.1106 -
  1.1107 -    if (!returnType)
  1.1108 -        return;
  1.1109 -
  1.1110 -    Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
  1.1111 -    if (!funtype)
  1.1112 -        return;
  1.1113 -
  1.1114 -    node->decl()->setType(funtype);
  1.1115 -}
  1.1116 -
  1.1117 -Type *
  1.1118 -SemanticAnalysis::buildArrayType(Handle<Type> type, ExpressionList *dimensions, bool isConst)
  1.1119 -{
  1.1120 -    Local<Type> arrayType(zone_, type);
  1.1121 -
  1.1122 -    unsigned dimcount = dimensions->length();
  1.1123 -    if (type->isArray())
  1.1124 -        dimcount += type->levels();
  1.1125 -
  1.1126 -    if (dimcount > MAX_ARRAY_DEPTH) {
  1.1127 -        cc_.reportError(dimensions->at(dimensions->length() - 1)->pos(),
  1.1128 -                        Message_MaximumArrayDepth);
  1.1129 -        return false;
  1.1130 -    }
  1.1131 -
  1.1132 -    // Note: constness is sort of bogus. Fix this sometime.
  1.1133 -    for (size_t i = dimensions->length() - 1; i < dimensions->length(); i--) {
  1.1134 -        Expression *expr = dimensions->at(i);
  1.1135 -        if (!expr) {
  1.1136 -            arrayType = zone_->types()->newArray(arrayType, Type::DYNAMIC_ARRAY_SIZE, isConst);
  1.1137 -            if (!arrayType)
  1.1138 -                return NULL;
  1.1139 -
  1.1140 -            continue;
  1.1141 -        }
  1.1142 -
  1.1143 -        BoxedPrimitive box;
  1.1144 -        if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
  1.1145 -            cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
  1.1146 -            return NULL;
  1.1147 -        }
  1.1148 -
  1.1149 -        if (box.toInt() <= 0) {
  1.1150 -            cc_.reportError(expr->pos(), Message_BadArraySize);
  1.1151 -            return NULL;
  1.1152 -        }
  1.1153 -
  1.1154 -        arrayType = zone_->types()->newArray(arrayType, box.toInt(), isConst);
  1.1155 -        if (!arrayType)
  1.1156 -            return NULL;
  1.1157 -    }
  1.1158 -
  1.1159 -    return arrayType;
  1.1160 -}
  1.1161 -
  1.1162 -bool
  1.1163 -SemanticAnalysis::preanalyze(FunctionStatement *node)
  1.1164 -{
  1.1165 -    Local<FixedArray> args(zone_);
  1.1166 -    Local<FixedArray> defaults(zone_);
  1.1167 -
  1.1168 -    const FunctionSignature &sig = node->signature();
  1.1169 -    if (!buildFunctionArgs(node,
  1.1170 -                           node->fun()->token(),
  1.1171 -                           sig,
  1.1172 -                           args.address(),
  1.1173 -                           defaults.address()))
  1.1174 -    {
  1.1175 -        return false;
  1.1176 -    }
  1.1177 -
  1.1178 -    Local<Type> returnType(zone_);
  1.1179 -    if (sig.returnType() ||
  1.1180 -        node->hasExplicitReturn() ||
  1.1181 -        node->fun()->isNative())
  1.1182 -    {
  1.1183 -        returnType = bindType(node->pos(), sig.returnType());
  1.1184 -    } else {
  1.1185 -        returnType = zone_->types()->getVoid();
  1.1186 -    }
  1.1187 -    if (!returnType)
  1.1188 -        return false;
  1.1189 -
  1.1190 -    if (sig.returnDimensions()) {
  1.1191 -        returnType = buildArrayType(returnType, sig.returnDimensions(), false);
  1.1192 -        if (!returnType)
  1.1193 -            return false;
  1.1194 -    }
  1.1195 -
  1.1196 -    if (IsScalarString(returnType)) {
  1.1197 -        cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.1198 -        return false;
  1.1199 -    }
  1.1200 -
  1.1201 -    Local<Type> funtype(zone_);
  1.1202 -    if (node->fun()->isNative())
  1.1203 -        funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
  1.1204 -    else
  1.1205 -        funtype = zone_->types()->newFunction(returnType, args, defaults);
  1.1206 -    if (!funtype)
  1.1207 -        return false;
  1.1208 -    
  1.1209 -    // If the function already has a type, it was forward declared before, and
  1.1210 -    // now this is our chance to type check the second declaration.
  1.1211 -    if (node->fun()->type()) {
  1.1212 -        Local<Type> forward(zone_, node->fun()->type());
  1.1213 -        if (!Type::Compare(funtype, forward)) {
  1.1214 -            cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  1.1215 -            return false;
  1.1216 -        }
  1.1217 -        node->fun()->setForwardType(forward);
  1.1218 -    }
  1.1219 -
  1.1220 -    node->fun()->setType(funtype);
  1.1221 -
  1.1222 -    return true;
  1.1223 -}
  1.1224 -
  1.1225 -void
  1.1226 -SemanticAnalysis::visit(FunctionStatement *node)
  1.1227 -{
  1.1228 -    function_ = node->fun();
  1.1229 -    scope_ = node->scope();
  1.1230 -
  1.1231 -    ControlScope control(&control_);
  1.1232 -    if (node->body()) {
  1.1233 -        node->body()->accept(this);
  1.1234 -
  1.1235 -        ControlStatus status = control.status();
  1.1236 -        if (status.returns() == Returns_Sometimes) {
  1.1237 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1.1238 -        } else if (status.returns() == Returns_Never) {
  1.1239 -            if (!function_->type()->returnType()->isVoid())
  1.1240 -                cc_.reportError(node->pos(), Message_MissingReturnValue);
  1.1241 -        }
  1.1242 -    }
  1.1243 -
  1.1244 -    scope_ = NULL;
  1.1245 -    function_ = NULL;
  1.1246 -}
  1.1247 -
  1.1248 -void
  1.1249 -SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
  1.1250 -{
  1.1251 -    cc_.reportError(pos, Message_TypeMismatch,
  1.1252 -                    GetTypeName(actual),
  1.1253 -                    GetTypeName(given));
  1.1254 -}
  1.1255 -
  1.1256 -bool
  1.1257 -SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.1258 -                                           Handle<Type> argActual, bool forAssign)
  1.1259 -{
  1.1260 -    Local<Type> actual(zone_, argActual);
  1.1261 -    Local<Type> given(zone_, argGiven);
  1.1262 -
  1.1263 -    if (!given->isArray()) {
  1.1264 -        cc_.reportError(pos, Message_ExpectedArray);
  1.1265 -        return false;
  1.1266 -    }
  1.1267 -    if (given->levels() != actual->levels()) {
  1.1268 -        cc_.reportError(pos, Message_ArrayDimensionsMismatch);
  1.1269 -        return false;
  1.1270 -    }
  1.1271 -
  1.1272 -    unsigned level = 1;
  1.1273 -    while (given->isArray()) {
  1.1274 -        if (actual->isFixedLength()) {
  1.1275 -            if (forAssign) {
  1.1276 -                if (!given->isFixedLength()) {
  1.1277 -                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1278 -                    return false;
  1.1279 -                }
  1.1280 -
  1.1281 -                if (actual->isCharArray()) {
  1.1282 -                    // String assignment can have a truncated |given|.
  1.1283 -                    if (given->fixedLength() > actual->fixedLength()) {
  1.1284 -                        cc_.reportError(pos, Message_ArrayAssignmentTooBig);
  1.1285 -                        return false;
  1.1286 -                    }
  1.1287 -                } else {
  1.1288 -                    if (given->fixedLength() != actual->fixedLength()) {
  1.1289 -                        cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1290 -                        return false;
  1.1291 -                    }
  1.1292 -                }
  1.1293 -            }
  1.1294 -        } else if (given->isFixedLength()) {
  1.1295 -            // We do not allow assignments in the form:
  1.1296 -            //    [][] = [][Y]
  1.1297 -            //
  1.1298 -            // Otherwise, the following code could break the size guarantees
  1.1299 -            // of the right-hand side:
  1.1300 -            //
  1.1301 -            //   new x[][5];
  1.1302 -            //   new y[][];
  1.1303 -            //   new z[3];
  1.1304 -            //
  1.1305 -            //   y = x;
  1.1306 -            //   y[0] = z;
  1.1307 -            //   
  1.1308 -            // Now |x[0]| contains a 4-length array.
  1.1309 -            if (level > 1) {
  1.1310 -                cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1311 -                return false;
  1.1312 -            }
  1.1313 -        }
  1.1314 -        given = given->contained();
  1.1315 -        actual = actual->contained();
  1.1316 -        level++;
  1.1317 -    }
  1.1318 -
  1.1319 -    return typeCheckAssignment(pos, given, actual, forAssign);
  1.1320 -}
  1.1321 -
  1.1322 -bool
  1.1323 -SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.1324 -                                      Handle<Type> argActual, bool forAssign)
  1.1325 -{
  1.1326 -    Local<Type> actual(zone_, argActual);
  1.1327 -    Local<Type> given(zone_, argGiven);
  1.1328 -
  1.1329 -    if (actual->isArray())
  1.1330 -        return typeCheckArrayAssignment(pos, given, actual, forAssign);
  1.1331 -
  1.1332 -    if (given->isArray()) {
  1.1333 -        cc_.reportError(pos, Message_CannotAssignArrayToScalar);
  1.1334 -        return false;
  1.1335 -    }
  1.1336 -
  1.1337 -    // The given type may not have been dereferenced.
  1.1338 -    if (given->isReference())
  1.1339 -        given = given->contained();
  1.1340 -    if (actual->isReference())
  1.1341 -        actual = actual->contained();
  1.1342 -
  1.1343 -    // We coerce unchecked to a few things.
  1.1344 -    if (actual->isUnchecked() || given->isUnchecked()) {
  1.1345 -        Type *check = actual->isUnchecked() ? given : actual;
  1.1346 -        if (check->isUnchecked() ||
  1.1347 -            check->isEnum() ||
  1.1348 -            check->isInt32() ||
  1.1349 -            check->isBool() ||
  1.1350 -            check->isFloat())
  1.1351 -        {
  1.1352 -            return true;
  1.1353 -        }
  1.1354 -        typeMismatch(pos, actual, given);
  1.1355 -        return false;
  1.1356 -    }
  1.1357 -
  1.1358 -    if (given->isFunction() && actual->isFunction()) {
  1.1359 -        if (!Type::Compare(given, actual)) {
  1.1360 -            typeMismatch(pos, actual, given);
  1.1361 -            return false;
  1.1362 -        }
  1.1363 -        return true;
  1.1364 -    }
  1.1365 -
  1.1366 -    if (actual->isEnum()) {
  1.1367 -        if (!given->isEnum() || actual != given) {
  1.1368 -            typeMismatch(pos, actual, given);
  1.1369 -            return false;
  1.1370 -        }
  1.1371 -        return true;
  1.1372 -    }
  1.1373 -
  1.1374 -    if (actual->isStruct()) {
  1.1375 -        if (!given->isStruct() || actual != given) {
  1.1376 -            typeMismatch(pos, actual, given);
  1.1377 -            return false;
  1.1378 -        }
  1.1379 -        return true;
  1.1380 -    }
  1.1381 -
  1.1382 -    if (given->isEnum() || given->isFunction() || given->isStruct()) {
  1.1383 -        typeMismatch(pos, actual, given);
  1.1384 -        return false;
  1.1385 -    }
  1.1386 -
  1.1387 -    // This coercion is trivial.
  1.1388 -    if (given->isBool() && actual->isInt32())
  1.1389 -        return true;
  1.1390 -
  1.1391 -    if (given->primitive() != actual->primitive()) {
  1.1392 -        typeMismatch(pos, actual, given);
  1.1393 -        return false;
  1.1394 -    }
  1.1395 -
  1.1396 -    return true;
  1.1397 -}
  1.1398 -
  1.1399 -bool
  1.1400 -SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  1.1401 -{
  1.1402 -    return typeCheckAssignment(node->pos(), given, actual, false);
  1.1403 -}
  1.1404 -
  1.1405 -bool
  1.1406 -SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
  1.1407 -{
  1.1408 -    if (type->parameters()->length() == actual)
  1.1409 -        return true;
  1.1410 -
  1.1411 -    if (actual > type->parameters()->length()) {
  1.1412 -        if (!type->isNative() || !type->isNativeVariadic())
  1.1413 -            return false;
  1.1414 -        return true;
  1.1415 -    }
  1.1416 -
  1.1417 -    if (!type->defaults())
  1.1418 -        return false;
  1.1419 -
  1.1420 -    // Missing arguments. See if there's a default argument for each missing
  1.1421 -    // actual.
  1.1422 -    for (unsigned i = actual; i < type->parameters()->length(); i++) {
  1.1423 -        if (!type->defaults()->at(i))
  1.1424 -            return false;
  1.1425 -    }
  1.1426 -
  1.1427 -    return true;
  1.1428 -}
  1.1429 -
  1.1430 -void
  1.1431 -SemanticAnalysis::visit(CallExpression *node)
  1.1432 -{
  1.1433 -    Local<Type> type(zone_, visitForLoad(node->callee()));
  1.1434 -    if (!type)
  1.1435 -        return;
  1.1436 -
  1.1437 -    if (!type->isFunction()) {
  1.1438 -        cc_.reportError(node->pos(), Message_CalleeNotFunction);
  1.1439 -        return;
  1.1440 -    }
  1.1441 -
  1.1442 -    if (!checkArgumentCount(type, node->arguments()->length())) {
  1.1443 -        cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  1.1444 -        return;
  1.1445 -    }
  1.1446 -
  1.1447 -    // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  1.1448 -    // if (fun->isForward()) {
  1.1449 -    //     cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  1.1450 -    //     return;
  1.1451 -    // }
  1.1452 -
  1.1453 -    for (unsigned i = 0; i < node->arguments()->length(); i++) {
  1.1454 -        // Note: we don't compute references unless the callee needs a
  1.1455 -        // reference type.
  1.1456 -        Expression *expression = node->arguments()->at(i);
  1.1457 -        Local<Type> given(zone_, visitAndApplyType(expression));
  1.1458 -        if (!given)
  1.1459 -            return;
  1.1460 -
  1.1461 -        // Since we skip a load, check for a call expression that returns void.
  1.1462 -        if (given->isVoid()) {
  1.1463 -            assert(expression->isCallExpression());
  1.1464 -            CallExpression *call = expression->toCallExpression();
  1.1465 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1.1466 -            return;
  1.1467 -        }
  1.1468 -        
  1.1469 -        bool mustComputeReference;
  1.1470 -        if (i >= type->parameters()->length()) {
  1.1471 -            // Special handling for natives. Arguments past the formal must
  1.1472 -            // always have references computed. However, arrays are already
  1.1473 -            // references for natives.  
  1.1474 -            assert(type->isNative() && type->isNativeVariadic());
  1.1475 -            mustComputeReference = !given->isReference() && !given->isArray();
  1.1476 -        } else {
  1.1477 -            Local<Type> actual(zone_, type->parameterAt(i));
  1.1478 -
  1.1479 -            if (expression->isIndexExpression()) {
  1.1480 -                // Disabled until we can make it work.
  1.1481 -#if 0
  1.1482 -                if (actual->isArray()) {
  1.1483 -                    // We special case the ability to pass x[y] into x[], which
  1.1484 -                    // creates an array slice. We only do this if we know the
  1.1485 -                    // assignment would otherwise not type-check.
  1.1486 -                    IndexExpression *index = expression->toIndexExpression();
  1.1487 -                    if (index->left()->type()->levels() == actual->levels())
  1.1488 -                        given = index->left()->type();
  1.1489 -                } else
  1.1490 -#endif
  1.1491 -                if (actual->isReference()) {
  1.1492 -                    cc_.reportError(expression->pos(), Message_CannotComputeIndexRef);
  1.1493 -                    return;
  1.1494 -                }
  1.1495 -            }
  1.1496 -
  1.1497 -            if (!typeCheckParameter(expression, given, actual))
  1.1498 -                return;
  1.1499 -            mustComputeReference = actual->isReference() && !given->isReference();
  1.1500 -        }
  1.1501 -
  1.1502 -        // If the actual is a reference, and the given is not, we'll need to
  1.1503 -        // compute a reference, which may be allocated on the stack.
  1.1504 -        if (mustComputeReference)
  1.1505 -            scope_->setUsesLifoHeap();
  1.1506 -    }
  1.1507 -
  1.1508 -    node->setType(type->returnType());
  1.1509 -}
  1.1510 -
  1.1511 -void
  1.1512 -SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
  1.1513 -{
  1.1514 -    if (other.returns() < status().returns())
  1.1515 -        return;
  1.1516 -
  1.1517 -    if (other.terminates())
  1.1518 -        terminate(other.returns());
  1.1519 -    else
  1.1520 -        returns(other.returns());
  1.1521 -}
  1.1522 -
  1.1523 -void
  1.1524 -SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  1.1525 -{
  1.1526 -    // If both sides terminate in a return, we consider this a return as well.
  1.1527 -    if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  1.1528 -        terminate(Returns_Always);
  1.1529 -        return;
  1.1530 -    }
  1.1531 -
  1.1532 -    ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  1.1533 -                          ? Returns_Never
  1.1534 -                          : Returns_Sometimes;
  1.1535 -
  1.1536 -    if (left.terminates() && right.terminates())
  1.1537 -        terminate(status);
  1.1538 -    else
  1.1539 -        returns(status);
  1.1540 -}
  1.1541 -
  1.1542 -void
  1.1543 -SemanticAnalysis::visit(IfStatement *node)
  1.1544 -{
  1.1545 -    Local<Type> type(zone_, visitForLoad(node->condition()));
  1.1546 -    if (!type)
  1.1547 -        return;
  1.1548 -
  1.1549 -    if (!canTest(node, type))
  1.1550 -        return;
  1.1551 -
  1.1552 -    ControlStatus trueBranch = visitForControl(node->ifTrue());
  1.1553 -    ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  1.1554 -
  1.1555 -    if (node->ifFalse())
  1.1556 -        falseBranch = visitForControl(node->ifFalse());
  1.1557 -
  1.1558 -    control_->merge(trueBranch, falseBranch);
  1.1559 -}
  1.1560 -
  1.1561 -void
  1.1562 -SemanticAnalysis::visit(IndexExpression *node)
  1.1563 -{
  1.1564 -    Local<Type> left(zone_, visitForLoad(node->left()));
  1.1565 -    Local<Type> right(zone_, visitForLoad(node->right()));
  1.1566 -
  1.1567 -    if (!left || !right)
  1.1568 -        return;
  1.1569 -
  1.1570 -    if (!right->isInt32() && !right->isEnum()) {
  1.1571 -        cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  1.1572 -        return;
  1.1573 -    }
  1.1574 -    if (!left->isArray()) {
  1.1575 -        cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  1.1576 -        return;
  1.1577 -    }
  1.1578 -
  1.1579 -    // Note: char arrays are automatically up-casted to return an int32.
  1.1580 -    if (left->isCharArray())
  1.1581 -        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.1582 -    else
  1.1583 -        node->setType(left->contained());
  1.1584 -}
  1.1585 -
  1.1586 -void
  1.1587 -SemanticAnalysis::visit(FieldExpression *node)
  1.1588 -{
  1.1589 -    Local<Type> left(zone_, visitForLoad(node->left()));
  1.1590 -    if (!left)
  1.1591 -        return;
  1.1592 -
  1.1593 -    if (!left->isStruct()) {
  1.1594 -        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.1595 -                        GetTypeName(left));
  1.1596 -        return;
  1.1597 -    }
  1.1598 -
  1.1599 -    Local<String> field(zone_, node->field());
  1.1600 -
  1.1601 -    unsigned offset;
  1.1602 -    Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
  1.1603 -    if (!desc) {
  1.1604 -        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.1605 -                        GetTypeName(left));
  1.1606 -        return;
  1.1607 -    }
  1.1608 -
  1.1609 -    node->setFieldIndex(offset);
  1.1610 -    node->setType(desc->type());
  1.1611 -}
  1.1612 -
  1.1613 -void
  1.1614 -SemanticAnalysis::visit(EnumStatement *node)
  1.1615 -{
  1.1616 -    Local<String> name(zone_, node->name());
  1.1617 -    Local<Type> type(zone_);
  1.1618 -    if (name)
  1.1619 -        type = zone_->types()->newEnum(name);
  1.1620 -    else
  1.1621 -        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.1622 -
  1.1623 -    if (!type)
  1.1624 -        return;
  1.1625 -
  1.1626 -    if (node->decl())
  1.1627 -        node->decl()->setType(type);
  1.1628 -
  1.1629 -    int value = 0;
  1.1630 -    for (size_t i = 0; i < node->entries()->length(); i++) {
  1.1631 -        EnumStatement::Entry &entry = node->entries()->at(i);
  1.1632 -
  1.1633 -        BoxedPrimitive box = BoxedPrimitive::Int(value);
  1.1634 -        if (entry.expr) {
  1.1635 -            entry.expr->accept(this);
  1.1636 -            if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
  1.1637 -                cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1.1638 -                return;
  1.1639 -            }
  1.1640 -
  1.1641 -            assert(box.type() == PrimitiveType_Int32);
  1.1642 -            value = box.toInt();
  1.1643 -        }
  1.1644 -
  1.1645 -        entry.name->set(type, box);
  1.1646 -        value++;
  1.1647 -    }
  1.1648 -}
  1.1649 -
  1.1650 -static int
  1.1651 -SortCaseIntValues(const void *p1, const void *p2)
  1.1652 -{
  1.1653 -    CaseValue *v1 = (CaseValue *)p1;
  1.1654 -    CaseValue *v2 = (CaseValue *)p2;
  1.1655 -
  1.1656 -    return v1->box.toInt() - v2->box.toInt();
  1.1657 -}
  1.1658 -
  1.1659 -void
  1.1660 -SemanticAnalysis::visit(SwitchStatement *node)
  1.1661 -{
  1.1662 -    Local<Type> caseType(zone_, visitForLoad(node->expression()));
  1.1663 -    if (!caseType)
  1.1664 -        return;
  1.1665 -
  1.1666 -    if (!caseType->isEnum() && !caseType->isInt32()) {
  1.1667 -        cc_.reportError(node->pos(), Message_CaseMustBeInteger);
  1.1668 -        return;
  1.1669 -    }
  1.1670 -
  1.1671 -    PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
  1.1672 -    ControlStatus status = ControlStatus(false, Returns_Never);
  1.1673 -
  1.1674 -    Local<Type> check(zone_);
  1.1675 -    for (size_t i = 0; i < node->cases()->length(); i++) {
  1.1676 -        Case *c = node->cases()->at(i);
  1.1677 -
  1.1678 -        check = visitForLoad(c->expression());
  1.1679 -        if (!check)
  1.1680 -            return;
  1.1681 -
  1.1682 -        if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
  1.1683 -            return;
  1.1684 -
  1.1685 -        CaseValue v(i);
  1.1686 -        if (!EvaluateForConstant(c->expression(), &v.box)) {
  1.1687 -            cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
  1.1688 -            return;
  1.1689 -        }
  1.1690 -        if (!values->append(v))
  1.1691 -            return;
  1.1692 -
  1.1693 -        if (c->others()) {
  1.1694 -            for (size_t j = 0; j < c->others()->length(); j++) {
  1.1695 -                Expression *expr = c->others()->at(j);
  1.1696 -                check = visitForLoad(expr);
  1.1697 -                if (!check)
  1.1698 -                    return;
  1.1699 -
  1.1700 -                if (!typeCheckAssignment(expr->pos(), check, caseType, false))
  1.1701 -                    return;
  1.1702 -
  1.1703 -                CaseValue v(i);
  1.1704 -                if (!EvaluateForConstant(expr, &v.box)) {
  1.1705 -                    cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
  1.1706 -                    return;
  1.1707 -                }
  1.1708 -                if (!values->append(v))
  1.1709 -                    return;
  1.1710 -            }
  1.1711 -        }
  1.1712 -
  1.1713 -        ControlStatus latest = visitForControl(c->statement());
  1.1714 -
  1.1715 -        if (i != 0)
  1.1716 -            control_->merge(status, latest);
  1.1717 -
  1.1718 -        status = latest;
  1.1719 -    }
  1.1720 -
  1.1721 -    if (node->defaultCase()) {
  1.1722 -        ControlStatus latest = visitForControl(node->defaultCase());
  1.1723 -
  1.1724 -        if (node->cases()->length()) {
  1.1725 -            // If we had any other cases, we must merge.
  1.1726 -            control_->merge(status, latest);
  1.1727 -        } else {
  1.1728 -            // Otherwise, control-flow always flows through here.
  1.1729 -            control_->inherit(latest);
  1.1730 -        }
  1.1731 -    } else if (node->cases()->length()) {
  1.1732 -        control_->merge(status, ControlStatus(false, Returns_Never));
  1.1733 -    }
  1.1734 -
  1.1735 -    if (values->length() > 1) {
  1.1736 -        qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
  1.1737 -
  1.1738 -        for (size_t i = 1; i < values->length(); i++) {
  1.1739 -            CaseValue &prev = values->at(i - 1);
  1.1740 -            CaseValue &cur = values->at(i);
  1.1741 -            if (prev.box.toInt() == cur.box.toInt()) {
  1.1742 -                cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
  1.1743 -                return;
  1.1744 -            }
  1.1745 -        }
  1.1746 -    }
  1.1747 -
  1.1748 -    node->setCaseValueList(values);
  1.1749 -}
  1.1750 -
  1.1751 -void
  1.1752 -SemanticAnalysis::visit(StructureStatement *node)
  1.1753 -{
  1.1754 -    // If this node already has a type, it was pre-analyzed, so skip it.
  1.1755 -    if (node->decl()->type())
  1.1756 -        return;
  1.1757 -
  1.1758 -    FieldList *fields = node->fields();
  1.1759 -    Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
  1.1760 -    if (!desctable)
  1.1761 -        return;
  1.1762 -
  1.1763 -    Vector<unsigned> composedList;
  1.1764 -    StructureBufferBuilder builder;
  1.1765 -
  1.1766 -    Local<Type> type(zone_);
  1.1767 -    Local<String> name(zone_);
  1.1768 -    Local<Descriptor> desc(zone_);
  1.1769 -    for (size_t i = 0; i < fields->length(); i++) {
  1.1770 -        StructureStatement::Field *field = fields->at(i);
  1.1771 -
  1.1772 -        type = bindType(field->pos(), field->type());
  1.1773 -        if (!type)
  1.1774 -            return;
  1.1775 -
  1.1776 -        if (field->dimensions()) {
  1.1777 -            type = buildArrayType(type, field->dimensions(), false);
  1.1778 -            if (!type)
  1.1779 -                return;
  1.1780 -
  1.1781 -            if (!ArrayMap::Attach(zone_, type))
  1.1782 -                return;
  1.1783 -        }
  1.1784 -
  1.1785 -        if (IsScalarString(type)) {
  1.1786 -            cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
  1.1787 -            return;
  1.1788 -        }
  1.1789 -
  1.1790 -        unsigned offset;
  1.1791 -        if (!builder.add(type, &offset))
  1.1792 -            return;
  1.1793 -
  1.1794 -        name = field->name();
  1.1795 -        desc = Descriptor::New(zone_, name, type, offset);
  1.1796 -        if (!desc)
  1.1797 -            return;
  1.1798 -
  1.1799 -        desctable->set(zone_, i, desc);
  1.1800 -
  1.1801 -        if (type->isStruct() || type->isArray()) {
  1.1802 -            if (!composedList.append(i))
  1.1803 -                return;
  1.1804 -        }
  1.1805 -    }
  1.1806 -
  1.1807 -    Local<FixedArray> composed(zone_);
  1.1808 -    if (composedList.length()) {
  1.1809 -        composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
  1.1810 -        if (!composed)
  1.1811 -            return;
  1.1812 -
  1.1813 -        for (unsigned i = 0; i < composedList.length(); i++)
  1.1814 -            composed->set(zone_, i, desctable->at(i));
  1.1815 -    }
  1.1816 -
  1.1817 -    Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
  1.1818 -    if (!map)
  1.1819 -        return;
  1.1820 -
  1.1821 -    name = node->decl()->name();
  1.1822 -    type = zone_->types()->newStruct(name, desctable, map);
  1.1823 -    if (!type)
  1.1824 -        return;
  1.1825 -
  1.1826 -    map->setType(type);
  1.1827 -    node->decl()->setType(type);
  1.1828 -}
  1.1829 -
  1.1830 -void
  1.1831 -SemanticAnalysis::visit(StringLiteral *node)
  1.1832 -{
  1.1833 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1.1834 -    if (!type)
  1.1835 -        return;
  1.1836 -
  1.1837 -    type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1.1838 -    if (!type)
  1.1839 -        return;
  1.1840 -
  1.1841 -    node->setType(type);
  1.1842 -}
  1.1843 -
  1.1844 -void
  1.1845 -SemanticAnalysis::visit(FloatLiteral *node)
  1.1846 -{
  1.1847 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1.1848 -    if (!type)
  1.1849 -        return;
  1.1850 -
  1.1851 -    node->setType(type);
  1.1852 -}
  1.1853 -
  1.1854 -void
  1.1855 -SemanticAnalysis::visit(BreakStatement *node)
  1.1856 -{
  1.1857 -    if (!loop_) {
  1.1858 -        cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1.1859 -        return;
  1.1860 -    }
  1.1861 -
  1.1862 -    // Note: ignore breaks that occur in unreachable control-flow.
  1.1863 -    if (!control_->status().terminates())
  1.1864 -        loop_->addBreak();
  1.1865 -
  1.1866 -    control_->terminate(Returns_Never);
  1.1867 -}
  1.1868 -
  1.1869 -void
  1.1870 -SemanticAnalysis::visit(ContinueStatement *node)
  1.1871 -{
  1.1872 -    if (!loop_) {
  1.1873 -        cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1.1874 -        return;
  1.1875 -    }
  1.1876 -
  1.1877 -    // Note: ignore continues that occur in unreachable control-flow.
  1.1878 -    if (!control_->status().terminates())
  1.1879 -        loop_->addContinue();
  1.1880 -
  1.1881 -    control_->terminate(Returns_Never);
  1.1882 -}
  1.1883 -
  1.1884 -void
  1.1885 -SemanticAnalysis::visit(ArrayLiteral *node)
  1.1886 -{
  1.1887 -    // We should never visit this.
  1.1888 -    cc_.reportError(node->pos(), Message_UnexpectedArrayLiteral);
  1.1889 -}
  1.1890 -