public void ExecuteFunction(JsFunction function, JsDictionaryObject that, JsInstance[] parameters, Type[] genericParameters)
{
if (function == null) {
return;
}
if (recursionLevel++ > MaxRecursions) {
throw new JsException(Global.ErrorClass.New("Too many recursions in the script."));
}
// ecma chapter 10.
// TODO: move creation of the activation object to the JsFunction
// create new argument object and instantinate arguments into it
JsArguments args = new JsArguments(Global, function, parameters);
// create new activation object and copy instantinated arguments to it
// Activation should be before the function.Scope hierarchy
JsScope functionScope = new JsScope(function.Scope ?? GlobalScope);
for (int i = 0; i < function.Arguments.Count; i++)
if (i < parameters.Length)
functionScope.DefineOwnProperty(
new LinkedDescriptor(
functionScope,
function.Arguments[i],
args.GetDescriptor(i.ToString()),
args
)
);
else
functionScope.DefineOwnProperty(
new ValueDescriptor(
functionScope,
function.Arguments[i],
JsUndefined.Instance
)
);
// define arguments variable
if (HasOption(Options.Strict))
functionScope.DefineOwnProperty(JsScope.ARGUMENTS, args);
else
args.DefineOwnProperty(JsScope.ARGUMENTS, args);
// set this variable
if (that != null)
functionScope.DefineOwnProperty(JsScope.THIS, that);
else
functionScope.DefineOwnProperty(JsScope.THIS, that = Global as JsObject);
// enter activation object
EnterScope(functionScope);
try {
PermissionSet.PermitOnly();
if (genericParameters != null && genericParameters.Length > 0)
Result = function.Execute(this, that, parameters, genericParameters);
else
Result = function.Execute(this, that, parameters);
// Resets the return flag
if (exit) {
exit = false;
}
}
finally {
// return to previous execution state
ExitScope();
CodeAccessPermission.RevertPermitOnly();
recursionLevel--;
}
}