src/OldSema.cpp
changeset 195 c1ba166f3fc4
child 263 ba85a47ee414
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/OldSema.cpp	Sat Nov 17 18:41:01 2012 -0800
     1.3 @@ -0,0 +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 +#endif
  1.1903 \ No newline at end of file