Support -x as a constant expression.
1 /* vim: set ts=4 sw=4 tw=99 et:
3 * Copyright (C) 2012 David Anderson
5 * This file is part of JITCraft.
7 * JITCraft is free software: you can redistribute it and/or modify it under
8 * the terms of the GNU General Public License as published by the Free
9 * Software Foundation, either version 3 of the License, or (at your option)
12 * Foobar is distributed in the hope that it will be useful, but WITHOUT ANY
13 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14 * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License along with
17 * JITCraft. If not, see http://www.gnu.org/licenses/.
20 #include "SemanticAnalysis.h"
23 #include "TypeManager.h"
25 #include "NameBinding.h"
32 IsPrimitiveType(Type *type, PrimitiveType primitive)
37 if (!type->isPrimitive())
40 return primitive == type->primitive();
44 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
49 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
53 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
62 EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
66 *out = BoxedPrimitive::Int(-inner.toInt());
75 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
77 switch (expression->kind()) {
78 case AstNode::kBinaryExpression:
82 BinaryExpression *b = expression->toBinaryExpression();
83 if (!EvaluateForConstant(b->left(), &left) ||
84 !EvaluateForConstant(b->right(), &right))
88 return EvaluateBinaryOperation(b->token(), left, right, out);
91 case AstNode::kUnaryExpression:
94 UnaryExpression *u = expression->toUnaryExpression();
95 if (!EvaluateForConstant(u->expression(), &inner))
97 return EvaluateUnaryOperation(u->token(), inner, out);
100 case AstNode::kNameProxy:
102 NameProxy *proxy = expression->toNameProxy();
103 if (proxy->binding()->kind() != BoundName::CONSTANT)
106 NamedConstant *c = proxy->binding()->toNamedConstant();
107 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
114 case AstNode::kIntegerLiteral:
115 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
123 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
133 SemanticAnalysis::analyze()
138 scope_ = tree_->scope();
140 for (size_t i = 0; i < tree_->statements()->length(); i++) {
141 Statement *statement = tree_->statements()->at(i);
142 if (statement->isFunctionStatement()) {
143 FunctionStatement *funstmt = statement->toFunctionStatement();
144 if (!preanalyze(funstmt))
149 for (size_t i = 0; i < tree_->statements()->length(); i++) {
150 Statement *statement = tree_->statements()->at(i);
151 statement->accept(this);
154 if (!determineLiveFunctions())
157 return !cc_.failures();
161 SemanticAnalysis::determineLiveFunctions()
163 Vector<NamedFunction *> worklist;
166 for (size_t i = 0; i < tree_->statements()->length(); i++) {
167 Statement *statement = tree_->statements()->at(i);
168 if (!statement->isFunctionStatement())
171 FunctionStatement *stmt = statement->toFunctionStatement();
172 NamedFunction *fun = stmt->fun();
176 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
177 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
179 // Names in these lists are always unused, however, we mark them
180 // as used while inserting into the work queue, to avoid double-
185 if (!worklist.append(name))
192 while (!worklist.empty()) {
193 NamedFunction *fun = worklist.popCopy();
195 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
196 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
199 if (!worklist.append(name))
210 SemanticAnalysis::visitAndApplyType(Expression *expression)
212 expression->accept(this);
213 return expression->type();
217 SemanticAnalysis::visitForLoad(Expression *expression)
219 Local<Type> type(zone_, visitAndApplyType(expression));
223 if (type->isReference()) {
224 expression->setType(type->contained());
225 } else if (expression->isIndexExpression()) {
227 expression->setType(type->contained());
228 } else if (expression->isCallExpression()) {
229 if (type->isVoid()) {
230 CallExpression *call = expression->toCallExpression();
231 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
236 return expression->type();
239 // :TODO: this leaks an interior pointer.
240 static inline const char *
241 GetTypeName(Type *type)
245 if (type->isFunction())
249 if (type->isReference())
250 type = type->contained();
252 return type->tag()->chars();
257 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
259 const char *op = TokenNames[token];
260 const char *name = GetTypeName(type);
262 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
266 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
268 const char *op = TokenNames[token];
269 const char *leftName = GetTypeName(left);
270 const char *rightName = GetTypeName(right);
272 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
276 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
278 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
279 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
281 // If either side is a float, the other side must be a float or int.
282 if (left->isFloat() || right->isFloat()) {
283 Type *floatType = left->isFloat() ? left : right;
284 Type *other = left->isFloat() ? right : left;
285 if (other->isFloat() || (other->isInt32() && !other->tag()))
290 if (token == TOK_OR || token == TOK_AND) {
291 if (!canTest(node, left) || !canTest(node, right))
293 return zone_->types()->getPrimitive(PrimitiveType_Int32);
296 if (token >= TOK_EQUALS && token <= TOK_GE) {
297 if ((left->isFloat() || (left->isInt32() && !left->tag())) &&
298 (right->isFloat() || (right->isInt32() && !right->tag())))
300 return zone_->types()->getPrimitive(PrimitiveType_Int32);
302 binaryTypeError(node, token, left, right);
306 if ((!left->isInt32() || left->tag()) ||
307 (!right->isInt32() || right->tag()))
309 binaryTypeError(node, token, left, right);
317 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
319 if (type->isArray() || (type->isInt32() && type->tag())) {
320 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
327 SemanticAnalysis::visitForLValue(Expression *expression)
329 if (expression->isIndexExpression()) {
330 Type *type = visitAndApplyType(expression);
334 if (type->isConst()) {
335 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
339 return type->contained();
342 if (!expression->isNameProxy()) {
343 cc_.reportError(expression->pos(), Message_ExpectedLValue);
347 NameProxy *proxy = expression->toNameProxy();
348 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
349 cc_.reportError(expression->pos(), Message_ExpectedLValue);
353 Variable *var = proxy->binding()->toVariable();
357 if (var->type()->isReference()) {
358 if (var->type()->isConst()) {
359 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
362 return var->type()->contained();
367 SemanticAnalysis::ControlStatus
368 SemanticAnalysis::visitForControl(Statement *statement)
370 ControlScope scope(&control_);
371 statement->accept(this);
372 return scope.status();
376 SemanticAnalysis::visit(NameProxy *name)
378 BoundName *binding = name->binding();
380 if (binding->scope()->kind() == Scope::GLOBAL) {
381 if (!function_ || function_->isPublic()) {
382 // Whatever we're referencing must be kept alive no matter what.
383 // As such, we simply mark it used, and don't do anything special.
385 } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
386 // Otherwise, we're inside a normal stock or function. Since we
387 // don't really know if we've been used yet, we shouldn't
388 // prematurely references as alive. Instead, we keep a list of
389 // which names have been used, so we can mark them later if needed.
391 // Note that we skip this step if the binding is already in the
393 if (!function_->addUsedGlobal(binding))
398 name->setType(binding->type());
402 SemanticAnalysis::visit(Assignment *node)
404 Local<Type> exprType(zone_, visitForLoad(node->expression()));
408 Local<Type> type(zone_, visitForLValue(node->lvalue()));
412 if (node->token() != TOK_ASSIGN) {
413 if (!typeCheckBinary(node, node->token(), type, exprType))
417 if (!typeCheckAssignment(node, exprType, type, true))
424 SemanticAnalysis::visit(IncDecExpression *node)
426 Local<Type> type(zone_, visitForLValue(node->expression()));
430 assert(!type->isReference());
432 if ((!type->isInt32() || (type->isInt32() && type->tag())) && !type->isFloat()) {
433 unaryTypeError(node, node->token(), type);
441 SemanticAnalysis::visit(UnaryExpression *node)
443 Local<Type> type(zone_, visitForLoad(node->expression()));
447 switch (node->token())
450 if (!canTest(node->expression(), type))
452 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
459 if (!type->isFloat() && (!type->isInt32() || type->tag())) {
460 unaryTypeError(node, node->token(), type);
468 Local<String> tag(zone_, node->tag());
469 Local<Type> to(zone_, zone_->types()->getPrimitiveForTag(tag));
473 if ((!type->isFloat() && !type->isInt32()) ||
474 (!to->isFloat() && !to->isInt32()))
476 unaryTypeError(node, node->token(), type);
485 assert(node->token() == TOK_TILDE);
486 if (!type->isInt32() || type->tag()) {
487 unaryTypeError(node, node->token(), type);
496 SemanticAnalysis::visit(TernaryExpression *node)
498 Local<Type> type(zone_, visitForLoad(node->condition()));
502 if (!canTest(node->condition(), type))
505 Local<Type> left(zone_, visitForLoad(node->left()));
506 Local<Type> right(zone_, visitForLoad(node->right()));
511 binaryTypeError(node, TOK_QMARK, left, right);
517 SemanticAnalysis::visit(BinaryExpression *node)
519 Local<Type> left(zone_, visitForLoad(node->left()));
520 Local<Type> right(zone_, visitForLoad(node->right()));
524 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
528 node->setType(result);
532 SemanticAnalysis::visit(ReturnStatement *node)
534 // Set this early, so if we error we don't get more errors.
535 control_->returns(Returns_Always);
537 if (!node->expression()) {
538 if (!function_->type()->returnType()->isVoid())
539 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
543 Local<Type> type(zone_, visitForLoad(node->expression()));
547 Local<Type> returnType(zone_, function_->type()->returnType());
548 if (!typeCheckAssignment(node, type, returnType, true))
553 SemanticAnalysis::visit(ForStatement *node)
555 LoopScope loop(&loop_);
558 scope_ = node->scope();
560 if (node->initialization())
561 node->initialization()->accept(this);
563 if (node->condition()) {
564 Local<Type> type(zone_, visitForLoad(node->condition()));
565 if (!type || !canTest(node->condition(), type)) {
571 node->update()->accept(this);
573 ControlStatus status = visitForControl(node->body());
575 // If there is a condition, we treat this like a while loop. Otherwise,
576 // join point is only reachable if the loop contains a break. The
577 // termination status doesn't tell us anything yet.
578 if (node->condition() || loop.breaks())
579 control_->merge(status, ControlStatus(false, Returns_Never));
581 control_->terminate(status.returns());
584 scope_ = scope_->enclosing();
588 SemanticAnalysis::visit(WhileStatement *node)
590 LoopScope loop(&loop_);
592 Local<Type> type(zone_, visitForLoad(node->condition()));
593 if (!type || !canTest(node->condition(), type)) {
597 ControlStatus status = visitForControl(node->body());
599 // Detect loops that will always have a fork in the control-flow graph.
600 // This will be a |while| loop, or a |do-while| loop whose body does
603 // For now, we treat these as an |if| regardless of the direction the
604 // branch can take. That means the control-flow is always conditional.
605 if (node->token() == TOK_WHILE ||
606 !status.terminates() ||
609 control_->merge(status, ControlStatus(false, Returns_Never));
611 // At this point, we've got a do-while loop with a |return| or
612 // |continue|, meaning that the rest of the block is unreachable.
613 control_->terminate(status.returns());
618 SemanticAnalysis::visit(BlockStatement *node)
621 scope_ = node->scope();
622 for (size_t i = 0; i < node->statements()->length(); i++) {
623 Statement *statement = node->statements()->at(i);
624 statement->accept(this);
627 scope_ = scope_->enclosing();
631 SemanticAnalysis::visit(VariableDeclaration *node)
633 Local<String> tag(zone_, node->tag());
634 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
638 if (node->postDimensions()) {
639 Local<Type> init(zone_);
640 if (node->initialization()) {
641 if ((init = visitForLoad(node->initialization())) == NULL)
645 if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
646 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
650 // If we have an initializer, make sure it's the same type.
651 if (init && node->postDimensions()->length() != init->levels()) {
652 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
656 Local<Type> check(zone_, init);
657 for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
658 Expression *expr = node->postDimensions()->at(i);
662 Local<Type> exprType(zone_, visitForLoad(expr));
666 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
667 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
672 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
675 cc_.reportError(expr->pos(), Message_BadArraySize);
678 if (size >= int(INT_MAX / sizeof(int))) {
679 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
684 if (check->elements() == -1) {
685 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
689 if (check->isCharArray()) {
690 if (check->elements() > size) {
691 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
694 } else if (check->elements() != size) {
695 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
701 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
705 // here until we get dynamic array support.
706 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
710 // Infer the size from the initializer.
712 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
715 if (init->elements() == -1) {
716 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
719 size = init->elements();
722 type = zone_->types()->unsafeArray(type, size, false);
727 check = check->contained();
730 // If this variable is stack allocated, we could use the LIFO heap
731 // to allocate it. If that's the case, make sure to reserve a slot
732 // so we can unwind the LIFO heap at the end of this scope.
733 if (!node->variable()->needsHeapAllocation())
734 scope_->setUsesLifoHeap();
736 if (node->initialization()) {
737 Local<Type> right(zone_, visitForLoad(node->initialization()));
740 if (!typeCheckAssignment(node, type, right, true))
743 if (type->primitive() == PrimitiveType_Char) {
744 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
749 node->variable()->setType(type);
753 SemanticAnalysis::visit(IntegerLiteral *node)
755 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
759 SemanticAnalysis::visit(BooleanLiteral *node)
761 node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
765 SemanticAnalysis::visit(ExpressionStatement *node)
767 visitAndApplyType(node->expression());
771 SemanticAnalysis::preanalyze(FunctionStatement *node)
773 Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
777 // Apply types to arguments.
778 for (size_t i = 0; i < node->parameters()->length(); i++) {
779 Parameter *parameter = node->parameters()->at(i);
781 Local<String> tag(zone_, parameter->tag());
782 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
786 if (parameter->reference()) {
787 if (parameter->dimensions()) {
788 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
792 type = zone_->types()->getReference(type, parameter->isConst());
795 } else if (parameter->dimensions()) {
796 if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
797 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
801 if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
802 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
806 for (size_t i = parameter->dimensions()->length() - 1;
807 i < parameter->dimensions()->length();
810 int size = Type::UNKNOWN_SIZE;
811 if (Expression *expr = parameter->dimensions()->at(i)) {
813 if (!EvaluateForConstant(expr, &box)) {
814 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
820 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
826 if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
827 (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
829 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
833 args->set(zone_, i, type);
834 parameter->variable()->setType(type);
837 Local<Type> returnType(zone_);
838 if (node->returnTag()) {
839 Local<String> tag(zone_, node->returnTag());
840 returnType = zone_->types()->getPrimitiveForTag(tag);
841 } else if (node->hasExplicitReturn() || node->fun()->isNative()) {
842 returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
844 returnType = zone_->types()->getVoid();
849 Local<Type> funtype(zone_);
850 if (node->fun()->isNative())
851 funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
853 funtype = zone_->types()->newFunction(returnType, args);
857 // If the function already has a type, it was forward declared before, and
858 // now this is our chance to type check the second declaration.
859 if (node->fun()->type()) {
860 Local<Type> forward(zone_, node->fun()->type());
861 if (!Type::Compare(funtype, forward)) {
862 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
865 node->fun()->setForwardType(forward);
868 node->fun()->setType(funtype);
874 SemanticAnalysis::visit(FunctionStatement *node)
876 function_ = node->fun();
877 scope_ = node->scope();
879 ControlScope control(&control_);
881 node->body()->accept(this);
883 ControlStatus status = control.status();
884 if (status.returns() == Returns_Sometimes) {
885 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
886 } else if (status.returns() == Returns_Never) {
887 if (!function_->type()->returnType()->isVoid())
888 cc_.reportError(node->pos(), Message_MissingReturnValue);
897 SemanticAnalysis::typeCheckArrayAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
899 Local<Type> actual(zone_, argActual);
900 Local<Type> given(zone_, argGiven);
902 if (!given->isArray()) {
903 cc_.reportError(node->pos(), Message_ExpectedArray);
906 if (given->levels() != actual->levels()) {
907 cc_.reportError(node->pos(), Message_ArrayDimensionsMismatch);
912 while (given->isArray()) {
913 if (actual->elements() != -1) {
915 if (given->elements() == -1 || actual->elements() == -1) {
916 cc_.reportError(node->pos(), Message_ArraySizeNotKnown);
920 if (actual->isCharArray()) {
921 // String assignment can have a truncated |given|.
922 if (given->elements() > actual->elements()) {
923 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
927 if (given->elements() != actual->elements()) {
928 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
933 if (actual->elements() != -1 && given->elements() != actual->elements()) {
934 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, level);
939 given = given->contained();
940 actual = actual->contained();
943 if (given->primitive() != actual->primitive()) {
944 // :TODO: leaks an interior pointer.
945 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
946 const char *actualTag = given->tag() ? given->tag()->chars() : "_";
947 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
955 SemanticAnalysis::typeCheckAssignment(AstNode *node, Handle<Type> argGiven, Handle<Type> argActual, bool forAssign)
957 Local<Type> actual(zone_, argActual);
958 Local<Type> given(zone_, argGiven);
960 if (actual->isArray())
961 return typeCheckArrayAssignment(node, given, actual, forAssign);
963 if (given->isArray()) {
964 cc_.reportError(node->pos(), Message_CannotAssignArrayToScalar);
968 // The given type may not have been dereferenced.
969 if (given->isReference())
970 given = given->contained();
971 if (actual->isReference())
972 actual = actual->contained();
974 if (!given->isPrimitive() || !actual->isPrimitive()) {
975 cc_.reportError(node->pos(), Message_UnsupportedType);
979 if (given->primitive() != actual->primitive()) {
980 // :TODO: leaks an interior pointer
981 const char *givenTag = given->tag() ? given->tag()->chars() : "_";
982 const char *actualTag = actual->tag() ? actual->tag()->chars() : "_";
983 cc_.reportError(node->pos(), Message_TagMismatch, actualTag, givenTag);
991 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
993 return typeCheckAssignment(node, given, actual, false);
997 SemanticAnalysis::visit(CallExpression *node)
999 Local<Type> type(zone_, visitForLoad(node->callee()));
1003 if (!type->isFunction()) {
1004 cc_.reportError(node->pos(), Message_CalleeNotFunction);
1007 if (node->arguments()->length() != type->parameters()->length()) {
1008 if (!type->isNative() ||
1009 !type->isNativeVariadic() ||
1010 node->arguments()->length() < type->parameters()->length())
1012 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
1017 // Currently, only calls from a NameProxy are possible.
1018 NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
1019 if (fun->isForward()) {
1020 cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
1024 for (unsigned i = 0; i < node->arguments()->length(); i++) {
1025 // Note: we don't compute references unless the callee needs a
1027 Expression *expression = node->arguments()->at(i);
1028 Local<Type> given(zone_, visitAndApplyType(expression));
1032 // Since we skip a load, check for a call expression that returns void.
1033 if (given->isVoid()) {
1034 assert(expression->isCallExpression());
1035 CallExpression *call = expression->toCallExpression();
1036 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
1040 // If it's an IndexExpression, we special case the ability to compute
1042 if (expression->isIndexExpression())
1043 given = given->contained();
1045 bool mustComputeReference;
1046 if (i >= type->parameters()->length()) {
1047 // Special handling for natives. Arguments past the formal must
1048 // always have references computed. However, arrays are already
1049 // references for natives.
1050 assert(type->isNative() && type->isNativeVariadic());
1051 mustComputeReference = !given->isReference() && !given->isArray();
1053 Local<Type> actual(zone_, type->parameterAt(i));
1054 if (!typeCheckParameter(expression, given, actual))
1056 mustComputeReference = actual->isReference() && !given->isReference();
1059 // If the actual is a reference, and the given is not, we'll need to
1060 // compute a reference, which may be allocated on the stack.
1061 if (mustComputeReference)
1062 scope_->setUsesLifoHeap();
1065 node->setType(fun->type()->returnType());
1069 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
1071 // If both sides terminate in a return, we consider this a return as well.
1072 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
1073 terminate(Returns_Always);
1077 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
1079 : Returns_Sometimes;
1081 if (left.terminates() && right.terminates())
1088 SemanticAnalysis::visit(IfStatement *node)
1090 Local<Type> type(zone_, visitForLoad(node->condition()));
1094 if (!canTest(node, type))
1097 ControlStatus trueBranch = visitForControl(node->ifTrue());
1098 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
1100 if (node->ifFalse())
1101 falseBranch = visitForControl(node->ifFalse());
1103 control_->merge(trueBranch, falseBranch);
1107 SemanticAnalysis::visit(IndexExpression *node)
1109 Local<Type> left(zone_, visitForLoad(node->left()));
1110 Local<Type> right(zone_, visitForLoad(node->right()));
1112 if (!left || !right)
1115 if (!right->isInt32()) {
1116 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
1119 if (!left->isArray()) {
1120 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
1123 node->setType(left);
1127 SemanticAnalysis::visit(EnumStatement *node)
1129 // Forbid the blessed types.
1130 Local<String> tag(zone_, node->name());
1131 if (!strcmp(tag->chars(), "Float") ||
1132 !strcmp(tag->chars(), "String") ||
1133 !strcmp(tag->chars(), "any") ||
1134 !strcmp(tag->chars(), "bool"))
1136 cc_.reportError(node->pos(), Message_InvalidEnumName);
1140 Local<Type> type(zone_, zone_->types()->getPrimitiveForTag(tag));
1145 for (size_t i = 0; i < node->entries()->length(); i++) {
1146 EnumStatement::Entry &entry = node->entries()->at(i);
1148 BoxedPrimitive box = BoxedPrimitive::Int(value);
1150 entry.expr->accept(this);
1151 if (!EvaluateForConstant(entry.expr, &box)) {
1152 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1156 assert(box.type() == PrimitiveType_Int32);
1157 value = box.toInt();
1160 entry.name->set(type, box);
1166 SemanticAnalysis::visit(StringLiteral *node)
1168 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1172 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1176 node->setType(type);
1180 SemanticAnalysis::visit(FloatLiteral *node)
1182 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1186 node->setType(type);
1190 SemanticAnalysis::visit(BreakStatement *node)
1193 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1197 // Note: ignore breaks that occur in unreachable control-flow.
1198 if (!control_->status().terminates())
1201 control_->terminate(Returns_Never);
1205 SemanticAnalysis::visit(ContinueStatement *node)
1208 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1212 // Note: ignore continues that occur in unreachable control-flow.
1213 if (!control_->status().terminates())
1214 loop_->addContinue();
1216 control_->terminate(Returns_Never);