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