src/API.cpp
changeset 129 86b368a4d80d
parent 92 e3974e7360e9
child 145 e9d804821c48
     1.1 --- a/src/API.cpp	Sun Jul 29 12:24:00 2012 -0700
     1.2 +++ b/src/API.cpp	Sun Jul 29 12:24:49 2012 -0700
     1.3 @@ -265,6 +265,12 @@
     1.4      ke::ZONE()->heap().reclaim();
     1.5  }
     1.6  
     1.7 +void
     1.8 +Ke::Keima::ClearPendingException()
     1.9 +{
    1.10 +    ke::ZONE()->clearPendingException();
    1.11 +}
    1.12 +
    1.13  unsigned
    1.14  Ke::Module::numPublics()
    1.15  {
    1.16 @@ -341,6 +347,44 @@
    1.17      native->bind(function);
    1.18  }
    1.19  
    1.20 +// :TODO: this leaks an interior pointer.
    1.21 +static const char *
    1.22 +GetTypeName(Type *type)
    1.23 +{
    1.24 +    if (type->isArray())
    1.25 +        return "array";
    1.26 +    if (type->isFunction())
    1.27 +        return "function";
    1.28 +    if (type->isVoid())
    1.29 +        return "void";
    1.30 +    if (type->isReference())
    1.31 +        type = type->contained();
    1.32 +    if (type->tag())
    1.33 +        return type->tag()->chars();
    1.34 +    return "int";
    1.35 +}
    1.36 +
    1.37 +static inline const char *
    1.38 +GetInvokeTypeName(Ke::Parameter::Type type)
    1.39 +{
    1.40 +    switch (type) {
    1.41 +      case Ke::Parameter::Array:
    1.42 +        return "array";
    1.43 +      case Ke::Parameter::CharArray:
    1.44 +        return "String";
    1.45 +      case Ke::Parameter::Float:
    1.46 +        return "Float";
    1.47 +      case Ke::Parameter::FloatRef:
    1.48 +        return "&Float";
    1.49 +      case Ke::Parameter::Int:
    1.50 +        return "int";
    1.51 +      case Ke::Parameter::IntRef:
    1.52 +        return "&int";
    1.53 +      default:
    1.54 +        return "<unknown>";
    1.55 +    }
    1.56 +}
    1.57 +
    1.58  static inline bool
    1.59  CheckInvokeType(const Ke::Parameter &param, Type *type)
    1.60  {
    1.61 @@ -365,8 +409,8 @@
    1.62      }
    1.63  }
    1.64  
    1.65 -bool
    1.66 -Ke::Keima::CheckInvokeTypes(Ke::Handle<Ke::Function> argFun, const Ke::Parameter *params, unsigned nparams)
    1.67 +static bool
    1.68 +CheckInvokeTypes(Ke::Handle<Ke::Function> argFun, const Ke::Parameter *params, unsigned nparams)
    1.69  {
    1.70      ke::Local<ke::Function> fun(ke::ZONE(), Open<Ke::Function, ke::Function>(argFun));
    1.71  
    1.72 @@ -374,20 +418,27 @@
    1.73          return false;
    1.74  
    1.75      for (unsigned i = 0; i < nparams; i++) {
    1.76 -        if (!CheckInvokeType(params[i], fun->argType(i)))
    1.77 +        if (!CheckInvokeType(params[i], fun->argType(i))) {
    1.78 +            ke::ZONE()->reportError(Message_TypeMismatchDuringInvoke,
    1.79 +                                    GetInvokeTypeName(params[i].type()),
    1.80 +                                    GetTypeName(fun->argType(i)));
    1.81              return false;
    1.82 +        }
    1.83      }
    1.84  
    1.85      // Functions can only return tagged cells, for ISPE1-compatible Invoke().
    1.86      ke::Local<ke::Type> returnType(ke::ZONE(), fun->type()->returnType());
    1.87 -    if ((!returnType->isPrimitive() && !returnType->isVoid()) || returnType->isTraceable())
    1.88 +    if (!returnType->isPrimitive() && !returnType->isVoid()) {
    1.89 +        ke::ZONE()->reportError(Message_CannotInvokeReturnType, GetTypeName(returnType));
    1.90          return false;
    1.91 +    }
    1.92  
    1.93      return true;
    1.94  }
    1.95  
    1.96  bool
    1.97 -Ke::Keima::Invoke(Handle<Function> argFun, const Parameter *params, unsigned nparams, int *retval)
    1.98 +Ke::Keima::Invoke(Handle<Function> argFun, const Parameter *params, unsigned nparams,
    1.99 +                  bool checkTypes, int *retval)
   1.100  {
   1.101      assert(CheckInvokeTypes(argFun, params, nparams));
   1.102  
   1.103 @@ -403,6 +454,9 @@
   1.104      if (!ke::ZONE()->stack().pushInvokeFrame(fun, args))
   1.105          return false;
   1.106  
   1.107 +    if (checkTypes && !CheckInvokeTypes(argFun, params, nparams))
   1.108 +        return false;
   1.109 +
   1.110      for (unsigned i = 0; i < nparams; i++) {
   1.111          ke::LocalSlot &slot = args.arg(i);
   1.112          switch (params[i].type()) {