Get preinc working again.
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"
24 #include "../Strings.h"
27 #include "../Heap-inl.h"
29 #include "NameBinding.h"
33 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
43 SemanticAnalysis::analyze()
53 IsPrimitiveType(Type *type, PrimitiveType primitive)
58 if (!type->isPrimitive())
61 return primitive == type->primitive();
65 EvaluateBinaryOperation(TokenKind kind, const BoxedPrimitive &left, const BoxedPrimitive &right,
70 *out = BoxedPrimitive::Int(left.toInt() + right.toInt());
74 *out = BoxedPrimitive::Int(left.toInt() << right.toInt());
83 EvaluateUnaryOperation(TokenKind kind, const BoxedPrimitive &inner, BoxedPrimitive *out)
87 *out = BoxedPrimitive::Int(-inner.toInt());
96 EvaluateForConstant(Expression *expression, BoxedPrimitive *out)
98 switch (expression->kind()) {
99 case AstNode::kBinaryExpression:
102 BoxedPrimitive right;
103 BinaryExpression *b = expression->toBinaryExpression();
104 if (!EvaluateForConstant(b->left(), &left) ||
105 !EvaluateForConstant(b->right(), &right))
109 return EvaluateBinaryOperation(b->token(), left, right, out);
112 case AstNode::kUnaryExpression:
114 BoxedPrimitive inner;
115 UnaryExpression *u = expression->toUnaryExpression();
116 if (!EvaluateForConstant(u->expression(), &inner))
118 return EvaluateUnaryOperation(u->token(), inner, out);
121 case AstNode::kNameProxy:
123 NameProxy *proxy = expression->toNameProxy();
124 if (proxy->binding()->kind() != BoundName::CONSTANT)
127 NamedConstant *c = proxy->binding()->toNamedConstant();
128 if (!IsPrimitiveType(c->type(), PrimitiveType_Int32))
135 case AstNode::kBooleanLiteral:
136 *out = BoxedPrimitive::Int(expression->toBooleanLiteral()->token() == TOK_TRUE ? 1 : 0);
139 case AstNode::kIntegerLiteral:
140 *out = BoxedPrimitive::Int(expression->toIntegerLiteral()->value());
148 SemanticAnalysis::SemanticAnalysis(Zone *zone, CompileContext &cc, ParseTree *tree)
158 SemanticAnalysis::analyze()
163 scope_ = tree_->globalScope();
164 assert(scope_->kind() == Scope::GLOBAL);
166 for (size_t i = 0; i < tree_->statements()->length(); i++) {
167 Statement *statement = tree_->statements()->at(i);
168 if (statement->isFunctionStatement()) {
169 FunctionStatement *funstmt = statement->toFunctionStatement();
170 if (!preanalyze(funstmt))
172 } else if (statement->isEnumStatement()) {
173 EnumStatement *enumstmt = statement->toEnumStatement();
175 // We pre-fill global enum types, since they may occur in function
176 // signatures. This should probably be somewhere else...
177 enumstmt->accept(this);
178 } else if (statement->isStructureStatement()) {
179 StructureStatement *node = statement->toStructureStatement();
181 if (!node->decl()->type())
183 } else if (statement->isFunctionTypeStatement()) {
184 FunctionTypeStatement *node = statement->toFunctionTypeStatement();
186 if (!node->decl()->type())
191 for (size_t i = 0; i < tree_->statements()->length(); i++) {
192 Statement *statement = tree_->statements()->at(i);
194 // We can't double-process these. Maybe put this check somewhere else.
195 if (statement->isEnumStatement())
198 statement->accept(this);
201 if (!determineLiveFunctions())
204 return !cc_.failures();
208 SemanticAnalysis::determineLiveFunctions()
210 Vector<NamedFunction *> worklist;
213 for (size_t i = 0; i < tree_->statements()->length(); i++) {
214 Statement *statement = tree_->statements()->at(i);
215 if (!statement->isFunctionStatement())
218 FunctionStatement *stmt = statement->toFunctionStatement();
219 NamedFunction *fun = stmt->fun();
223 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
224 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
226 // Names in these lists are always unused, however, we mark them
227 // as used while inserting into the work queue, to avoid double-
232 if (!worklist.append(name))
239 while (!worklist.empty()) {
240 NamedFunction *fun = worklist.popCopy();
242 for (size_t i = 0; i < fun->usedGlobals()->length(); i++) {
243 NamedFunction *name = fun->usedGlobals()->at(i)->toNamedFunction();
246 if (!worklist.append(name))
256 SemanticAnalysis::bindType(const SourcePosition &pos, BoundName *name)
259 return zone_->types()->getPrimitive(PrimitiveType_Int32);
261 if (name->kind() == BoundName::UNBOUND) {
262 cc_.reportError(pos, Message_TypeNotFound, name->name()->chars());
266 if (name->kind() != BoundName::TYPE) {
267 cc_.reportError(pos, Message_IdentifierIsNotAType, name->name()->chars());
278 SemanticAnalysis::visitAndApplyType(Expression *expression)
280 expression->accept(this);
281 return expression->type();
285 SemanticAnalysis::visitForLoad(Expression *expression)
287 Local<Type> type(zone_, visitAndApplyType(expression));
291 if (type->isReference()) {
292 expression->setType(type->contained());
293 } else if (expression->isCallExpression()) {
294 if (type->isVoid()) {
295 CallExpression *call = expression->toCallExpression();
296 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
301 return expression->type();
305 SemanticAnalysis::unaryTypeError(AstNode *node, TokenKind token, Handle<Type> type)
307 const char *op = TokenNames[token];
308 const char *name = GetTypeName(type);
310 cc_.reportError(node->pos(), Message_UnaryTypeError, op, name);
314 SemanticAnalysis::binaryTypeError(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
316 const char *op = TokenNames[token];
317 const char *leftName = GetTypeName(left);
318 const char *rightName = GetTypeName(right);
320 cc_.reportError(node->pos(), Message_BinaryTypeError, op, leftName, rightName);
324 SemanticAnalysis::typeCheckBinary(AstNode *node, TokenKind token, Handle<Type> left, Handle<Type> right)
326 if ((token >= TOK_PLUS && token <= TOK_SLASH) ||
327 (token >= TOK_ASSIGN_ADD && token <= TOK_ASSIGN_DIV))
329 // If either side is a float, the other side must be a float or int.
330 if (left->isFloat() || right->isFloat()) {
331 Type *floatType = left->isFloat() ? left : right;
332 Type *other = left->isFloat() ? right : left;
333 if (other->isFloat() || other->isInt32())
338 if (token == TOK_OR || token == TOK_AND) {
339 if (!canTest(node, left) || !canTest(node, right))
341 return zone_->types()->getPrimitive(PrimitiveType_Bool);
344 if (token >= TOK_EQUALS && token <= TOK_GE) {
345 if ((left->isFloat() || left->isInt32()) &&
346 (right->isFloat() || right->isInt32()))
348 return zone_->types()->getPrimitive(PrimitiveType_Bool);
350 binaryTypeError(node, token, left, right);
354 if (!left->isInt32() || !right->isInt32()) {
355 binaryTypeError(node, token, left, right);
363 SemanticAnalysis::canTest(AstNode *node, Handle<Type> type)
365 if (!type->isPrimitive() && !type->isEnum()) {
366 cc_.reportError(node->pos(), Message_ArrayIsNotBoolean);
373 SemanticAnalysis::visitForLValue(Expression *expression)
375 if (expression->isIndexExpression()) {
376 Type *type = visitAndApplyType(expression);
380 // if (type->isConst()) {
381 // cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
388 if (expression->isFieldExpression()) {
389 Type *type = visitAndApplyType(expression);
393 // if (expression->toFieldExpression()->left()->type()->isConst()) {
394 // cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
401 if (!expression->isNameProxy()) {
402 cc_.reportError(expression->pos(), Message_ExpectedLValue);
406 NameProxy *proxy = expression->toNameProxy();
407 if (!proxy->binding()->kind() == BoundName::VARIABLE) {
408 cc_.reportError(expression->pos(), Message_ExpectedLValue);
412 Variable *var = proxy->binding()->toVariable();
416 if (var->type()->isReference()) {
417 if (var->type()->isConst()) {
418 cc_.reportError(expression->pos(), Message_ReferenceIsConstant);
421 return var->type()->contained();
426 SemanticAnalysis::ControlStatus
427 SemanticAnalysis::visitForControl(Statement *statement)
429 ControlScope scope(&control_);
430 statement->accept(this);
431 return scope.status();
435 SemanticAnalysis::visit(NameProxy *name)
437 BoundName *binding = name->binding();
439 if (binding->scope()->kind() == Scope::GLOBAL) {
440 if (!function_ || function_->isPublic()) {
441 // Whatever we're referencing must be kept alive no matter what.
442 // As such, we simply mark it used, and don't do anything special.
444 } else if (!binding->used() && binding->kind() == BoundName::FUNCTION) {
445 // Otherwise, we're inside a normal stock or function. Since we
446 // don't really know if we've been used yet, we shouldn't
447 // prematurely references as alive. Instead, we keep a list of
448 // which names have been used, so we can mark them later if needed.
450 // Note that we skip this step if the binding is already in the
452 if (!function_->addUsedGlobal(binding))
457 name->setType(binding->type());
461 SemanticAnalysis::visit(Assignment *node)
463 Local<Type> exprType(zone_, visitForLoad(node->expression()));
467 Local<Type> type(zone_, visitForLValue(node->lvalue()));
471 if (node->token() != TOK_ASSIGN) {
472 if (!typeCheckBinary(node, node->token(), type, exprType))
476 if (!typeCheckAssignment(node->pos(), exprType, type, true))
483 SemanticAnalysis::visit(IncDecExpression *node)
485 Local<Type> type(zone_, visitForLValue(node->expression()));
489 assert(!type->isReference());
491 if (!type->isInt32() && !type->isFloat()) {
492 unaryTypeError(node, node->token(), type);
500 SemanticAnalysis::visit(UnaryExpression *node)
502 Local<Type> type(zone_, visitForLoad(node->expression()));
506 switch (node->token())
509 if (!canTest(node->expression(), type))
511 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
518 if (!type->isFloat() && !type->isInt32()) {
519 unaryTypeError(node, node->token(), type);
527 Local<Type> to(zone_, bindType(node->pos(), node->type()));
531 if ((!type->isFloat() && !type->isInt32OrEnum()) ||
532 (!to->isFloat() && !to->isInt32OrEnum()))
534 unaryTypeError(node, node->token(), type);
544 if (!type->isArray()) {
545 cc_.reportError(node->pos(), Message_SizeofNeedsArray);
548 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
553 assert(node->token() == TOK_TILDE);
554 if (!type->isInt32()) {
555 unaryTypeError(node, node->token(), type);
564 SemanticAnalysis::visit(TernaryExpression *node)
566 Local<Type> type(zone_, visitForLoad(node->condition()));
570 if (!canTest(node->condition(), type))
573 Local<Type> left(zone_, visitForLoad(node->left()));
574 Local<Type> right(zone_, visitForLoad(node->right()));
579 binaryTypeError(node, TOK_QMARK, left, right);
585 SemanticAnalysis::visit(BinaryExpression *node)
587 Local<Type> left(zone_, visitForLoad(node->left()));
588 Local<Type> right(zone_, visitForLoad(node->right()));
592 Local<Type> result(zone_, typeCheckBinary(node, node->token(), left, right));
596 node->setType(result);
600 SemanticAnalysis::visit(ReturnStatement *node)
602 // Set this early, so if we error we don't get more errors.
603 control_->returns(Returns_Always);
605 if (!node->expression()) {
606 if (!function_->type()->returnType()->isVoid())
607 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
611 Local<Type> type(zone_, visitForLoad(node->expression()));
615 Local<Type> returnType(zone_, function_->type()->returnType());
616 if (!typeCheckAssignment(node->pos(), type, returnType, true))
621 SemanticAnalysis::visit(ForStatement *node)
623 LoopScope loop(&loop_);
626 scope_ = node->scope();
628 if (node->initialization())
629 node->initialization()->accept(this);
631 if (node->condition()) {
632 Local<Type> type(zone_, visitForLoad(node->condition()));
633 if (!type || !canTest(node->condition(), type)) {
639 node->update()->accept(this);
641 ControlStatus status = visitForControl(node->body());
643 // If there is a condition, we treat this like a while loop. Otherwise,
644 // join point is only reachable if the loop contains a break. The
645 // termination status doesn't tell us anything yet.
646 if (node->condition() || loop.breaks())
647 control_->merge(status, ControlStatus(false, Returns_Never));
649 control_->terminate(status.returns());
652 scope_ = scope_->enclosing();
656 SemanticAnalysis::visit(WhileStatement *node)
658 LoopScope loop(&loop_);
660 Local<Type> type(zone_, visitForLoad(node->condition()));
661 if (!type || !canTest(node->condition(), type)) {
665 ControlStatus status = visitForControl(node->body());
667 // Detect loops that will always have a fork in the control-flow graph.
668 // This will be a |while| loop, or a |do-while| loop whose body does
671 // For now, we treat these as an |if| regardless of the direction the
672 // branch can take. That means the control-flow is always conditional.
673 if (node->token() == TOK_WHILE ||
674 !status.terminates() ||
677 control_->merge(status, ControlStatus(false, Returns_Never));
679 // At this point, we've got a do-while loop with a |return| or
680 // |continue|, meaning that the rest of the block is unreachable.
681 control_->terminate(status.returns());
686 SemanticAnalysis::visit(BlockStatement *node)
689 scope_ = node->scope();
690 for (size_t i = 0; i < node->statements()->length(); i++) {
691 Statement *statement = node->statements()->at(i);
692 statement->accept(this);
695 scope_ = scope_->enclosing();
699 IsScalarString(Type *type)
701 if (type->isPrimitive() && type->primitive() == PrimitiveType_Char)
703 if (type->isReference())
704 return IsScalarString(type->contained());
708 static const int INFER_ARRAY_SIZE = 0;
709 static const int EVAL_ARRAY_SIZE = -1;
710 static const int DYNAMIC_ARRAY_SIZE = -2;
713 SemanticAnalysis::evaluateDimensions(ExpressionList *exprs, int dims[MAX_ARRAY_DEPTH])
715 bool hadEmptySize = false;
717 for (size_t i = 0; i < exprs->length(); i++) {
718 Expression *expr = exprs->at(i);
720 dims[i] = INFER_ARRAY_SIZE;
726 if (EvaluateForConstant(expr, &box) && box.type() == PrimitiveType_Int32) {
727 int size = box.toInt();
729 cc_.reportError(expr->pos(), Message_BadArraySize);
737 Local<Type> exprType(zone_, visitForLoad(expr));
741 if (!IsPrimitiveType(exprType, PrimitiveType_Int32)) {
742 cc_.reportError(expr->pos(), Message_ArrayDimensionNotInteger);
747 cc_.reportError(expr->pos(), Message_BadDynamicInitializer);
751 dims[i] = EVAL_ARRAY_SIZE;
758 SemanticAnalysis::inferFixedArrayLiteral(ArrayLiteral *literal, Handle<Type> contained,
759 int dims[MAX_ARRAY_DEPTH],
760 unsigned dimcount, unsigned level)
762 if (dims[level] == EVAL_ARRAY_SIZE) {
763 cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
767 if (dims[level] == INFER_ARRAY_SIZE) {
768 // Strings always become dynamic arrays.
769 if (level != dimcount - 1 || !IsPrimitiveType(contained, PrimitiveType_Char))
770 dims[level] = literal->expressions()->length();
771 } else if (dims[level] == DYNAMIC_ARRAY_SIZE) {
772 cc_.reportError(literal->pos(), Message_CannotInitializeEvalArray);
775 if (literal->expressions()->length() != unsigned(dims[level])) {
776 cc_.reportError(literal->pos(), Message_ArrayDimensionSizeMismatch, level + 1);
781 if (level == dimcount - 2 && IsPrimitiveType(contained, PrimitiveType_Char)) {
782 for (size_t i = 0; i < literal->expressions()->length(); i++) {
783 Expression *expr = literal->expressions()->at(i);
784 if (!expr->isStringLiteral()) {
785 cc_.reportError(expr->pos(), Message_ExpectedStringLiteral);
789 StringLiteral *lit = expr->toStringLiteral();
790 if (dims[level + 1] > 0 &&
791 unsigned(dims[level]) < lit->string()->length())
793 cc_.reportError(lit->pos(), Message_ArrayDimensionSizeMismatch, level + 2);
796 if (!visitAndApplyType(lit))
799 } else if (level == dimcount - 1) {
800 Local<Type> type(zone_);
801 for (size_t i = 0; i < literal->expressions()->length(); i++) {
802 Expression *expr = literal->expressions()->at(i);
803 if (expr->isArrayLiteral()) {
804 cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
808 if ((type = visitAndApplyType(expr)) == NULL)
811 if (!typeCheckAssignment(expr->pos(), type, contained, true))
815 for (size_t i = 0; i < literal->expressions()->length(); i++) {
816 Expression *expr = literal->expressions()->at(i);
817 if (!expr->isArrayLiteral()) {
818 cc_.reportError(expr->pos(), Message_ArrayDimensionsMismatch);
822 assert(expr->toArrayLiteral()->isFixed());
824 if (!inferFixedArrayLiteral(expr->toArrayLiteral(),
839 SemanticAnalysis::visit(VariableDeclaration *node)
841 Local<Type> type(zone_, bindType(node->pos(), node->type()));
846 if (node->postDimensions() || type->isArray()) {
847 // The type could be an array type, so sum the type and postDimensions
849 unsigned dimcount = node->postDimensions()->length();
851 dimcount += type->levels();
852 if (dimcount > MAX_ARRAY_DEPTH) {
853 cc_.reportError(node->pos(), Message_MaximumArrayDepth);
857 // Take an initial guess at the array dimension sizes.
858 int dims[MAX_ARRAY_DEPTH];
859 if (!evaluateDimensions(node->postDimensions(), dims))
862 // Now add in the type's array dimensions.
863 Local<Type> contained(zone_, type);
864 for (size_t i = node->postDimensions()->length(); i < dimcount; i++) {
865 if (type->isFixedLength())
866 dims[i] = type->fixedLength();
868 dims[i] = DYNAMIC_ARRAY_SIZE;
869 contained = contained->contained();
872 Expression *initializer = node->initialization();
874 initializer->isArrayLiteral() &&
875 initializer->toArrayLiteral()->isFixed())
877 // Fixed array initializers are special; we use them to infer any
878 // missing information in the original array. We do not evaluate
879 // the array initializer as an expression.
880 if (!inferFixedArrayLiteral(initializer->toArrayLiteral(),
891 // We now have enough information to build the actual array type.
892 // Start from the original dimcount, not the one computed for
894 for (size_t i = node->postDimensions()->length() - 1;
895 i < node->postDimensions()->length();
898 int size = dims[i] > 0
900 : Type::DYNAMIC_ARRAY_SIZE;
902 type = zone_->types()->newArray(type, size, false);
907 // Finally, if we had a non-fixed initializer, make sure it type
910 Local<Type> right(zone_, visitForLoad(initializer));
914 if (!typeCheckAssignment(node->pos(), right, type, true))
918 if (node->initialization()) {
919 Local<Type> right(zone_, visitForLoad(node->initialization()));
922 if (!typeCheckAssignment(node->pos(), right, type, true))
926 if (type->isPrimitive() && type->primitive() == PrimitiveType_Char) {
927 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
934 // If this variable is stack allocated, we could use the LIFO heap
935 // to allocate it. If that's the case, make sure to reserve a slot
936 // so we can unwind the LIFO heap at the end of this scope.
937 if (!node->variable()->needsHeapAllocation()) {
938 if (type->isArray() || type->isStruct())
939 scope_->setUsesLifoHeap();
942 node->variable()->setType(type);
947 SemanticAnalysis::visit(IntegerLiteral *node)
949 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
953 SemanticAnalysis::visit(BooleanLiteral *node)
955 node->setType(zone_->types()->getPrimitive(PrimitiveType_Bool));
959 SemanticAnalysis::visit(ExpressionStatement *node)
961 visitAndApplyType(node->expression());
965 SemanticAnalysis::evaluateDefaultParameter(Handle<Type> type, Parameter *parameter)
967 Local<Type> given(zone_, visitForLoad(parameter->initializer()));
970 if (EvaluateForConstant(parameter->initializer(), &prim)) {
971 if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
974 if (prim.type() == PrimitiveType_Int32)
975 return Box::New(zone_, given, prim.toInt());
976 return Box::New(zone_, given, prim.toFloat());
977 } else if (parameter->initializer()->isStringLiteral()) {
978 StringLiteral *literal = parameter->initializer()->toStringLiteral();
980 if (!typeCheckAssignment(parameter->initializer()->pos(), given, type, false))
983 Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, given));
987 Local<Array> array(zone_,
988 Array::NewString(zone_,
990 literal->string()->raw(),
991 literal->string()->length(),
996 return Box::NewObj(zone_, given, array, Heap::Tenure_Old);
999 cc_.reportError(parameter->initializer()->pos(), Message_MustBeConstant);
1004 SemanticAnalysis::buildFunctionArgs(AstNode *node, TokenKind kind, const FunctionSignature &sig,
1005 FixedArray **argsp, FixedArray **defaultsp)
1007 Local<FixedArray> args(zone_, FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old));
1011 Local<FixedArray> defaults(zone_);
1013 // Apply types to arguments.
1014 for (size_t i = 0; i < sig.parameters()->length(); i++) {
1015 Parameter *parameter = sig.parameters()->at(i);
1018 Local<Type> type(zone_, bindType(parameter->variable()->pos(), parameter->type()));
1022 if (parameter->reference()) {
1023 if (parameter->dimensions()) {
1024 cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
1028 if (type->isStruct()) {
1029 cc_.reportError(parameter->variable()->pos(), Message_StructCantBeReference);
1033 type = zone_->types()->getReference(type, parameter->isConst());
1036 } else if (parameter->dimensions()) {
1037 type = buildArrayType(type, parameter->dimensions(), parameter->isConst());
1041 if (kind == TOK_NATIVE && type->levels() > 1) {
1042 cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
1047 if (IsScalarString(type)) {
1048 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
1052 args->set(zone_, i, type);
1053 parameter->variable()->setType(type);
1055 if (parameter->initializer()) {
1057 defaults = FixedArray::New(zone_, sig.parameters()->length(), Heap::Tenure_Old);
1062 Local<Box> box(zone_, evaluateDefaultParameter(type, parameter));
1066 defaults->set(zone_, i, box);
1072 *defaultsp = defaults;
1078 SemanticAnalysis::visit(FunctionTypeStatement *node)
1080 if (node->decl()->type())
1083 Local<FixedArray> args(zone_);
1084 Local<FixedArray> defaults(zone_);
1086 const FunctionSignature &sig= node->signature();
1087 if (!buildFunctionArgs(node,
1091 defaults.address()))
1097 Local<Type> returnType(zone_);
1098 if (sig.returnType())
1099 returnType = bindType(node->pos(), sig.returnType());
1101 returnType = zone_->types()->getPrimitive(PrimitiveType_Int32);
1106 Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args, defaults));
1110 node->decl()->setType(funtype);
1115 SemanticAnalysis::buildArrayType(Handle<Type> type, ExpressionList *dimensions, bool isConst)
1117 Local<Type> arrayType(zone_, type);
1119 unsigned dimcount = dimensions->length();
1120 if (type->isArray())
1121 dimcount += type->levels();
1123 if (dimcount > MAX_ARRAY_DEPTH) {
1124 cc_.reportError(dimensions->at(dimensions->length() - 1)->pos(),
1125 Message_MaximumArrayDepth);
1129 // Note: constness is sort of bogus. Fix this sometime.
1130 for (size_t i = dimensions->length() - 1; i < dimensions->length(); i--) {
1131 Expression *expr = dimensions->at(i);
1133 arrayType = zone_->types()->newArray(arrayType, Type::DYNAMIC_ARRAY_SIZE, isConst);
1141 if (!EvaluateForConstant(expr, &box) || box.type() != PrimitiveType_Int32) {
1142 cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant);
1146 if (box.toInt() <= 0) {
1147 cc_.reportError(expr->pos(), Message_BadArraySize);
1151 arrayType = zone_->types()->newArray(arrayType, box.toInt(), isConst);
1160 SemanticAnalysis::preanalyze(FunctionStatement *node)
1162 Local<FixedArray> args(zone_);
1163 Local<FixedArray> defaults(zone_);
1165 const FunctionSignature &sig = node->signature();
1166 if (!buildFunctionArgs(node,
1167 node->fun()->token(),
1170 defaults.address()))
1176 Local<Type> returnType(zone_);
1177 if (sig.returnType() ||
1178 node->hasExplicitReturn() ||
1179 node->fun()->isNative())
1181 returnType = bindType(node->pos(), sig.returnType());
1183 returnType = zone_->types()->getVoid();
1188 if (sig.returnDimensions()) {
1189 returnType = buildArrayType(returnType, sig.returnDimensions(), false);
1194 if (IsScalarString(returnType)) {
1195 cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
1199 Local<Type> funtype(zone_);
1200 if (node->fun()->isNative())
1201 funtype = zone_->types()->newNative(returnType, args, defaults, node->fun()->isNativeVariadic());
1203 funtype = zone_->types()->newFunction(returnType, args, defaults);
1207 // If the function already has a type, it was forward declared before, and
1208 // now this is our chance to type check the second declaration.
1209 if (node->fun()->type()) {
1210 Local<Type> forward(zone_, node->fun()->type());
1211 if (!Type::Compare(funtype, forward)) {
1212 cc_.reportError(node->pos(), Message_ForwardDeclareMismatches);
1215 node->fun()->setForwardType(forward);
1218 node->fun()->setType(funtype);
1225 SemanticAnalysis::visit(FunctionStatement *node)
1227 function_ = node->fun();
1228 scope_ = node->scope();
1230 ControlScope control(&control_);
1232 node->body()->accept(this);
1234 ControlStatus status = control.status();
1235 if (status.returns() == Returns_Sometimes) {
1236 cc_.reportError(node->pos(), Message_NotAllPathsReturnValue);
1237 } else if (status.returns() == Returns_Never) {
1238 if (!function_->type()->returnType()->isVoid())
1239 cc_.reportError(node->pos(), Message_MissingReturnValue);
1248 SemanticAnalysis::typeMismatch(const SourcePosition &pos, Handle<Type> actual, Handle<Type> given)
1250 cc_.reportError(pos, Message_TypeMismatch,
1251 GetTypeName(actual),
1252 GetTypeName(given));
1256 SemanticAnalysis::typeCheckArrayAssignment(const SourcePosition &pos, Handle<Type> argGiven,
1257 Handle<Type> argActual, bool forAssign)
1259 Local<Type> actual(zone_, argActual);
1260 Local<Type> given(zone_, argGiven);
1262 if (!given->isArray()) {
1263 cc_.reportError(pos, Message_ExpectedArray);
1266 if (given->levels() != actual->levels()) {
1267 cc_.reportError(pos, Message_ArrayDimensionsMismatch);
1272 while (given->isArray()) {
1273 if (actual->isFixedLength()) {
1275 if (!given->isFixedLength()) {
1276 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1280 if (actual->isCharArray()) {
1281 // String assignment can have a truncated |given|.
1282 if (given->fixedLength() > actual->fixedLength()) {
1283 cc_.reportError(pos, Message_ArrayAssignmentTooBig);
1287 if (given->fixedLength() != actual->fixedLength()) {
1288 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1293 } else if (given->isFixedLength()) {
1294 // We do not allow assignments in the form:
1297 // Otherwise, the following code could break the size guarantees
1298 // of the right-hand side:
1307 // Now |x[0]| contains a 4-length array.
1309 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1313 given = given->contained();
1314 actual = actual->contained();
1318 return typeCheckAssignment(pos, given, actual, forAssign);
1322 SemanticAnalysis::typeCheckAssignment(const SourcePosition &pos, Handle<Type> argGiven,
1323 Handle<Type> argActual, bool forAssign)
1325 Local<Type> actual(zone_, argActual);
1326 Local<Type> given(zone_, argGiven);
1328 if (actual->isArray())
1329 return typeCheckArrayAssignment(pos, given, actual, forAssign);
1331 if (given->isArray()) {
1332 cc_.reportError(pos, Message_CannotAssignArrayToScalar);
1336 // The given type may not have been dereferenced.
1337 if (given->isReference())
1338 given = given->contained();
1339 if (actual->isReference())
1340 actual = actual->contained();
1342 // We coerce unchecked to a few things.
1343 if (actual->isUnchecked() || given->isUnchecked()) {
1344 Type *check = actual->isUnchecked() ? given : actual;
1345 if (check->isUnchecked() ||
1353 typeMismatch(pos, actual, given);
1357 if (given->isFunction() && actual->isFunction()) {
1358 if (!Type::Compare(given, actual)) {
1359 typeMismatch(pos, actual, given);
1365 if (actual->isEnum()) {
1366 if (!given->isEnum() || actual != given) {
1367 typeMismatch(pos, actual, given);
1373 if (actual->isStruct()) {
1374 if (!given->isStruct() || actual != given) {
1375 typeMismatch(pos, actual, given);
1381 if (given->isEnum() || given->isFunction() || given->isStruct()) {
1382 typeMismatch(pos, actual, given);
1386 // This coercion is trivial.
1387 if (given->isBool() && actual->isInt32())
1390 if (given->primitive() != actual->primitive()) {
1391 typeMismatch(pos, actual, given);
1399 SemanticAnalysis::typeCheckParameter(AstNode *node, Handle<Type> given, Handle<Type> actual)
1401 return typeCheckAssignment(node->pos(), given, actual, false);
1405 SemanticAnalysis::checkArgumentCount(Handle<Type> type, unsigned actual)
1407 if (type->parameters()->length() == actual)
1410 if (actual > type->parameters()->length()) {
1411 if (!type->isNative() || !type->isNativeVariadic())
1416 if (!type->defaults())
1419 // Missing arguments. See if there's a default argument for each missing
1421 for (unsigned i = actual; i < type->parameters()->length(); i++) {
1422 if (!type->defaults()->at(i))
1430 SemanticAnalysis::visit(CallExpression *node)
1432 Local<Type> type(zone_, visitForLoad(node->callee()));
1436 if (!type->isFunction()) {
1437 cc_.reportError(node->pos(), Message_CalleeNotFunction);
1441 if (!checkArgumentCount(type, node->arguments()->length())) {
1442 cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
1446 // NamedFunction *fun = node->callee()->toNameProxy()->binding()->toNamedFunction();
1447 // if (fun->isForward()) {
1448 // cc_.reportError(node->pos(), Message_ForwardNotImplemented, fun->name()->chars());
1452 for (unsigned i = 0; i < node->arguments()->length(); i++) {
1453 // Note: we don't compute references unless the callee needs a
1455 Expression *expression = node->arguments()->at(i);
1456 Local<Type> given(zone_, visitAndApplyType(expression));
1460 // Since we skip a load, check for a call expression that returns void.
1461 if (given->isVoid()) {
1462 assert(expression->isCallExpression());
1463 CallExpression *call = expression->toCallExpression();
1464 cc_.reportError(call->callee()->pos(), Message_FunctionDoesNotReturnValue);
1468 bool mustComputeReference;
1469 if (i >= type->parameters()->length()) {
1470 // Special handling for natives. Arguments past the formal must
1471 // always have references computed. However, arrays are already
1472 // references for natives.
1473 assert(type->isNative() && type->isNativeVariadic());
1474 mustComputeReference = !given->isReference() && !given->isArray();
1476 Local<Type> actual(zone_, type->parameterAt(i));
1478 if (expression->isIndexExpression()) {
1479 // Disabled until we can make it work.
1481 if (actual->isArray()) {
1482 // We special case the ability to pass x[y] into x[], which
1483 // creates an array slice. We only do this if we know the
1484 // assignment would otherwise not type-check.
1485 IndexExpression *index = expression->toIndexExpression();
1486 if (index->left()->type()->levels() == actual->levels())
1487 given = index->left()->type();
1490 if (actual->isReference()) {
1491 cc_.reportError(expression->pos(), Message_CannotComputeIndexRef);
1496 if (!typeCheckParameter(expression, given, actual))
1498 mustComputeReference = actual->isReference() && !given->isReference();
1501 // If the actual is a reference, and the given is not, we'll need to
1502 // compute a reference, which may be allocated on the stack.
1503 if (mustComputeReference)
1504 scope_->setUsesLifoHeap();
1507 node->setType(type->returnType());
1511 SemanticAnalysis::ControlScope::inherit(const ControlStatus &other)
1513 if (other.returns() < status().returns())
1516 if (other.terminates())
1517 terminate(other.returns());
1519 returns(other.returns());
1523 SemanticAnalysis::ControlScope::merge(const ControlStatus &left, const ControlStatus &right)
1525 // If both sides terminate in a return, we consider this a return as well.
1526 if (left.returns() == Returns_Always && right.returns() == Returns_Always) {
1527 terminate(Returns_Always);
1531 ReturnStatus status = (left.returns() == Returns_Never && right.returns() == Returns_Never)
1533 : Returns_Sometimes;
1535 if (left.terminates() && right.terminates())
1542 SemanticAnalysis::visit(IfStatement *node)
1544 Local<Type> type(zone_, visitForLoad(node->condition()));
1548 if (!canTest(node, type))
1551 ControlStatus trueBranch = visitForControl(node->ifTrue());
1552 ControlStatus falseBranch = ControlStatus(false, Returns_Never);
1554 if (node->ifFalse())
1555 falseBranch = visitForControl(node->ifFalse());
1557 control_->merge(trueBranch, falseBranch);
1561 SemanticAnalysis::visit(IndexExpression *node)
1563 Local<Type> left(zone_, visitForLoad(node->left()));
1564 Local<Type> right(zone_, visitForLoad(node->right()));
1566 if (!left || !right)
1569 if (!right->isInt32() && !right->isEnum()) {
1570 cc_.reportError(node->right()->pos(), Message_IndexMustBeInteger);
1573 if (!left->isArray()) {
1574 cc_.reportError(node->left()->pos(), Message_IndexBaseMustBeArray);
1578 // Note: char arrays are automatically up-casted to return an int32.
1579 if (left->isCharArray())
1580 node->setType(zone_->types()->getPrimitive(PrimitiveType_Int32));
1582 node->setType(left->contained());
1586 SemanticAnalysis::visit(FieldExpression *node)
1588 Local<Type> left(zone_, visitForLoad(node->left()));
1592 if (!left->isStruct()) {
1593 cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
1598 Local<String> field(zone_, node->field());
1601 Local<Descriptor> desc(zone_, left->lookupField(field, &offset));
1603 cc_.reportError(node->pos(), Message_PropertyNotFound, node->field()->chars(),
1608 node->setFieldIndex(offset);
1609 node->setType(desc->type());
1613 SemanticAnalysis::visit(EnumStatement *node)
1615 Local<String> name(zone_, node->name());
1616 Local<Type> type(zone_);
1618 type = zone_->types()->newEnum(name);
1620 type = zone_->types()->getPrimitive(PrimitiveType_Int32);
1626 node->decl()->setType(type);
1629 for (size_t i = 0; i < node->entries()->length(); i++) {
1630 EnumStatement::Entry &entry = node->entries()->at(i);
1632 BoxedPrimitive box = BoxedPrimitive::Int(value);
1634 entry.expr->accept(this);
1635 if (!EvaluateForConstant(entry.expr, &box) || box.type() != PrimitiveType_Int32) {
1636 cc_.reportError(entry.expr->pos(), Message_EnumFieldNotConstant);
1640 assert(box.type() == PrimitiveType_Int32);
1641 value = box.toInt();
1645 entry.name->set(type, box);
1652 SortCaseIntValues(const void *p1, const void *p2)
1654 CaseValue *v1 = (CaseValue *)p1;
1655 CaseValue *v2 = (CaseValue *)p2;
1657 return v1->box.toInt() - v2->box.toInt();
1661 SemanticAnalysis::visit(SwitchStatement *node)
1663 Local<Type> caseType(zone_, visitForLoad(node->expression()));
1667 if (!caseType->isEnum() && !caseType->isInt32()) {
1668 cc_.reportError(node->pos(), Message_CaseMustBeInteger);
1672 PoolList<CaseValue> *values = new (zone_->pool()) PoolList<CaseValue>();
1673 ControlStatus status = ControlStatus(false, Returns_Never);
1675 Local<Type> check(zone_);
1676 for (size_t i = 0; i < node->cases()->length(); i++) {
1677 Case *c = node->cases()->at(i);
1679 check = visitForLoad(c->expression());
1683 if (!typeCheckAssignment(c->expression()->pos(), check, caseType, false))
1687 if (!EvaluateForConstant(c->expression(), &v.box)) {
1688 cc_.reportError(c->expression()->pos(), Message_CaseMustBeConstant);
1691 if (!values->append(v))
1695 for (size_t j = 0; j < c->others()->length(); j++) {
1696 Expression *expr = c->others()->at(j);
1697 check = visitForLoad(expr);
1701 if (!typeCheckAssignment(expr->pos(), check, caseType, false))
1705 if (!EvaluateForConstant(expr, &v.box)) {
1706 cc_.reportError(expr->pos(), Message_CaseMustBeConstant);
1709 if (!values->append(v))
1714 ControlStatus latest = visitForControl(c->statement());
1717 control_->merge(status, latest);
1722 if (node->defaultCase()) {
1723 ControlStatus latest = visitForControl(node->defaultCase());
1725 if (node->cases()->length()) {
1726 // If we had any other cases, we must merge.
1727 control_->merge(status, latest);
1729 // Otherwise, control-flow always flows through here.
1730 control_->inherit(latest);
1732 } else if (node->cases()->length()) {
1733 control_->merge(status, ControlStatus(false, Returns_Never));
1736 if (values->length() > 1) {
1737 qsort(values->buffer(), values->length(), sizeof(CaseValue), SortCaseIntValues);
1739 for (size_t i = 1; i < values->length(); i++) {
1740 CaseValue &prev = values->at(i - 1);
1741 CaseValue &cur = values->at(i);
1742 if (prev.box.toInt() == cur.box.toInt()) {
1743 cc_.reportError(node->cases()->at(cur.statement)->expression()->pos(), Message_CaseHasSameValue);
1749 node->setCaseValueList(values);
1753 SemanticAnalysis::visit(StructureStatement *node)
1756 // If this node already has a type, it was pre-analyzed, so skip it.
1757 if (node->decl()->type())
1760 FieldList *fields = node->fields();
1761 Local<FixedArray> desctable(zone_, FixedArray::New(zone_, fields->length(), Heap::Tenure_Old));
1765 Vector<unsigned> composedList;
1766 StructureBufferBuilder builder;
1768 Local<Type> type(zone_);
1769 Local<String> name(zone_);
1770 Local<Descriptor> desc(zone_);
1771 for (size_t i = 0; i < fields->length(); i++) {
1772 StructureStatement::Field *field = fields->at(i);
1774 type = bindType(field->pos(), field->type());
1778 if (field->dimensions()) {
1779 type = buildArrayType(type, field->dimensions(), false);
1783 if (!ArrayMap::Attach(zone_, type))
1787 if (IsScalarString(type)) {
1788 cc_.reportError(field->pos(), Message_CannotDeclareStringCell);
1793 if (!builder.add(type, &offset))
1796 name = field->name();
1797 desc = Descriptor::New(zone_, name, type, offset);
1801 desctable->set(zone_, i, desc);
1803 if (type->isStruct() || type->isArray()) {
1804 if (!composedList.append(i))
1809 Local<FixedArray> composed(zone_);
1810 if (composedList.length()) {
1811 composed = FixedArray::New(zone_, composedList.length(), Heap::Tenure_Old);
1815 for (unsigned i = 0; i < composedList.length(); i++)
1816 composed->set(zone_, i, desctable->at(i));
1819 Local<StructMap> map(zone_, StructMap::New(zone_, builder, composed));
1823 name = node->decl()->name();
1824 type = zone_->types()->newStruct(name, desctable, map);
1829 node->decl()->setType(type);
1834 SemanticAnalysis::visit(StringLiteral *node)
1836 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Char));
1840 type = Type::NewArray(zone_, type, node->string()->length() + 1, true);
1844 node->setType(type);
1848 SemanticAnalysis::visit(FloatLiteral *node)
1850 Local<Type> type(zone_, zone_->types()->getPrimitive(PrimitiveType_Float));
1854 node->setType(type);
1858 SemanticAnalysis::visit(BreakStatement *node)
1861 cc_.reportError(node->pos(), Message_BreakOutsideLoop);
1865 // Note: ignore breaks that occur in unreachable control-flow.
1866 if (!control_->status().terminates())
1869 control_->terminate(Returns_Never);
1873 SemanticAnalysis::visit(ContinueStatement *node)
1876 cc_.reportError(node->pos(), Message_ContinueOutsideLoop);
1880 // Note: ignore continues that occur in unreachable control-flow.
1881 if (!control_->status().terminates())
1882 loop_->addContinue();
1884 control_->terminate(Returns_Never);
1888 SemanticAnalysis::visit(ArrayLiteral *node)
1890 // We should never visit this.
1891 cc_.reportError(node->pos(), Message_UnexpectedArrayLiteral);
1895 SemanticAnalysis::visit(ImportStatement *node)