public FunctionObject(string name, MemberInfo methodOrConstructor, Scriptable scope)
{
// API class
if (methodOrConstructor is ConstructorInfo)
{
member = new MemberBox((ConstructorInfo<object>)methodOrConstructor);
isStatic = true;
}
else
{
// well, doesn't take a 'this'
member = new MemberBox((MethodInfo)methodOrConstructor);
isStatic = member.IsStatic();
}
string methodName = member.GetName();
this.functionName = name;
Type[] types = member.argTypes;
int arity = types.Length;
if (arity == 4 && (types[1].IsArray || types[2].IsArray))
{
// Either variable args or an error.
if (types[1].IsArray)
{
if (!isStatic || types[0] != ScriptRuntime.ContextClass || types[1].GetElementType() != ScriptRuntime.ObjectClass || types[2] != ScriptRuntime.FunctionClass || types[3] != typeof(bool))
{
throw Context.ReportRuntimeError1("msg.varargs.ctor", methodName);
}
parmsLength = VARARGS_CTOR;
}
else
{
if (!isStatic || types[0] != ScriptRuntime.ContextClass || types[1] != ScriptRuntime.ScriptableClass || types[2].GetElementType() != ScriptRuntime.ObjectClass || types[3] != ScriptRuntime.FunctionClass)
{
throw Context.ReportRuntimeError1("msg.varargs.fun", methodName);
}
parmsLength = VARARGS_METHOD;
}
}
else
{
parmsLength = arity;
if (arity > 0)
{
typeTags = new byte[arity];
for (int i = 0; i != arity; ++i)
{
int tag = GetTypeTag(types[i]);
if (tag == JAVA_UNSUPPORTED_TYPE)
{
throw Context.ReportRuntimeError2("msg.bad.parms", types[i].FullName, methodName);
}
typeTags[i] = unchecked((byte)tag);
}
}
}
if (member.IsMethod())
{
MethodInfo method = member.Method();
Type returnType = method.ReturnType;
if (returnType == typeof(void))
{
hasVoidReturn = true;
}
else
{
returnTypeTag = GetTypeTag(returnType);
}
}
else
{
Type ctorType = member.GetDeclaringClass();
if (!ScriptRuntime.ScriptableClass.IsAssignableFrom(ctorType))
{
throw Context.ReportRuntimeError1("msg.bad.ctor.return", ctorType.FullName);
}
}
ScriptRuntime.SetFunctionProtoAndParent(this, scope);
}