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