mirror of
https://github.com/SSCLI/sscli_20021101
synced 2026-06-08 12:28:57 +00:00
9fa3874800
Moved the original file to the archive subfolder.
145 lines
5.1 KiB
C#
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);
|
|
}
|
|
}
|
|
}
|