Added runtime support for default arguments.
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"
33 IsPrimitiveType(Type *type, PrimitiveType primitive)
38 if (!type->isPrimitive())
41 return primitive == type->primitive();
45 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
50 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
54 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
63 EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
67 *out = BoxedPrimitive::Int(-inner.toInt());
76 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
78 switch (expression->kind()) {
79 case AstNode::kBinaryExpression:
83 BinaryExpression *b = expression->toBinaryExpression();
84 if (!EvaluateForConstant(b->left(), &left) ||
85 !EvaluateForConstant(b->right(), &right))
89 return EvaluateBinaryOperation(b->token(), left, right, out);
92 case AstNode::kUnaryExpression:
95 UnaryExpression *u = expression->toUnaryExpression();
96 if (!EvaluateForConstant(u->expression(), &inner))
98 return EvaluateUnaryOperation(u->token(), inner, out);
101 case AstNode::kNameProxy:
103 NameProxy *proxy = expression->toNameProxy();
104 if (proxy->binding()->kind() != BoundName::CONSTANT)
107 NamedConstant *c = proxy->binding()->toNamedConstant();
108 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
115 case AstNode::kBooleanLiteral:
116 *out = BoxedPrimitive::Bool(expression->toBooleanLiteral()->token() == TOK_TRUE);
119 case AstNode::kIntegerLiteral:
120 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
128 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
138 SemanticAnalysis::analyze()
143 scope_ = tree_->scope();
145 for (size_t i = 0; i < tree_->statements()->length(); i++) {
146 Statement *statement = tree_->statements()->at(i);
147 if (statement->isFunctionStatement()) {
148 FunctionStatement *funstmt = statement->toFunctionStatement();
149 if (!preanalyze(funstmt))
151 } else if (statement->isEnumStatement()) {
152 EnumStatement *enumstmt = statement->toEnumStatement();
154 // We pre-fill global enum types, since they may occur in function
155 // signatures. This should probably be somewhere else...
156 Local<String> name(zone_, enumstmt->name());
157 Local<Type> type(zone_);
159 type = zone_->types()->newEnum(name);
161 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
166 enumstmt->decl()->setType(type);
167 } else if (statement->isStructureStatement()) {
168 StructureStatement *node = statement->toStructureStatement();
170 if (!node->decl()->type())
175 for (size_t i = 0; i < tree_->statements()->length(); i++) {
176 Statement *statement = tree_->statements()->at(i);
177 statement->accept(this);
180 if (!determineLiveFunctions())
183 return !cc_.failures();
187 SemanticAnalysis::determineLiveFunctions()
189 Vector<NamedFunction *> worklist;
192 for (size_t i = 0; i < tree_->statements()->length(); i++) {
193 Statement *statement = tree_->statements()->at(i);
194 if (!statement->isFunctionStatement())
197 FunctionStatement *stmt = statement->toFunctionStatement();
198 NamedFunction *fun = stmt->fun();
202 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
203 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
205 // Names in these lists are always unused, however, we mark them
206 // as used while inserting into the work queue, to avoid double-
211 if (!worklist.append(name))
218 while (!worklist.empty()) {
219 NamedFunction *fun = worklist.popCopy();
221 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
222 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
225 if (!worklist.append(name))
235 SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
238 return zone_->types()->getPrimitive(PrimitiveType_Int32);
240 if (name->kind() == BoundName::UNBOUND) {
241 cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
245 if (name->kind() != BoundName::TYPE) {
246 cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
257 SemanticAnalysis::visitAndApplyType(Expression *expression)
259 expression->accept(this);
260 return expression->type();
264 SemanticAnalysis::visitForLoad(Expression *expression)
266 Local<Type> type(zone_, visitAndApplyType(expression));
270 if (type->isReference()) {
271 expression->setType(type->contained());
272 } else if (expression->isCallExpression()) {
273 if (type->isVoid()) {
274 CallExpression *call = expression->toCallExpression();
275 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
280 return expression->type();
283 // :TODO: this leaks an interior pointer.
285 ke::GetTypeName(Type *type)
289 if (type->isFunction())
293 if (type->isEnum() || type->isStruct())
294 return type->name()->chars();
295 if (type->isReference())
296 type = type->contained();
297 switch (type->primitive()) {
298 case PrimitiveType_Bool:
300 case PrimitiveType_Char:
302 case PrimitiveType_Int32:
304 case PrimitiveType_Float:
312 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
314 const char *op = TokenNames[token];
315 const char *name = GetTypeName(type);
317 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
321 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
323 const char *op = TokenNames[token];
324 const char *leftName = GetTypeName(left);
325 const char *rightName = GetTypeName(right);
327 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
331 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
333 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
334 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
336 // If either side is a float, the other side must be a float or int.
337 if (left->isFloat() || right->isFloat()) {
338 Type *floatType = left->isFloat() ? left : right;
339 Type *other = left->isFloat() ? right : left;
340 if (other->isFloat() || other->isInt32())
345 if (token == TOK_OR || token == TOK_AND) {
346 if (!canTest(node, left) || !canTest(node, right))
348 return zone_->types()->getPrimitive(PrimitiveType_Bool);
351 if (token >= TOK_EQUALS && token <= TOK_GE) {
352 if ((left->isFloat() || left->isInt32()) &&
353 (right->isFloat() || right->isInt32()))
355 return zone_->types()->getPrimitive(PrimitiveType_Bool);
357 binaryTypeError(node, token, left, right);
361 if (!left->isInt32() || !right->isInt32()) {
362 binaryTypeError(node, token, left, right);
370 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
372 if (!type->isPrimitive() && !type->isEnum()) {
373 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
380 SemanticAnalysis::visitForLValue(Expression *expression)
382 if (expression->isIndexExpression()) {
383 Type *type = visitAndApplyType(expression);
387 // if (type->isConst()) {
388 // cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
395 if (expression->isFieldExpression()) {
396 Type *type = visitAndApplyType(expression);
400 // if (expression->toFieldExpression()->left()->type()->isConst()) {
401 // cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
408 if (!expression->isNameProxy()) {
409 cc_.reportError(expression->pos(), Message_ExpectedLValue);
413 NameProxy *proxy = expression->toNameProxy();
414 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
415 cc_.reportError(expression->pos(), Message_ExpectedLValue);
419 Variable *var = proxy->binding()->toVariable();
423 if (var->type()->isReference()) {
424 if (var->type()->isConst()) {
425 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
428 return var->type()->contained();
433 SemanticAnalysis::ControlStatus
434 SemanticAnalysis::visitForControl(Statement *statement)
436 ControlScope scope(&control_);
437 statement->accept(this);
438 return scope.status();
442 SemanticAnalysis::visit(NameProxy *name)
444 BoundName *binding = name->binding();
446 if (binding->scope()->kind() == Scope::GLOBAL) {
447 if (!function_ || function_->isPublic()) {
448 // Whatever we're referencing must be kept alive no matter what.
449 // As such, we simply mark it used, and don't do anything special.
451 } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
452 // Otherwise, we're inside a normal stock or function. Since we
453 // don't really know if we've been used yet, we shouldn't
454 // prematurely references as alive. Instead, we keep a list of
455 // which names have been used, so we can mark them later if needed.
457 // Note that we skip this step if the binding is already in the
459 if (!function_->addUsedGlobal(binding))
464 name->setType(binding->type());
468 SemanticAnalysis::visit(Assignment *node)
470 Local<Type> exprType(zone_, visitForLoad(node->expression()));
474 Local<Type> type(zone_, visitForLValue(node->lvalue()));
478 if (node->token() != TOK_ASSIGN) {
479 if (!typeCheckBinary(node, node->token(), type, exprType))
483 if (!typeCheckAssignment(node->pos(), exprType, type, true))
490 SemanticAnalysis::visit(IncDecExpression *node)
492 Local<Type> type(zone_, visitForLValue(node->expression()));
496 assert(!type->isReference());
498 if (!type->isInt32() && !type->isFloat()) {
499 unaryTypeError(node, node->token(), type);
507 SemanticAnalysis::visit(UnaryExpression *node)
509 Local<Type> type(zone_, visitForLoad(node->expression()));
513 switch (node->token())
516 if (!canTest(node->expression(), type))
518 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
525 if (!type->isFloat() && !type->isInt32()) {
526 unaryTypeError(node, node->token(), type);
534 Local<Type> to(zone_, bindType(node->pos(), node->type()));
538 if ((!type->isFloat() && !type->isInt32OrEnum()) ||
539 (!to->isFloat() && !to->isInt32OrEnum()))
541 unaryTypeError(node, node->token(), type);
550 assert(node->token() == TOK_TILDE);
551 if (!type->isInt32()) {
552 unaryTypeError(node, node->token(), type);
561 SemanticAnalysis::visit(TernaryExpression *node)
563 Local<Type> type(zone_, visitForLoad(node->condition()));
567 if (!canTest(node->condition(), type))
570 Local<Type> left(zone_, visitForLoad(node->left()));
571 Local<Type> right(zone_, visitForLoad(node->right()));
576 binaryTypeError(node, TOK_QMARK, left, right);
582 SemanticAnalysis::visit(BinaryExpression *node)
584 Local<Type> left(zone_, visitForLoad(node->left()));
585 Local<Type> right(zone_, visitForLoad(node->right()));
589 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
593 node->setType(result);
597 SemanticAnalysis::visit(ReturnStatement *node)
599 // Set this early, so if we error we don't get more errors.
600 control_->returns(Returns_Always);
602 if (!node->expression()) {
603 if (!function_->type()->returnType()->isVoid())
604 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
608 Local<Type> type(zone_, visitForLoad(node->expression()));
612 Local<Type> returnType(zone_, function_->type()->returnType());
613 if (!typeCheckAssignment(node->pos(), type, returnType, true))
618 SemanticAnalysis::visit(ForStatement *node)
620 LoopScope loop(&loop_);
623 scope_ = node->scope();
625 if (node->initialization())
626 node->initialization()->accept(this);
628 if (node->condition()) {
629 Local<Type> type(zone_, visitForLoad(node->condition()));
630 if (!type || !canTest(node->condition(), type)) {
636 node->update()->accept(this);
638 ControlStatus status = visitForControl(node->body());
640 // If there is a condition, we treat this like a while loop. Otherwise,
641 // join point is only reachable if the loop contains a break. The
642 // termination status doesn't tell us anything yet.
643 if (node->condition() || loop.breaks())
644 control_->merge(status, ControlStatus(false, Returns_Never));
646 control_->terminate(status.returns());
649 scope_ = scope_->enclosing();
653 SemanticAnalysis::visit(WhileStatement *node)
655 LoopScope loop(&loop_);
657 Local<Type> type(zone_, visitForLoad(node->condition()));
658 if (!type || !canTest(node->condition(), type)) {
662 ControlStatus status = visitForControl(node->body());
664 // Detect loops that will always have a fork in the control-flow graph.
665 // This will be a |while| loop, or a |do-while| loop whose body does
668 // For now, we treat these as an |if| regardless of the direction the
669 // branch can take. That means the control-flow is always conditional.
670 if (node->token() == TOK_WHILE ||
671 !status.terminates() ||
674 control_->merge(status, ControlStatus(false, Returns_Never));
676 // At this point, we've got a do-while loop with a |return| or
677 // |continue|, meaning that the rest of the block is unreachable.
678 control_->terminate(status.returns());
683 SemanticAnalysis::visit(BlockStatement *node)
686 scope_ = node->scope();
687 for (size_t i = 0; i < node->statements()->length(); i++) {
688 Statement *statement = node->statements()->at(i);
689 statement->accept(this);
692 scope_ = scope_->enclosing();
696 IsScalarString(Type *type)
698 if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
700 if (type->isReference())
701 return IsScalarString(type->contained());
706 SemanticAnalysis::visit(VariableDeclaration *node)
708 Local<Type> type(zone_, bindType(node->pos(), node->type()));
712 if (node->postDimensions()) {
713 Local<Type> init(zone_);
714 if (node->initialization()) {
715 if ((init = visitForLoad(node->initialization())) == NULL)
719 if (node->postDimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
720 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
724 // If we have an initializer, make sure it's the same type.
725 if (init && node->postDimensions()->length() != init->levels()) {
726 cc_.reportError(node->pos(), Message_ArrayInitializerDepth);
730 Local<Type> check(zone_, init);
731 for (size_t i = node->postDimensions()->length() - 1; i < node->postDimensions()->length(); i--) {
732 Expression *expr = node->postDimensions()->at(i);
736 Local<Type> exprType(zone_, visitForLoad(expr));
740 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
741 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
746 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
749 cc_.reportError(expr->pos(), Message_BadArraySize);
752 if (size >= int(INT_MAX / sizeof(int))) {
753 cc_.reportError(expr->pos(), Message_ArraySizeTooBig);
758 if (check->elements() == -1) {
759 cc_.reportError(expr->pos(), Message_ArraySizeCannotBeDetermined);
763 if (check->isCharArray()) {
764 if (check->elements() > size) {
765 cc_.reportError(node->pos(), Message_ArrayAssignmentTooBig);
768 } else if (check->elements() != size) {
769 cc_.reportError(node->pos(), Message_ArrayDimensionSizeMismatch, unsigned(i));
775 cc_.reportError(node->pos(), Message_DynamicArrayHasInitializer);
779 // here until we get dynamic array support.
780 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
784 // Infer the size from the initializer.
786 cc_.reportError(node->pos(), Message_ArraySizeNotSpecified);
789 if (init->elements() == -1) {
790 cc_.reportError(node->pos(), Message_ArraySizeCannotBeDetermined);
793 size = init->elements();
796 type = zone_->types()->unsafeArray(type, size, false);
801 check = check->contained();
804 if (node->initialization()) {
805 Local<Type> right(zone_, visitForLoad(node->initialization()));
808 if (!typeCheckAssignment(node->pos(), type, right, true))
812 if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
813 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
818 // If this variable is stack allocated, we could use the LIFO heap
819 // to allocate it. If that's the case, make sure to reserve a slot
820 // so we can unwind the LIFO heap at the end of this scope.
821 if (!node->variable()->needsHeapAllocation()) {
822 if (type->isArray() || type->isStruct())
823 scope_->setUsesLifoHeap();
826 node->variable()->setType(type);
830 SemanticAnalysis::visit(IntegerLiteral *node)
832 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
836 SemanticAnalysis::visit(BooleanLiteral *node)
838 node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
842 SemanticAnalysis::visit(ExpressionStatement *node)
844 visitAndApplyType(node->expression());
848 SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
850 // First see if we can get a constant expression.
852 if (EvaluateForConstant(parameter->initializer(), &prim)) {
853 Local<Type> given(zone_, zone_->types()->getPrimitive(prim.type()));
854 if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
857 if (prim.type() == PrimitiveType_Int32)
858 return Box::New(zone_, type, prim.toInt());
859 return Box::New(zone_, type, int(prim.toBool()));
862 cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
867 SemanticAnalysis::preanalyze(FunctionStatement *node)
869 Local<FixedArray> args(zone_, FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old));
873 Local<FixedArray> defaults(zone_);
875 // Apply types to arguments.
876 for (size_t i = 0; i < node->parameters()->length(); i++) {
877 Parameter *parameter = node->parameters()->at(i);
879 Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
883 if (parameter->initializer()) {
885 defaults = FixedArray::New(zone_, node->parameters()->length(), Heap::Tenure_Old);
890 Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
894 defaults->set(zone_, i, box);
897 if (parameter->reference()) {
898 if (parameter->dimensions()) {
899 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
903 if (type->isStruct()) {
904 cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
908 type = zone_->types()->getReference(type, parameter->isConst());
911 } else if (parameter->dimensions()) {
912 if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
913 cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
917 if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
918 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
922 for (size_t i = parameter->dimensions()->length() - 1;
923 i < parameter->dimensions()->length();
926 int size = Type::UNKNOWN_SIZE;
927 if (Expression *expr = parameter->dimensions()->at(i)) {
929 if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
930 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
936 type = zone_->types()->unsafeArray(type, size, parameter->isConst());
942 if (IsScalarString(type)) {
943 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
947 args->set(zone_, i, type);
948 parameter->variable()->setType(type);
951 Local<Type> returnType(zone_);
952 if (node->returnType() ||
953 node->hasExplicitReturn() ||
954 node->fun()->isNative())
956 returnType = bindType(node->pos(), node->returnType());
958 returnType = zone_->types()->getVoid();
963 Local<Type> funtype(zone_);
964 if (node->fun()->isNative())
965 funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
967 funtype = zone_->types()->newFunction(returnType, args, defaults);
971 // If the function already has a type, it was forward declared before, and
972 // now this is our chance to type check the second declaration.
973 if (node->fun()->type()) {
974 Local<Type> forward(zone_, node->fun()->type());
975 if (!Type::Compare(funtype, forward)) {
976 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
979 node->fun()->setForwardType(forward);
982 node->fun()->setType(funtype);
988 SemanticAnalysis::visit(FunctionStatement *node)
990 function_ = node->fun();
991 scope_ = node->scope();
993 ControlScope control(&control_);
995 node->body()->accept(this);
997 ControlStatus status = control.status();
998 if (status.returns() == Returns_Sometimes) {
999 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
1000 } else if (status.returns() == Returns_Never) {
1001 if (!function_->type()->returnType()->isVoid())
1002 cc_.reportError(node->pos(), Message_MissingReturnValue);
1011 SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
1013 cc_.reportError(pos, Message_TypeMismatch,
1014 GetTypeName(actual),
1015 GetTypeName(given));
1019 SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
1020 Handle<Type> argActual, bool forAssign)
1022 Local<Type> actual(zone_, argActual);
1023 Local<Type> given(zone_, argGiven);
1025 if (!given->isArray()) {
1026 cc_.reportError(pos, Message_ExpectedArray);
1029 if (given->levels() != actual->levels()) {
1030 cc_.reportError(pos, Message_ArrayDimensionsMismatch);
1035 while (given->isArray()) {
1036 if (actual->elements() != -1) {
1038 if (given->elements() == -1 || actual->elements() == -1) {
1039 cc_.reportError(pos, Message_ArraySizeNotKnown);
1043 if (actual->isCharArray()) {
1044 // String assignment can have a truncated |given|.
1045 if (given->elements() > actual->elements()) {
1046 cc_.reportError(pos, Message_ArrayAssignmentTooBig);
1050 if (given->elements() != actual->elements()) {
1051 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1056 if (actual->elements() != -1 && given->elements() != actual->elements()) {
1057 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1062 given = given->contained();
1063 actual = actual->contained();
1066 return typeCheckAssignment(pos, given, actual, forAssign);
1070 SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
1071 Handle<Type> argActual, bool forAssign)
1073 Local<Type> actual(zone_, argActual);
1074 Local<Type> given(zone_, argGiven);
1076 if (actual->isArray())
1077 return typeCheckArrayAssignment(pos, given, actual, forAssign);
1079 if (given->isArray()) {
1080 cc_.reportError(pos, Message_CannotAssignArrayToScalar);
1084 // The given type may not have been dereferenced.
1085 if (given->isReference())
1086 given = given->contained();
1087 if (actual->isReference())
1088 actual = actual->contained();
1090 // We coerce unchecked to a few things.
1091 if (actual->isUnchecked() || given->isUnchecked()) {
1092 Type *check = actual->isUnchecked() ? given : actual;
1093 if (check->isUnchecked() ||
1101 typeMismatch(pos, actual, given);
1105 if (actual->isEnum()) {
1106 if (!given->isEnum() || actual != given) {
1107 typeMismatch(pos, actual, given);
1113 if (actual->isStruct()) {
1114 if (!given->isStruct() || actual != given) {
1115 typeMismatch(pos, actual, given);
1121 if (given->isEnum() || given->isFunction() || given->isStruct()) {
1122 typeMismatch(pos, actual, given);
1126 // This coercion is trivial.
1127 if (given->isBool() && actual->isInt32())
1130 if (given->primitive() != actual->primitive()) {
1131 typeMismatch(pos, actual, given);
1139 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
1141 return typeCheckAssignment(node->pos(), given, actual, false);
1145 SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
1147 if (type->parameters()->length() == actual)
1150 if (actual > type->parameters()->length()) {
1151 if (!type->isNative() || !type->isNativeVariadic())
1156 if (!type->defaults())
1159 // Missing arguments. See if there's a default argument for each missing
1161 for (unsigned i = actual; i < type->parameters()->length(); i++) {
1162 if (!type->defaults()->at(i))
1170 SemanticAnalysis::visit(CallExpression *node)
1172 Local<Type> type(zone_, visitForLoad(node->callee()));
1176 if (!type->isFunction()) {
1177 cc_.reportError(node->pos(), Message_CalleeNotFunction);
1181 if (!checkArgumentCount(type, node->arguments()->length())) {
1182 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
1186 // Currently, only calls from a NameProxy are possible.
1187 NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
1188 if (fun->isForward()) {
1189 cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
1193 for (unsigned i = 0; i < node->arguments()->length(); i++) {
1194 // Note: we don't compute references unless the callee needs a
1196 Expression *expression = node->arguments()->at(i);
1197 Local<Type> given(zone_, visitAndApplyType(expression));
1201 // Since we skip a load, check for a call expression that returns void.
1202 if (given->isVoid()) {
1203 assert(expression->isCallExpression());
1204 CallExpression *call = expression->toCallExpression();
1205 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
1209 bool mustComputeReference;
1210 if (i >= type->parameters()->length()) {
1211 // Special handling for natives. Arguments past the formal must
1212 // always have references computed. However, arrays are already
1213 // references for natives.
1214 assert(type->isNative() && type->isNativeVariadic());
1215 mustComputeReference = !given->isReference() && !given->isArray();
1217 Local<Type> actual(zone_, type->parameterAt(i));
1219 if (expression->isIndexExpression() && actual->isArray()) {
1220 // We special case the ability to pass x[y] into x[], which
1221 // creates an array slice. We only do this if we know the
1222 // assignment would otherwise not type-check.
1223 IndexExpression *index = expression->toIndexExpression();
1224 if (index->left()->type()->levels() == actual->levels())
1225 given = index->left()->type();
1228 if (!typeCheckParameter(expression, given, actual))
1230 mustComputeReference = actual->isReference() && !given->isReference();
1233 // If the actual is a reference, and the given is not, we'll need to
1234 // compute a reference, which may be allocated on the stack.
1235 if (mustComputeReference)
1236 scope_->setUsesLifoHeap();
1239 node->setType(fun->type()->returnType());
1243 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
1245 // If both sides terminate in a return, we consider this a return as well.
1246 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
1247 terminate(Returns_Always);
1251 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
1253 : Returns_Sometimes;
1255 if (left.terminates() && right.terminates())
1262 SemanticAnalysis::visit(IfStatement *node)
1264 Local<Type> type(zone_, visitForLoad(node->condition()));
1268 if (!canTest(node, type))
1271 ControlStatus trueBranch = visitForControl(node->ifTrue());
1272 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
1274 if (node->ifFalse())
1275 falseBranch = visitForControl(node->ifFalse());
1277 control_->merge(trueBranch, falseBranch);
1281 SemanticAnalysis::visit(IndexExpression *node)
1283 Local<Type> left(zone_, visitForLoad(node->left()));
1284 Local<Type> right(zone_, visitForLoad(node->right()));
1286 if (!left || !right)
1289 if (!right->isInt32() && !right->isEnum()) {
1290 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
1293 if (!left->isArray()) {
1294 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
1298 // Note: char arrays are automatically up-casted to return an int32.
1299 if (left->isCharArray())
1300 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
1302 node->setType(left->contained());
1306 SemanticAnalysis::visit(FieldExpression *node)
1308 Local<Type> left(zone_, visitForLoad(node->left()));
1312 if (!left->isStruct()) {
1313 cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
1318 Local<String> field(zone_, node->field());
1321 Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
1323 cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
1328 node->setFieldIndex(offset);
1329 node->setType(desc->type());
1333 SemanticAnalysis::visit(EnumStatement *node)
1335 Local<Type> type(zone_, node->decl()->type());
1340 for (size_t i = 0; i < node->entries()->length(); i++) {
1341 EnumStatement::Entry &entry = node->entries()->at(i);
1343 BoxedPrimitive box = BoxedPrimitive::Int(value);
1345 entry.expr->accept(this);
1346 if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
1347 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1351 assert(box.type() == PrimitiveType_Int32);
1352 value = box.toInt();
1355 entry.name->set(type, box);
1361 SemanticAnalysis::visit(StructureStatement *node)
1363 // If this node already has a type, it was pre-analyzed, so skip it.
1364 if (node->decl()->type())
1367 FieldList *fields = node->fields();
1368 Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
1372 Vector<unsigned> composedList;
1373 StructureBufferBuilder builder;
1375 Local<Type> type(zone_);
1376 Local<String> name(zone_);
1377 Local<Descriptor> desc(zone_);
1378 for (size_t i = 0; i < fields->length(); i++) {
1379 StructureStatement::Field *field = fields->at(i);
1381 type = bindType(field->pos(), field->type());
1385 if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
1386 cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
1391 if (!builder.add(type, &offset))
1394 name = field->name();
1395 desc = Descriptor::New(zone_, name, type, offset);
1399 desctable->set(zone_, i, desc);
1401 if (type->isStruct() || type->isArray()) {
1402 if (!composedList.append(i))
1407 Local<FixedArray> composed(zone_);
1408 if (composedList.length()) {
1409 composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
1413 for (unsigned i = 0; i < composedList.length(); i++)
1414 composed->set(zone_, i, desctable->at(i));
1417 Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
1421 name = node->decl()->name();
1422 type = zone_->types()->newStruct(name, desctable, map);
1427 node->decl()->setType(type);
1431 SemanticAnalysis::visit(StringLiteral *node)
1433 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1437 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1441 node->setType(type);
1445 SemanticAnalysis::visit(FloatLiteral *node)
1447 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1451 node->setType(type);
1455 SemanticAnalysis::visit(BreakStatement *node)
1458 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1462 // Note: ignore breaks that occur in unreachable control-flow.
1463 if (!control_->status().terminates())
1466 control_->terminate(Returns_Never);
1470 SemanticAnalysis::visit(ContinueStatement *node)
1473 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1477 // Note: ignore continues that occur in unreachable control-flow.
1478 if (!control_->status().terminates())
1479 loop_->addContinue();
1481 control_->terminate(Returns_Never);