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

214 lines
8.3 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.Reflection.Emit;
internal sealed class ThisLiteral : AST{
internal bool isSuper;
private MethodInfo method;
internal ThisLiteral(Context context, bool isSuper)
: base(context){
this.isSuper = isSuper;
this.method = null;
}
internal override void CheckIfOKToUseInSuperConstructorCall(){
this.context.HandleError(JSError.NotAllowedInSuperConstructorCall);
}
internal override Object Evaluate(){
ScriptObject top = Globals.ScopeStack.Peek();
while (top is WithObject || top is BlockScope)
top = top.GetParent();
if (top is StackFrame)
return ((StackFrame)top).thisObject;
else //Code is either local to function/method/constructor/initializer (StackFrame) or global (GlobalScope)
return ((GlobalScope)top).thisObject;
}
internal override IReflect InferType(JSField inference_target){
if (this.method != null){
ParameterInfo[] pars = this.method.GetParameters();
if (pars == null || pars.Length == 0)
return this.method.ReturnType;
else
return pars[0].ParameterType;
}
ScriptObject top = Globals.ScopeStack.Peek();
while (top is WithObject)
top = top.GetParent();
if (top is GlobalScope)
return top;
else if (top is FunctionScope && ((FunctionScope)top).isMethod){
ClassScope csc = (ClassScope)((FunctionScope)top).owner.enclosing_scope;
if (this.isSuper)
return csc.GetSuperType();
else
return csc;
}
return Typeob.Object;
}
internal override AST PartiallyEvaluate(){
ScriptObject top = Globals.ScopeStack.Peek();
while (top is WithObject)
top = top.GetParent();
bool isStatic = false;
if (top is FunctionScope)
isStatic = ((FunctionScope)top).isStatic && ((FunctionScope)top).isMethod;
else if (top is StackFrame)
isStatic = ((StackFrame)top).thisObject is Type;
if (isStatic){
this.context.HandleError(JSError.NotAccessible);
return (new Lookup("this", this.context)).PartiallyEvaluate();
}
return this;
}
internal override AST PartiallyEvaluateAsReference(){
this.context.HandleError(JSError.CantAssignThis);
return (new Lookup("this", this.context)).PartiallyEvaluateAsReference();
}
internal void ResolveAssignmentToDefaultIndexedProperty(ASTList args, IReflect[] argIRs, AST rhvalue){
IReflect ir = this.InferType(null);
Type t = ir is Type ? (Type)ir : null;
if (ir is ClassScope) t = ((ClassScope)ir).GetBakedSuperType();
MemberInfo[] defaultMembers = JSBinder.GetDefaultMembers(t);
if (defaultMembers != null && defaultMembers.Length > 0){
try{
PropertyInfo prop = JSBinder.SelectProperty(defaultMembers, argIRs); //Returns property getters as well
if (prop != null){
this.method = JSProperty.GetSetMethod(prop, true);
if (this.method == null)
this.context.HandleError(JSError.AssignmentToReadOnly, true);
if (!Binding.CheckParameters(prop.GetIndexParameters(), argIRs, args, this.context, 0, false, true))
this.method = null;
return;
}
}catch(AmbiguousMatchException){
this.context.HandleError(JSError.AmbiguousMatch);
return;
}
}
String tname = ir is ClassScope ? ((ClassScope)ir).GetName() : ((Type)ir).Name;
this.context.HandleError(JSError.NotIndexable, tname);
}
internal override void ResolveCall(ASTList args, IReflect[] argIRs, bool constructor, bool brackets){
if (constructor || !brackets){
if (this.isSuper)
this.context.HandleError(JSError.IllegalUseOfSuper);
else
this.context.HandleError(JSError.IllegalUseOfThis);
return;
}
IReflect ir = this.InferType(null);
Type t = ir is Type ? (Type)ir : null;
if (ir is ClassScope) t = ((ClassScope)ir).GetBakedSuperType();
MemberInfo[] defaultMembers = JSBinder.GetDefaultMembers(t);
if (defaultMembers != null && defaultMembers.Length > 0){
try{
this.method = JSBinder.SelectMethod(defaultMembers, argIRs); //Returns property getters as well
if (this.method != null){
if (!Binding.CheckParameters(this.method.GetParameters(), argIRs, args, this.context, 0, false, true))
this.method = null;
return;
}
}catch(AmbiguousMatchException){
this.context.HandleError(JSError.AmbiguousMatch);
return;
}
}
String tname = ir is ClassScope ? ((ClassScope)ir).GetName() : ((Type)ir).Name;
this.context.HandleError(JSError.NotIndexable, tname);
}
internal override void TranslateToIL(ILGenerator il, Type rtype){
if (rtype == Typeob.Void) return;
IReflect ir = this.InferType(null);
if (ir is GlobalScope){
this.EmitILToLoadEngine(il);
if (rtype == Typeob.LenientGlobalObject)
il.Emit(OpCodes.Call, CompilerGlobals.getLenientGlobalObjectMethod);
else{
il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod);
il.Emit(OpCodes.Castclass, CompilerGlobals.iActivationObjectClass);
il.Emit(OpCodes.Callvirt, CompilerGlobals.getDefaultThisObjectMethod);
}
return;
}
il.Emit(OpCodes.Ldarg_0);
Convert.Emit(this, il, Convert.ToType(this.InferType(null)), rtype);
}
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets){
MethodInfo meth = this.method;
if (meth != null){
Type t = meth.ReflectedType;
if (!meth.IsStatic){
this.method = null;
this.TranslateToIL(il, t);
this.method = meth;
}
ParameterInfo[] pars = meth.GetParameters();
Binding.PlaceArgumentsOnStack(il, pars, argList, 0, 0, Binding.ReflectionMissingCW);
if (meth.IsVirtual && !meth.IsFinal && !t.IsSealed)
il.Emit(OpCodes.Callvirt, meth);
else
il.Emit(OpCodes.Call, meth);
Convert.Emit(this, il, meth.ReturnType, rtype);
}else
base.TranslateToILCall(il, rtype, argList, construct, brackets);
}
internal override void TranslateToILPreSet(ILGenerator il, ASTList argList){
MethodInfo meth = this.method;
if (meth != null){
Type t = meth.ReflectedType;
if (!meth.IsStatic)
this.TranslateToIL(il, t);
Binding.PlaceArgumentsOnStack(il, meth.GetParameters(), argList, 0, 1, Binding.ReflectionMissingCW);
}else
base.TranslateToILPreSet(il, argList);
}
internal override void TranslateToILSet(ILGenerator il, AST rhvalue){
MethodInfo meth = this.method;
if (meth != null){
if (rhvalue != null)
rhvalue.TranslateToIL(il, meth.GetParameters()[0].ParameterType);
Type t = meth.ReflectedType;
if (meth.IsVirtual && !meth.IsFinal && !t.IsSealed)
il.Emit(OpCodes.Callvirt, meth);
else
il.Emit(OpCodes.Call, meth);
if (meth.ReturnType != Typeob.Void) //Should never be the case if the property is well formed, but there is no gaurantee
il.Emit(OpCodes.Pop);
}else
base.TranslateToILSet(il, rhvalue);
}
internal override void TranslateToILInitializer(ILGenerator il){
}
}
}