jitcraft/SemanticAnalysis.cpp
changeset 68 b40b0e18a918
parent 67 b765a6383849
child 71 f7e573226c2b
     1.1 --- a/jitcraft/SemanticAnalysis.cpp	Mon Jul 09 22:25:52 2012 -0700
     1.2 +++ b/jitcraft/SemanticAnalysis.cpp	Tue Jul 10 02:11:13 2012 -0700
     1.3 @@ -546,11 +546,6 @@
     1.4          if (!type)
     1.5              return false;
     1.6  
     1.7 -        if (type->primitive() == PrimitiveType_Char) {
     1.8 -            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
     1.9 -            return false;
    1.10 -        }
    1.11 -
    1.12          if (parameter->reference()) {
    1.13              if (parameter->dimensions()) {
    1.14                  cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference);
    1.15 @@ -562,7 +557,12 @@
    1.16                  return false;
    1.17          } else if (parameter->dimensions()) {
    1.18              if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) {
    1.19 -                cc_.reportError(node->pos(), Message_MaximumArrayDepth);
    1.20 +                cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth);
    1.21 +                return false;
    1.22 +            }
    1.23 +
    1.24 +            if (node->fun()->isNative() && parameter->dimensions()->length() > 1) {
    1.25 +                cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative);
    1.26                  return false;
    1.27              }
    1.28  
    1.29 @@ -586,6 +586,13 @@
    1.30              }
    1.31          }
    1.32  
    1.33 +        if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) ||
    1.34 +            (type->isReference() && type->contained()->primitive() == PrimitiveType_Char))
    1.35 +        {
    1.36 +            cc_.reportError(node->pos(), Message_CannotDeclareStringCell);
    1.37 +            return false;
    1.38 +        }
    1.39 +
    1.40          args->set(zone_, i, type);
    1.41          parameter->variable()->setType(type);
    1.42      }
    1.43 @@ -594,7 +601,11 @@
    1.44      if (!returnType)
    1.45          return false;
    1.46  
    1.47 -    Local<Type> funtype(zone_, zone_->types()->newFunction(returnType, args));
    1.48 +    Local<Type> funtype(zone_);
    1.49 +    if (node->fun()->isNative())
    1.50 +        funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic());
    1.51 +    else
    1.52 +        funtype = zone_->types()->newFunction(returnType, args);
    1.53      if (!funtype)
    1.54          return false;
    1.55      
    1.56 @@ -737,8 +748,13 @@
    1.57          return;
    1.58      }
    1.59      if (node->arguments()->length() != type->parameters()->length()) {
    1.60 -        cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
    1.61 -        return;
    1.62 +        if (!type->isNative() ||
    1.63 +            !type->isNativeVariadic() ||
    1.64 +            node->arguments()->length() < type->parameters()->length())
    1.65 +        {
    1.66 +            cc_.reportError(node->pos(), Message_ArgumentCountMismatch);
    1.67 +            return;
    1.68 +        }
    1.69      }
    1.70  
    1.71      // Currently, only calls from a NameProxy are possible.
    1.72 @@ -761,13 +777,23 @@
    1.73          if (expression->isIndexExpression())
    1.74              given = given->contained();
    1.75  
    1.76 -        Local<Type> actual(zone_, type->parameterAt(i));
    1.77 -        if (!typeCheckParameter(expression, given, actual))
    1.78 -            return;
    1.79 +        bool mustComputeReference;
    1.80 +        if (i >= type->parameters()->length()) {
    1.81 +            // Special handling for natives. Arguments past the formal must
    1.82 +            // always have references computed. However, arrays are already
    1.83 +            // references for natives.  
    1.84 +            assert(type->isNative() && type->isNativeVariadic());
    1.85 +            mustComputeReference = !given->isReference() && !given->isArray();
    1.86 +        } else {
    1.87 +            Local<Type> actual(zone_, type->parameterAt(i));
    1.88 +            if (!typeCheckParameter(expression, given, actual))
    1.89 +                return;
    1.90 +            mustComputeReference = actual->isReference() && !given->isReference();
    1.91 +        }
    1.92  
    1.93          // If the actual is a reference, and the given is not, we'll need to
    1.94          // compute a reference, which may be allocated on the stack.
    1.95 -        if (actual->isReference() && !given->isReference())
    1.96 +        if (mustComputeReference)
    1.97              scope_->setUsesLifoHeap();
    1.98      }
    1.99