Files
yallie 9fa3874800 Added the contents of the archive.
Moved the original file to the archive subfolder.
2017-11-20 16:11:42 +03:00

194 lines
6.5 KiB
C#

// ==++==
//
//
// Copyright (c) 2002 Microsoft Corporation. All rights reserved.
//
// The use and distribution terms for this software are contained in the file
// named license.txt, which can be found in the root of this distribution.
// By using this software in any fashion, you are agreeing to be bound by the
// terms of this license.
//
// You must not remove this notice, or any other, from this software.
//
//
// ==--==
namespace Microsoft.JScript
{
using System;
using System.Reflection;
using System.Globalization;
using System.Diagnostics;
public abstract class ScriptFunction : JSObject{
protected int ilength;
internal String name;
internal Object proto;
internal ScriptFunction(ScriptObject parent)
: base(parent) {
this.ilength = 0;
this.name = "Function.prototype";
this.proto = Missing.Value;
}
protected ScriptFunction(ScriptObject parent, String name)
: base(parent, Typeob.ScriptFunction) {
this.ilength = length;
this.name = name;
this.proto = new JSPrototypeObject(parent.GetParent(), this);
}
internal ScriptFunction(ScriptObject parent, String name, int length)
: base(parent) {
this.ilength = length;
this.name = name;
this.proto = new JSPrototypeObject(parent.GetParent(), this);
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
internal abstract Object Call(Object[] args, Object thisob);
internal virtual Object Call(Object[] args, Object thisob, Binder binder, CultureInfo culture){
return this.Call(args, thisob);
}
internal virtual Object Call(Object[] args, Object thisob, ScriptObject enclosing_scope, Closure calleeClosure, Binder binder, CultureInfo culture){
return this.Call(args, thisob);
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
internal virtual Object Construct(Object[] args){
JSObject newob = new JSObject(null, false);
newob.SetParent(this.GetPrototypeForConstructedObject());
Object result = this.Call(args, newob);
if (result is ScriptObject || (this is BuiltinFunction && ((BuiltinFunction)this).method.Name.Equals("CreateInstance")))
return result;
return newob;
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
[JSFunctionAttribute(JSFunctionAttributeEnum.HasVarArgs)]
public Object CreateInstance(params Object[] args){
return this.Construct(args);
}
internal override String GetClassName(){
return "Function";
}
internal virtual int GetNumberOfFormalParameters(){
return this.ilength;
}
protected ScriptObject GetPrototypeForConstructedObject(){
Object ob = this.proto;
if (ob is JSObject)
return (JSObject)ob;
else if (ob is ClassScope)
return (ClassScope)ob;
else
return (ObjectPrototype)(this.GetParent().GetParent()); //The prototype of function is FunctionPrototype, its Prototype is ObjectPrototype
}
internal virtual bool HasInstance(Object ob){
if (!(ob is JSObject))
return false;
Object proto = this.proto;
if (!(proto is ScriptObject))
throw new JScriptException(JSError.InvalidPrototype);
ScriptObject parent = ((JSObject)ob).GetParent();
ScriptObject prot = (ScriptObject)proto;
while (parent != null){
if (parent == prot)
return true;
else if (parent is WithObject){
Object wob = ((WithObject)parent).contained_object;
if (wob == prot && wob is ClassScope) return true;
}
parent = parent.GetParent();
}
return false;
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
[JSFunctionAttribute(JSFunctionAttributeEnum.HasThisObject|JSFunctionAttributeEnum.HasVarArgs)]
public Object Invoke(Object thisob, params Object[] args){
return this.Call(args, thisob);
}
#if !DEBUG
[DebuggerStepThroughAttribute]
[DebuggerHiddenAttribute]
#endif
public override Object InvokeMember(String name, BindingFlags invokeAttr, Binder binder, Object target, Object[] args,
ParameterModifier[] modifiers, CultureInfo culture, String[] namedParameters){
if (target != this)
throw new TargetException();
String thisName = "this";
if (name == null || name == String.Empty){
if ((invokeAttr & BindingFlags.CreateInstance) != 0){
if ((invokeAttr & (BindingFlags.InvokeMethod|BindingFlags.GetField|BindingFlags.GetProperty|
BindingFlags.SetField|BindingFlags.SetProperty|BindingFlags.PutDispProperty)) != 0)
throw new ArgumentException();
return this.Construct(args);
}
if ((invokeAttr & BindingFlags.InvokeMethod) != 0){
//Get the this object
Object thisob = null;
if (namedParameters != null){
int i = Array.IndexOf(namedParameters, thisName);
if (i == 0){
thisob = args[0];
int n = args.Length-1;
Object[] args2 = new Object[n];
ArrayObject.Copy(args, 1, args2, 0, n);
args = args2;
}
if (i != 0 || namedParameters.Length != 1)
throw new ArgumentException();
}
//Prefer call only if there GetXXX is not set, or there is one or more args.
if (args.Length > 0 || (invokeAttr & (BindingFlags.GetField|BindingFlags.GetProperty)) == 0)
return this.Call(args, thisob, binder, culture);
}
}
return base.InvokeMember(name, invokeAttr, binder, target, args, modifiers, culture, namedParameters);
}
public virtual int length{
get{return this.ilength;}
set{}
}
public override String ToString(){
return "function "+this.name+"() {\n [native code]\n}";
}
public Object prototype{
get{return this.proto;}
set{
if (!this.noExpando)
this.proto = value;
}
}
}
}