2 // ScriptBlock.cs: Represents a file, which maps to a 'JScript N' class in the assembly.
4 // Author: Cesar Octavio Lopez Nataren
6 // (C) Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
7 // Copyright (C) 2005 Novell Inc (http://novell.com)
11 // Permission is hereby granted, free of charge, to any person obtaining
12 // a copy of this software and associated documentation files (the
13 // "Software"), to deal in the Software without restriction, including
14 // without limitation the rights to use, copy, modify, merge, publish,
15 // distribute, sublicense, and/or sell copies of the Software, and to
16 // permit persons to whom the Software is furnished to do so, subject to
17 // the following conditions:
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
22 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
23 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
24 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
25 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
26 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
27 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
32 using System.Reflection;
33 using Microsoft.JScript.Vsa;
34 using System.Reflection.Emit;
35 using System.Runtime.CompilerServices;
37 namespace Microsoft.JScript {
39 public class ScriptBlock : AST, ICanModifyContext {
41 private TypeBuilder type_builder;
42 private MethodBuilder global_code;
43 private ILGenerator global_code_ig;
44 private EmitContext base_emit_context;
45 internal Block src_elems;
47 internal MethodBuilder GlobalCode {
48 get { return global_code; }
51 internal TypeBuilder TypeBuilder {
52 get { return type_builder; }
55 internal ScriptBlock ()
58 src_elems = new Block (null, null);
61 internal ScriptBlock (Location location)
62 : base (null, location)
64 src_elems = new Block (null, location);
67 internal void Add (AST e)
72 internal void EmitDecls (ModuleBuilder mb)
74 base_emit_context = new EmitContext (type_builder, mb, global_code_ig);
75 EmitInitGlobalCode ();
76 ((ICanModifyContext) src_elems).EmitDecls (base_emit_context);
81 Emit (base_emit_context);
85 internal override void Emit (EmitContext ec)
91 void ICanModifyContext.PopulateContext (Environment env, string ns)
93 ((ICanModifyContext) src_elems).PopulateContext (env, ns);
96 void ICanModifyContext.EmitDecls (EmitContext ec)
100 internal override bool Resolve (Environment env)
102 return src_elems.Resolve (env);
106 internal void InitTypeBuilder (ModuleBuilder moduleBuilder, string next_type)
108 type_builder = moduleBuilder.DefineType (next_type, TypeAttributes.Public);
109 type_builder.SetParent (typeof (GlobalScope));
110 type_builder.SetCustomAttribute (new CustomAttributeBuilder
111 (typeof (CompilerGlobalScopeAttribute).GetConstructor (new Type [] {}), new object [] {}));
114 internal void CreateType ()
116 type_builder.CreateType ();
119 internal void EmitTypeCtr ()
121 ConstructorBuilder cons_builder;
122 cons_builder = type_builder.DefineConstructor (MethodAttributes.Public,
123 CallingConventions.Standard,
124 new Type [] { typeof (GlobalScope) });
125 ILGenerator ig = cons_builder.GetILGenerator ();
126 ig.Emit (OpCodes.Ldarg_0);
127 ig.Emit (OpCodes.Ldarg_1);
128 ig.Emit (OpCodes.Dup);
129 ig.Emit (OpCodes.Ldfld,
130 typeof (ScriptObject).GetField ("engine"));
132 ig.Emit (OpCodes.Call,
133 typeof (GlobalScope).GetConstructor (new Type [] {typeof (GlobalScope),
134 typeof (VsaEngine)}));
135 ig.Emit (OpCodes.Ret);
138 internal void InitGlobalCode ()
140 global_code = type_builder.DefineMethod ("Global Code", MethodAttributes.Public,
141 typeof (System.Object), new Type [] {});
142 global_code_ig = global_code.GetILGenerator ();
145 private void EmitInitGlobalCode ()
147 ILGenerator ig = global_code_ig;
149 ig.Emit (OpCodes.Ldarg_0);
150 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
151 ig.Emit (OpCodes.Ldarg_0);
152 ig.Emit (OpCodes.Call,
153 typeof (VsaEngine).GetMethod ("PushScriptObject",
154 new Type [] { typeof (ScriptObject)}));
157 private void EmitEndGlobalCode ()
159 ILGenerator ig = global_code_ig;
161 ig.Emit (OpCodes.Ldnull);
162 ig.Emit (OpCodes.Ldarg_0);
163 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
164 ig.Emit (OpCodes.Call, typeof (VsaEngine).GetMethod ("PopScriptObject"));
165 ig.Emit (OpCodes.Pop);
166 ig.Emit (OpCodes.Ret);