/// <summary> Function.prototype.apply and Function.prototype.call /// /// See Ecma 15.3.4.[34] /// </summary> public static object applyOrCall(bool isApply, Context cx, IScriptable scope, IScriptable thisObj, object [] args) { int L = args.Length; ICallable function; if (thisObj is ICallable) { function = (ICallable)thisObj; } else { object value = thisObj.GetDefaultValue (typeof (IFunction)); if (!(value is ICallable)) { throw ScriptRuntime.NotFunctionError (value, thisObj); } function = (ICallable)value; } IScriptable callThis = null; if (L != 0) { callThis = ScriptConvert.ToObjectOrNull (cx, args [0]); } if (callThis == null) { // This covers the case of args[0] == (null|undefined) as well. callThis = getTopCallScope (cx); } object [] callArgs; if (isApply) { // Follow Ecma 15.3.4.3 if (L <= 1) { callArgs = ScriptRuntime.EmptyArgs; } else { object arg1 = args [1]; if (arg1 == null || arg1 == Undefined.Value) { callArgs = ScriptRuntime.EmptyArgs; } else if (arg1 is BuiltinArray || arg1 is Arguments) { callArgs = cx.GetElements ((IScriptable)arg1); } else { throw ScriptRuntime.TypeErrorById ("msg.arg.isnt.array"); } } } else { // Follow Ecma 15.3.4.4 if (L <= 1) { callArgs = ScriptRuntime.EmptyArgs; } else { callArgs = new object [L - 1]; Array.Copy (args, 1, callArgs, 0, L - 1); } } return function.Call (cx, scope, callThis, callArgs); }