* roottypes.cs: Rename from tree.cs.
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / ScriptBlock.cs
1 //
2 // ScriptBlock.cs: Represents a file, which maps to a 'JScript N' class in the assembly.
3 //
4 // Author: Cesar Octavio Lopez Nataren
5 //
6 // (C) Cesar Octavio Lopez Nataren, <cesar@ciencias.unam.mx>
7 // Copyright (C) 2005 Novell Inc (http://novell.com)
8 //
9
10 //
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:
18 // 
19 // The above copyright notice and this permission notice shall be
20 // included in all copies or substantial portions of the Software.
21 // 
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.
29 //
30
31 using System;
32 using System.Reflection;
33 using Microsoft.JScript.Vsa;
34 using System.Reflection.Emit;
35 using System.Runtime.CompilerServices;
36
37 namespace Microsoft.JScript {
38
39         public class ScriptBlock : AST, ICanModifyContext {
40
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;
46                 
47                 internal MethodBuilder GlobalCode {
48                         get { return global_code; }
49                 }
50
51                 internal TypeBuilder TypeBuilder {
52                         get { return type_builder; }
53                 }
54
55                 internal ScriptBlock ()
56                         : base (null, null)
57                 {
58                         src_elems = new Block (null, null);
59                 }
60
61                 internal ScriptBlock (Location location)
62                         : base (null, location)
63                 {
64                         src_elems = new Block (null, location);
65                 }
66
67                 internal void Add (AST e)
68                 {
69                         src_elems.Add (e);
70                 }
71
72                 internal void EmitDecls (ModuleBuilder mb)
73                 {
74                         base_emit_context = new EmitContext (type_builder, mb, global_code_ig);
75                         EmitInitGlobalCode ();
76                         ((ICanModifyContext) src_elems).EmitDecls (base_emit_context);
77                 }
78
79                 internal void Emit ()
80                 {
81                         Emit (base_emit_context);
82                         EmitEndGlobalCode ();
83                 }
84
85                 internal override void Emit (EmitContext ec)
86                 {
87                         EmitTypeCtr ();
88                         src_elems.Emit (ec);
89                 }
90
91                 void ICanModifyContext.PopulateContext (Environment env, string ns)
92                 {
93                         ((ICanModifyContext) src_elems).PopulateContext (env, ns);
94                 }
95
96                 void ICanModifyContext.EmitDecls (EmitContext ec)
97                 {
98                 }
99
100                 internal override bool Resolve (Environment env)
101                 {
102                         return src_elems.Resolve (env);
103                 }
104
105
106                 internal void InitTypeBuilder (ModuleBuilder moduleBuilder, string next_type)
107                 { 
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 [] {}));
112                 }
113
114                 internal void CreateType ()
115                 {
116                         type_builder.CreateType ();
117                 }
118
119                 internal void EmitTypeCtr ()
120                 {
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"));
131                         
132                         ig.Emit (OpCodes.Call, 
133                                  typeof (GlobalScope).GetConstructor (new Type [] {typeof (GlobalScope), 
134                                                                                    typeof (VsaEngine)}));
135                         ig.Emit (OpCodes.Ret);
136                 }
137
138                 internal void InitGlobalCode ()
139                 {
140                         global_code = type_builder.DefineMethod ("Global Code", MethodAttributes.Public,
141                                                          typeof (System.Object), new Type [] {});
142                         global_code_ig = global_code.GetILGenerator ();
143                 }
144
145                 private void EmitInitGlobalCode ()
146                 {
147                         ILGenerator ig = global_code_ig;
148
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)}));
155                 }
156
157                 private void EmitEndGlobalCode ()
158                 {
159                         ILGenerator ig = global_code_ig;
160
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);
167                 }
168         }
169 }