1.1 --- a/jitcraft/SemanticAnalysis.cpp Sat Jun 30 20:20:39 2012 -0700
1.2 +++ b/jitcraft/SemanticAnalysis.cpp Sat Jun 30 22:31:14 2012 -0700
1.3 @@ -120,8 +120,12 @@
1.4 SemanticAnalysis::visitForLoad(Expression *expression)
1.5 {
1.6 expression->accept(this);
1.7 - if (expression->type() && expression->type()->isArray())
1.8 - expression->setType(expression->type()->contained());
1.9 + if (expression->type()) {
1.10 + // :TODO: use Local
1.11 + Type *type = expression->type();
1.12 + if (type->isArray() || type->isReference())
1.13 + expression->setType(type->contained());
1.14 + }
1.15 return expression->type();
1.16 }
1.17
1.18 @@ -163,7 +167,10 @@
1.19 }
1.20
1.21 Variable *var = proxy->binding()->toVariable();
1.22 - node->setType(var->type());
1.23 + if (var->type()->isReference())
1.24 + node->setType(var->type()->contained());
1.25 + else
1.26 + node->setType(var->type());
1.27 }
1.28
1.29 assert(TypeCheck(node->type(), node->expression()->type()));
1.30 @@ -247,6 +254,7 @@
1.31 void
1.32 SemanticAnalysis::visit(VariableDeclaration *node)
1.33 {
1.34 + // :TODO: use locals
1.35 Type *type = ZONE()->types()->getPrimitiveForTag(node->tag());
1.36 if (!type)
1.37 return;
1.38 @@ -308,17 +316,100 @@
1.39 node->expression()->accept(this);
1.40 }
1.41
1.42 +bool
1.43 +SemanticAnalysis::preanalyze(FunctionStatement *node)
1.44 +{
1.45 + // :TODO: use Local
1.46 +
1.47 + FixedArray *args = FixedArray::New(ZONE(), node->parameters()->size(), Heap::Tenure_Old);
1.48 + if (!args)
1.49 + return false;
1.50 +
1.51 + // Apply types to arguments.
1.52 + for (size_t i = 0; i < node->parameters()->size(); i++) {
1.53 + Parameter *parameter = node->parameters()->at(i);
1.54 +
1.55 + Type *type = ZONE()->types()->getPrimitiveForTag(parameter->tag());
1.56 + if (!type)
1.57 + return false;
1.58 +
1.59 + if (parameter->reference()) {
1.60 + type = ZONE()->types()->getReference(type);
1.61 + if (!type)
1.62 + return false;
1.63 + }
1.64 +
1.65 + args->set(ZONE(), i, type);
1.66 + parameter->variable()->setType(type);
1.67 + }
1.68 +
1.69 + Type *returnType = ZONE()->types()->getPrimitive(PrimitiveType_Int32);
1.70 + if (!returnType)
1.71 + return false;
1.72 +
1.73 + Type *funtype = ZONE()->types()->newFunction(returnType, args);
1.74 + if (!funtype)
1.75 + return false;
1.76 +
1.77 + node->fun()->setType(funtype);
1.78 + return true;
1.79 +}
1.80 +
1.81 void
1.82 SemanticAnalysis::visit(FunctionStatement *node)
1.83 {
1.84 scope_ = node->scope();
1.85 +
1.86 + // :TODO: call this ahead of time.
1.87 + if (!preanalyze(node))
1.88 + return;
1.89 +
1.90 node->body()->accept(this);
1.91 scope_ = NULL;
1.92 }
1.93
1.94 +// :TODO: use handles
1.95 +static inline bool
1.96 +TypeCheckParameter(Type *given, Type *actual)
1.97 +{
1.98 + if (actual->isReference()) {
1.99 + if (given->isReference())
1.100 + given = given->contained();
1.101 + return TypeCheck(given, actual->contained());
1.102 + }
1.103 +
1.104 + return TypeCheck(given, actual);
1.105 +}
1.106 +
1.107 void
1.108 SemanticAnalysis::visit(CallExpression *node)
1.109 {
1.110 + visitForLoad(node->callee());
1.111 +
1.112 + // :TODO: use locals
1.113 + Type *type = node->callee()->type();
1.114 + if (!type)
1.115 + return;
1.116 +
1.117 + assert(type->isFunction());
1.118 + assert(node->arguments()->size() == type->parameters()->length());
1.119 +
1.120 + for (unsigned i = 0; i < node->arguments()->size(); i++) {
1.121 + Expression *expression = node->arguments()->at(i);
1.122 + expression->accept(this);
1.123 +
1.124 + Type *given = expression->type();
1.125 + if (!given)
1.126 + return;
1.127 +
1.128 + Type *actual = Type::cast(type->parameters()->at(i));
1.129 + assert(TypeCheckParameter(given, actual));
1.130 +
1.131 + // If the actual is a reference, and the given is not, we'll need to
1.132 + // compute a reference, which may be allocated on the stack.
1.133 + if (actual->isReference() && !given->isReference())
1.134 + scope_->setUsesLifoHeap();
1.135 + }
1.136 }
1.137
1.138 void
1.139 @@ -333,6 +424,7 @@
1.140 void
1.141 SemanticAnalysis::visit(IndexExpression *node)
1.142 {
1.143 + // :TODO: use locals
1.144 Type *left = visitForRef(node->left());
1.145 Type *right = visitForLoad(node->right());
1.146