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

145 lines
5.1 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;
public sealed class With : AST{
private AST obj;
private AST block;
private Completion completion;
private FunctionScope enclosing_function;
internal With(Context context, AST obj, AST block)
: base(context) {
this.obj = obj;
this.block = block;
this.completion = new Completion();
ScriptObject scope = Globals.ScopeStack.Peek();
if (scope is FunctionScope)
this.enclosing_function = (FunctionScope)scope;
else
this.enclosing_function = null;
}
internal override Object Evaluate(){
try{
JScriptWith(this.obj.Evaluate(), this.Engine);
}catch(JScriptException e){
e.context = this.obj.context;
throw e;
}
Completion c = null;
try{
c = (Completion)this.block.Evaluate();
}finally{
Globals.ScopeStack.Pop();
}
if (c.Continue > 1)
this.completion.Continue = c.Continue - 1;
else
this.completion.Continue = 0;
if (c.Exit > 0)
this.completion.Exit = c.Exit - 1;
else
this.completion.Exit = 0;
if (c.Return)
return c;
return this.completion;
}
public static Object JScriptWith(Object withOb, VsaEngine engine){
Object ob = Convert.ToObject(withOb, engine);
if (ob == null)
throw new JScriptException(JSError.ObjectExpected);
Globals glob = engine.Globals;
glob.ScopeStack.GuardedPush(new WithObject(glob.ScopeStack.Peek(), ob));
return ob;
}
internal override AST PartiallyEvaluate(){
this.obj = this.obj.PartiallyEvaluate();
WithObject wob;
if (this.obj is ConstantWrapper){
Object ob = Convert.ToObject(this.obj.Evaluate(), this.Engine);
wob = new WithObject(Globals.ScopeStack.Peek(), ob);
if (ob is JSObject && ((JSObject)ob).noExpando)
wob.isKnownAtCompileTime = true;
}else
wob = new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false));
Globals.ScopeStack.Push(wob);
try{
this.block = this.block.PartiallyEvaluate();
}finally{
Globals.ScopeStack.Pop();
}
return this;
}
internal override void TranslateToIL(ILGenerator il, Type rtype){
//This assumes that rtype == Void.class
this.context.EmitLineInfo(il);
Globals.ScopeStack.Push(new WithObject(Globals.ScopeStack.Peek(), new JSObject(null, false)));
bool savedInsideProtectedRegion = compilerGlobals.InsideProtectedRegion;
compilerGlobals.InsideProtectedRegion = true;
Label lab = il.DefineLabel();
compilerGlobals.BreakLabelStack.Push(lab);
compilerGlobals.ContinueLabelStack.Push(lab);
this.obj.TranslateToIL(il, Typeob.Object);
this.EmitILToLoadEngine(il);
il.Emit(OpCodes.Call, CompilerGlobals.jScriptWithMethod); // JScriptWith returns the with object as an 'Object' (used by the debugger EE)
// define a local named 'with()' that the debugger EE will use to bind to the with object
LocalBuilder withObj = null;
if (context.document.debugOn){
il.BeginScope(); // used by the debugger to mark a with block
withObj = il.DeclareLocal(Typeob.Object);
withObj.SetLocalSymInfo("with()");
il.Emit(OpCodes.Stloc, withObj);
}else
il.Emit(OpCodes.Pop);
il.BeginExceptionBlock();
this.block.TranslateToILInitializer(il);
this.block.TranslateToIL(il, Typeob.Void);
il.BeginFinallyBlock();
if (context.document.debugOn){
// null the local used by the debugger EE
il.Emit(OpCodes.Ldnull);
il.Emit(OpCodes.Stloc, withObj);
}
this.EmitILToLoadEngine(il);
il.Emit(OpCodes.Call, CompilerGlobals.popScriptObjectMethod);
il.Emit(OpCodes.Pop);
il.EndExceptionBlock();
if (context.document.debugOn)
il.EndScope(); // used by the debugger to mark a with block
il.MarkLabel(lab);
compilerGlobals.BreakLabelStack.Pop();
compilerGlobals.ContinueLabelStack.Pop();
compilerGlobals.InsideProtectedRegion = savedInsideProtectedRegion;
Globals.ScopeStack.Pop();
}
internal override void TranslateToILInitializer(ILGenerator il){
this.obj.TranslateToILInitializer(il);
}
}
}