src/OldSema.cpp
changeset 263 ba85a47ee414
parent 195 c1ba166f3fc4
     1.1 --- a/src/OldSema.cpp	Mon Jun 10 00:46:29 2013 +0100
     1.2 +++ b/src/OldSema.cpp	Mon Jun 10 01:04:43 2013 +0100
     1.3 @@ -1,1899 +1,1899 @@
     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 "../Strings.h"
    1.28 -#include "../Box.h"
    1.29 -#include "../Array.h"
    1.30 -#include "../Heap-inl.h"
    1.31 -#include "Scopes.h"
    1.32 -#include "NameBinding.h"
    1.33 -
    1.34 -using namespace ke;
    1.35 -
    1.36 -SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
    1.37 -  : zone_(zone),
    1.38 -    cc_(cc),
    1.39 -    tree_(tree),
    1.40 -    scope_(NULL),
    1.41 -    loop_(NULL)
    1.42 -{
    1.43 -}
    1.44 -
    1.45 -bool
    1.46 -SemanticAnalysis::analyze()
    1.47 -{
    1.48 -    assert(false);
    1.49 -    return false;
    1.50 -}
    1.51 -
    1.52 -
    1.53 -#if 0
    1.54 -
    1.55 -static inline bool
    1.56 -IsPrimitiveType(Type *type, PrimitiveType primitive)
    1.57 -{
    1.58 -    if (!type)
    1.59 -        return false;
    1.60 -
    1.61 -    if (!type->isPrimitive())
    1.62 -        return false;
    1.63 -
    1.64 -    return primitive == type->primitive();
    1.65 -}
    1.66 -
    1.67 -static inline bool
    1.68 -EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
    1.69 -                        BoxedPrimitive *out)
    1.70 -{
    1.71 -    switch (kind) {
    1.72 -      case TOK_PLUS:
    1.73 -        *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
    1.74 -        return true;
    1.75 -
    1.76 -      case TOK_SHL:
    1.77 -        *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
    1.78 -        return true;
    1.79 -
    1.80 -      default:
    1.81 -        return false;
    1.82 -    }
    1.83 -}
    1.84 -
    1.85 -static inline bool
    1.86 -EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
    1.87 -{
    1.88 -  switch (kind) {
    1.89 -    case TOK_MINUS:
    1.90 -      *out = BoxedPrimitive::Int(-inner.toInt());
    1.91 -      return true;
    1.92 -
    1.93 -    default:
    1.94 -      return false;
    1.95 -  }
    1.96 -}
    1.97 -
    1.98 -static bool
    1.99 -EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
   1.100 -{
   1.101 -    switch (expression->kind()) {
   1.102 -      case AstNode::kBinaryExpression:
   1.103 -      {
   1.104 -        BoxedPrimitive left;
   1.105 -        BoxedPrimitive right;
   1.106 -        BinaryExpression *b = expression->toBinaryExpression();
   1.107 -        if (!EvaluateForConstant(b->left(), &left) ||
   1.108 -            !EvaluateForConstant(b->right(), &right))
   1.109 -        {
   1.110 -            return false;
   1.111 -        }
   1.112 -        return EvaluateBinaryOperation(b->token(), left, right, out);
   1.113 -      }
   1.114 -
   1.115 -      case AstNode::kUnaryExpression:
   1.116 -      {
   1.117 -        BoxedPrimitive inner;
   1.118 -        UnaryExpression *u = expression->toUnaryExpression();
   1.119 -        if (!EvaluateForConstant(u->expression(), &inner))
   1.120 -            return false;
   1.121 -        return EvaluateUnaryOperation(u->token(), inner, out);
   1.122 -      }
   1.123 -
   1.124 -      case AstNode::kNameProxy:
   1.125 -      {
   1.126 -        NameProxy *proxy = expression->toNameProxy();
   1.127 -        if (proxy->binding()->kind() != BoundName::CONSTANT)
   1.128 -            return false;
   1.129 -
   1.130 -        NamedConstant *c = proxy->binding()->toNamedConstant();
   1.131 -        if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
   1.132 -            return false;
   1.133 -
   1.134 -        *out = c->value();
   1.135 -        return true;
   1.136 -      }
   1.137 -
   1.138 -      case AstNode::kBooleanLiteral:
   1.139 -        *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
   1.140 -        return true;
   1.141 -
   1.142 -      case AstNode::kIntegerLiteral:
   1.143 -        *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
   1.144 -        return true;
   1.145 -
   1.146 -      default:
   1.147 -        return false;
   1.148 -    }
   1.149 -}
   1.150 -
   1.151 -SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
   1.152 -  : zone_(zone),
   1.153 -    cc_(cc),
   1.154 -    tree_(tree),
   1.155 -    scope_(NULL),
   1.156 -    loop_(NULL)
   1.157 -{
   1.158 -}
   1.159 -
   1.160 -bool
   1.161 -SemanticAnalysis::analyze()
   1.162 -{
   1.163 -    if (cc_.failures())
   1.164 -        return false;
   1.165 -
   1.166 -    scope_ = tree_->globalScope();
   1.167 -    assert(scope_->kind() == Scope::GLOBAL);
   1.168 -
   1.169 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.170 -        Statement *statement = tree_->statements()->at(i);
   1.171 -        if (statement->isFunctionStatement()) {
   1.172 -            FunctionStatement *funstmt = statement->toFunctionStatement();
   1.173 -            if (!preanalyze(funstmt))
   1.174 -                return false;
   1.175 -        } else if (statement->isEnumStatement()) {
   1.176 -            EnumStatement *enumstmt = statement->toEnumStatement();
   1.177 -
   1.178 -            // We pre-fill global enum types, since they may occur in function
   1.179 -            // signatures. This should probably be somewhere else...
   1.180 -            enumstmt->accept(this);
   1.181 -        } else if (statement->isStructureStatement()) {
   1.182 -            StructureStatement *node = statement->toStructureStatement();
   1.183 -            node->accept(this);
   1.184 -            if (!node->decl()->type())
   1.185 -                return false;
   1.186 -        } else if (statement->isFunctionTypeStatement()) {
   1.187 -            FunctionTypeStatement *node = statement->toFunctionTypeStatement();
   1.188 -            node->accept(this);
   1.189 -            if (!node->decl()->type())
   1.190 -                return false;
   1.191 -        }
   1.192 -    }
   1.193 -
   1.194 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.195 -        Statement *statement = tree_->statements()->at(i);
   1.196 -
   1.197 -        // We can't double-process these. Maybe put this check somewhere else.
   1.198 -        if (statement->isEnumStatement())
   1.199 -            continue;
   1.200 -
   1.201 -        statement->accept(this);
   1.202 -    }
   1.203 -
   1.204 -    if (!determineLiveFunctions())
   1.205 -        return false;
   1.206 -
   1.207 -    return !cc_.failures();
   1.208 -}
   1.209 -
   1.210 -bool
   1.211 -SemanticAnalysis::determineLiveFunctions()
   1.212 -{
   1.213 -    Vector<NamedFunction *> worklist;
   1.214 -
   1.215 -    // Add the root set.
   1.216 -    for (size_t i = 0; i < tree_->statements()->length(); i++) {
   1.217 -        Statement *statement = tree_->statements()->at(i);
   1.218 -        if (!statement->isFunctionStatement())
   1.219 -            continue;
   1.220 -
   1.221 -        FunctionStatement *stmt = statement->toFunctionStatement();
   1.222 -        NamedFunction  *fun = stmt->fun();
   1.223 -        if (!fun->used())
   1.224 -            continue;
   1.225 -
   1.226 -        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   1.227 -            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   1.228 -
   1.229 -            // Names in these lists are always unused, however, we mark them
   1.230 -            // as used while inserting into the work queue, to avoid double-
   1.231 -            // insertion.
   1.232 -            if (name->used())
   1.233 -                continue;
   1.234 -
   1.235 -            if (!worklist.append(name))
   1.236 -                return false;
   1.237 -
   1.238 -            name->setUsed();
   1.239 -        }
   1.240 -    }
   1.241 -
   1.242 -    while (!worklist.empty()) {
   1.243 -        NamedFunction *fun = worklist.popCopy();
   1.244 -
   1.245 -        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
   1.246 -            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
   1.247 -            if (name->used())
   1.248 -                continue;
   1.249 -            if (!worklist.append(name))
   1.250 -                return false;
   1.251 -            name->setUsed();
   1.252 -        }
   1.253 -    }
   1.254 -
   1.255 -    return true;
   1.256 -}
   1.257 -
   1.258 -Type *
   1.259 -SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
   1.260 -{
   1.261 -    if (!name)
   1.262 -        return zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.263 -
   1.264 -    if (name->kind() == BoundName::UNBOUND) {
   1.265 -        cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
   1.266 -        return NULL;
   1.267 -    }
   1.268 -
   1.269 -    if (name->kind() != BoundName::TYPE) {
   1.270 -        cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
   1.271 -        return NULL;
   1.272 -    }
   1.273 -
   1.274 -    if (!name->type())
   1.275 -        return NULL;
   1.276 -
   1.277 -    return name->type();
   1.278 -}
   1.279 -
   1.280 -Type *
   1.281 -SemanticAnalysis::visitAndApplyType(Expression *expression)
   1.282 -{
   1.283 -    expression->accept(this);
   1.284 -    return expression->type();
   1.285 -}
   1.286 -
   1.287 -Type *
   1.288 -SemanticAnalysis::visitForLoad(Expression *expression)
   1.289 -{
   1.290 -    Local<Type> type(zone_, visitAndApplyType(expression));
   1.291 -    if (!type)
   1.292 -        return NULL;
   1.293 -
   1.294 -    if (type->isReference()) {
   1.295 -        expression->setType(type->contained());
   1.296 -    } else if (expression->isCallExpression()) {
   1.297 -        if (type->isVoid()) {
   1.298 -            CallExpression *call = expression->toCallExpression();
   1.299 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
   1.300 -            return NULL;
   1.301 -        }
   1.302 -    }
   1.303 -
   1.304 -    return expression->type();
   1.305 -}
   1.306 -
   1.307 -void
   1.308 -SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
   1.309 -{
   1.310 -    const char *op = TokenNames[token];
   1.311 -    const char *name = GetTypeName(type);
   1.312 -
   1.313 -    cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
   1.314 -}
   1.315 -
   1.316 -void
   1.317 -SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   1.318 -{
   1.319 -    const char *op = TokenNames[token];
   1.320 -    const char *leftName = GetTypeName(left);
   1.321 -    const char *rightName = GetTypeName(right);
   1.322 -
   1.323 -    cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
   1.324 -}
   1.325 -
   1.326 -Type *
   1.327 -SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
   1.328 -{
   1.329 -    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
   1.330 -        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
   1.331 -    {
   1.332 -        // If either side is a float, the other side must be a float or int.
   1.333 -        if (left->isFloat() || right->isFloat()) {
   1.334 -            Type *floatType = left->isFloat() ? left : right;
   1.335 -            Type *other = left->isFloat() ? right : left;
   1.336 -            if (other->isFloat() || other->isInt32())
   1.337 -                return floatType;
   1.338 -        }
   1.339 -    }
   1.340 -
   1.341 -    if (token == TOK_OR || token == TOK_AND) {
   1.342 -        if (!canTest(node, left) || !canTest(node, right))
   1.343 -            return NULL;
   1.344 -        return zone_->types()->getPrimitive(PrimitiveType_Bool);
   1.345 -    }
   1.346 -
   1.347 -    if (token >= TOK_EQUALS && token <= TOK_GE) {
   1.348 -        if ((left->isFloat() || left->isInt32()) &&
   1.349 -            (right->isFloat() || right->isInt32()))
   1.350 -        {
   1.351 -            return zone_->types()->getPrimitive(PrimitiveType_Bool);
   1.352 -        }
   1.353 -        binaryTypeError(node, token, left, right);
   1.354 -        return NULL;
   1.355 -    }
   1.356 -
   1.357 -    if (!left->isInt32() || !right->isInt32()) {
   1.358 -        binaryTypeError(node, token, left, right);
   1.359 -        return NULL;
   1.360 -    }
   1.361 -
   1.362 -    return left;
   1.363 -}
   1.364 -
   1.365 -bool
   1.366 -SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
   1.367 -{
   1.368 -    if (!type->isPrimitive() && !type->isEnum()) {
   1.369 -        cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
   1.370 -        return false;
   1.371 -    }
   1.372 -    return true;
   1.373 -}
   1.374 -
   1.375 -Type *
   1.376 -SemanticAnalysis::visitForLValue(Expression *expression)
   1.377 -{
   1.378 -    if (expression->isIndexExpression()) {
   1.379 -        Type *type = visitAndApplyType(expression);
   1.380 -        if (!type)
   1.381 -            return NULL;
   1.382 -
   1.383 -        // if (type->isConst()) {
   1.384 -        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.385 -        //     return NULL;
   1.386 -        // }
   1.387 -
   1.388 -        return type;
   1.389 -    }
   1.390 -
   1.391 -    if (expression->isFieldExpression()) {
   1.392 -        Type *type = visitAndApplyType(expression);
   1.393 -        if (!type)
   1.394 -            return NULL;
   1.395 -
   1.396 -        // if (expression->toFieldExpression()->left()->type()->isConst()) {
   1.397 -        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.398 -        //     return NULL;
   1.399 -        // }
   1.400 -
   1.401 -        return type;
   1.402 -    }
   1.403 -
   1.404 -    if (!expression->isNameProxy()) {
   1.405 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
   1.406 -        return NULL;
   1.407 -    }
   1.408 -
   1.409 -    NameProxy *proxy = expression->toNameProxy();
   1.410 -    if (!proxy->binding()->kind() == BoundName::VARIABLE) {
   1.411 -        cc_.reportError(expression->pos(), Message_ExpectedLValue);
   1.412 -        return NULL;
   1.413 -    }
   1.414 -
   1.415 -    Variable *var = proxy->binding()->toVariable();
   1.416 -    if (!var->type())
   1.417 -        return NULL;
   1.418 -
   1.419 -    if  (var->type()->isReference()) {
   1.420 -        if (var->type()->isConst()) {
   1.421 -            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
   1.422 -            return NULL;
   1.423 -        }
   1.424 -        return var->type()->contained();
   1.425 -    }
   1.426 -    return var->type();
   1.427 -}
   1.428 -
   1.429 -SemanticAnalysis::ControlStatus
   1.430 -SemanticAnalysis::visitForControl(Statement *statement)
   1.431 -{
   1.432 -    ControlScope scope(&control_);
   1.433 -    statement->accept(this);
   1.434 -    return scope.status();
   1.435 -}
   1.436 -
   1.437 -void
   1.438 -SemanticAnalysis::visit(NameProxy *name)
   1.439 -{
   1.440 -    BoundName *binding = name->binding();
   1.441 -
   1.442 -    if (binding->scope()->kind() == Scope::GLOBAL) {
   1.443 -        if (!function_ || function_->isPublic()) {
   1.444 -            // Whatever we're referencing must be kept alive no matter what.
   1.445 -            // As such, we simply mark it used, and don't do anything special.
   1.446 -            binding->setUsed();
   1.447 -        } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
   1.448 -            // Otherwise, we're inside a normal stock or function. Since we
   1.449 -            // don't really know if we've been used yet, we shouldn't
   1.450 -            // prematurely references as alive. Instead, we keep a list of
   1.451 -            // which names have been used, so we can mark them later if needed.
   1.452 -            //
   1.453 -            // Note that we skip this step if the binding is already in the
   1.454 -            // root set.
   1.455 -            if (!function_->addUsedGlobal(binding))
   1.456 -                return;
   1.457 -        }
   1.458 -    }
   1.459 -
   1.460 -    name->setType(binding->type());
   1.461 -}
   1.462 -
   1.463 -void
   1.464 -SemanticAnalysis::visit(Assignment *node)
   1.465 -{
   1.466 -    Local<Type> exprType(zone_, visitForLoad(node->expression()));
   1.467 -    if (!exprType)
   1.468 -        return ;
   1.469 -
   1.470 -    Local<Type> type(zone_, visitForLValue(node->lvalue()));
   1.471 -    if (!type)
   1.472 -        return;
   1.473 -
   1.474 -    if (node->token() != TOK_ASSIGN) {
   1.475 -        if (!typeCheckBinary(node, node->token(), type, exprType))
   1.476 -            return;
   1.477 -    }
   1.478 -
   1.479 -    if (!typeCheckAssignment(node->pos(), exprType, type, true))
   1.480 -        return;
   1.481 -
   1.482 -    node->setType(type);
   1.483 -}
   1.484 -
   1.485 -void
   1.486 -SemanticAnalysis::visit(IncDecExpression *node)
   1.487 -{
   1.488 -    Local<Type> type(zone_, visitForLValue(node->expression()));
   1.489 -    if (!type)
   1.490 -        return;
   1.491 -
   1.492 -    assert(!type->isReference());
   1.493 -
   1.494 -    if (!type->isInt32() && !type->isFloat()) {
   1.495 -        unaryTypeError(node, node->token(), type);
   1.496 -        return;
   1.497 -    }
   1.498 -
   1.499 -    node->setType(type);
   1.500 -}
   1.501 -
   1.502 -void
   1.503 -SemanticAnalysis::visit(UnaryExpression *node)
   1.504 -{
   1.505 -    Local<Type> type(zone_, visitForLoad(node->expression()));
   1.506 -    if (!type)
   1.507 -        return;
   1.508 -
   1.509 -    switch (node->token())
   1.510 -    {
   1.511 -      case TOK_NOT:
   1.512 -        if (!canTest(node->expression(), type))
   1.513 -            return;
   1.514 -        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
   1.515 -        if (!type)
   1.516 -            return;
   1.517 -        node->setType(type);
   1.518 -        break;
   1.519 -
   1.520 -      case TOK_MINUS:
   1.521 -        if (!type->isFloat() && !type->isInt32()) {
   1.522 -            unaryTypeError(node, node->token(), type);
   1.523 -            return;
   1.524 -        }
   1.525 -        node->setType(type);
   1.526 -        break;
   1.527 -
   1.528 -      case TOK_LABEL:
   1.529 -      {
   1.530 -        Local<Type> to(zone_, bindType(node->pos(), node->type()));
   1.531 -        if (!to)
   1.532 -            return;
   1.533 -
   1.534 -        if ((!type->isFloat() && !type->isInt32OrEnum()) ||
   1.535 -            (!to->isFloat() && !to->isInt32OrEnum()))
   1.536 -        {
   1.537 -            unaryTypeError(node, node->token(), type);
   1.538 -            return;
   1.539 -        }
   1.540 -
   1.541 -        node->setType(to);
   1.542 -        break;
   1.543 -      }
   1.544 -
   1.545 -      case TOK_SIZEOF:
   1.546 -      {
   1.547 -        if (!type->isArray()) {
   1.548 -            cc_.reportError(node->pos(), Message_SizeofNeedsArray);
   1.549 -            return;
   1.550 -        }
   1.551 -        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   1.552 -        break;
   1.553 -      }
   1.554 -
   1.555 -      default:
   1.556 -        assert(node->token() == TOK_TILDE);
   1.557 -        if (!type->isInt32()) {
   1.558 -            unaryTypeError(node, node->token(), type);
   1.559 -            return;
   1.560 -        }
   1.561 -        node->setType(type);
   1.562 -        break;
   1.563 -    }
   1.564 -}
   1.565 -
   1.566 -void
   1.567 -SemanticAnalysis::visit(TernaryExpression *node)
   1.568 -{
   1.569 -    Local<Type> type(zone_, visitForLoad(node->condition()));
   1.570 -    if (!type)
   1.571 -        return;
   1.572 -
   1.573 -    if (!canTest(node->condition(), type))
   1.574 -        return;
   1.575 -
   1.576 -    Local<Type> left(zone_, visitForLoad(node->left()));
   1.577 -    Local<Type> right(zone_, visitForLoad(node->right()));
   1.578 -    if (!left || !right)
   1.579 -        return;
   1.580 -
   1.581 -    if (left != right) {
   1.582 -        binaryTypeError(node, TOK_QMARK, left, right);
   1.583 -        return;
   1.584 -    }
   1.585 -}
   1.586 -
   1.587 -void
   1.588 -SemanticAnalysis::visit(BinaryExpression *node)
   1.589 -{
   1.590 -    Local<Type> left(zone_, visitForLoad(node->left()));
   1.591 -    Local<Type> right(zone_, visitForLoad(node->right()));
   1.592 -    if (!left || !right)
   1.593 -        return;
   1.594 -
   1.595 -    Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
   1.596 -    if (!result)
   1.597 -        return;
   1.598 -
   1.599 -    node->setType(result);
   1.600 -}
   1.601 -
   1.602 -void
   1.603 -SemanticAnalysis::visit(ReturnStatement *node)
   1.604 -{
   1.605 -    // Set this early, so if we error we don't get more errors.
   1.606 -    control_->returns(Returns_Always);
   1.607 -
   1.608 -    if (!node->expression()) {
   1.609 -        if (!function_->type()->returnType()->isVoid())
   1.610 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
   1.611 -        return;
   1.612 -    }
   1.613 -
   1.614 -    Local<Type> type(zone_, visitForLoad(node->expression()));
   1.615 -    if (!type)
   1.616 -        return;
   1.617 -
   1.618 -    Local<Type> returnType(zone_, function_->type()->returnType());
   1.619 -    if (!typeCheckAssignment(node->pos(), type, returnType, true))
   1.620 -        return;
   1.621 -}
   1.622 -
   1.623 -void
   1.624 -SemanticAnalysis::visit(ForStatement *node)
   1.625 -{
   1.626 -    LoopScope loop(&loop_);
   1.627 -
   1.628 -    if (node->scope())
   1.629 -        scope_ = node->scope();
   1.630 -
   1.631 -    if (node->initialization())
   1.632 -        node->initialization()->accept(this);
   1.633 -
   1.634 -    if (node->condition()) {
   1.635 -        Local<Type> type(zone_, visitForLoad(node->condition()));
   1.636 -        if (!type || !canTest(node->condition(), type)) {
   1.637 -            return;
   1.638 -        }
   1.639 -    }
   1.640 -
   1.641 -    if (node->update())
   1.642 -        node->update()->accept(this);
   1.643 -
   1.644 -    ControlStatus status = visitForControl(node->body());
   1.645 -
   1.646 -    // If there is a condition, we treat this like a while loop. Otherwise,
   1.647 -    // join point is only reachable if the loop contains a break. The
   1.648 -    // termination status doesn't tell us anything yet.
   1.649 -    if (node->condition() || loop.breaks())
   1.650 -        control_->merge(status, ControlStatus(false, Returns_Never));
   1.651 -    else
   1.652 -        control_->terminate(status.returns());
   1.653 -
   1.654 -    if (node->scope())
   1.655 -        scope_ = scope_->enclosing();
   1.656 -}
   1.657 -
   1.658 -void 
   1.659 -SemanticAnalysis::visit(WhileStatement *node)
   1.660 -{
   1.661 -    LoopScope loop(&loop_);
   1.662 -
   1.663 -    Local<Type> type(zone_, visitForLoad(node->condition()));
   1.664 -    if (!type || !canTest(node->condition(), type)) {
   1.665 -        return;
   1.666 -    }
   1.667 -
   1.668 -    ControlStatus status = visitForControl(node->body());
   1.669 -
   1.670 -    // Detect loops that will always have a fork in the control-flow graph.
   1.671 -    // This will be a |while| loop, or a |do-while| loop whose body does
   1.672 -    // not terminate.
   1.673 -    //
   1.674 -    // For now, we treat these as an |if| regardless of the direction the
   1.675 -    // branch can take. That means the control-flow is always conditional.
   1.676 -    if (node->token() == TOK_WHILE ||
   1.677 -        !status.terminates() ||
   1.678 -        loop.breaks())
   1.679 -    {
   1.680 -        control_->merge(status, ControlStatus(false, Returns_Never));
   1.681 -    } else {
   1.682 -        // At this point, we've got a do-while loop with a |return| or
   1.683 -        // |continue|, meaning that the rest of the block is unreachable.
   1.684 -        control_->terminate(status.returns());
   1.685 -    }
   1.686 -}
   1.687 -
   1.688 -void
   1.689 -SemanticAnalysis::visit(BlockStatement *node)
   1.690 -{
   1.691 -    if (node->scope())
   1.692 -        scope_ = node->scope();
   1.693 -    for (size_t i = 0; i < node->statements()->length(); i++) {
   1.694 -        Statement *statement = node->statements()->at(i);
   1.695 -        statement->accept(this);
   1.696 -    }
   1.697 -    if (node->scope())
   1.698 -        scope_ = scope_->enclosing();
   1.699 -}
   1.700 -
   1.701 -static inline bool
   1.702 -IsScalarString(Type *type)
   1.703 -{
   1.704 -    if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
   1.705 -        return true;
   1.706 -    if (type->isReference())
   1.707 -        return IsScalarString(type->contained());
   1.708 -    return false;
   1.709 -}
   1.710 -
   1.711 -static const int INFER_ARRAY_SIZE = 0;
   1.712 -static const int EVAL_ARRAY_SIZE = -1;
   1.713 -static const int DYNAMIC_ARRAY_SIZE = -2;
   1.714 -
   1.715 -bool
   1.716 -SemanticAnalysis::evaluateDimensions(ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH])
   1.717 -{
   1.718 -    bool hadEmptySize = false;
   1.719 -
   1.720 -    for (size_t i = 0; i < exprs->length(); i++) {
   1.721 -        Expression *expr = exprs->at(i);
   1.722 -        if (!expr) {
   1.723 -            dims[i] = INFER_ARRAY_SIZE;
   1.724 -            hadEmptySize = true;
   1.725 -            continue;
   1.726 -        }
   1.727 -
   1.728 -        BoxedPrimitive box;
   1.729 -        if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
   1.730 -            int size = box.toInt();
   1.731 -            if (size <= 0) {
   1.732 -                cc_.reportError(expr->pos(), Message_BadArraySize);
   1.733 -                return false;
   1.734 -            }
   1.735 -
   1.736 -            dims[i] = size;
   1.737 -            continue;
   1.738 -        }
   1.739 -
   1.740 -        Local<Type> exprType(zone_, visitForLoad(expr));
   1.741 -        if (!exprType)
   1.742 -            return false;
   1.743 -
   1.744 -        if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
   1.745 -            cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
   1.746 -            return false;
   1.747 -        }
   1.748 -
   1.749 -        if (hadEmptySize) {
   1.750 -            cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
   1.751 -            return false;
   1.752 -        }
   1.753 -
   1.754 -        dims[i] = EVAL_ARRAY_SIZE;
   1.755 -    }
   1.756 -
   1.757 -    return true;
   1.758 -}
   1.759 -
   1.760 -bool
   1.761 -SemanticAnalysis::inferFixedArrayLiteral(ArrayLiteral *literal, Handle<Type> contained,
   1.762 -                                         int dims[MAX_ARRAY_DEPTH],
   1.763 -                                         unsigned dimcount, unsigned level)
   1.764 -{
   1.765 -    if (dims[level] == EVAL_ARRAY_SIZE) {
   1.766 -        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   1.767 -        return false;
   1.768 -    }
   1.769 -
   1.770 -    if (dims[level] == INFER_ARRAY_SIZE) {
   1.771 -        // Strings always become dynamic arrays.
   1.772 -        if (level != dimcount - 1 || !IsPrimitiveType(contained, PrimitiveType_Char))
   1.773 -            dims[level] = literal->expressions()->length();
   1.774 -    } else if (dims[level] == DYNAMIC_ARRAY_SIZE) {
   1.775 -        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
   1.776 -        return false;
   1.777 -    } else {
   1.778 -        if (literal->expressions()->length() != unsigned(dims[level])) {
   1.779 -            cc_.reportError(literal->pos(), Message_ArrayDimensionSizeMismatch, level + 1);
   1.780 -            return false;
   1.781 -        }
   1.782 -    }
   1.783 -
   1.784 -    if (level == dimcount - 2 && IsPrimitiveType(contained, PrimitiveType_Char)) {
   1.785 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.786 -            Expression *expr = literal->expressions()->at(i);
   1.787 -            if (!expr->isStringLiteral()) {
   1.788 -                cc_.reportError(expr->pos(), Message_ExpectedStringLiteral);
   1.789 -                return false;
   1.790 -            }
   1.791 -
   1.792 -            StringLiteral *lit = expr->toStringLiteral();
   1.793 -            if (dims[level + 1] > 0 &&
   1.794 -                unsigned(dims[level]) < lit->string()->length())
   1.795 -            {
   1.796 -                cc_.reportError(lit->pos(), Message_ArrayDimensionSizeMismatch, level + 2);
   1.797 -                return false;
   1.798 -            }
   1.799 -            if (!visitAndApplyType(lit))
   1.800 -                return false;
   1.801 -        }
   1.802 -    } else if (level == dimcount - 1) {
   1.803 -        Local<Type> type(zone_);
   1.804 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.805 -            Expression *expr = literal->expressions()->at(i);
   1.806 -            if (expr->isArrayLiteral()) {
   1.807 -                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   1.808 -                return false;
   1.809 -            }
   1.810 -
   1.811 -            if ((type = visitAndApplyType(expr)) == NULL)
   1.812 -                return false;
   1.813 -
   1.814 -            if (!typeCheckAssignment(expr->pos(), type, contained, true))
   1.815 -                return false;
   1.816 -        }
   1.817 -    } else {
   1.818 -        for (size_t i = 0; i < literal->expressions()->length(); i++) {
   1.819 -            Expression *expr = literal->expressions()->at(i);
   1.820 -            if (!expr->isArrayLiteral()) {
   1.821 -                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
   1.822 -                return false;
   1.823 -            }
   1.824 -
   1.825 -            assert(expr->toArrayLiteral()->isFixed());
   1.826 -
   1.827 -            if (!inferFixedArrayLiteral(expr->toArrayLiteral(),
   1.828 -                                        contained,
   1.829 -                                        dims,
   1.830 -                                        dimcount,
   1.831 -                                        level + 1))
   1.832 -            {
   1.833 -                return false;
   1.834 -            }
   1.835 -        }
   1.836 -    }
   1.837 -
   1.838 -    return true;
   1.839 -}
   1.840 -
   1.841 -void
   1.842 -SemanticAnalysis::visit(VariableDeclaration *node)
   1.843 -{
   1.844 -    Local<Type> type(zone_, bindType(node->pos(), node->type()));
   1.845 -    if (!type)
   1.846 -        return;
   1.847 -
   1.848 -#if 0
   1.849 -    if (node->postDimensions() || type->isArray()) {
   1.850 -        // The type could be an array type, so sum the type and postDimensions
   1.851 -        // together.
   1.852 -        unsigned dimcount = node->postDimensions()->length();
   1.853 -        if (type->isArray())
   1.854 -            dimcount += type->levels();
   1.855 -        if (dimcount > MAX_ARRAY_DEPTH) {
   1.856 -            cc_.reportError(node->pos(), Message_MaximumArrayDepth);
   1.857 -            return;
   1.858 -        }
   1.859 -
   1.860 -        // Take an initial guess at the array dimension sizes.
   1.861 -        int dims[MAX_ARRAY_DEPTH];
   1.862 -        if (!evaluateDimensions(node->postDimensions(), dims))
   1.863 -            return;
   1.864 -
   1.865 -        // Now add in the type's array dimensions.
   1.866 -        Local<Type> contained(zone_, type);
   1.867 -        for (size_t i = node->postDimensions()->length(); i < dimcount; i++) {
   1.868 -            if (type->isFixedLength())
   1.869 -                dims[i] = type->fixedLength();
   1.870 -            else
   1.871 -                dims[i] = DYNAMIC_ARRAY_SIZE;
   1.872 -            contained = contained->contained();
   1.873 -        }
   1.874 -
   1.875 -        Expression *initializer = node->initialization();
   1.876 -        if (initializer &&
   1.877 -            initializer->isArrayLiteral() &&
   1.878 -            initializer->toArrayLiteral()->isFixed())
   1.879 -        {
   1.880 -            // Fixed array initializers are special; we use them to infer any
   1.881 -            // missing information in the original array. We do not evaluate
   1.882 -            // the array initializer as an expression.
   1.883 -            if (!inferFixedArrayLiteral(initializer->toArrayLiteral(),
   1.884 -                                        contained,
   1.885 -                                        dims,
   1.886 -                                        dimcount,
   1.887 -                                        0))
   1.888 -            {
   1.889 -                return;
   1.890 -            }
   1.891 -            initializer = NULL;
   1.892 -        }
   1.893 -
   1.894 -        // We now have enough information to build the actual array type.
   1.895 -        // Start from the original dimcount, not the one computed for
   1.896 -        // initializers.
   1.897 -        for (size_t i = node->postDimensions()->length() - 1;
   1.898 -             i < node->postDimensions()->length();
   1.899 -             i--)
   1.900 -        {
   1.901 -            int size = dims[i] > 0
   1.902 -                       ? dims[i]
   1.903 -                       : Type::DYNAMIC_ARRAY_SIZE;
   1.904 -
   1.905 -            type = zone_->types()->newArray(type, size, false);
   1.906 -            if (!type)
   1.907 -                return;
   1.908 -        }
   1.909 -
   1.910 -        // Finally, if we had a non-fixed initializer, make sure it type
   1.911 -        // checks. 
   1.912 -        if (initializer) {
   1.913 -            Local<Type> right(zone_, visitForLoad(initializer));
   1.914 -            if (!right)
   1.915 -                return;
   1.916 -
   1.917 -            if (!typeCheckAssignment(node->pos(), right, type, true))
   1.918 -                return;
   1.919 -        }
   1.920 -    } else {
   1.921 -        if (node->initialization()) {
   1.922 -            Local<Type> right(zone_, visitForLoad(node->initialization()));
   1.923 -            if (!right)
   1.924 -                return;
   1.925 -            if (!typeCheckAssignment(node->pos(), right, type, true))
   1.926 -                return;
   1.927 -        }
   1.928 -
   1.929 -        if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
   1.930 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
   1.931 -            return;
   1.932 -        }
   1.933 -    }
   1.934 -#endif
   1.935 -
   1.936 -#if 0
   1.937 -    // If this variable is stack allocated, we could use the LIFO heap
   1.938 -    // to allocate it. If that's the case, make sure to reserve a slot
   1.939 -    // so we can unwind the LIFO heap at the end of this scope.
   1.940 -    if (!node->variable()->needsHeapAllocation()) {
   1.941 -        if (type->isArray() || type->isStruct())
   1.942 -            scope_->setUsesLifoHeap();
   1.943 -    }
   1.944 -
   1.945 -    node->variable()->setType(type);
   1.946 -#endif
   1.947 -}
   1.948 -
   1.949 -void
   1.950 -SemanticAnalysis::visit(IntegerLiteral *node)
   1.951 -{
   1.952 -    node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
   1.953 -}
   1.954 -
   1.955 -void
   1.956 -SemanticAnalysis::visit(BooleanLiteral *node)
   1.957 -{
   1.958 -    node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
   1.959 -}
   1.960 -
   1.961 -void
   1.962 -SemanticAnalysis::visit(ExpressionStatement *node)
   1.963 -{
   1.964 -    visitAndApplyType(node->expression());
   1.965 -}
   1.966 -
   1.967 -Box *
   1.968 -SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
   1.969 -{
   1.970 -    Local<Type> given(zone_, visitForLoad(parameter->initializer()));
   1.971 -
   1.972 -    BoxedPrimitive prim;
   1.973 -    if (EvaluateForConstant(parameter->initializer(), &prim)) {
   1.974 -        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   1.975 -            return NULL;
   1.976 -
   1.977 -        if (prim.type() == PrimitiveType_Int32)
   1.978 -            return Box::New(zone_, given, prim.toInt());
   1.979 -        return Box::New(zone_, given, prim.toFloat());
   1.980 -    } else if (parameter->initializer()->isStringLiteral()) {
   1.981 -        StringLiteral *literal = parameter->initializer()->toStringLiteral();
   1.982 -
   1.983 -        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
   1.984 -            return NULL;
   1.985 -
   1.986 -        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
   1.987 -        if (!map)
   1.988 -            return NULL;
   1.989 -
   1.990 -        Local<Array> array(zone_,
   1.991 -            Array::NewString(zone_,
   1.992 -                             map,
   1.993 -                             literal->string()->raw(),
   1.994 -                             literal->string()->length(),
   1.995 -                             Heap::Tenure_Old));
   1.996 -        if (!array)
   1.997 -            return NULL;
   1.998 -
   1.999 -        return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
  1.1000 -    }
  1.1001 -
  1.1002 -    cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
  1.1003 -    return NULL;
  1.1004 -}
  1.1005 -
  1.1006 -bool
  1.1007 -SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
  1.1008 -                                    FixedArray **argsp, FixedArray **defaultsp)
  1.1009 -{
  1.1010 -    Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
  1.1011 -    if (!args)
  1.1012 -        return false;
  1.1013 -
  1.1014 -    Local<FixedArray> defaults(zone_);
  1.1015 -
  1.1016 -    // Apply types to arguments.
  1.1017 -    for (size_t i = 0; i < sig.parameters()->length(); i++) {
  1.1018 -        Parameter *parameter = sig.parameters()->at(i);
  1.1019 -        
  1.1020 -#if 0
  1.1021 -        Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
  1.1022 -        if (!type)
  1.1023 -            return false;
  1.1024 -
  1.1025 -        if (parameter->reference()) {
  1.1026 -            if (parameter->dimensions()) {
  1.1027 -                cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
  1.1028 -                return false;
  1.1029 -            }
  1.1030 -
  1.1031 -            if (type->isStruct()) {
  1.1032 -                cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
  1.1033 -                return false;
  1.1034 -            }
  1.1035 -
  1.1036 -            type = zone_->types()->getReference(type, parameter->isConst());
  1.1037 -            if (!type)
  1.1038 -                return false;
  1.1039 -        } else if (parameter->dimensions()) {
  1.1040 -            type = buildArrayType(type, parameter->dimensions(), parameter->isConst());
  1.1041 -            if (!type)
  1.1042 -                return false;
  1.1043 -
  1.1044 -            if (kind == TOK_NATIVE && type->levels() > 1) {
  1.1045 -                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
  1.1046 -                return false;
  1.1047 -            }
  1.1048 -        }
  1.1049 -
  1.1050 -        if (IsScalarString(type)) {
  1.1051 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.1052 -            return false;
  1.1053 -        }
  1.1054 -
  1.1055 -        args->set(zone_, i, type);
  1.1056 -        parameter->variable()->setType(type);
  1.1057 -
  1.1058 -        if (parameter->initializer()) {
  1.1059 -            if (!defaults) {
  1.1060 -                defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
  1.1061 -                if (!defaults)
  1.1062 -                    return false;
  1.1063 -            }
  1.1064 -
  1.1065 -            Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
  1.1066 -            if (!box)
  1.1067 -                return false;
  1.1068 -
  1.1069 -            defaults->set(zone_, i, box);
  1.1070 -        }
  1.1071 -#endif
  1.1072 -    }
  1.1073 -
  1.1074 -    *argsp = args;
  1.1075 -    *defaultsp = defaults;
  1.1076 -
  1.1077 -    return true;
  1.1078 -}
  1.1079 -
  1.1080 -void
  1.1081 -SemanticAnalysis::visit(FunctionTypeStatement *node)
  1.1082 -{
  1.1083 -    if (node->decl()->type())
  1.1084 -        return;
  1.1085 -
  1.1086 -    Local<FixedArray> args(zone_);
  1.1087 -    Local<FixedArray> defaults(zone_);
  1.1088 -
  1.1089 -    const FunctionSignature &sig= node->signature();
  1.1090 -    if (!buildFunctionArgs(node,
  1.1091 -                           TOK_STOCK,
  1.1092 -                           sig,
  1.1093 -                           args.address(),
  1.1094 -                           defaults.address()))
  1.1095 -    {
  1.1096 -        return;
  1.1097 -    }
  1.1098 -
  1.1099 -#if 0
  1.1100 -    Local<Type> returnType(zone_);
  1.1101 -    if (sig.returnType())
  1.1102 -        returnType = bindType(node->pos(), sig.returnType());
  1.1103 -    else
  1.1104 -        returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.1105 -
  1.1106 -    if (!returnType)
  1.1107 -        return;
  1.1108 -
  1.1109 -    Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
  1.1110 -    if (!funtype)
  1.1111 -        return;
  1.1112 -
  1.1113 -    node->decl()->setType(funtype);
  1.1114 -#endif
  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 -#if 0
  1.1179 -    Local<Type> returnType(zone_);
  1.1180 -    if (sig.returnType() ||
  1.1181 -        node->hasExplicitReturn() ||
  1.1182 -        node->fun()->isNative())
  1.1183 -    {
  1.1184 -        returnType = bindType(node->pos(), sig.returnType());
  1.1185 -    } else {
  1.1186 -        returnType = zone_->types()->getVoid();
  1.1187 -    }
  1.1188 -    if (!returnType)
  1.1189 -        return false;
  1.1190 -
  1.1191 -    if (sig.returnDimensions()) {
  1.1192 -        returnType = buildArrayType(returnType, sig.returnDimensions(), false);
  1.1193 -        if (!returnType)
  1.1194 -            return false;
  1.1195 -    }
  1.1196 -
  1.1197 -    if (IsScalarString(returnType)) {
  1.1198 -        cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.1199 -        return false;
  1.1200 -    }
  1.1201 -
  1.1202 -    Local<Type> funtype(zone_);
  1.1203 -    if (node->fun()->isNative())
  1.1204 -        funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
  1.1205 -    else
  1.1206 -        funtype = zone_->types()->newFunction(returnType, args, defaults);
  1.1207 -    if (!funtype)
  1.1208 -        return false;
  1.1209 -    
  1.1210 -    // If the function already has a type, it was forward declared before, and
  1.1211 -    // now this is our chance to type check the second declaration.
  1.1212 -    if (node->fun()->type()) {
  1.1213 -        Local<Type> forward(zone_, node->fun()->type());
  1.1214 -        if (!Type::Compare(funtype, forward)) {
  1.1215 -            cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  1.1216 -            return false;
  1.1217 -        }
  1.1218 -        node->fun()->setForwardType(forward);
  1.1219 -    }
  1.1220 -
  1.1221 -    node->fun()->setType(funtype);
  1.1222 -#endif
  1.1223 -
  1.1224 -    return true;
  1.1225 -}
  1.1226 -
  1.1227 -void
  1.1228 -SemanticAnalysis::visit(FunctionStatement *node)
  1.1229 -{
  1.1230 -    function_ = node->fun();
  1.1231 -    scope_ = node->scope();
  1.1232 -
  1.1233 -    ControlScope control(&control_);
  1.1234 -    if (node->body()) {
  1.1235 -        node->body()->accept(this);
  1.1236 -
  1.1237 -        ControlStatus status = control.status();
  1.1238 -        if (status.returns() == Returns_Sometimes) {
  1.1239 -            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1.1240 -        } else if (status.returns() == Returns_Never) {
  1.1241 -            if (!function_->type()->returnType()->isVoid())
  1.1242 -                cc_.reportError(node->pos(), Message_MissingReturnValue);
  1.1243 -        }
  1.1244 -    }
  1.1245 -
  1.1246 -    scope_ = NULL;
  1.1247 -    function_ = NULL;
  1.1248 -}
  1.1249 -
  1.1250 -void
  1.1251 -SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
  1.1252 -{
  1.1253 -    cc_.reportError(pos, Message_TypeMismatch,
  1.1254 -                    GetTypeName(actual),
  1.1255 -                    GetTypeName(given));
  1.1256 -}
  1.1257 -
  1.1258 -bool
  1.1259 -SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.1260 -                                           Handle<Type> argActual, bool forAssign)
  1.1261 -{
  1.1262 -    Local<Type> actual(zone_, argActual);
  1.1263 -    Local<Type> given(zone_, argGiven);
  1.1264 -
  1.1265 -    if (!given->isArray()) {
  1.1266 -        cc_.reportError(pos, Message_ExpectedArray);
  1.1267 -        return false;
  1.1268 -    }
  1.1269 -    if (given->levels() != actual->levels()) {
  1.1270 -        cc_.reportError(pos, Message_ArrayDimensionsMismatch);
  1.1271 -        return false;
  1.1272 -    }
  1.1273 -
  1.1274 -    unsigned level = 1;
  1.1275 -    while (given->isArray()) {
  1.1276 -        if (actual->isFixedLength()) {
  1.1277 -            if (forAssign) {
  1.1278 -                if (!given->isFixedLength()) {
  1.1279 -                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1280 -                    return false;
  1.1281 -                }
  1.1282 -
  1.1283 -                if (actual->isCharArray()) {
  1.1284 -                    // String assignment can have a truncated |given|.
  1.1285 -                    if (given->fixedLength() > actual->fixedLength()) {
  1.1286 -                        cc_.reportError(pos, Message_ArrayAssignmentTooBig);
  1.1287 -                        return false;
  1.1288 -                    }
  1.1289 -                } else {
  1.1290 -                    if (given->fixedLength() != actual->fixedLength()) {
  1.1291 -                        cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1292 -                        return false;
  1.1293 -                    }
  1.1294 -                }
  1.1295 -            }
  1.1296 -        } else if (given->isFixedLength()) {
  1.1297 -            // We do not allow assignments in the form:
  1.1298 -            //    [][] = [][Y]
  1.1299 -            //
  1.1300 -            // Otherwise, the following code could break the size guarantees
  1.1301 -            // of the right-hand side:
  1.1302 -            //
  1.1303 -            //   new x[][5];
  1.1304 -            //   new y[][];
  1.1305 -            //   new z[3];
  1.1306 -            //
  1.1307 -            //   y = x;
  1.1308 -            //   y[0] = z;
  1.1309 -            //   
  1.1310 -            // Now |x[0]| contains a 4-length array.
  1.1311 -            if (level > 1) {
  1.1312 -                cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.1313 -                return false;
  1.1314 -            }
  1.1315 -        }
  1.1316 -        given = given->contained();
  1.1317 -        actual = actual->contained();
  1.1318 -        level++;
  1.1319 -    }
  1.1320 -
  1.1321 -    return typeCheckAssignment(pos, given, actual, forAssign);
  1.1322 -}
  1.1323 -
  1.1324 -bool
  1.1325 -SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.1326 -                                      Handle<Type> argActual, bool forAssign)
  1.1327 -{
  1.1328 -    Local<Type> actual(zone_, argActual);
  1.1329 -    Local<Type> given(zone_, argGiven);
  1.1330 -
  1.1331 -    if (actual->isArray())
  1.1332 -        return typeCheckArrayAssignment(pos, given, actual, forAssign);
  1.1333 -
  1.1334 -    if (given->isArray()) {
  1.1335 -        cc_.reportError(pos, Message_CannotAssignArrayToScalar);
  1.1336 -        return false;
  1.1337 -    }
  1.1338 -
  1.1339 -    // The given type may not have been dereferenced.
  1.1340 -    if (given->isReference())
  1.1341 -        given = given->contained();
  1.1342 -    if (actual->isReference())
  1.1343 -        actual = actual->contained();
  1.1344 -
  1.1345 -    // We coerce unchecked to a few things.
  1.1346 -    if (actual->isUnchecked() || given->isUnchecked()) {
  1.1347 -        Type *check = actual->isUnchecked() ? given : actual;
  1.1348 -        if (check->isUnchecked() ||
  1.1349 -            check->isEnum() ||
  1.1350 -            check->isInt32() ||
  1.1351 -            check->isBool() ||
  1.1352 -            check->isFloat())
  1.1353 -        {
  1.1354 -            return true;
  1.1355 -        }
  1.1356 -        typeMismatch(pos, actual, given);
  1.1357 -        return false;
  1.1358 -    }
  1.1359 -
  1.1360 -    if (given->isFunction() && actual->isFunction()) {
  1.1361 -        if (!Type::Compare(given, actual)) {
  1.1362 -            typeMismatch(pos, actual, given);
  1.1363 -            return false;
  1.1364 -        }
  1.1365 -        return true;
  1.1366 -    }
  1.1367 -
  1.1368 -    if (actual->isEnum()) {
  1.1369 -        if (!given->isEnum() || actual != given) {
  1.1370 -            typeMismatch(pos, actual, given);
  1.1371 -            return false;
  1.1372 -        }
  1.1373 -        return true;
  1.1374 -    }
  1.1375 -
  1.1376 -    if (actual->isStruct()) {
  1.1377 -        if (!given->isStruct() || actual != given) {
  1.1378 -            typeMismatch(pos, actual, given);
  1.1379 -            return false;
  1.1380 -        }
  1.1381 -        return true;
  1.1382 -    }
  1.1383 -
  1.1384 -    if (given->isEnum() || given->isFunction() || given->isStruct()) {
  1.1385 -        typeMismatch(pos, actual, given);
  1.1386 -        return false;
  1.1387 -    }
  1.1388 -
  1.1389 -    // This coercion is trivial.
  1.1390 -    if (given->isBool() && actual->isInt32())
  1.1391 -        return true;
  1.1392 -
  1.1393 -    if (given->primitive() != actual->primitive()) {
  1.1394 -        typeMismatch(pos, actual, given);
  1.1395 -        return false;
  1.1396 -    }
  1.1397 -
  1.1398 -    return true;
  1.1399 -}
  1.1400 -
  1.1401 -bool
  1.1402 -SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  1.1403 -{
  1.1404 -    return typeCheckAssignment(node->pos(), given, actual, false);
  1.1405 -}
  1.1406 -
  1.1407 -bool
  1.1408 -SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
  1.1409 -{
  1.1410 -    if (type->parameters()->length() == actual)
  1.1411 -        return true;
  1.1412 -
  1.1413 -    if (actual > type->parameters()->length()) {
  1.1414 -        if (!type->isNative() || !type->isNativeVariadic())
  1.1415 -            return false;
  1.1416 -        return true;
  1.1417 -    }
  1.1418 -
  1.1419 -    if (!type->defaults())
  1.1420 -        return false;
  1.1421 -
  1.1422 -    // Missing arguments. See if there's a default argument for each missing
  1.1423 -    // actual.
  1.1424 -    for (unsigned i = actual; i < type->parameters()->length(); i++) {
  1.1425 -        if (!type->defaults()->at(i))
  1.1426 -            return false;
  1.1427 -    }
  1.1428 -
  1.1429 -    return true;
  1.1430 -}
  1.1431 -
  1.1432 -void
  1.1433 -SemanticAnalysis::visit(CallExpression *node)
  1.1434 -{
  1.1435 -    Local<Type> type(zone_, visitForLoad(node->callee()));
  1.1436 -    if (!type)
  1.1437 -        return;
  1.1438 -
  1.1439 -    if (!type->isFunction()) {
  1.1440 -        cc_.reportError(node->pos(), Message_CalleeNotFunction);
  1.1441 -        return;
  1.1442 -    }
  1.1443 -
  1.1444 -    if (!checkArgumentCount(type, node->arguments()->length())) {
  1.1445 -        cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  1.1446 -        return;
  1.1447 -    }
  1.1448 -
  1.1449 -    // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  1.1450 -    // if (fun->isForward()) {
  1.1451 -    //     cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  1.1452 -    //     return;
  1.1453 -    // }
  1.1454 -
  1.1455 -    for (unsigned i = 0; i < node->arguments()->length(); i++) {
  1.1456 -        // Note: we don't compute references unless the callee needs a
  1.1457 -        // reference type.
  1.1458 -        Expression *expression = node->arguments()->at(i);
  1.1459 -        Local<Type> given(zone_, visitAndApplyType(expression));
  1.1460 -        if (!given)
  1.1461 -            return;
  1.1462 -
  1.1463 -        // Since we skip a load, check for a call expression that returns void.
  1.1464 -        if (given->isVoid()) {
  1.1465 -            assert(expression->isCallExpression());
  1.1466 -            CallExpression *call = expression->toCallExpression();
  1.1467 -            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1.1468 -            return;
  1.1469 -        }
  1.1470 -        
  1.1471 -        bool mustComputeReference;
  1.1472 -        if (i >= type->parameters()->length()) {
  1.1473 -            // Special handling for natives. Arguments past the formal must
  1.1474 -            // always have references computed. However, arrays are already
  1.1475 -            // references for natives.  
  1.1476 -            assert(type->isNative() && type->isNativeVariadic());
  1.1477 -            mustComputeReference = !given->isReference() && !given->isArray();
  1.1478 -        } else {
  1.1479 -            Local<Type> actual(zone_, type->parameterAt(i));
  1.1480 -
  1.1481 -            if (expression->isIndexExpression()) {
  1.1482 -                // Disabled until we can make it work.
  1.1483 -#if 0
  1.1484 -                if (actual->isArray()) {
  1.1485 -                    // We special case the ability to pass x[y] into x[], which
  1.1486 -                    // creates an array slice. We only do this if we know the
  1.1487 -                    // assignment would otherwise not type-check.
  1.1488 -                    IndexExpression *index = expression->toIndexExpression();
  1.1489 -                    if (index->left()->type()->levels() == actual->levels())
  1.1490 -                        given = index->left()->type();
  1.1491 -                } else
  1.1492 -#endif
  1.1493 -                if (actual->isReference()) {
  1.1494 -                    cc_.reportError(expression->pos(), Message_CannotComputeIndexRef);
  1.1495 -                    return;
  1.1496 -                }
  1.1497 -            }
  1.1498 -
  1.1499 -            if (!typeCheckParameter(expression, given, actual))
  1.1500 -                return;
  1.1501 -            mustComputeReference = actual->isReference() && !given->isReference();
  1.1502 -        }
  1.1503 -
  1.1504 -        // If the actual is a reference, and the given is not, we'll need to
  1.1505 -        // compute a reference, which may be allocated on the stack.
  1.1506 -        if (mustComputeReference)
  1.1507 -            scope_->setUsesLifoHeap();
  1.1508 -    }
  1.1509 -
  1.1510 -    node->setType(type->returnType());
  1.1511 -}
  1.1512 -
  1.1513 -void
  1.1514 -SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
  1.1515 -{
  1.1516 -    if (other.returns() < status().returns())
  1.1517 -        return;
  1.1518 -
  1.1519 -    if (other.terminates())
  1.1520 -        terminate(other.returns());
  1.1521 -    else
  1.1522 -        returns(other.returns());
  1.1523 -}
  1.1524 -
  1.1525 -void
  1.1526 -SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  1.1527 -{
  1.1528 -    // If both sides terminate in a return, we consider this a return as well.
  1.1529 -    if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  1.1530 -        terminate(Returns_Always);
  1.1531 -        return;
  1.1532 -    }
  1.1533 -
  1.1534 -    ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  1.1535 -                          ? Returns_Never
  1.1536 -                          : Returns_Sometimes;
  1.1537 -
  1.1538 -    if (left.terminates() && right.terminates())
  1.1539 -        terminate(status);
  1.1540 -    else
  1.1541 -        returns(status);
  1.1542 -}
  1.1543 -
  1.1544 -void
  1.1545 -SemanticAnalysis::visit(IfStatement *node)
  1.1546 -{
  1.1547 -    Local<Type> type(zone_, visitForLoad(node->condition()));
  1.1548 -    if (!type)
  1.1549 -        return;
  1.1550 -
  1.1551 -    if (!canTest(node, type))
  1.1552 -        return;
  1.1553 -
  1.1554 -    ControlStatus trueBranch = visitForControl(node->ifTrue());
  1.1555 -    ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  1.1556 -
  1.1557 -    if (node->ifFalse())
  1.1558 -        falseBranch = visitForControl(node->ifFalse());
  1.1559 -
  1.1560 -    control_->merge(trueBranch, falseBranch);
  1.1561 -}
  1.1562 -
  1.1563 -void
  1.1564 -SemanticAnalysis::visit(IndexExpression *node)
  1.1565 -{
  1.1566 -    Local<Type> left(zone_, visitForLoad(node->left()));
  1.1567 -    Local<Type> right(zone_, visitForLoad(node->right()));
  1.1568 -
  1.1569 -    if (!left || !right)
  1.1570 -        return;
  1.1571 -
  1.1572 -    if (!right->isInt32() && !right->isEnum()) {
  1.1573 -        cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  1.1574 -        return;
  1.1575 -    }
  1.1576 -    if (!left->isArray()) {
  1.1577 -        cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  1.1578 -        return;
  1.1579 -    }
  1.1580 -
  1.1581 -    // Note: char arrays are automatically up-casted to return an int32.
  1.1582 -    if (left->isCharArray())
  1.1583 -        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.1584 -    else
  1.1585 -        node->setType(left->contained());
  1.1586 -}
  1.1587 -
  1.1588 -void
  1.1589 -SemanticAnalysis::visit(FieldExpression *node)
  1.1590 -{
  1.1591 -    Local<Type> left(zone_, visitForLoad(node->left()));
  1.1592 -    if (!left)
  1.1593 -        return;
  1.1594 -
  1.1595 -    if (!left->isStruct()) {
  1.1596 -        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.1597 -                        GetTypeName(left));
  1.1598 -        return;
  1.1599 -    }
  1.1600 -
  1.1601 -    Local<String> field(zone_, node->field());
  1.1602 -
  1.1603 -    unsigned offset;
  1.1604 -    Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
  1.1605 -    if (!desc) {
  1.1606 -        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.1607 -                        GetTypeName(left));
  1.1608 -        return;
  1.1609 -    }
  1.1610 -
  1.1611 -    node->setFieldIndex(offset);
  1.1612 -    node->setType(desc->type());
  1.1613 -}
  1.1614 -
  1.1615 -void
  1.1616 -SemanticAnalysis::visit(EnumStatement *node)
  1.1617 -{
  1.1618 -    Local<String> name(zone_, node->name());
  1.1619 -    Local<Type> type(zone_);
  1.1620 -    if (name)
  1.1621 -        type = zone_->types()->newEnum(name);
  1.1622 -    else
  1.1623 -        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.1624 -
  1.1625 -    if (!type)
  1.1626 -        return;
  1.1627 -
  1.1628 -    if (node->decl())
  1.1629 -        node->decl()->setType(type);
  1.1630 -
  1.1631 -    int value = 0;
  1.1632 -    for (size_t i = 0; i < node->entries()->length(); i++) {
  1.1633 -        EnumStatement::Entry &entry = node->entries()->at(i);
  1.1634 -
  1.1635 -        BoxedPrimitive box = BoxedPrimitive::Int(value);
  1.1636 -        if (entry.expr) {
  1.1637 -            entry.expr->accept(this);
  1.1638 -            if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
  1.1639 -                cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1.1640 -                return;
  1.1641 -            }
  1.1642 -
  1.1643 -            assert(box.type() == PrimitiveType_Int32);
  1.1644 -            value = box.toInt();
  1.1645 -        }
  1.1646 -
  1.1647 -#if 0
  1.1648 -        entry.name->set(type, box);
  1.1649 -#endif
  1.1650 -        value++;
  1.1651 -    }
  1.1652 -}
  1.1653 -
  1.1654 -static int
  1.1655 -SortCaseIntValues(const void *p1, const void *p2)
  1.1656 -{
  1.1657 -    CaseValue *v1 = (CaseValue *)p1;
  1.1658 -    CaseValue *v2 = (CaseValue *)p2;
  1.1659 -
  1.1660 -    return v1->box.toInt() - v2->box.toInt();
  1.1661 -}
  1.1662 -
  1.1663 -void
  1.1664 -SemanticAnalysis::visit(SwitchStatement *node)
  1.1665 -{
  1.1666 -    Local<Type> caseType(zone_, visitForLoad(node->expression()));
  1.1667 -    if (!caseType)
  1.1668 -        return;
  1.1669 -
  1.1670 -    if (!caseType->isEnum() && !caseType->isInt32()) {
  1.1671 -        cc_.reportError(node->pos(), Message_CaseMustBeInteger);
  1.1672 -        return;
  1.1673 -    }
  1.1674 -
  1.1675 -    PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
  1.1676 -    ControlStatus status = ControlStatus(false, Returns_Never);
  1.1677 -
  1.1678 -    Local<Type> check(zone_);
  1.1679 -    for (size_t i = 0; i < node->cases()->length(); i++) {
  1.1680 -        Case *c = node->cases()->at(i);
  1.1681 -
  1.1682 -        check = visitForLoad(c->expression());
  1.1683 -        if (!check)
  1.1684 -            return;
  1.1685 -
  1.1686 -        if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
  1.1687 -            return;
  1.1688 -
  1.1689 -        CaseValue v(i);
  1.1690 -        if (!EvaluateForConstant(c->expression(), &v.box)) {
  1.1691 -            cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
  1.1692 -            return;
  1.1693 -        }
  1.1694 -        if (!values->append(v))
  1.1695 -            return;
  1.1696 -
  1.1697 -        if (c->others()) {
  1.1698 -            for (size_t j = 0; j < c->others()->length(); j++) {
  1.1699 -                Expression *expr = c->others()->at(j);
  1.1700 -                check = visitForLoad(expr);
  1.1701 -                if (!check)
  1.1702 -                    return;
  1.1703 -
  1.1704 -                if (!typeCheckAssignment(expr->pos(), check, caseType, false))
  1.1705 -                    return;
  1.1706 -
  1.1707 -                CaseValue v(i);
  1.1708 -                if (!EvaluateForConstant(expr, &v.box)) {
  1.1709 -                    cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
  1.1710 -                    return;
  1.1711 -                }
  1.1712 -                if (!values->append(v))
  1.1713 -                    return;
  1.1714 -            }
  1.1715 -        }
  1.1716 -
  1.1717 -        ControlStatus latest = visitForControl(c->statement());
  1.1718 -
  1.1719 -        if (i != 0)
  1.1720 -            control_->merge(status, latest);
  1.1721 -
  1.1722 -        status = latest;
  1.1723 -    }
  1.1724 -
  1.1725 -    if (node->defaultCase()) {
  1.1726 -        ControlStatus latest = visitForControl(node->defaultCase());
  1.1727 -
  1.1728 -        if (node->cases()->length()) {
  1.1729 -            // If we had any other cases, we must merge.
  1.1730 -            control_->merge(status, latest);
  1.1731 -        } else {
  1.1732 -            // Otherwise, control-flow always flows through here.
  1.1733 -            control_->inherit(latest);
  1.1734 -        }
  1.1735 -    } else if (node->cases()->length()) {
  1.1736 -        control_->merge(status, ControlStatus(false, Returns_Never));
  1.1737 -    }
  1.1738 -
  1.1739 -    if (values->length() > 1) {
  1.1740 -        qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
  1.1741 -
  1.1742 -        for (size_t i = 1; i < values->length(); i++) {
  1.1743 -            CaseValue &prev = values->at(i - 1);
  1.1744 -            CaseValue &cur = values->at(i);
  1.1745 -            if (prev.box.toInt() == cur.box.toInt()) {
  1.1746 -                cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
  1.1747 -                return;
  1.1748 -            }
  1.1749 -        }
  1.1750 -    }
  1.1751 -
  1.1752 -    node->setCaseValueList(values);
  1.1753 -}
  1.1754 -
  1.1755 -void
  1.1756 -SemanticAnalysis::visit(StructureStatement *node)
  1.1757 -{
  1.1758 -#if 0
  1.1759 -    // If this node already has a type, it was pre-analyzed, so skip it.
  1.1760 -    if (node->decl()->type())
  1.1761 -        return;
  1.1762 -
  1.1763 -    FieldList *fields = node->fields();
  1.1764 -    Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
  1.1765 -    if (!desctable)
  1.1766 -        return;
  1.1767 -
  1.1768 -    Vector<unsigned> composedList;
  1.1769 -    StructureBufferBuilder builder;
  1.1770 -
  1.1771 -    Local<Type> type(zone_);
  1.1772 -    Local<String> name(zone_);
  1.1773 -    Local<Descriptor> desc(zone_);
  1.1774 -    for (size_t i = 0; i < fields->length(); i++) {
  1.1775 -        StructureStatement::Field *field = fields->at(i);
  1.1776 -
  1.1777 -        type = bindType(field->pos(), field->type());
  1.1778 -        if (!type)
  1.1779 -            return;
  1.1780 -
  1.1781 -        if (field->dimensions()) {
  1.1782 -            type = buildArrayType(type, field->dimensions(), false);
  1.1783 -            if (!type)
  1.1784 -                return;
  1.1785 -
  1.1786 -            if (!ArrayMap::Attach(zone_, type))
  1.1787 -                return;
  1.1788 -        }
  1.1789 -
  1.1790 -        if (IsScalarString(type)) {
  1.1791 -            cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
  1.1792 -            return;
  1.1793 -        }
  1.1794 -
  1.1795 -        unsigned offset;
  1.1796 -        if (!builder.add(type, &offset))
  1.1797 -            return;
  1.1798 -
  1.1799 -        name = field->name();
  1.1800 -        desc = Descriptor::New(zone_, name, type, offset);
  1.1801 -        if (!desc)
  1.1802 -            return;
  1.1803 -
  1.1804 -        desctable->set(zone_, i, desc);
  1.1805 -
  1.1806 -        if (type->isStruct() || type->isArray()) {
  1.1807 -            if (!composedList.append(i))
  1.1808 -                return;
  1.1809 -        }
  1.1810 -    }
  1.1811 -
  1.1812 -    Local<FixedArray> composed(zone_);
  1.1813 -    if (composedList.length()) {
  1.1814 -        composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
  1.1815 -        if (!composed)
  1.1816 -            return;
  1.1817 -
  1.1818 -        for (unsigned i = 0; i < composedList.length(); i++)
  1.1819 -            composed->set(zone_, i, desctable->at(i));
  1.1820 -    }
  1.1821 -
  1.1822 -    Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
  1.1823 -    if (!map)
  1.1824 -        return;
  1.1825 -
  1.1826 -    name = node->decl()->name();
  1.1827 -    type = zone_->types()->newStruct(name, desctable, map);
  1.1828 -    if (!type)
  1.1829 -        return;
  1.1830 -
  1.1831 -    map->setType(type);
  1.1832 -    node->decl()->setType(type);
  1.1833 -#endif
  1.1834 -}
  1.1835 -
  1.1836 -void
  1.1837 -SemanticAnalysis::visit(StringLiteral *node)
  1.1838 -{
  1.1839 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1.1840 -    if (!type)
  1.1841 -        return;
  1.1842 -
  1.1843 -    type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1.1844 -    if (!type)
  1.1845 -        return;
  1.1846 -
  1.1847 -    node->setType(type);
  1.1848 -}
  1.1849 -
  1.1850 -void
  1.1851 -SemanticAnalysis::visit(FloatLiteral *node)
  1.1852 -{
  1.1853 -    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1.1854 -    if (!type)
  1.1855 -        return;
  1.1856 -
  1.1857 -    node->setType(type);
  1.1858 -}
  1.1859 -
  1.1860 -void
  1.1861 -SemanticAnalysis::visit(BreakStatement *node)
  1.1862 -{
  1.1863 -    if (!loop_) {
  1.1864 -        cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1.1865 -        return;
  1.1866 -    }
  1.1867 -
  1.1868 -    // Note: ignore breaks that occur in unreachable control-flow.
  1.1869 -    if (!control_->status().terminates())
  1.1870 -        loop_->addBreak();
  1.1871 -
  1.1872 -    control_->terminate(Returns_Never);
  1.1873 -}
  1.1874 -
  1.1875 -void
  1.1876 -SemanticAnalysis::visit(ContinueStatement *node)
  1.1877 -{
  1.1878 -    if (!loop_) {
  1.1879 -        cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1.1880 -        return;
  1.1881 -    }
  1.1882 -
  1.1883 -    // Note: ignore continues that occur in unreachable control-flow.
  1.1884 -    if (!control_->status().terminates())
  1.1885 -        loop_->addContinue();
  1.1886 -
  1.1887 -    control_->terminate(Returns_Never);
  1.1888 -}
  1.1889 -
  1.1890 -void
  1.1891 -SemanticAnalysis::visit(ArrayLiteral *node)
  1.1892 -{
  1.1893 -    // We should never visit this.
  1.1894 -    cc_.reportError(node->pos(), Message_UnexpectedArrayLiteral);
  1.1895 -}
  1.1896 -
  1.1897 -void
  1.1898 -SemanticAnalysis::visit(ImportStatement *node)
  1.1899 -{
  1.1900 -}
  1.1901 -
  1.1902 +/* vim: set ts=4 sw=4 tw=99 et:
  1.1903 + *
  1.1904 + * Copyright (C) 2012 David Anderson
  1.1905 + *
  1.1906 + * This file is part of JITCraft.
  1.1907 + *
  1.1908 + * JITCraft is free software: you can redistribute it and/or modify it under
  1.1909 + * the terms of the GNU General Public License as published by the Free
  1.1910 + * Software Foundation, either version 3 of the License, or (at your option)
  1.1911 + * any later version.
  1.1912 + * 
  1.1913 + * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
  1.1914 + * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  1.1915 + * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  1.1916 + *
  1.1917 + * You should have received a copy of the GNU General Public License along with
  1.1918 + * JITCraft. If not, see http://www.gnu.org/licenses/.
  1.1919 + */
  1.1920 +#include <string.h>
  1.1921 +#include "SemanticAnalysis.h"
  1.1922 +#include "../Types.h"
  1.1923 +#include "../Zone.h"
  1.1924 +#include "../TypeManager.h"
  1.1925 +#include "../Strings.h"
  1.1926 +#include "../Box.h"
  1.1927 +#include "../Array.h"
  1.1928 +#include "../Heap-inl.h"
  1.1929 +#include "Scopes.h"
  1.1930 +#include "NameBinding.h"
  1.1931 +
  1.1932 +using namespace ke;
  1.1933 +
  1.1934 +SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
  1.1935 +  : zone_(zone),
  1.1936 +    cc_(cc),
  1.1937 +    tree_(tree),
  1.1938 +    scope_(NULL),
  1.1939 +    loop_(NULL)
  1.1940 +{
  1.1941 +}
  1.1942 +
  1.1943 +bool
  1.1944 +SemanticAnalysis::analyze()
  1.1945 +{
  1.1946 +    assert(false);
  1.1947 +    return false;
  1.1948 +}
  1.1949 +
  1.1950 +
  1.1951 +#if 0
  1.1952 +
  1.1953 +static inline bool
  1.1954 +IsPrimitiveType(Type *type, PrimitiveType primitive)
  1.1955 +{
  1.1956 +    if (!type)
  1.1957 +        return false;
  1.1958 +
  1.1959 +    if (!type->isPrimitive())
  1.1960 +        return false;
  1.1961 +
  1.1962 +    return primitive == type->primitive();
  1.1963 +}
  1.1964 +
  1.1965 +static inline bool
  1.1966 +EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
  1.1967 +                        BoxedPrimitive *out)
  1.1968 +{
  1.1969 +    switch (kind) {
  1.1970 +      case TOK_PLUS:
  1.1971 +        *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
  1.1972 +        return true;
  1.1973 +
  1.1974 +      case TOK_SHL:
  1.1975 +        *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
  1.1976 +        return true;
  1.1977 +
  1.1978 +      default:
  1.1979 +        return false;
  1.1980 +    }
  1.1981 +}
  1.1982 +
  1.1983 +static inline bool
  1.1984 +EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
  1.1985 +{
  1.1986 +  switch (kind) {
  1.1987 +    case TOK_MINUS:
  1.1988 +      *out = BoxedPrimitive::Int(-inner.toInt());
  1.1989 +      return true;
  1.1990 +
  1.1991 +    default:
  1.1992 +      return false;
  1.1993 +  }
  1.1994 +}
  1.1995 +
  1.1996 +static bool
  1.1997 +EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
  1.1998 +{
  1.1999 +    switch (expression->kind()) {
  1.2000 +      case AstNode::kBinaryExpression:
  1.2001 +      {
  1.2002 +        BoxedPrimitive left;
  1.2003 +        BoxedPrimitive right;
  1.2004 +        BinaryExpression *b = expression->toBinaryExpression();
  1.2005 +        if (!EvaluateForConstant(b->left(), &left) ||
  1.2006 +            !EvaluateForConstant(b->right(), &right))
  1.2007 +        {
  1.2008 +            return false;
  1.2009 +        }
  1.2010 +        return EvaluateBinaryOperation(b->token(), left, right, out);
  1.2011 +      }
  1.2012 +
  1.2013 +      case AstNode::kUnaryExpression:
  1.2014 +      {
  1.2015 +        BoxedPrimitive inner;
  1.2016 +        UnaryExpression *u = expression->toUnaryExpression();
  1.2017 +        if (!EvaluateForConstant(u->expression(), &inner))
  1.2018 +            return false;
  1.2019 +        return EvaluateUnaryOperation(u->token(), inner, out);
  1.2020 +      }
  1.2021 +
  1.2022 +      case AstNode::kNameProxy:
  1.2023 +      {
  1.2024 +        NameProxy *proxy = expression->toNameProxy();
  1.2025 +        if (proxy->binding()->kind() != BoundName::CONSTANT)
  1.2026 +            return false;
  1.2027 +
  1.2028 +        NamedConstant *c = proxy->binding()->toNamedConstant();
  1.2029 +        if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
  1.2030 +            return false;
  1.2031 +
  1.2032 +        *out = c->value();
  1.2033 +        return true;
  1.2034 +      }
  1.2035 +
  1.2036 +      case AstNode::kBooleanLiteral:
  1.2037 +        *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
  1.2038 +        return true;
  1.2039 +
  1.2040 +      case AstNode::kIntegerLiteral:
  1.2041 +        *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
  1.2042 +        return true;
  1.2043 +
  1.2044 +      default:
  1.2045 +        return false;
  1.2046 +    }
  1.2047 +}
  1.2048 +
  1.2049 +SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
  1.2050 +  : zone_(zone),
  1.2051 +    cc_(cc),
  1.2052 +    tree_(tree),
  1.2053 +    scope_(NULL),
  1.2054 +    loop_(NULL)
  1.2055 +{
  1.2056 +}
  1.2057 +
  1.2058 +bool
  1.2059 +SemanticAnalysis::analyze()
  1.2060 +{
  1.2061 +    if (cc_.failures())
  1.2062 +        return false;
  1.2063 +
  1.2064 +    scope_ = tree_->globalScope();
  1.2065 +    assert(scope_->kind() == Scope::GLOBAL);
  1.2066 +
  1.2067 +    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  1.2068 +        Statement *statement = tree_->statements()->at(i);
  1.2069 +        if (statement->isFunctionStatement()) {
  1.2070 +            FunctionStatement *funstmt = statement->toFunctionStatement();
  1.2071 +            if (!preanalyze(funstmt))
  1.2072 +                return false;
  1.2073 +        } else if (statement->isEnumStatement()) {
  1.2074 +            EnumStatement *enumstmt = statement->toEnumStatement();
  1.2075 +
  1.2076 +            // We pre-fill global enum types, since they may occur in function
  1.2077 +            // signatures. This should probably be somewhere else...
  1.2078 +            enumstmt->accept(this);
  1.2079 +        } else if (statement->isStructureStatement()) {
  1.2080 +            StructureStatement *node = statement->toStructureStatement();
  1.2081 +            node->accept(this);
  1.2082 +            if (!node->decl()->type())
  1.2083 +                return false;
  1.2084 +        } else if (statement->isFunctionTypeStatement()) {
  1.2085 +            FunctionTypeStatement *node = statement->toFunctionTypeStatement();
  1.2086 +            node->accept(this);
  1.2087 +            if (!node->decl()->type())
  1.2088 +                return false;
  1.2089 +        }
  1.2090 +    }
  1.2091 +
  1.2092 +    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  1.2093 +        Statement *statement = tree_->statements()->at(i);
  1.2094 +
  1.2095 +        // We can't double-process these. Maybe put this check somewhere else.
  1.2096 +        if (statement->isEnumStatement())
  1.2097 +            continue;
  1.2098 +
  1.2099 +        statement->accept(this);
  1.2100 +    }
  1.2101 +
  1.2102 +    if (!determineLiveFunctions())
  1.2103 +        return false;
  1.2104 +
  1.2105 +    return !cc_.failures();
  1.2106 +}
  1.2107 +
  1.2108 +bool
  1.2109 +SemanticAnalysis::determineLiveFunctions()
  1.2110 +{
  1.2111 +    Vector<NamedFunction *> worklist;
  1.2112 +
  1.2113 +    // Add the root set.
  1.2114 +    for (size_t i = 0; i < tree_->statements()->length(); i++) {
  1.2115 +        Statement *statement = tree_->statements()->at(i);
  1.2116 +        if (!statement->isFunctionStatement())
  1.2117 +            continue;
  1.2118 +
  1.2119 +        FunctionStatement *stmt = statement->toFunctionStatement();
  1.2120 +        NamedFunction  *fun = stmt->fun();
  1.2121 +        if (!fun->used())
  1.2122 +            continue;
  1.2123 +
  1.2124 +        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
  1.2125 +            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
  1.2126 +
  1.2127 +            // Names in these lists are always unused, however, we mark them
  1.2128 +            // as used while inserting into the work queue, to avoid double-
  1.2129 +            // insertion.
  1.2130 +            if (name->used())
  1.2131 +                continue;
  1.2132 +
  1.2133 +            if (!worklist.append(name))
  1.2134 +                return false;
  1.2135 +
  1.2136 +            name->setUsed();
  1.2137 +        }
  1.2138 +    }
  1.2139 +
  1.2140 +    while (!worklist.empty()) {
  1.2141 +        NamedFunction *fun = worklist.popCopy();
  1.2142 +
  1.2143 +        for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
  1.2144 +            NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
  1.2145 +            if (name->used())
  1.2146 +                continue;
  1.2147 +            if (!worklist.append(name))
  1.2148 +                return false;
  1.2149 +            name->setUsed();
  1.2150 +        }
  1.2151 +    }
  1.2152 +
  1.2153 +    return true;
  1.2154 +}
  1.2155 +
  1.2156 +Type *
  1.2157 +SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
  1.2158 +{
  1.2159 +    if (!name)
  1.2160 +        return zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.2161 +
  1.2162 +    if (name->kind() == BoundName::UNBOUND) {
  1.2163 +        cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
  1.2164 +        return NULL;
  1.2165 +    }
  1.2166 +
  1.2167 +    if (name->kind() != BoundName::TYPE) {
  1.2168 +        cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
  1.2169 +        return NULL;
  1.2170 +    }
  1.2171 +
  1.2172 +    if (!name->type())
  1.2173 +        return NULL;
  1.2174 +
  1.2175 +    return name->type();
  1.2176 +}
  1.2177 +
  1.2178 +Type *
  1.2179 +SemanticAnalysis::visitAndApplyType(Expression *expression)
  1.2180 +{
  1.2181 +    expression->accept(this);
  1.2182 +    return expression->type();
  1.2183 +}
  1.2184 +
  1.2185 +Type *
  1.2186 +SemanticAnalysis::visitForLoad(Expression *expression)
  1.2187 +{
  1.2188 +    Local<Type> type(zone_, visitAndApplyType(expression));
  1.2189 +    if (!type)
  1.2190 +        return NULL;
  1.2191 +
  1.2192 +    if (type->isReference()) {
  1.2193 +        expression->setType(type->contained());
  1.2194 +    } else if (expression->isCallExpression()) {
  1.2195 +        if (type->isVoid()) {
  1.2196 +            CallExpression *call = expression->toCallExpression();
  1.2197 +            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1.2198 +            return NULL;
  1.2199 +        }
  1.2200 +    }
  1.2201 +
  1.2202 +    return expression->type();
  1.2203 +}
  1.2204 +
  1.2205 +void
  1.2206 +SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
  1.2207 +{
  1.2208 +    const char *op = TokenNames[token];
  1.2209 +    const char *name = GetTypeName(type);
  1.2210 +
  1.2211 +    cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
  1.2212 +}
  1.2213 +
  1.2214 +void
  1.2215 +SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
  1.2216 +{
  1.2217 +    const char *op = TokenNames[token];
  1.2218 +    const char *leftName = GetTypeName(left);
  1.2219 +    const char *rightName = GetTypeName(right);
  1.2220 +
  1.2221 +    cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
  1.2222 +}
  1.2223 +
  1.2224 +Type *
  1.2225 +SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
  1.2226 +{
  1.2227 +    if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
  1.2228 +        (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
  1.2229 +    {
  1.2230 +        // If either side is a float, the other side must be a float or int.
  1.2231 +        if (left->isFloat() || right->isFloat()) {
  1.2232 +            Type *floatType = left->isFloat() ? left : right;
  1.2233 +            Type *other = left->isFloat() ? right : left;
  1.2234 +            if (other->isFloat() || other->isInt32())
  1.2235 +                return floatType;
  1.2236 +        }
  1.2237 +    }
  1.2238 +
  1.2239 +    if (token == TOK_OR || token == TOK_AND) {
  1.2240 +        if (!canTest(node, left) || !canTest(node, right))
  1.2241 +            return NULL;
  1.2242 +        return zone_->types()->getPrimitive(PrimitiveType_Bool);
  1.2243 +    }
  1.2244 +
  1.2245 +    if (token >= TOK_EQUALS && token <= TOK_GE) {
  1.2246 +        if ((left->isFloat() || left->isInt32()) &&
  1.2247 +            (right->isFloat() || right->isInt32()))
  1.2248 +        {
  1.2249 +            return zone_->types()->getPrimitive(PrimitiveType_Bool);
  1.2250 +        }
  1.2251 +        binaryTypeError(node, token, left, right);
  1.2252 +        return NULL;
  1.2253 +    }
  1.2254 +
  1.2255 +    if (!left->isInt32() || !right->isInt32()) {
  1.2256 +        binaryTypeError(node, token, left, right);
  1.2257 +        return NULL;
  1.2258 +    }
  1.2259 +
  1.2260 +    return left;
  1.2261 +}
  1.2262 +
  1.2263 +bool
  1.2264 +SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
  1.2265 +{
  1.2266 +    if (!type->isPrimitive() && !type->isEnum()) {
  1.2267 +        cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
  1.2268 +        return false;
  1.2269 +    }
  1.2270 +    return true;
  1.2271 +}
  1.2272 +
  1.2273 +Type *
  1.2274 +SemanticAnalysis::visitForLValue(Expression *expression)
  1.2275 +{
  1.2276 +    if (expression->isIndexExpression()) {
  1.2277 +        Type *type = visitAndApplyType(expression);
  1.2278 +        if (!type)
  1.2279 +            return NULL;
  1.2280 +
  1.2281 +        // if (type->isConst()) {
  1.2282 +        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
  1.2283 +        //     return NULL;
  1.2284 +        // }
  1.2285 +
  1.2286 +        return type;
  1.2287 +    }
  1.2288 +
  1.2289 +    if (expression->isFieldExpression()) {
  1.2290 +        Type *type = visitAndApplyType(expression);
  1.2291 +        if (!type)
  1.2292 +            return NULL;
  1.2293 +
  1.2294 +        // if (expression->toFieldExpression()->left()->type()->isConst()) {
  1.2295 +        //     cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
  1.2296 +        //     return NULL;
  1.2297 +        // }
  1.2298 +
  1.2299 +        return type;
  1.2300 +    }
  1.2301 +
  1.2302 +    if (!expression->isNameProxy()) {
  1.2303 +        cc_.reportError(expression->pos(), Message_ExpectedLValue);
  1.2304 +        return NULL;
  1.2305 +    }
  1.2306 +
  1.2307 +    NameProxy *proxy = expression->toNameProxy();
  1.2308 +    if (!proxy->binding()->kind() == BoundName::VARIABLE) {
  1.2309 +        cc_.reportError(expression->pos(), Message_ExpectedLValue);
  1.2310 +        return NULL;
  1.2311 +    }
  1.2312 +
  1.2313 +    Variable *var = proxy->binding()->toVariable();
  1.2314 +    if (!var->type())
  1.2315 +        return NULL;
  1.2316 +
  1.2317 +    if  (var->type()->isReference()) {
  1.2318 +        if (var->type()->isConst()) {
  1.2319 +            cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
  1.2320 +            return NULL;
  1.2321 +        }
  1.2322 +        return var->type()->contained();
  1.2323 +    }
  1.2324 +    return var->type();
  1.2325 +}
  1.2326 +
  1.2327 +SemanticAnalysis::ControlStatus
  1.2328 +SemanticAnalysis::visitForControl(Statement *statement)
  1.2329 +{
  1.2330 +    ControlScope scope(&control_);
  1.2331 +    statement->accept(this);
  1.2332 +    return scope.status();
  1.2333 +}
  1.2334 +
  1.2335 +void
  1.2336 +SemanticAnalysis::visit(NameProxy *name)
  1.2337 +{
  1.2338 +    BoundName *binding = name->binding();
  1.2339 +
  1.2340 +    if (binding->scope()->kind() == Scope::GLOBAL) {
  1.2341 +        if (!function_ || function_->isPublic()) {
  1.2342 +            // Whatever we're referencing must be kept alive no matter what.
  1.2343 +            // As such, we simply mark it used, and don't do anything special.
  1.2344 +            binding->setUsed();
  1.2345 +        } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
  1.2346 +            // Otherwise, we're inside a normal stock or function. Since we
  1.2347 +            // don't really know if we've been used yet, we shouldn't
  1.2348 +            // prematurely references as alive. Instead, we keep a list of
  1.2349 +            // which names have been used, so we can mark them later if needed.
  1.2350 +            //
  1.2351 +            // Note that we skip this step if the binding is already in the
  1.2352 +            // root set.
  1.2353 +            if (!function_->addUsedGlobal(binding))
  1.2354 +                return;
  1.2355 +        }
  1.2356 +    }
  1.2357 +
  1.2358 +    name->setType(binding->type());
  1.2359 +}
  1.2360 +
  1.2361 +void
  1.2362 +SemanticAnalysis::visit(Assignment *node)
  1.2363 +{
  1.2364 +    Local<Type> exprType(zone_, visitForLoad(node->expression()));
  1.2365 +    if (!exprType)
  1.2366 +        return ;
  1.2367 +
  1.2368 +    Local<Type> type(zone_, visitForLValue(node->lvalue()));
  1.2369 +    if (!type)
  1.2370 +        return;
  1.2371 +
  1.2372 +    if (node->token() != TOK_ASSIGN) {
  1.2373 +        if (!typeCheckBinary(node, node->token(), type, exprType))
  1.2374 +            return;
  1.2375 +    }
  1.2376 +
  1.2377 +    if (!typeCheckAssignment(node->pos(), exprType, type, true))
  1.2378 +        return;
  1.2379 +
  1.2380 +    node->setType(type);
  1.2381 +}
  1.2382 +
  1.2383 +void
  1.2384 +SemanticAnalysis::visit(IncDecExpression *node)
  1.2385 +{
  1.2386 +    Local<Type> type(zone_, visitForLValue(node->expression()));
  1.2387 +    if (!type)
  1.2388 +        return;
  1.2389 +
  1.2390 +    assert(!type->isReference());
  1.2391 +
  1.2392 +    if (!type->isInt32() && !type->isFloat()) {
  1.2393 +        unaryTypeError(node, node->token(), type);
  1.2394 +        return;
  1.2395 +    }
  1.2396 +
  1.2397 +    node->setType(type);
  1.2398 +}
  1.2399 +
  1.2400 +void
  1.2401 +SemanticAnalysis::visit(UnaryExpression *node)
  1.2402 +{
  1.2403 +    Local<Type> type(zone_, visitForLoad(node->expression()));
  1.2404 +    if (!type)
  1.2405 +        return;
  1.2406 +
  1.2407 +    switch (node->token())
  1.2408 +    {
  1.2409 +      case TOK_NOT:
  1.2410 +        if (!canTest(node->expression(), type))
  1.2411 +            return;
  1.2412 +        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.2413 +        if (!type)
  1.2414 +            return;
  1.2415 +        node->setType(type);
  1.2416 +        break;
  1.2417 +
  1.2418 +      case TOK_MINUS:
  1.2419 +        if (!type->isFloat() && !type->isInt32()) {
  1.2420 +            unaryTypeError(node, node->token(), type);
  1.2421 +            return;
  1.2422 +        }
  1.2423 +        node->setType(type);
  1.2424 +        break;
  1.2425 +
  1.2426 +      case TOK_LABEL:
  1.2427 +      {
  1.2428 +        Local<Type> to(zone_, bindType(node->pos(), node->type()));
  1.2429 +        if (!to)
  1.2430 +            return;
  1.2431 +
  1.2432 +        if ((!type->isFloat() && !type->isInt32OrEnum()) ||
  1.2433 +            (!to->isFloat() && !to->isInt32OrEnum()))
  1.2434 +        {
  1.2435 +            unaryTypeError(node, node->token(), type);
  1.2436 +            return;
  1.2437 +        }
  1.2438 +
  1.2439 +        node->setType(to);
  1.2440 +        break;
  1.2441 +      }
  1.2442 +
  1.2443 +      case TOK_SIZEOF:
  1.2444 +      {
  1.2445 +        if (!type->isArray()) {
  1.2446 +            cc_.reportError(node->pos(), Message_SizeofNeedsArray);
  1.2447 +            return;
  1.2448 +        }
  1.2449 +        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.2450 +        break;
  1.2451 +      }
  1.2452 +
  1.2453 +      default:
  1.2454 +        assert(node->token() == TOK_TILDE);
  1.2455 +        if (!type->isInt32()) {
  1.2456 +            unaryTypeError(node, node->token(), type);
  1.2457 +            return;
  1.2458 +        }
  1.2459 +        node->setType(type);
  1.2460 +        break;
  1.2461 +    }
  1.2462 +}
  1.2463 +
  1.2464 +void
  1.2465 +SemanticAnalysis::visit(TernaryExpression *node)
  1.2466 +{
  1.2467 +    Local<Type> type(zone_, visitForLoad(node->condition()));
  1.2468 +    if (!type)
  1.2469 +        return;
  1.2470 +
  1.2471 +    if (!canTest(node->condition(), type))
  1.2472 +        return;
  1.2473 +
  1.2474 +    Local<Type> left(zone_, visitForLoad(node->left()));
  1.2475 +    Local<Type> right(zone_, visitForLoad(node->right()));
  1.2476 +    if (!left || !right)
  1.2477 +        return;
  1.2478 +
  1.2479 +    if (left != right) {
  1.2480 +        binaryTypeError(node, TOK_QMARK, left, right);
  1.2481 +        return;
  1.2482 +    }
  1.2483 +}
  1.2484 +
  1.2485 +void
  1.2486 +SemanticAnalysis::visit(BinaryExpression *node)
  1.2487 +{
  1.2488 +    Local<Type> left(zone_, visitForLoad(node->left()));
  1.2489 +    Local<Type> right(zone_, visitForLoad(node->right()));
  1.2490 +    if (!left || !right)
  1.2491 +        return;
  1.2492 +
  1.2493 +    Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
  1.2494 +    if (!result)
  1.2495 +        return;
  1.2496 +
  1.2497 +    node->setType(result);
  1.2498 +}
  1.2499 +
  1.2500 +void
  1.2501 +SemanticAnalysis::visit(ReturnStatement *node)
  1.2502 +{
  1.2503 +    // Set this early, so if we error we don't get more errors.
  1.2504 +    control_->returns(Returns_Always);
  1.2505 +
  1.2506 +    if (!node->expression()) {
  1.2507 +        if (!function_->type()->returnType()->isVoid())
  1.2508 +            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1.2509 +        return;
  1.2510 +    }
  1.2511 +
  1.2512 +    Local<Type> type(zone_, visitForLoad(node->expression()));
  1.2513 +    if (!type)
  1.2514 +        return;
  1.2515 +
  1.2516 +    Local<Type> returnType(zone_, function_->type()->returnType());
  1.2517 +    if (!typeCheckAssignment(node->pos(), type, returnType, true))
  1.2518 +        return;
  1.2519 +}
  1.2520 +
  1.2521 +void
  1.2522 +SemanticAnalysis::visit(ForStatement *node)
  1.2523 +{
  1.2524 +    LoopScope loop(&loop_);
  1.2525 +
  1.2526 +    if (node->scope())
  1.2527 +        scope_ = node->scope();
  1.2528 +
  1.2529 +    if (node->initialization())
  1.2530 +        node->initialization()->accept(this);
  1.2531 +
  1.2532 +    if (node->condition()) {
  1.2533 +        Local<Type> type(zone_, visitForLoad(node->condition()));
  1.2534 +        if (!type || !canTest(node->condition(), type)) {
  1.2535 +            return;
  1.2536 +        }
  1.2537 +    }
  1.2538 +
  1.2539 +    if (node->update())
  1.2540 +        node->update()->accept(this);
  1.2541 +
  1.2542 +    ControlStatus status = visitForControl(node->body());
  1.2543 +
  1.2544 +    // If there is a condition, we treat this like a while loop. Otherwise,
  1.2545 +    // join point is only reachable if the loop contains a break. The
  1.2546 +    // termination status doesn't tell us anything yet.
  1.2547 +    if (node->condition() || loop.breaks())
  1.2548 +        control_->merge(status, ControlStatus(false, Returns_Never));
  1.2549 +    else
  1.2550 +        control_->terminate(status.returns());
  1.2551 +
  1.2552 +    if (node->scope())
  1.2553 +        scope_ = scope_->enclosing();
  1.2554 +}
  1.2555 +
  1.2556 +void 
  1.2557 +SemanticAnalysis::visit(WhileStatement *node)
  1.2558 +{
  1.2559 +    LoopScope loop(&loop_);
  1.2560 +
  1.2561 +    Local<Type> type(zone_, visitForLoad(node->condition()));
  1.2562 +    if (!type || !canTest(node->condition(), type)) {
  1.2563 +        return;
  1.2564 +    }
  1.2565 +
  1.2566 +    ControlStatus status = visitForControl(node->body());
  1.2567 +
  1.2568 +    // Detect loops that will always have a fork in the control-flow graph.
  1.2569 +    // This will be a |while| loop, or a |do-while| loop whose body does
  1.2570 +    // not terminate.
  1.2571 +    //
  1.2572 +    // For now, we treat these as an |if| regardless of the direction the
  1.2573 +    // branch can take. That means the control-flow is always conditional.
  1.2574 +    if (node->token() == TOK_WHILE ||
  1.2575 +        !status.terminates() ||
  1.2576 +        loop.breaks())
  1.2577 +    {
  1.2578 +        control_->merge(status, ControlStatus(false, Returns_Never));
  1.2579 +    } else {
  1.2580 +        // At this point, we've got a do-while loop with a |return| or
  1.2581 +        // |continue|, meaning that the rest of the block is unreachable.
  1.2582 +        control_->terminate(status.returns());
  1.2583 +    }
  1.2584 +}
  1.2585 +
  1.2586 +void
  1.2587 +SemanticAnalysis::visit(BlockStatement *node)
  1.2588 +{
  1.2589 +    if (node->scope())
  1.2590 +        scope_ = node->scope();
  1.2591 +    for (size_t i = 0; i < node->statements()->length(); i++) {
  1.2592 +        Statement *statement = node->statements()->at(i);
  1.2593 +        statement->accept(this);
  1.2594 +    }
  1.2595 +    if (node->scope())
  1.2596 +        scope_ = scope_->enclosing();
  1.2597 +}
  1.2598 +
  1.2599 +static inline bool
  1.2600 +IsScalarString(Type *type)
  1.2601 +{
  1.2602 +    if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
  1.2603 +        return true;
  1.2604 +    if (type->isReference())
  1.2605 +        return IsScalarString(type->contained());
  1.2606 +    return false;
  1.2607 +}
  1.2608 +
  1.2609 +static const int INFER_ARRAY_SIZE = 0;
  1.2610 +static const int EVAL_ARRAY_SIZE = -1;
  1.2611 +static const int DYNAMIC_ARRAY_SIZE = -2;
  1.2612 +
  1.2613 +bool
  1.2614 +SemanticAnalysis::evaluateDimensions(ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH])
  1.2615 +{
  1.2616 +    bool hadEmptySize = false;
  1.2617 +
  1.2618 +    for (size_t i = 0; i < exprs->length(); i++) {
  1.2619 +        Expression *expr = exprs->at(i);
  1.2620 +        if (!expr) {
  1.2621 +            dims[i] = INFER_ARRAY_SIZE;
  1.2622 +            hadEmptySize = true;
  1.2623 +            continue;
  1.2624 +        }
  1.2625 +
  1.2626 +        BoxedPrimitive box;
  1.2627 +        if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
  1.2628 +            int size = box.toInt();
  1.2629 +            if (size <= 0) {
  1.2630 +                cc_.reportError(expr->pos(), Message_BadArraySize);
  1.2631 +                return false;
  1.2632 +            }
  1.2633 +
  1.2634 +            dims[i] = size;
  1.2635 +            continue;
  1.2636 +        }
  1.2637 +
  1.2638 +        Local<Type> exprType(zone_, visitForLoad(expr));
  1.2639 +        if (!exprType)
  1.2640 +            return false;
  1.2641 +
  1.2642 +        if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
  1.2643 +            cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
  1.2644 +            return false;
  1.2645 +        }
  1.2646 +
  1.2647 +        if (hadEmptySize) {
  1.2648 +            cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
  1.2649 +            return false;
  1.2650 +        }
  1.2651 +
  1.2652 +        dims[i] = EVAL_ARRAY_SIZE;
  1.2653 +    }
  1.2654 +
  1.2655 +    return true;
  1.2656 +}
  1.2657 +
  1.2658 +bool
  1.2659 +SemanticAnalysis::inferFixedArrayLiteral(ArrayLiteral *literal, Handle<Type> contained,
  1.2660 +                                         int dims[MAX_ARRAY_DEPTH],
  1.2661 +                                         unsigned dimcount, unsigned level)
  1.2662 +{
  1.2663 +    if (dims[level] == EVAL_ARRAY_SIZE) {
  1.2664 +        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
  1.2665 +        return false;
  1.2666 +    }
  1.2667 +
  1.2668 +    if (dims[level] == INFER_ARRAY_SIZE) {
  1.2669 +        // Strings always become dynamic arrays.
  1.2670 +        if (level != dimcount - 1 || !IsPrimitiveType(contained, PrimitiveType_Char))
  1.2671 +            dims[level] = literal->expressions()->length();
  1.2672 +    } else if (dims[level] == DYNAMIC_ARRAY_SIZE) {
  1.2673 +        cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
  1.2674 +        return false;
  1.2675 +    } else {
  1.2676 +        if (literal->expressions()->length() != unsigned(dims[level])) {
  1.2677 +            cc_.reportError(literal->pos(), Message_ArrayDimensionSizeMismatch, level + 1);
  1.2678 +            return false;
  1.2679 +        }
  1.2680 +    }
  1.2681 +
  1.2682 +    if (level == dimcount - 2 && IsPrimitiveType(contained, PrimitiveType_Char)) {
  1.2683 +        for (size_t i = 0; i < literal->expressions()->length(); i++) {
  1.2684 +            Expression *expr = literal->expressions()->at(i);
  1.2685 +            if (!expr->isStringLiteral()) {
  1.2686 +                cc_.reportError(expr->pos(), Message_ExpectedStringLiteral);
  1.2687 +                return false;
  1.2688 +            }
  1.2689 +
  1.2690 +            StringLiteral *lit = expr->toStringLiteral();
  1.2691 +            if (dims[level + 1] > 0 &&
  1.2692 +                unsigned(dims[level]) < lit->string()->length())
  1.2693 +            {
  1.2694 +                cc_.reportError(lit->pos(), Message_ArrayDimensionSizeMismatch, level + 2);
  1.2695 +                return false;
  1.2696 +            }
  1.2697 +            if (!visitAndApplyType(lit))
  1.2698 +                return false;
  1.2699 +        }
  1.2700 +    } else if (level == dimcount - 1) {
  1.2701 +        Local<Type> type(zone_);
  1.2702 +        for (size_t i = 0; i < literal->expressions()->length(); i++) {
  1.2703 +            Expression *expr = literal->expressions()->at(i);
  1.2704 +            if (expr->isArrayLiteral()) {
  1.2705 +                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
  1.2706 +                return false;
  1.2707 +            }
  1.2708 +
  1.2709 +            if ((type = visitAndApplyType(expr)) == NULL)
  1.2710 +                return false;
  1.2711 +
  1.2712 +            if (!typeCheckAssignment(expr->pos(), type, contained, true))
  1.2713 +                return false;
  1.2714 +        }
  1.2715 +    } else {
  1.2716 +        for (size_t i = 0; i < literal->expressions()->length(); i++) {
  1.2717 +            Expression *expr = literal->expressions()->at(i);
  1.2718 +            if (!expr->isArrayLiteral()) {
  1.2719 +                cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
  1.2720 +                return false;
  1.2721 +            }
  1.2722 +
  1.2723 +            assert(expr->toArrayLiteral()->isFixed());
  1.2724 +
  1.2725 +            if (!inferFixedArrayLiteral(expr->toArrayLiteral(),
  1.2726 +                                        contained,
  1.2727 +                                        dims,
  1.2728 +                                        dimcount,
  1.2729 +                                        level + 1))
  1.2730 +            {
  1.2731 +                return false;
  1.2732 +            }
  1.2733 +        }
  1.2734 +    }
  1.2735 +
  1.2736 +    return true;
  1.2737 +}
  1.2738 +
  1.2739 +void
  1.2740 +SemanticAnalysis::visit(VariableDeclaration *node)
  1.2741 +{
  1.2742 +    Local<Type> type(zone_, bindType(node->pos(), node->type()));
  1.2743 +    if (!type)
  1.2744 +        return;
  1.2745 +
  1.2746 +#if 0
  1.2747 +    if (node->postDimensions() || type->isArray()) {
  1.2748 +        // The type could be an array type, so sum the type and postDimensions
  1.2749 +        // together.
  1.2750 +        unsigned dimcount = node->postDimensions()->length();
  1.2751 +        if (type->isArray())
  1.2752 +            dimcount += type->levels();
  1.2753 +        if (dimcount > MAX_ARRAY_DEPTH) {
  1.2754 +            cc_.reportError(node->pos(), Message_MaximumArrayDepth);
  1.2755 +            return;
  1.2756 +        }
  1.2757 +
  1.2758 +        // Take an initial guess at the array dimension sizes.
  1.2759 +        int dims[MAX_ARRAY_DEPTH];
  1.2760 +        if (!evaluateDimensions(node->postDimensions(), dims))
  1.2761 +            return;
  1.2762 +
  1.2763 +        // Now add in the type's array dimensions.
  1.2764 +        Local<Type> contained(zone_, type);
  1.2765 +        for (size_t i = node->postDimensions()->length(); i < dimcount; i++) {
  1.2766 +            if (type->isFixedLength())
  1.2767 +                dims[i] = type->fixedLength();
  1.2768 +            else
  1.2769 +                dims[i] = DYNAMIC_ARRAY_SIZE;
  1.2770 +            contained = contained->contained();
  1.2771 +        }
  1.2772 +
  1.2773 +        Expression *initializer = node->initialization();
  1.2774 +        if (initializer &&
  1.2775 +            initializer->isArrayLiteral() &&
  1.2776 +            initializer->toArrayLiteral()->isFixed())
  1.2777 +        {
  1.2778 +            // Fixed array initializers are special; we use them to infer any
  1.2779 +            // missing information in the original array. We do not evaluate
  1.2780 +            // the array initializer as an expression.
  1.2781 +            if (!inferFixedArrayLiteral(initializer->toArrayLiteral(),
  1.2782 +                                        contained,
  1.2783 +                                        dims,
  1.2784 +                                        dimcount,
  1.2785 +                                        0))
  1.2786 +            {
  1.2787 +                return;
  1.2788 +            }
  1.2789 +            initializer = NULL;
  1.2790 +        }
  1.2791 +
  1.2792 +        // We now have enough information to build the actual array type.
  1.2793 +        // Start from the original dimcount, not the one computed for
  1.2794 +        // initializers.
  1.2795 +        for (size_t i = node->postDimensions()->length() - 1;
  1.2796 +             i < node->postDimensions()->length();
  1.2797 +             i--)
  1.2798 +        {
  1.2799 +            int size = dims[i] > 0
  1.2800 +                       ? dims[i]
  1.2801 +                       : Type::DYNAMIC_ARRAY_SIZE;
  1.2802 +
  1.2803 +            type = zone_->types()->newArray(type, size, false);
  1.2804 +            if (!type)
  1.2805 +                return;
  1.2806 +        }
  1.2807 +
  1.2808 +        // Finally, if we had a non-fixed initializer, make sure it type
  1.2809 +        // checks. 
  1.2810 +        if (initializer) {
  1.2811 +            Local<Type> right(zone_, visitForLoad(initializer));
  1.2812 +            if (!right)
  1.2813 +                return;
  1.2814 +
  1.2815 +            if (!typeCheckAssignment(node->pos(), right, type, true))
  1.2816 +                return;
  1.2817 +        }
  1.2818 +    } else {
  1.2819 +        if (node->initialization()) {
  1.2820 +            Local<Type> right(zone_, visitForLoad(node->initialization()));
  1.2821 +            if (!right)
  1.2822 +                return;
  1.2823 +            if (!typeCheckAssignment(node->pos(), right, type, true))
  1.2824 +                return;
  1.2825 +        }
  1.2826 +
  1.2827 +        if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
  1.2828 +            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.2829 +            return;
  1.2830 +        }
  1.2831 +    }
  1.2832 +#endif
  1.2833 +
  1.2834 +#if 0
  1.2835 +    // If this variable is stack allocated, we could use the LIFO heap
  1.2836 +    // to allocate it. If that's the case, make sure to reserve a slot
  1.2837 +    // so we can unwind the LIFO heap at the end of this scope.
  1.2838 +    if (!node->variable()->needsHeapAllocation()) {
  1.2839 +        if (type->isArray() || type->isStruct())
  1.2840 +            scope_->setUsesLifoHeap();
  1.2841 +    }
  1.2842 +
  1.2843 +    node->variable()->setType(type);
  1.2844 +#endif
  1.2845 +}
  1.2846 +
  1.2847 +void
  1.2848 +SemanticAnalysis::visit(IntegerLiteral *node)
  1.2849 +{
  1.2850 +    node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.2851 +}
  1.2852 +
  1.2853 +void
  1.2854 +SemanticAnalysis::visit(BooleanLiteral *node)
  1.2855 +{
  1.2856 +    node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
  1.2857 +}
  1.2858 +
  1.2859 +void
  1.2860 +SemanticAnalysis::visit(ExpressionStatement *node)
  1.2861 +{
  1.2862 +    visitAndApplyType(node->expression());
  1.2863 +}
  1.2864 +
  1.2865 +Box *
  1.2866 +SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
  1.2867 +{
  1.2868 +    Local<Type> given(zone_, visitForLoad(parameter->initializer()));
  1.2869 +
  1.2870 +    BoxedPrimitive prim;
  1.2871 +    if (EvaluateForConstant(parameter->initializer(), &prim)) {
  1.2872 +        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
  1.2873 +            return NULL;
  1.2874 +
  1.2875 +        if (prim.type() == PrimitiveType_Int32)
  1.2876 +            return Box::New(zone_, given, prim.toInt());
  1.2877 +        return Box::New(zone_, given, prim.toFloat());
  1.2878 +    } else if (parameter->initializer()->isStringLiteral()) {
  1.2879 +        StringLiteral *literal = parameter->initializer()->toStringLiteral();
  1.2880 +
  1.2881 +        if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
  1.2882 +            return NULL;
  1.2883 +
  1.2884 +        Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
  1.2885 +        if (!map)
  1.2886 +            return NULL;
  1.2887 +
  1.2888 +        Local<Array> array(zone_,
  1.2889 +            Array::NewString(zone_,
  1.2890 +                             map,
  1.2891 +                             literal->string()->raw(),
  1.2892 +                             literal->string()->length(),
  1.2893 +                             Heap::Tenure_Old));
  1.2894 +        if (!array)
  1.2895 +            return NULL;
  1.2896 +
  1.2897 +        return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
  1.2898 +    }
  1.2899 +
  1.2900 +    cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
  1.2901 +    return NULL;
  1.2902 +}
  1.2903 +
  1.2904 +bool
  1.2905 +SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
  1.2906 +                                    FixedArray **argsp, FixedArray **defaultsp)
  1.2907 +{
  1.2908 +    Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
  1.2909 +    if (!args)
  1.2910 +        return false;
  1.2911 +
  1.2912 +    Local<FixedArray> defaults(zone_);
  1.2913 +
  1.2914 +    // Apply types to arguments.
  1.2915 +    for (size_t i = 0; i < sig.parameters()->length(); i++) {
  1.2916 +        Parameter *parameter = sig.parameters()->at(i);
  1.2917 +        
  1.2918 +#if 0
  1.2919 +        Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
  1.2920 +        if (!type)
  1.2921 +            return false;
  1.2922 +
  1.2923 +        if (parameter->reference()) {
  1.2924 +            if (parameter->dimensions()) {
  1.2925 +                cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
  1.2926 +                return false;
  1.2927 +            }
  1.2928 +
  1.2929 +            if (type->isStruct()) {
  1.2930 +                cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
  1.2931 +                return false;
  1.2932 +            }
  1.2933 +
  1.2934 +            type = zone_->types()->getReference(type, parameter->isConst());
  1.2935 +            if (!type)
  1.2936 +                return false;
  1.2937 +        } else if (parameter->dimensions()) {
  1.2938 +            type = buildArrayType(type, parameter->dimensions(), parameter->isConst());
  1.2939 +            if (!type)
  1.2940 +                return false;
  1.2941 +
  1.2942 +            if (kind == TOK_NATIVE && type->levels() > 1) {
  1.2943 +                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
  1.2944 +                return false;
  1.2945 +            }
  1.2946 +        }
  1.2947 +
  1.2948 +        if (IsScalarString(type)) {
  1.2949 +            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.2950 +            return false;
  1.2951 +        }
  1.2952 +
  1.2953 +        args->set(zone_, i, type);
  1.2954 +        parameter->variable()->setType(type);
  1.2955 +
  1.2956 +        if (parameter->initializer()) {
  1.2957 +            if (!defaults) {
  1.2958 +                defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
  1.2959 +                if (!defaults)
  1.2960 +                    return false;
  1.2961 +            }
  1.2962 +
  1.2963 +            Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
  1.2964 +            if (!box)
  1.2965 +                return false;
  1.2966 +
  1.2967 +            defaults->set(zone_, i, box);
  1.2968 +        }
  1.2969 +#endif
  1.2970 +    }
  1.2971 +
  1.2972 +    *argsp = args;
  1.2973 +    *defaultsp = defaults;
  1.2974 +
  1.2975 +    return true;
  1.2976 +}
  1.2977 +
  1.2978 +void
  1.2979 +SemanticAnalysis::visit(FunctionTypeStatement *node)
  1.2980 +{
  1.2981 +    if (node->decl()->type())
  1.2982 +        return;
  1.2983 +
  1.2984 +    Local<FixedArray> args(zone_);
  1.2985 +    Local<FixedArray> defaults(zone_);
  1.2986 +
  1.2987 +    const FunctionSignature &sig= node->signature();
  1.2988 +    if (!buildFunctionArgs(node,
  1.2989 +                           TOK_STOCK,
  1.2990 +                           sig,
  1.2991 +                           args.address(),
  1.2992 +                           defaults.address()))
  1.2993 +    {
  1.2994 +        return;
  1.2995 +    }
  1.2996 +
  1.2997 +#if 0
  1.2998 +    Local<Type> returnType(zone_);
  1.2999 +    if (sig.returnType())
  1.3000 +        returnType = bindType(node->pos(), sig.returnType());
  1.3001 +    else
  1.3002 +        returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.3003 +
  1.3004 +    if (!returnType)
  1.3005 +        return;
  1.3006 +
  1.3007 +    Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
  1.3008 +    if (!funtype)
  1.3009 +        return;
  1.3010 +
  1.3011 +    node->decl()->setType(funtype);
  1.3012 +#endif
  1.3013 +}
  1.3014 +
  1.3015 +Type *
  1.3016 +SemanticAnalysis::buildArrayType(Handle<Type> type, ExpressionList *dimensions, bool isConst)
  1.3017 +{
  1.3018 +    Local<Type> arrayType(zone_, type);
  1.3019 +
  1.3020 +    unsigned dimcount = dimensions->length();
  1.3021 +    if (type->isArray())
  1.3022 +        dimcount += type->levels();
  1.3023 +
  1.3024 +    if (dimcount > MAX_ARRAY_DEPTH) {
  1.3025 +        cc_.reportError(dimensions->at(dimensions->length() - 1)->pos(),
  1.3026 +                        Message_MaximumArrayDepth);
  1.3027 +        return false;
  1.3028 +    }
  1.3029 +
  1.3030 +    // Note: constness is sort of bogus. Fix this sometime.
  1.3031 +    for (size_t i = dimensions->length() - 1; i < dimensions->length(); i--) {
  1.3032 +        Expression *expr = dimensions->at(i);
  1.3033 +        if (!expr) {
  1.3034 +            arrayType = zone_->types()->newArray(arrayType, Type::DYNAMIC_ARRAY_SIZE, isConst);
  1.3035 +            if (!arrayType)
  1.3036 +                return NULL;
  1.3037 +
  1.3038 +            continue;
  1.3039 +        }
  1.3040 +
  1.3041 +        BoxedPrimitive box;
  1.3042 +        if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
  1.3043 +            cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
  1.3044 +            return NULL;
  1.3045 +        }
  1.3046 +
  1.3047 +        if (box.toInt() <= 0) {
  1.3048 +            cc_.reportError(expr->pos(), Message_BadArraySize);
  1.3049 +            return NULL;
  1.3050 +        }
  1.3051 +
  1.3052 +        arrayType = zone_->types()->newArray(arrayType, box.toInt(), isConst);
  1.3053 +        if (!arrayType)
  1.3054 +            return NULL;
  1.3055 +    }
  1.3056 +
  1.3057 +    return arrayType;
  1.3058 +}
  1.3059 +
  1.3060 +bool
  1.3061 +SemanticAnalysis::preanalyze(FunctionStatement *node)
  1.3062 +{
  1.3063 +    Local<FixedArray> args(zone_);
  1.3064 +    Local<FixedArray> defaults(zone_);
  1.3065 +
  1.3066 +    const FunctionSignature &sig = node->signature();
  1.3067 +    if (!buildFunctionArgs(node,
  1.3068 +                           node->fun()->token(),
  1.3069 +                           sig,
  1.3070 +                           args.address(),
  1.3071 +                           defaults.address()))
  1.3072 +    {
  1.3073 +        return false;
  1.3074 +    }
  1.3075 +
  1.3076 +#if 0
  1.3077 +    Local<Type> returnType(zone_);
  1.3078 +    if (sig.returnType() ||
  1.3079 +        node->hasExplicitReturn() ||
  1.3080 +        node->fun()->isNative())
  1.3081 +    {
  1.3082 +        returnType = bindType(node->pos(), sig.returnType());
  1.3083 +    } else {
  1.3084 +        returnType = zone_->types()->getVoid();
  1.3085 +    }
  1.3086 +    if (!returnType)
  1.3087 +        return false;
  1.3088 +
  1.3089 +    if (sig.returnDimensions()) {
  1.3090 +        returnType = buildArrayType(returnType, sig.returnDimensions(), false);
  1.3091 +        if (!returnType)
  1.3092 +            return false;
  1.3093 +    }
  1.3094 +
  1.3095 +    if (IsScalarString(returnType)) {
  1.3096 +        cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
  1.3097 +        return false;
  1.3098 +    }
  1.3099 +
  1.3100 +    Local<Type> funtype(zone_);
  1.3101 +    if (node->fun()->isNative())
  1.3102 +        funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
  1.3103 +    else
  1.3104 +        funtype = zone_->types()->newFunction(returnType, args, defaults);
  1.3105 +    if (!funtype)
  1.3106 +        return false;
  1.3107 +    
  1.3108 +    // If the function already has a type, it was forward declared before, and
  1.3109 +    // now this is our chance to type check the second declaration.
  1.3110 +    if (node->fun()->type()) {
  1.3111 +        Local<Type> forward(zone_, node->fun()->type());
  1.3112 +        if (!Type::Compare(funtype, forward)) {
  1.3113 +            cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
  1.3114 +            return false;
  1.3115 +        }
  1.3116 +        node->fun()->setForwardType(forward);
  1.3117 +    }
  1.3118 +
  1.3119 +    node->fun()->setType(funtype);
  1.3120 +#endif
  1.3121 +
  1.3122 +    return true;
  1.3123 +}
  1.3124 +
  1.3125 +void
  1.3126 +SemanticAnalysis::visit(FunctionStatement *node)
  1.3127 +{
  1.3128 +    function_ = node->fun();
  1.3129 +    scope_ = node->scope();
  1.3130 +
  1.3131 +    ControlScope control(&control_);
  1.3132 +    if (node->body()) {
  1.3133 +        node->body()->accept(this);
  1.3134 +
  1.3135 +        ControlStatus status = control.status();
  1.3136 +        if (status.returns() == Returns_Sometimes) {
  1.3137 +            cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
  1.3138 +        } else if (status.returns() == Returns_Never) {
  1.3139 +            if (!function_->type()->returnType()->isVoid())
  1.3140 +                cc_.reportError(node->pos(), Message_MissingReturnValue);
  1.3141 +        }
  1.3142 +    }
  1.3143 +
  1.3144 +    scope_ = NULL;
  1.3145 +    function_ = NULL;
  1.3146 +}
  1.3147 +
  1.3148 +void
  1.3149 +SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
  1.3150 +{
  1.3151 +    cc_.reportError(pos, Message_TypeMismatch,
  1.3152 +                    GetTypeName(actual),
  1.3153 +                    GetTypeName(given));
  1.3154 +}
  1.3155 +
  1.3156 +bool
  1.3157 +SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.3158 +                                           Handle<Type> argActual, bool forAssign)
  1.3159 +{
  1.3160 +    Local<Type> actual(zone_, argActual);
  1.3161 +    Local<Type> given(zone_, argGiven);
  1.3162 +
  1.3163 +    if (!given->isArray()) {
  1.3164 +        cc_.reportError(pos, Message_ExpectedArray);
  1.3165 +        return false;
  1.3166 +    }
  1.3167 +    if (given->levels() != actual->levels()) {
  1.3168 +        cc_.reportError(pos, Message_ArrayDimensionsMismatch);
  1.3169 +        return false;
  1.3170 +    }
  1.3171 +
  1.3172 +    unsigned level = 1;
  1.3173 +    while (given->isArray()) {
  1.3174 +        if (actual->isFixedLength()) {
  1.3175 +            if (forAssign) {
  1.3176 +                if (!given->isFixedLength()) {
  1.3177 +                    cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.3178 +                    return false;
  1.3179 +                }
  1.3180 +
  1.3181 +                if (actual->isCharArray()) {
  1.3182 +                    // String assignment can have a truncated |given|.
  1.3183 +                    if (given->fixedLength() > actual->fixedLength()) {
  1.3184 +                        cc_.reportError(pos, Message_ArrayAssignmentTooBig);
  1.3185 +                        return false;
  1.3186 +                    }
  1.3187 +                } else {
  1.3188 +                    if (given->fixedLength() != actual->fixedLength()) {
  1.3189 +                        cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.3190 +                        return false;
  1.3191 +                    }
  1.3192 +                }
  1.3193 +            }
  1.3194 +        } else if (given->isFixedLength()) {
  1.3195 +            // We do not allow assignments in the form:
  1.3196 +            //    [][] = [][Y]
  1.3197 +            //
  1.3198 +            // Otherwise, the following code could break the size guarantees
  1.3199 +            // of the right-hand side:
  1.3200 +            //
  1.3201 +            //   new x[][5];
  1.3202 +            //   new y[][];
  1.3203 +            //   new z[3];
  1.3204 +            //
  1.3205 +            //   y = x;
  1.3206 +            //   y[0] = z;
  1.3207 +            //   
  1.3208 +            // Now |x[0]| contains a 4-length array.
  1.3209 +            if (level > 1) {
  1.3210 +                cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
  1.3211 +                return false;
  1.3212 +            }
  1.3213 +        }
  1.3214 +        given = given->contained();
  1.3215 +        actual = actual->contained();
  1.3216 +        level++;
  1.3217 +    }
  1.3218 +
  1.3219 +    return typeCheckAssignment(pos, given, actual, forAssign);
  1.3220 +}
  1.3221 +
  1.3222 +bool
  1.3223 +SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
  1.3224 +                                      Handle<Type> argActual, bool forAssign)
  1.3225 +{
  1.3226 +    Local<Type> actual(zone_, argActual);
  1.3227 +    Local<Type> given(zone_, argGiven);
  1.3228 +
  1.3229 +    if (actual->isArray())
  1.3230 +        return typeCheckArrayAssignment(pos, given, actual, forAssign);
  1.3231 +
  1.3232 +    if (given->isArray()) {
  1.3233 +        cc_.reportError(pos, Message_CannotAssignArrayToScalar);
  1.3234 +        return false;
  1.3235 +    }
  1.3236 +
  1.3237 +    // The given type may not have been dereferenced.
  1.3238 +    if (given->isReference())
  1.3239 +        given = given->contained();
  1.3240 +    if (actual->isReference())
  1.3241 +        actual = actual->contained();
  1.3242 +
  1.3243 +    // We coerce unchecked to a few things.
  1.3244 +    if (actual->isUnchecked() || given->isUnchecked()) {
  1.3245 +        Type *check = actual->isUnchecked() ? given : actual;
  1.3246 +        if (check->isUnchecked() ||
  1.3247 +            check->isEnum() ||
  1.3248 +            check->isInt32() ||
  1.3249 +            check->isBool() ||
  1.3250 +            check->isFloat())
  1.3251 +        {
  1.3252 +            return true;
  1.3253 +        }
  1.3254 +        typeMismatch(pos, actual, given);
  1.3255 +        return false;
  1.3256 +    }
  1.3257 +
  1.3258 +    if (given->isFunction() && actual->isFunction()) {
  1.3259 +        if (!Type::Compare(given, actual)) {
  1.3260 +            typeMismatch(pos, actual, given);
  1.3261 +            return false;
  1.3262 +        }
  1.3263 +        return true;
  1.3264 +    }
  1.3265 +
  1.3266 +    if (actual->isEnum()) {
  1.3267 +        if (!given->isEnum() || actual != given) {
  1.3268 +            typeMismatch(pos, actual, given);
  1.3269 +            return false;
  1.3270 +        }
  1.3271 +        return true;
  1.3272 +    }
  1.3273 +
  1.3274 +    if (actual->isStruct()) {
  1.3275 +        if (!given->isStruct() || actual != given) {
  1.3276 +            typeMismatch(pos, actual, given);
  1.3277 +            return false;
  1.3278 +        }
  1.3279 +        return true;
  1.3280 +    }
  1.3281 +
  1.3282 +    if (given->isEnum() || given->isFunction() || given->isStruct()) {
  1.3283 +        typeMismatch(pos, actual, given);
  1.3284 +        return false;
  1.3285 +    }
  1.3286 +
  1.3287 +    // This coercion is trivial.
  1.3288 +    if (given->isBool() && actual->isInt32())
  1.3289 +        return true;
  1.3290 +
  1.3291 +    if (given->primitive() != actual->primitive()) {
  1.3292 +        typeMismatch(pos, actual, given);
  1.3293 +        return false;
  1.3294 +    }
  1.3295 +
  1.3296 +    return true;
  1.3297 +}
  1.3298 +
  1.3299 +bool
  1.3300 +SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
  1.3301 +{
  1.3302 +    return typeCheckAssignment(node->pos(), given, actual, false);
  1.3303 +}
  1.3304 +
  1.3305 +bool
  1.3306 +SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
  1.3307 +{
  1.3308 +    if (type->parameters()->length() == actual)
  1.3309 +        return true;
  1.3310 +
  1.3311 +    if (actual > type->parameters()->length()) {
  1.3312 +        if (!type->isNative() || !type->isNativeVariadic())
  1.3313 +            return false;
  1.3314 +        return true;
  1.3315 +    }
  1.3316 +
  1.3317 +    if (!type->defaults())
  1.3318 +        return false;
  1.3319 +
  1.3320 +    // Missing arguments. See if there's a default argument for each missing
  1.3321 +    // actual.
  1.3322 +    for (unsigned i = actual; i < type->parameters()->length(); i++) {
  1.3323 +        if (!type->defaults()->at(i))
  1.3324 +            return false;
  1.3325 +    }
  1.3326 +
  1.3327 +    return true;
  1.3328 +}
  1.3329 +
  1.3330 +void
  1.3331 +SemanticAnalysis::visit(CallExpression *node)
  1.3332 +{
  1.3333 +    Local<Type> type(zone_, visitForLoad(node->callee()));
  1.3334 +    if (!type)
  1.3335 +        return;
  1.3336 +
  1.3337 +    if (!type->isFunction()) {
  1.3338 +        cc_.reportError(node->pos(), Message_CalleeNotFunction);
  1.3339 +        return;
  1.3340 +    }
  1.3341 +
  1.3342 +    if (!checkArgumentCount(type, node->arguments()->length())) {
  1.3343 +        cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
  1.3344 +        return;
  1.3345 +    }
  1.3346 +
  1.3347 +    // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
  1.3348 +    // if (fun->isForward()) {
  1.3349 +    //     cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
  1.3350 +    //     return;
  1.3351 +    // }
  1.3352 +
  1.3353 +    for (unsigned i = 0; i < node->arguments()->length(); i++) {
  1.3354 +        // Note: we don't compute references unless the callee needs a
  1.3355 +        // reference type.
  1.3356 +        Expression *expression = node->arguments()->at(i);
  1.3357 +        Local<Type> given(zone_, visitAndApplyType(expression));
  1.3358 +        if (!given)
  1.3359 +            return;
  1.3360 +
  1.3361 +        // Since we skip a load, check for a call expression that returns void.
  1.3362 +        if (given->isVoid()) {
  1.3363 +            assert(expression->isCallExpression());
  1.3364 +            CallExpression *call = expression->toCallExpression();
  1.3365 +            cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
  1.3366 +            return;
  1.3367 +        }
  1.3368 +        
  1.3369 +        bool mustComputeReference;
  1.3370 +        if (i >= type->parameters()->length()) {
  1.3371 +            // Special handling for natives. Arguments past the formal must
  1.3372 +            // always have references computed. However, arrays are already
  1.3373 +            // references for natives.  
  1.3374 +            assert(type->isNative() && type->isNativeVariadic());
  1.3375 +            mustComputeReference = !given->isReference() && !given->isArray();
  1.3376 +        } else {
  1.3377 +            Local<Type> actual(zone_, type->parameterAt(i));
  1.3378 +
  1.3379 +            if (expression->isIndexExpression()) {
  1.3380 +                // Disabled until we can make it work.
  1.3381 +#if 0
  1.3382 +                if (actual->isArray()) {
  1.3383 +                    // We special case the ability to pass x[y] into x[], which
  1.3384 +                    // creates an array slice. We only do this if we know the
  1.3385 +                    // assignment would otherwise not type-check.
  1.3386 +                    IndexExpression *index = expression->toIndexExpression();
  1.3387 +                    if (index->left()->type()->levels() == actual->levels())
  1.3388 +                        given = index->left()->type();
  1.3389 +                } else
  1.3390 +#endif
  1.3391 +                if (actual->isReference()) {
  1.3392 +                    cc_.reportError(expression->pos(), Message_CannotComputeIndexRef);
  1.3393 +                    return;
  1.3394 +                }
  1.3395 +            }
  1.3396 +
  1.3397 +            if (!typeCheckParameter(expression, given, actual))
  1.3398 +                return;
  1.3399 +            mustComputeReference = actual->isReference() && !given->isReference();
  1.3400 +        }
  1.3401 +
  1.3402 +        // If the actual is a reference, and the given is not, we'll need to
  1.3403 +        // compute a reference, which may be allocated on the stack.
  1.3404 +        if (mustComputeReference)
  1.3405 +            scope_->setUsesLifoHeap();
  1.3406 +    }
  1.3407 +
  1.3408 +    node->setType(type->returnType());
  1.3409 +}
  1.3410 +
  1.3411 +void
  1.3412 +SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
  1.3413 +{
  1.3414 +    if (other.returns() < status().returns())
  1.3415 +        return;
  1.3416 +
  1.3417 +    if (other.terminates())
  1.3418 +        terminate(other.returns());
  1.3419 +    else
  1.3420 +        returns(other.returns());
  1.3421 +}
  1.3422 +
  1.3423 +void
  1.3424 +SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
  1.3425 +{
  1.3426 +    // If both sides terminate in a return, we consider this a return as well.
  1.3427 +    if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
  1.3428 +        terminate(Returns_Always);
  1.3429 +        return;
  1.3430 +    }
  1.3431 +
  1.3432 +    ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
  1.3433 +                          ? Returns_Never
  1.3434 +                          : Returns_Sometimes;
  1.3435 +
  1.3436 +    if (left.terminates() && right.terminates())
  1.3437 +        terminate(status);
  1.3438 +    else
  1.3439 +        returns(status);
  1.3440 +}
  1.3441 +
  1.3442 +void
  1.3443 +SemanticAnalysis::visit(IfStatement *node)
  1.3444 +{
  1.3445 +    Local<Type> type(zone_, visitForLoad(node->condition()));
  1.3446 +    if (!type)
  1.3447 +        return;
  1.3448 +
  1.3449 +    if (!canTest(node, type))
  1.3450 +        return;
  1.3451 +
  1.3452 +    ControlStatus trueBranch = visitForControl(node->ifTrue());
  1.3453 +    ControlStatus falseBranch = ControlStatus(false, Returns_Never);
  1.3454 +
  1.3455 +    if (node->ifFalse())
  1.3456 +        falseBranch = visitForControl(node->ifFalse());
  1.3457 +
  1.3458 +    control_->merge(trueBranch, falseBranch);
  1.3459 +}
  1.3460 +
  1.3461 +void
  1.3462 +SemanticAnalysis::visit(IndexExpression *node)
  1.3463 +{
  1.3464 +    Local<Type> left(zone_, visitForLoad(node->left()));
  1.3465 +    Local<Type> right(zone_, visitForLoad(node->right()));
  1.3466 +
  1.3467 +    if (!left || !right)
  1.3468 +        return;
  1.3469 +
  1.3470 +    if (!right->isInt32() && !right->isEnum()) {
  1.3471 +        cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
  1.3472 +        return;
  1.3473 +    }
  1.3474 +    if (!left->isArray()) {
  1.3475 +        cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
  1.3476 +        return;
  1.3477 +    }
  1.3478 +
  1.3479 +    // Note: char arrays are automatically up-casted to return an int32.
  1.3480 +    if (left->isCharArray())
  1.3481 +        node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
  1.3482 +    else
  1.3483 +        node->setType(left->contained());
  1.3484 +}
  1.3485 +
  1.3486 +void
  1.3487 +SemanticAnalysis::visit(FieldExpression *node)
  1.3488 +{
  1.3489 +    Local<Type> left(zone_, visitForLoad(node->left()));
  1.3490 +    if (!left)
  1.3491 +        return;
  1.3492 +
  1.3493 +    if (!left->isStruct()) {
  1.3494 +        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.3495 +                        GetTypeName(left));
  1.3496 +        return;
  1.3497 +    }
  1.3498 +
  1.3499 +    Local<String> field(zone_, node->field());
  1.3500 +
  1.3501 +    unsigned offset;
  1.3502 +    Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
  1.3503 +    if (!desc) {
  1.3504 +        cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
  1.3505 +                        GetTypeName(left));
  1.3506 +        return;
  1.3507 +    }
  1.3508 +
  1.3509 +    node->setFieldIndex(offset);
  1.3510 +    node->setType(desc->type());
  1.3511 +}
  1.3512 +
  1.3513 +void
  1.3514 +SemanticAnalysis::visit(EnumStatement *node)
  1.3515 +{
  1.3516 +    Local<String> name(zone_, node->name());
  1.3517 +    Local<Type> type(zone_);
  1.3518 +    if (name)
  1.3519 +        type = zone_->types()->newEnum(name);
  1.3520 +    else
  1.3521 +        type = zone_->types()->getPrimitive(PrimitiveType_Int32);
  1.3522 +
  1.3523 +    if (!type)
  1.3524 +        return;
  1.3525 +
  1.3526 +    if (node->decl())
  1.3527 +        node->decl()->setType(type);
  1.3528 +
  1.3529 +    int value = 0;
  1.3530 +    for (size_t i = 0; i < node->entries()->length(); i++) {
  1.3531 +        EnumStatement::Entry &entry = node->entries()->at(i);
  1.3532 +
  1.3533 +        BoxedPrimitive box = BoxedPrimitive::Int(value);
  1.3534 +        if (entry.expr) {
  1.3535 +            entry.expr->accept(this);
  1.3536 +            if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
  1.3537 +                cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
  1.3538 +                return;
  1.3539 +            }
  1.3540 +
  1.3541 +            assert(box.type() == PrimitiveType_Int32);
  1.3542 +            value = box.toInt();
  1.3543 +        }
  1.3544 +
  1.3545 +#if 0
  1.3546 +        entry.name->set(type, box);
  1.3547 +#endif
  1.3548 +        value++;
  1.3549 +    }
  1.3550 +}
  1.3551 +
  1.3552 +static int
  1.3553 +SortCaseIntValues(const void *p1, const void *p2)
  1.3554 +{
  1.3555 +    CaseValue *v1 = (CaseValue *)p1;
  1.3556 +    CaseValue *v2 = (CaseValue *)p2;
  1.3557 +
  1.3558 +    return v1->box.toInt() - v2->box.toInt();
  1.3559 +}
  1.3560 +
  1.3561 +void
  1.3562 +SemanticAnalysis::visit(SwitchStatement *node)
  1.3563 +{
  1.3564 +    Local<Type> caseType(zone_, visitForLoad(node->expression()));
  1.3565 +    if (!caseType)
  1.3566 +        return;
  1.3567 +
  1.3568 +    if (!caseType->isEnum() && !caseType->isInt32()) {
  1.3569 +        cc_.reportError(node->pos(), Message_CaseMustBeInteger);
  1.3570 +        return;
  1.3571 +    }
  1.3572 +
  1.3573 +    PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
  1.3574 +    ControlStatus status = ControlStatus(false, Returns_Never);
  1.3575 +
  1.3576 +    Local<Type> check(zone_);
  1.3577 +    for (size_t i = 0; i < node->cases()->length(); i++) {
  1.3578 +        Case *c = node->cases()->at(i);
  1.3579 +
  1.3580 +        check = visitForLoad(c->expression());
  1.3581 +        if (!check)
  1.3582 +            return;
  1.3583 +
  1.3584 +        if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
  1.3585 +            return;
  1.3586 +
  1.3587 +        CaseValue v(i);
  1.3588 +        if (!EvaluateForConstant(c->expression(), &v.box)) {
  1.3589 +            cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
  1.3590 +            return;
  1.3591 +        }
  1.3592 +        if (!values->append(v))
  1.3593 +            return;
  1.3594 +
  1.3595 +        if (c->others()) {
  1.3596 +            for (size_t j = 0; j < c->others()->length(); j++) {
  1.3597 +                Expression *expr = c->others()->at(j);
  1.3598 +                check = visitForLoad(expr);
  1.3599 +                if (!check)
  1.3600 +                    return;
  1.3601 +
  1.3602 +                if (!typeCheckAssignment(expr->pos(), check, caseType, false))
  1.3603 +                    return;
  1.3604 +
  1.3605 +                CaseValue v(i);
  1.3606 +                if (!EvaluateForConstant(expr, &v.box)) {
  1.3607 +                    cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
  1.3608 +                    return;
  1.3609 +                }
  1.3610 +                if (!values->append(v))
  1.3611 +                    return;
  1.3612 +            }
  1.3613 +        }
  1.3614 +
  1.3615 +        ControlStatus latest = visitForControl(c->statement());
  1.3616 +
  1.3617 +        if (i != 0)
  1.3618 +            control_->merge(status, latest);
  1.3619 +
  1.3620 +        status = latest;
  1.3621 +    }
  1.3622 +
  1.3623 +    if (node->defaultCase()) {
  1.3624 +        ControlStatus latest = visitForControl(node->defaultCase());
  1.3625 +
  1.3626 +        if (node->cases()->length()) {
  1.3627 +            // If we had any other cases, we must merge.
  1.3628 +            control_->merge(status, latest);
  1.3629 +        } else {
  1.3630 +            // Otherwise, control-flow always flows through here.
  1.3631 +            control_->inherit(latest);
  1.3632 +        }
  1.3633 +    } else if (node->cases()->length()) {
  1.3634 +        control_->merge(status, ControlStatus(false, Returns_Never));
  1.3635 +    }
  1.3636 +
  1.3637 +    if (values->length() > 1) {
  1.3638 +        qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
  1.3639 +
  1.3640 +        for (size_t i = 1; i < values->length(); i++) {
  1.3641 +            CaseValue &prev = values->at(i - 1);
  1.3642 +            CaseValue &cur = values->at(i);
  1.3643 +            if (prev.box.toInt() == cur.box.toInt()) {
  1.3644 +                cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
  1.3645 +                return;
  1.3646 +            }
  1.3647 +        }
  1.3648 +    }
  1.3649 +
  1.3650 +    node->setCaseValueList(values);
  1.3651 +}
  1.3652 +
  1.3653 +void
  1.3654 +SemanticAnalysis::visit(StructureStatement *node)
  1.3655 +{
  1.3656 +#if 0
  1.3657 +    // If this node already has a type, it was pre-analyzed, so skip it.
  1.3658 +    if (node->decl()->type())
  1.3659 +        return;
  1.3660 +
  1.3661 +    FieldList *fields = node->fields();
  1.3662 +    Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
  1.3663 +    if (!desctable)
  1.3664 +        return;
  1.3665 +
  1.3666 +    Vector<unsigned> composedList;
  1.3667 +    StructureBufferBuilder builder;
  1.3668 +
  1.3669 +    Local<Type> type(zone_);
  1.3670 +    Local<String> name(zone_);
  1.3671 +    Local<Descriptor> desc(zone_);
  1.3672 +    for (size_t i = 0; i < fields->length(); i++) {
  1.3673 +        StructureStatement::Field *field = fields->at(i);
  1.3674 +
  1.3675 +        type = bindType(field->pos(), field->type());
  1.3676 +        if (!type)
  1.3677 +            return;
  1.3678 +
  1.3679 +        if (field->dimensions()) {
  1.3680 +            type = buildArrayType(type, field->dimensions(), false);
  1.3681 +            if (!type)
  1.3682 +                return;
  1.3683 +
  1.3684 +            if (!ArrayMap::Attach(zone_, type))
  1.3685 +                return;
  1.3686 +        }
  1.3687 +
  1.3688 +        if (IsScalarString(type)) {
  1.3689 +            cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
  1.3690 +            return;
  1.3691 +        }
  1.3692 +
  1.3693 +        unsigned offset;
  1.3694 +        if (!builder.add(type, &offset))
  1.3695 +            return;
  1.3696 +
  1.3697 +        name = field->name();
  1.3698 +        desc = Descriptor::New(zone_, name, type, offset);
  1.3699 +        if (!desc)
  1.3700 +            return;
  1.3701 +
  1.3702 +        desctable->set(zone_, i, desc);
  1.3703 +
  1.3704 +        if (type->isStruct() || type->isArray()) {
  1.3705 +            if (!composedList.append(i))
  1.3706 +                return;
  1.3707 +        }
  1.3708 +    }
  1.3709 +
  1.3710 +    Local<FixedArray> composed(zone_);
  1.3711 +    if (composedList.length()) {
  1.3712 +        composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
  1.3713 +        if (!composed)
  1.3714 +            return;
  1.3715 +
  1.3716 +        for (unsigned i = 0; i < composedList.length(); i++)
  1.3717 +            composed->set(zone_, i, desctable->at(i));
  1.3718 +    }
  1.3719 +
  1.3720 +    Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
  1.3721 +    if (!map)
  1.3722 +        return;
  1.3723 +
  1.3724 +    name = node->decl()->name();
  1.3725 +    type = zone_->types()->newStruct(name, desctable, map);
  1.3726 +    if (!type)
  1.3727 +        return;
  1.3728 +
  1.3729 +    map->setType(type);
  1.3730 +    node->decl()->setType(type);
  1.3731 +#endif
  1.3732 +}
  1.3733 +
  1.3734 +void
  1.3735 +SemanticAnalysis::visit(StringLiteral *node)
  1.3736 +{
  1.3737 +    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
  1.3738 +    if (!type)
  1.3739 +        return;
  1.3740 +
  1.3741 +    type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
  1.3742 +    if (!type)
  1.3743 +        return;
  1.3744 +
  1.3745 +    node->setType(type);
  1.3746 +}
  1.3747 +
  1.3748 +void
  1.3749 +SemanticAnalysis::visit(FloatLiteral *node)
  1.3750 +{
  1.3751 +    Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
  1.3752 +    if (!type)
  1.3753 +        return;
  1.3754 +
  1.3755 +    node->setType(type);
  1.3756 +}
  1.3757 +
  1.3758 +void
  1.3759 +SemanticAnalysis::visit(BreakStatement *node)
  1.3760 +{
  1.3761 +    if (!loop_) {
  1.3762 +        cc_.reportError(node->pos(), Message_BreakOutsideLoop);
  1.3763 +        return;
  1.3764 +    }
  1.3765 +
  1.3766 +    // Note: ignore breaks that occur in unreachable control-flow.
  1.3767 +    if (!control_->status().terminates())
  1.3768 +        loop_->addBreak();
  1.3769 +
  1.3770 +    control_->terminate(Returns_Never);
  1.3771 +}
  1.3772 +
  1.3773 +void
  1.3774 +SemanticAnalysis::visit(ContinueStatement *node)
  1.3775 +{
  1.3776 +    if (!loop_) {
  1.3777 +        cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
  1.3778 +        return;
  1.3779 +    }
  1.3780 +
  1.3781 +    // Note: ignore continues that occur in unreachable control-flow.
  1.3782 +    if (!control_->status().terminates())
  1.3783 +        loop_->addContinue();
  1.3784 +
  1.3785 +    control_->terminate(Returns_Never);
  1.3786 +}
  1.3787 +
  1.3788 +void
  1.3789 +SemanticAnalysis::visit(ArrayLiteral *node)
  1.3790 +{
  1.3791 +    // We should never visit this.
  1.3792 +    cc_.reportError(node->pos(), Message_UnexpectedArrayLiteral);
  1.3793 +}
  1.3794 +
  1.3795 +void
  1.3796 +SemanticAnalysis::visit(ImportStatement *node)
  1.3797 +{
  1.3798 +}
  1.3799 +
  1.3800  #endif
  1.3801 \ No newline at end of file