src/BytecodeCompiler.cpp
changeset 168 4d0fff61d65e
parent 164 3bf7c007883d
child 169 0456a16c2a63
     1.1 --- a/src/BytecodeCompiler.cpp	Sun Aug 05 15:38:52 2012 -0700
     1.2 +++ b/src/BytecodeCompiler.cpp	Sun Aug 05 21:24:41 2012 -0700
     1.3 @@ -25,6 +25,7 @@
     1.4  #include "Strings.h"
     1.5  #include "Zone.h"
     1.6  #include "Environments.h"
     1.7 +#include "Box.h"
     1.8  #include "Heap-inl.h"
     1.9  
    1.10  using namespace ke;
    1.11 @@ -839,9 +840,12 @@
    1.12          native = node->callee()->toNameProxy()->binding()->toNamedFunction();
    1.13      }
    1.14  
    1.15 +    Local<Type> given(zone_);
    1.16      for (size_t i = node->arguments()->length() - 1; i < node->arguments()->length(); i--) {
    1.17          Expression *arg = node->arguments()->at(i);
    1.18  
    1.19 +        given = arg->type();
    1.20 +
    1.21          // We need to compute a reference if the parameter was in the form:
    1.22          //  f(&a)
    1.23          // Note this form does not allow: f({})
    1.24 @@ -849,7 +853,6 @@
    1.25          // We also need to compute references for all variadic native
    1.26          // arguments, but arrays and references are already in the
    1.27          // appropriate form.
    1.28 -        Local<Type> given(zone_, arg->type());
    1.29          bool mustPushReference = false;
    1.30          if (i >= funType->parameters()->length()) {
    1.31              assert(funType->isNative() && funType->isNativeVariadic());
    1.32 @@ -892,14 +895,41 @@
    1.33          }
    1.34      }
    1.35  
    1.36 +    unsigned argc = node->arguments()->length();
    1.37 +
    1.38 +    // If there are missing arguments, then we're not done and have to push
    1.39 +    // default parameters.
    1.40 +    Local<Box> box(zone_);
    1.41 +    for (size_t i = node->arguments()->length(); i < funType->parameters()->length(); i++) {
    1.42 +        box = Box::cast(funType->defaults()->at(i));
    1.43 +
    1.44 +        if (box->type()->isPod()) {
    1.45 +            if (box->type()->pod() == PrimitiveType_Int32)
    1.46 +                __ int_(box->toInt32());
    1.47 +            else if (box->type()->pod() == PrimitiveType_Float)
    1.48 +                __ float_(box->toFloat());
    1.49 +            else
    1.50 +                assert(false);
    1.51 +        } else {
    1.52 +            assert(false);
    1.53 +        }
    1.54 +
    1.55 +        if (funType->parameterAt(i)->isReference()) {
    1.56 +            __ note_position(node->pos());
    1.57 +            __ slotref_lifo();
    1.58 +        }
    1.59 +
    1.60 +        argc++;
    1.61 +    }
    1.62 +
    1.63      __ note_position(node->pos());
    1.64      if (native) {
    1.65 -        __ callnative(native->slot(), node->arguments()->length());
    1.66 -        __ drop(node->arguments()->length());
    1.67 +        __ callnative(native->slot(), argc);
    1.68 +        __ drop(argc);
    1.69      } else {
    1.70          node->callee()->accept(this);
    1.71          __ call(funType);
    1.72 -        __ drop(node->arguments()->length() + 1);
    1.73 +        __ drop(argc + 1);
    1.74      }
    1.75  }
    1.76