# HG changeset patch # User David Anderson # Date 1341895220 25200 # Node ID cbba1997dc71d824f8ce22c2a664417412d54d6c # Parent 7c942b5adebc8b0931777c6f6a7a84ae8ef6c60d Add support for passing arrays. diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/AST.h --- a/jitcraft/AST.h Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/AST.h Mon Jul 09 21:40:20 2012 -0700 @@ -198,12 +198,14 @@ Variable *variable_; ScopedRoot tag_; bool reference_; + ExpressionList *dimensions_; public: - Parameter(Variable *var, Handle tag, bool reference) + Parameter(Variable *var, Handle tag, bool reference, ExpressionList *dimensions) : variable_(var), tag_(tag), - reference_(reference) + reference_(reference), + dimensions_(dimensions) { } @@ -216,6 +218,9 @@ bool reference() const { return reference_; } + ExpressionList *dimensions() const { + return dimensions_; + } }; class NameProxy : public Expression diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/Array.cpp --- a/jitcraft/Array.cpp Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/Array.cpp Mon Jul 09 21:40:20 2012 -0700 @@ -58,7 +58,7 @@ return NULL; array->nelements_ = elements; - array->elements_ = VoidPtr((Array *)array + 1); + array->elements_ = (Array *)array + 1; memset(array->elements_, 0, elementBytes); return array; } diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/BytecodeCompiler.cpp --- a/jitcraft/BytecodeCompiler.cpp Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/BytecodeCompiler.cpp Mon Jul 09 21:40:20 2012 -0700 @@ -763,6 +763,8 @@ if (!moduleData_->publics.append(root)) return NULL; } + + Disassemble(code, stdout); return fun; } diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/Messages.tbl --- a/jitcraft/Messages.tbl Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/Messages.tbl Mon Jul 09 21:40:20 2012 -0700 @@ -43,4 +43,6 @@ MSG(ErrorReadingFile, SyntaxError, "error reading file") MSG(ExpectedGlobal, SyntaxError, "expected global variable or function") MSG(ForwardNotImplemented, SyntaxError, "forward '%s' not implemented") -MSG(ForwardDeclareMismatches, SyntaxError, "declaration does not match original forward signature") \ No newline at end of file +MSG(ForwardDeclareMismatches, SyntaxError, "declaration does not match original forward signature") +MSG(ArrayCantBeReference, SyntaxError, "a parameter cannot be both an array and a reference") +MSG(ArraySizeMustBeConstant, SyntaxError, "array size must be a constant integer") \ No newline at end of file diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/Objects.h --- a/jitcraft/Objects.h Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/Objects.h Mon Jul 09 21:40:20 2012 -0700 @@ -60,8 +60,6 @@ MapKinds_Total }; -typedef void * VoidPtr; - // All garbage collected objects must inherit from GCObject. Note that using // virtual functions is illegal, as the |map| field would be displaced. class Object diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/Parser.cpp --- a/jitcraft/Parser.cpp Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/Parser.cpp Mon Jul 09 21:40:20 2012 -0700 @@ -896,6 +896,11 @@ while (true) { bool ref = match(TOK_AMPERSAND); + SourcePosition begin = scanner_.begin(); + Local tag(zone_); + if (matchName(tag.ref(), TOK_LABEL) && !tag) + return NULL; + Local name(zone_, expectName()); if (!name) return NULL; @@ -908,8 +913,25 @@ if (!arg) return NULL; - Local tag(zone_); - Parameter *parameter = new (pool_) Parameter(arg, tag, ref); + // Look for dimensions. + ExpressionList *postDimensions = NULL; + while (match(TOK_LBRACKET)) { + if (!postDimensions) + postDimensions = new (pool_) ExpressionList(); + + Expression *dim = NULL; + if (!match(TOK_RBRACKET)) { + if ((dim = expression()) == NULL) + return NULL; + if (!expect(TOK_RBRACKET)) + return NULL; + } + + if (!postDimensions->append(dim)) + return NULL; + } + + Parameter *parameter = new (pool_) Parameter(arg, tag, ref, postDimensions); if (!parameters->append(parameter)) return NULL; diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/SemanticAnalysis.cpp --- a/jitcraft/SemanticAnalysis.cpp Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/SemanticAnalysis.cpp Mon Jul 09 21:40:20 2012 -0700 @@ -542,9 +542,38 @@ } if (parameter->reference()) { + if (parameter->dimensions()) { + cc_.reportError(parameter->variable()->pos(), Message_ArrayCantBeReference); + return NULL; + } + type = zone_->types()->getReference(type); if (!type) return false; + } else if (parameter->dimensions()) { + if (parameter->dimensions()->length() > Type::MAX_UNSAFE_ARRAY_DEPTH) { + cc_.reportError(node->pos(), Message_MaximumArrayDepth); + return false; + } + + for (size_t i = parameter->dimensions()->length() - 1; + i < parameter->dimensions()->length(); + i++) + { + int size = Type::UNKNOWN_SIZE; + if (Expression *expr = parameter->dimensions()->at(i)) { + BoxedPrimitive box; + if (!EvaluateForConstant(expr, &box)) { + cc_.reportError(expr->pos(), Message_ArraySizeMustBeConstant); + return false; + } + size = box.toInt(); + } + + type = Type::NewArray(zone_, type, size, false); + if (!type) + return false; + } } args->set(zone_, i, type); @@ -731,6 +760,8 @@ if (actual->isReference() && !given->isReference()) scope_->setUsesLifoHeap(); } + + node->setType(fun->type()->returnType()); } void diff -r 7c942b5adebc -r cbba1997dc71 jitcraft/main.cpp --- a/jitcraft/main.cpp Mon Jul 09 01:22:03 2012 -0700 +++ b/jitcraft/main.cpp Mon Jul 09 21:40:20 2012 -0700 @@ -76,7 +76,7 @@ if (!module) return 1; - Ke::Root root = Ke::Root::New(module); + } Ke::Keima::Shutdown(); diff -r 7c942b5adebc -r cbba1997dc71 tests/prototype/passarray.jc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/tests/prototype/passarray.jc Mon Jul 09 21:40:20 2012 -0700 @@ -0,0 +1,12 @@ +f(a[]) +{ + return a[3]; +} + +public main() +{ + new b[5]; + b[2] = 3; + return f(b); +} +