1.1 --- a/src/compiler/SemanticAnalysis.cpp Sat Dec 22 23:18:57 2012 -0800
1.2 +++ b/src/compiler/SemanticAnalysis.cpp Mon Dec 24 02:49:20 2012 -0800
1.3 @@ -429,31 +429,31 @@
1.4 PoolScope poolScope(zone_->pool());
1.5 RootScope rootScope(zone_);
1.6
1.7 + Local<Type> type(zone_, node->sym()->type());
1.8 +
1.9 if (node->initialization()) {
1.10 HIR *hir = NULL;
1.11
1.12 if ((hir = eval(node->initialization())) == NULL)
1.13 return;
1.14 - if ((hir = coerce(hir, node->sym()->type(), Coerce_Assign)) == NULL)
1.15 + if ((hir = coerce(hir, type, Coerce_Assign)) == NULL)
1.16 return;
1.17
1.18 discharge(hir);
1.19 } else {
1.20 - if (node->sym()->type()->isInt32() ||
1.21 - node->sym()->type()->isEnum() ||
1.22 - node->sym()->type()->isChar() ||
1.23 - node->sym()->type()->isBool())
1.24 + if (type->isInt32() || type->isEnum() ||
1.25 + type->isChar() || type->isBool())
1.26 {
1.27 __ int_(0);
1.28 - } else if (node->sym()->type()->isFloat()) {
1.29 + } else if (type->isFloat()) {
1.30 __ float_(0);
1.31 - } else if (node->sym()->type()->isArray()) {
1.32 - Local<ArrayType> type(zone_, ArrayType::cast(node->sym()->type()));
1.33 - Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, type));
1.34 + } else if (type->isArray()) {
1.35 + Local<ArrayType> atype(zone_, ArrayType::cast(type));
1.36 + Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, atype));
1.37 if (!map)
1.38 return;
1.39
1.40 - if (type->isFixedLength()) {
1.41 + if (atype->isFixedLength()) {
1.42 __ newarray(OP_NEWFIXED, map, InferTenure(node->sym()));
1.43 } else if (node->dims()) {
1.44 assert(false);
1.45 @@ -461,11 +461,15 @@
1.46 } else {
1.47 __ newarray(OP_NEWEMPTY, map, InferTenure(node->sym()));
1.48 }
1.49 + } else {
1.50 + assert(false);
1.51 }
1.52 }
1.53
1.54 - if (!__ allocate(node->sym()))
1.55 - return;
1.56 + if (node->sym()->scope()->kind() != Scope::GLOBAL) {
1.57 + if (!__ allocate(node->sym()))
1.58 + return;
1.59 + }
1.60
1.61 set(node->sym());
1.62 __ pop();
1.63 @@ -613,6 +617,13 @@
1.64 }
1.65
1.66 void
1.67 +SemanticAnalysis::visitStringLiteral(StringLiteral *node)
1.68 +{
1.69 + Type *type = zone_->types()->getPrimitive(PrimitiveType_String);
1.70 + hir_ = new (pool_) HString(node, type, node->string());
1.71 +}
1.72 +
1.73 +void
1.74 SemanticAnalysis::visitCallExpression(CallExpression *node)
1.75 {
1.76 HIR *callee = eval(node->callee());
1.77 @@ -804,15 +815,55 @@
1.78 return left->type();
1.79 }
1.80
1.81 -bool
1.82 +HIR *
1.83 SemanticAnalysis::typeCheckArray(const SourcePosition &pos,
1.84 - Handle<Type> argGiven,
1.85 + HIR *from,
1.86 Handle<Type> argActual,
1.87 CoercionKind kind)
1.88 {
1.89 + Local<Type> argGiven(zone_, from->type());
1.90 +
1.91 + // Special case: if we receive a string literal, and this is a char array,
1.92 + // we allow a coercion.
1.93 + if (from->isString() &&
1.94 + argGiven->isString() &&
1.95 + argActual->isArray() &&
1.96 + ArrayType::cast(argActual)->isCharArray())
1.97 + {
1.98 + HString *hir = from->toString();
1.99 + Local<ArrayType> actual(zone_, ArrayType::cast(argActual));
1.100 +
1.101 + // If assigning or returning, and the desired type is fixed length,
1.102 + // make sure there is enough room.
1.103 + if ((kind == Coerce_Return || kind == Coerce_Assign) && actual->isFixedLength()) {
1.104 + if (hir->string()->length() + 1 > actual->fixedLength()) {
1.105 + cc_.reportError(pos, Message_ArrayAssignmentTooBig);
1.106 + return NULL;
1.107 + }
1.108 + }
1.109 +
1.110 + // Transform the string literal into an array literal. We give it the
1.111 + // type of the left-hand side. The constness of the destination type
1.112 + // will determine whether HArray duplicates it or not.
1.113 + Local<ArrayMap> map(zone_, ArrayMap::Attach(zone_, actual));
1.114 + if (!map)
1.115 + return NULL;
1.116 +
1.117 + Local<Array> array(zone_);
1.118 + array = Array::NewString(zone_,
1.119 + map,
1.120 + hir->string()->chars(),
1.121 + hir->string()->length(),
1.122 + Heap::Tenure_Old);
1.123 + if (!array)
1.124 + return NULL;
1.125 +
1.126 + return new (pool_) HArray(hir->node(), actual, array);
1.127 + }
1.128 +
1.129 if (!argGiven->isArray()) {
1.130 cc_.reportError(pos, Message_ExpectedArray);
1.131 - return false;
1.132 + return NULL;
1.133 }
1.134
1.135 Local<ArrayType> actual(zone_, ArrayType::cast(argActual));
1.136 @@ -820,7 +871,7 @@
1.137
1.138 if (actual->levels() != given->levels()) {
1.139 cc_.reportError(pos, Message_ArrayDimensionsMismatch);
1.140 - return false;
1.141 + return NULL;
1.142 }
1.143
1.144 unsigned level = 1;
1.145 @@ -829,19 +880,19 @@
1.146 if (kind == Coerce_Return || kind == Coerce_Assign) {
1.147 if (!given->isFixedLength()) {
1.148 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1.149 - return false;
1.150 + return NULL;
1.151 }
1.152
1.153 if (actual->isCharArray()) {
1.154 // String assignment can have a truncated |given|.
1.155 if (given->fixedLength() > actual->fixedLength()) {
1.156 cc_.reportError(pos, Message_ArrayAssignmentTooBig);
1.157 - return false;
1.158 + return NULL;
1.159 }
1.160 } else {
1.161 if (given->fixedLength() != actual->fixedLength()) {
1.162 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1.163 - return false;
1.164 + return NULL;
1.165 }
1.166 }
1.167 }
1.168 @@ -863,7 +914,7 @@
1.169 // Now |x[0]| contains a 3-length array.
1.170 if (level > 1) {
1.171 cc_.reportError(pos, Message_ArrayDimensionSizeMismatch, level);
1.172 - return false;
1.173 + return NULL;
1.174 }
1.175 }
1.176
1.177 @@ -882,7 +933,7 @@
1.178 return false;
1.179 }
1.180
1.181 - return true;
1.182 + return from;
1.183 }
1.184
1.185 HIR *
1.186 @@ -897,21 +948,18 @@
1.187 HIR *
1.188 SemanticAnalysis::coerce(HIR *hir, Handle<Type> to, CoercionKind kind)
1.189 {
1.190 - Handle<Type> from = hir->type();
1.191 + Local<Type> from(zone_, hir->type());
1.192
1.193 if (from->isInt32() && to->isFloat())
1.194 return new (pool_) HConvert(hir->node(), to, OP_CVT_I2F, hir);
1.195 if (from->isInt32() && to->isBool())
1.196 return new (pool_) HConvert(hir->node(), to, OP_CVT_I2B, hir);
1.197
1.198 - if (to->isEnum() && from != to)
1.199 + if (to->isEnum() && *from != to)
1.200 return typeFailure(hir->node()->pos(), from, to);
1.201
1.202 - if (to->isArray()) {
1.203 - if (!typeCheckArray(SourcePosition(), from, to, kind))
1.204 - return NULL;
1.205 - return hir;
1.206 - }
1.207 + if (to->isArray())
1.208 + return typeCheckArray(SourcePosition(), hir, to, kind);
1.209
1.210 return hir;
1.211 }
1.212 @@ -1003,7 +1051,7 @@
1.213 hir = eval(expr->toUnaryExpression()->expression());
1.214 if (!hir)
1.215 return;
1.216 - if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL)
1.217 + if ((hir = coerce(hir, boolType, Coerce_Arg)) == NULL)
1.218 return;
1.219
1.220 discharge(hir);
1.221 @@ -1033,7 +1081,7 @@
1.222 HIR *hir = binary(bin, bin->token(), left, right);
1.223 if (!hir)
1.224 return;
1.225 - if ((hir = coerce(hir, boolType, Coerce_Assign)) == NULL)
1.226 + if ((hir = coerce(hir, boolType, Coerce_Arg)) == NULL)
1.227 return;
1.228
1.229 discharge(hir);