diff -r cf82769eb136 -r 4d0fff61d65e src/BytecodeCompiler.cpp --- a/src/BytecodeCompiler.cpp Sun Aug 05 15:38:52 2012 -0700 +++ b/src/BytecodeCompiler.cpp Sun Aug 05 21:24:41 2012 -0700 @@ -25,6 +25,7 @@ #include "Strings.h" #include "Zone.h" #include "Environments.h" +#include "Box.h" #include "Heap-inl.h" using namespace ke; @@ -839,9 +840,12 @@ native = node->callee()->toNameProxy()->binding()->toNamedFunction(); } + Local given(zone_); for (size_t i = node->arguments()->length() - 1; i < node->arguments()->length(); i--) { Expression *arg = node->arguments()->at(i); + given = arg->type(); + // We need to compute a reference if the parameter was in the form: // f(&a) // Note this form does not allow: f({}) @@ -849,7 +853,6 @@ // We also need to compute references for all variadic native // arguments, but arrays and references are already in the // appropriate form. - Local given(zone_, arg->type()); bool mustPushReference = false; if (i >= funType->parameters()->length()) { assert(funType->isNative() && funType->isNativeVariadic()); @@ -892,14 +895,41 @@ } } + unsigned argc = node->arguments()->length(); + + // If there are missing arguments, then we're not done and have to push + // default parameters. + Local box(zone_); + for (size_t i = node->arguments()->length(); i < funType->parameters()->length(); i++) { + box = Box::cast(funType->defaults()->at(i)); + + if (box->type()->isPod()) { + if (box->type()->pod() == PrimitiveType_Int32) + __ int_(box->toInt32()); + else if (box->type()->pod() == PrimitiveType_Float) + __ float_(box->toFloat()); + else + assert(false); + } else { + assert(false); + } + + if (funType->parameterAt(i)->isReference()) { + __ note_position(node->pos()); + __ slotref_lifo(); + } + + argc++; + } + __ note_position(node->pos()); if (native) { - __ callnative(native->slot(), node->arguments()->length()); - __ drop(node->arguments()->length()); + __ callnative(native->slot(), argc); + __ drop(argc); } else { node->callee()->accept(this); __ call(funType); - __ drop(node->arguments()->length() + 1); + __ drop(argc + 1); } }