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

126 lines
4.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 Microsoft.JScript.Vsa;
using System;
using System.Reflection;
using System.Reflection.Emit;
internal sealed class CallableExpression : Binding{
internal AST expression;
private IReflect expressionInferredType;
internal CallableExpression(AST expression)
: base(expression.context, ""){
this.expression = expression;
JSLocalField field = new JSLocalField("", null, 0, Missing.Value);
this.expressionInferredType = expression.InferType(field);
field.inferred_type = this.expressionInferredType;
this.member = field;
this.members = new MemberInfo[]{field};
}
internal override LateBinding EvaluateAsLateBinding(){
return new LateBinding(null, this.expression.Evaluate(), VsaEngine.executeForJSEE);
}
protected override Object GetObject(){
return this.GetObject2();
}
internal Object GetObject2(){
Call c = this.expression as Call;
if (c == null || !c.inBrackets)
return Convert.ToObject(this.expression.Evaluate(), this.Engine);
else
return Convert.ToObject(c.func.Evaluate(), this.Engine);
}
protected override void HandleNoSuchMemberError(){
throw new JScriptException(JSError.InternalError, this.context);
}
internal override AST PartiallyEvaluate(){
return this;
}
//Called when there is an early binding to default members on rtype
internal override void TranslateToIL(ILGenerator il, Type rtype){
this.expression.TranslateToIL(il, rtype);
}
internal override void TranslateToILCall(ILGenerator il, Type rtype, ASTList argList, bool construct, bool brackets){
if (this.defaultMember != null && construct && brackets){
base.TranslateToILCall(il, rtype, argList, construct, brackets);
return;
}
JSGlobalField gf = this.member as JSGlobalField;
if (gf != null && gf.IsLiteral && argList.count == 1){
Type t = Convert.ToType((IReflect)gf.value);
argList[0].TranslateToIL(il, t);
Convert.Emit(this, il, t, rtype);
return;
}
this.TranslateToILWithDupOfThisOb(il);
argList.TranslateToIL(il, typeof(Object[]));
if (construct)
il.Emit(OpCodes.Ldc_I4_1);
else
il.Emit(OpCodes.Ldc_I4_0);
if (brackets)
il.Emit(OpCodes.Ldc_I4_1);
else
il.Emit(OpCodes.Ldc_I4_0);
this.EmitILToLoadEngine(il);
il.Emit(OpCodes.Call, CompilerGlobals.callValueMethod);
Convert.Emit(this, il, Typeob.Object, rtype);
}
protected override void TranslateToILObject(ILGenerator il, Type obType, bool noValue){
this.EmitILToLoadEngine(il);
il.Emit(OpCodes.Call, CompilerGlobals.scriptObjectStackTopMethod);
il.Emit(OpCodes.Castclass, CompilerGlobals.iActivationObjectClass);
il.Emit(OpCodes.Callvirt, CompilerGlobals.getGlobalScopeMethod);
}
//Called when a late bound call is being made
protected override void TranslateToILWithDupOfThisOb(ILGenerator il){
Call c = this.expression as Call;
if (c == null || !c.inBrackets)
this.TranslateToILObject(il, null, false);
else if (c.isConstructor && c.inBrackets){
//Dealing with (new T[x])[..] or (new T[x])(...), being handled late bound because it is an edge case
c.TranslateToIL(il, Typeob.Object);
il.Emit(OpCodes.Dup);
return;
}else
c.func.TranslateToIL(il, Typeob.Object);
this.expression.TranslateToIL(il, Typeob.Object);
}
internal override void TranslateToILInitializer(ILGenerator il){
this.expression.TranslateToILInitializer(il);
if (!this.expressionInferredType.Equals(this.expression.InferType(null))){
MemberInfo[] savedMembers = this.members;
this.InvalidateBinding();
this.members = savedMembers;
}
}
}
}