diff -r b765a6383849 -r b40b0e18a918 jitcraft/SemanticAnalysis.cpp --- a/jitcraft/SemanticAnalysis.cpp Mon Jul 09 22:25:52 2012 -0700 +++ b/jitcraft/SemanticAnalysis.cpp Tue Jul 10 02:11:13 2012 -0700 @@ -546,11 +546,6 @@ if (!type) return false; - if (type->primitive() == PrimitiveType_Char) { - cc_.reportError(node->pos(), Message_CannotDeclareStringCell); - return false; - } - if (parameter->reference()) { if (parameter->dimensions()) { cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference); @@ -562,7 +557,12 @@ return false; } else if (parameter->dimensions()) { if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) { - cc_.reportError(node->pos(), Message_MaximumArrayDepth); + cc_.reportError(parameter->variable()->pos(), Message_MaximumArrayDepth); + return false; + } + + if (node->fun()->isNative() && parameter->dimensions()->length() > 1) { + cc_.reportError(parameter->variable()->pos(), Message_MultiArrayInNative); return false; } @@ -586,6 +586,13 @@ } } + if ((type->isPrimitive() && type->primitive() == PrimitiveType_Char) || + (type->isReference() && type->contained()->primitive() == PrimitiveType_Char)) + { + cc_.reportError(node->pos(), Message_CannotDeclareStringCell); + return false; + } + args->set(zone_, i, type); parameter->variable()->setType(type); } @@ -594,7 +601,11 @@ if (!returnType) return false; - Local funtype(zone_, zone_->types()->newFunction(returnType, args)); + Local funtype(zone_); + if (node->fun()->isNative()) + funtype = zone_->types()->newNative(returnType, args, node->fun()->isNativeVariadic()); + else + funtype = zone_->types()->newFunction(returnType, args); if (!funtype) return false; @@ -737,8 +748,13 @@ return; } if (node->arguments()->length() != type->parameters()->length()) { - cc_.reportError(node->pos(), Message_ArgumentCountMismatch); - return; + if (!type->isNative() || + !type->isNativeVariadic() || + node->arguments()->length() < type->parameters()->length()) + { + cc_.reportError(node->pos(), Message_ArgumentCountMismatch); + return; + } } // Currently, only calls from a NameProxy are possible. @@ -761,13 +777,23 @@ if (expression->isIndexExpression()) given = given->contained(); - Local actual(zone_, type->parameterAt(i)); - if (!typeCheckParameter(expression, given, actual)) - return; + bool mustComputeReference; + if (i >= type->parameters()->length()) { + // Special handling for natives. Arguments past the formal must + // always have references computed. However, arrays are already + // references for natives. + assert(type->isNative() && type->isNativeVariadic()); + mustComputeReference = !given->isReference() && !given->isArray(); + } else { + Local actual(zone_, type->parameterAt(i)); + if (!typeCheckParameter(expression, given, actual)) + return; + mustComputeReference = actual->isReference() && !given->isReference(); + } // If the actual is a reference, and the given is not, we'll need to // compute a reference, which may be allocated on the stack. - if (actual->isReference() && !given->isReference()) + if (mustComputeReference) scope_->setUsesLifoHeap(); }