fixed tests
[mono.git] / mcs / class / Microsoft.JScript / Microsoft.JScript / expression.cs
1 //
2 // expression.cs: Everything related to expressions
3 //
4 // Author:
5 //      Cesar Lopez Nataren (cesar@ciencias.unam.mx)
6 //
7 // (C) 2003, 2004 Cesar Lopez Nataren
8 // (C) 2005, Novell Inc. (http://novell.com)
9 //
10
11 //
12 // Permission is hereby granted, free of charge, to any person obtaining
13 // a copy of this software and associated documentation files (the
14 // "Software"), to deal in the Software without restriction, including
15 // without limitation the rights to use, copy, modify, merge, publish,
16 // distribute, sublicense, and/or sell copies of the Software, and to
17 // permit persons to whom the Software is furnished to do so, subject to
18 // the following conditions:
19 // 
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
22 // 
23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
25 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
27 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
28 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
29 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
30 //
31
32 using System;
33 using System.Text;
34 using System.Collections;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using Microsoft.JScript.Vsa;
38
39 namespace Microsoft.JScript {
40         
41         public abstract class Exp : AST {
42                 internal bool no_effect;
43                 internal abstract bool Resolve (Environment env, bool no_effect);
44
45                 internal Exp (AST parent, Location location)
46                         : base (parent, location)
47                 {
48                 }
49         }
50         
51         internal class Unary : UnaryOp {
52
53                 private bool deletable = false;
54                 private bool isCtr = false;
55
56                 internal Unary (AST parent, JSToken oper, Location location)
57                         : base (parent, location)
58                 {               
59                         this.oper = oper;
60                 }
61
62                 public override string ToString ()
63                 {
64                         StringBuilder sb = new StringBuilder ();
65                         
66                         if (oper != JSToken.None)
67                                 sb.Append (oper + " ");
68                         
69                         if (operand != null)
70                                 sb.Append (operand.ToString ());
71                         
72                         return sb.ToString ();
73                 }
74
75                 internal override bool Resolve (Environment env)
76                 {
77                         bool r = false;                
78
79                         if (operand is Binary) {
80                                 Binary bin = (Binary) operand;
81                                 if (oper == JSToken.Delete && bin.AccessField)
82                                         this.deletable = bin.IsDeletable (out isCtr);
83                                 bin.Resolve (env);
84                         } else if (operand is Exp) {
85                                 if (oper != JSToken.Increment && oper != JSToken.Decrement)
86                                         r = ((Exp) operand).Resolve (env, no_effect);
87                         } else 
88                                 r = operand.Resolve (env);
89                         return r;
90                 }
91
92                 internal override bool Resolve (Environment env, bool no_effect)
93                 {
94                         this.no_effect = no_effect;
95                         return Resolve (env);
96                 }
97
98                 internal override void Emit (EmitContext ec)
99                 {
100                         ILGenerator ig = ec.ig;
101
102                         switch (oper) {
103                         case JSToken.Void:
104                                 operand.Emit (ec);
105                                 ig.Emit (OpCodes.Pop);
106                                 ig.Emit (OpCodes.Ldnull);
107                                 break;
108
109                         case JSToken.Typeof:
110                                 operand.Emit (ec);
111                                 CodeGenerator.EmitBox (ig, operand);
112                                 ig.Emit (OpCodes.Call, typeof (Typeof).GetMethod ("JScriptTypeof"));
113                                 break;
114
115                         case JSToken.Delete:
116                                 Expression exp = operand as Expression;
117                                 if (exp != null)
118                                         operand = exp.exprs [exp.exprs.Count - 1] as AST;
119
120                                 Binary arg = operand as Binary;
121                                 if (arg != null) {
122                                         if (arg.op == JSToken.LeftBracket || arg.op == JSToken.AccessField ) {
123                                                 if (deletable) {
124                                                         arg.left.Emit (ec);
125                                                         arg.right.Emit (ec);
126                                                         ig.Emit (OpCodes.Ldc_I4_1);
127                                                         ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToString",
128                                                                                                            new Type [] { typeof (object), typeof (bool) }));
129                                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("DeleteMember",
130                                                                                                                new Type [] { typeof (object), typeof (string) }));
131                                                 } else {
132                                                         if (isCtr)
133                                                                 Console.WriteLine ("{0}({1},0) : warning: " +
134                                                                            "JS1164: '{2}' is not deletable", 
135                                                                            location.SourceName, location.LineNumber, arg.ToString ());
136
137                                                         if (arg.left is Identifier && arg.right is Identifier) {
138                                                                 //string _base = ((Identifier) arg.left).name.Value;
139                                                                 string property = ((Identifier) arg.right).name.Value;
140
141                                                                 Type lb_type = typeof (LateBinding);
142                                                                 LocalBuilder lb = ig.DeclareLocal (lb_type);
143                                                                 
144                                                                 ig.Emit (OpCodes.Ldstr, property);
145                                                                 ig.Emit (OpCodes.Newobj, lb_type.GetConstructor (new Type [] { typeof (string) }));
146                                                                 ig.Emit (OpCodes.Stloc, lb);
147                                                                 ig.Emit (OpCodes.Ldloc, lb);
148                                                                 ig.Emit (OpCodes.Dup);
149                                                                 arg.left.Emit (ec);
150                                                                 ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
151                                                                 ig.Emit (OpCodes.Call, lb_type.GetMethod ("Delete"));
152                                                         }
153                                                 }
154                                         } else {
155                                                 Console.WriteLine ("emit_unary_op: Delete: unknown operand type {0}", arg.op);
156                                                 throw new NotImplementedException ();
157                                         }
158                                 } else {
159                                         Console.WriteLine ("emit_unary_op: Delete: unknown operand {0} ({1})", operand, operand.GetType ());
160                                         throw new NotImplementedException ();
161                                 }
162
163
164                                 if (no_effect)
165                                         ig.Emit (OpCodes.Pop);
166                                 break;
167
168                         case JSToken.Plus:
169                                 operand.Emit (ec);
170                                 ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToNumber", new Type [] { typeof (object) }));
171                                 //
172                                 // FIXME: investigate the real
173                                 // discriminate for generating this
174                                 // box.
175                                 if (!no_effect)
176                                         ig.Emit (OpCodes.Box, typeof (double));
177                                 break;
178
179                         case JSToken.Minus:
180                                 if (SemanticAnalyser.IsNumericConstant (operand)) {
181                                         operand.Emit (ec);
182                                         ig.Emit (OpCodes.Neg);
183                                 } else if (operand is Identifier && 
184                                            ((Identifier) operand).name.Value == "Infinity")
185                                         ig.Emit (OpCodes.Ldc_R8, Double.NegativeInfinity);
186                                 else
187                                         emit_non_numeric_unary (ec, operand, (byte) 47);
188                                 break;
189
190                         case JSToken.BitwiseNot:
191                                 if (SemanticAnalyser.IsNumericConstant (operand)) {
192                                         operand.Emit (ec);
193                                         ig.Emit (OpCodes.Not);
194                                 } else
195                                         emit_non_numeric_unary (ec, operand, (byte) 40);
196                                 break;
197
198                         case JSToken.LogicalNot:
199                                 operand.Emit (ec);
200                                 if (SemanticAnalyser.NeedsToBoolean (operand)) {
201                                         CodeGenerator.EmitBox (ec.ig, operand);
202                                         ig.Emit (OpCodes.Ldc_I4_1);
203                                         ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToBoolean",
204                                                                                    new Type [] { typeof (object), typeof (bool) }));
205                                 }
206                                 ig.Emit (OpCodes.Ldc_I4_0);
207                                 ig.Emit (OpCodes.Ceq);
208                                 break;
209
210                         default:
211                                 Console.WriteLine ("Unimplemented Unary Op: {0}", oper);
212                                 throw new NotImplementedException ();
213                         }
214                 }
215
216                 private void emit_non_numeric_unary (EmitContext ec, AST operand, byte oper)
217                 {
218                         ILGenerator ig = ec.ig;
219
220                         Type unary_type = typeof (NumericUnary);
221                         LocalBuilder unary_builder = ig.DeclareLocal (unary_type);
222
223                         ig.Emit (OpCodes.Ldc_I4_S, oper);
224                         ig.Emit (OpCodes.Newobj, unary_type.GetConstructor (new Type [] { typeof (int) }));
225                         ig.Emit (OpCodes.Stloc, unary_builder);
226                         ig.Emit (OpCodes.Ldloc, unary_builder);
227
228                         operand.Emit (ec);
229
230                         ig.Emit (OpCodes.Call, unary_type.GetMethod ("EvaluateUnary"));
231                 }
232         }
233
234         internal class Binary : BinaryOp, IAssignable {
235
236                 internal bool assign, late_bind = false;
237                 internal AST right_side;
238
239                 internal Binary (AST parent, AST left, JSToken op, Location location)
240                         : this (parent, left, null, op, location)
241                 {
242                 }
243                 
244                 internal Binary (AST parent, AST left, AST right, JSToken op, Location location)
245                         : base (parent, left, right, op, location)
246                 {
247                 }
248                 
249                 public override string ToString ()
250                 {
251                         StringBuilder sb = new StringBuilder ();
252                         sb.Append (left.ToString ());
253                         
254                         if (op == JSToken.AccessField)
255                                 sb.Append (".");
256                         else sb.Append (op);
257                         
258                         if (right != null)
259                                 sb.Append (right.ToString ());
260
261                         return sb.ToString ();
262                 }
263
264                 internal bool AccessField {
265                         get { return op == JSToken.AccessField; }
266                 }
267
268                 internal bool LateBinding {
269                         get { return late_bind; }
270                 }
271
272                 internal override bool Resolve (Environment env)
273                 {
274                         bool found = true;
275
276                         if (left != null)
277                                 if (op == JSToken.AccessField && left is ICanLookupPrototype) {
278                                         found &= ((ICanLookupPrototype) left).ResolveFieldAccess (right);
279                                         if (!found)
280                                                 late_bind = true;
281                                 } else
282                                         found &= left.Resolve (env);
283                         if (right != null)
284                                 if (op == JSToken.AccessField && right is IAccessible) {
285                                         found &= ((IAccessible) right).ResolveFieldAccess (left);
286                                         if (!found)
287                                                 late_bind = true;
288                                 } else
289                                         found &= right.Resolve (env);
290                         return found;
291                 }
292
293                 internal override bool Resolve (Environment env, bool no_effect)
294                 {
295                         this.no_effect = no_effect;
296                         return Resolve (env);
297                 }
298                 
299                 public bool ResolveAssign (Environment env, AST right_side)
300                 {
301                         if (op == JSToken.LeftBracket || op == JSToken.AccessField) {
302                                 this.no_effect = false;
303                                 this.assign = true;
304                                 this.right_side = right_side;
305                                 return Resolve (env);
306                         } else 
307                                 throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
308                 }
309
310                 internal MemberInfo Binding {
311                         get { 
312                                 return SemanticAnalyser.get_member (left, right);
313                         }
314                 }
315
316                 internal override void Emit (EmitContext ec)
317                 {
318                         ILGenerator ig = ec.ig;                 
319                         if (op == JSToken.None) {
320                                 if (left != null)
321                                         left.Emit (ec);
322                         } else if (op == JSToken.LogicalAnd || op == JSToken.LogicalOr)
323                                 emit_jumping_code (ec);
324                         else if (op == JSToken.LeftBracket) {
325                                 if (!assign)
326                                         get_default_this (ig);
327                                 if (left != null)
328                                         left.Emit (ec);
329                                 emit_array_access (ec);                         
330                         } else if (op == JSToken.AccessField) {
331                                 if (late_bind)
332                                         emit_late_binding (ec);
333                                 else
334                                         emit_access (left, right, ec);
335                         } else {
336                                 emit_operator (ig);
337                                 if (left != null) {
338                                         left.Emit (ec);
339                                         CodeGenerator.EmitBox (ig, left);
340                                 }
341                                 if (right != null) {
342                                         right.Emit (ec);
343                                         CodeGenerator.EmitBox (ig, right);
344                                 }
345                                 emit_op_eval (ig);
346                         }
347                         if (no_effect)
348                                 ig.Emit (OpCodes.Pop);
349                 }
350
351                 void emit_access (AST obj, AST prop_name, EmitContext ec)
352                 {
353                         MemberInfo minfo = SemanticAnalyser.get_member (obj, prop_name);        
354                         ILGenerator ig = ec.ig;
355                         MemberTypes minfo_type = minfo.MemberType;
356
357                         switch (minfo_type) {
358                         case MemberTypes.Field:
359                                 FieldInfo finfo = (FieldInfo) minfo;
360                                 object value = finfo.GetValue (finfo);
361                                 Type type = value.GetType ();
362                                 if (type == typeof (double))
363                                         ig.Emit (OpCodes.Ldc_R8, (double) value);
364                                 break;
365                         case MemberTypes.Property:
366                                 PropertyInfo property = (PropertyInfo) minfo;
367                                 Type decl_type = property.DeclaringType;
368                                 Type t = null;
369
370                                 if (decl_type == typeof (RegExpConstructor)) {
371                                         t = typeof (GlobalObject);
372                                         ig.Emit (OpCodes.Call, t.GetProperty (FieldName (decl_type)).GetGetMethod ());
373                                         CodeGenerator.load_engine (InFunction, ig);
374                                         ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToObject2"));
375                                         ig.Emit (OpCodes.Castclass, decl_type);
376                                 } else if (decl_type == typeof (ScriptFunction) ||
377                                            decl_type == typeof (ScriptObject)) {
378                                         t = typeof (GlobalObject);
379                                         ig.Emit (OpCodes.Call, t.GetProperty (((Identifier) obj).name.Value).GetGetMethod ());
380                                 }
381                                 ig.Emit (OpCodes.Call, decl_type.GetProperty (property.Name).GetGetMethod ());
382                                 break;
383                         default:
384                                 Type lb_type = typeof (LateBinding);
385                                 LocalBuilder lateBinder = ig.DeclareLocal (lb_type);
386                                 Identifier prop = (Identifier) prop_name;
387
388                                 ig.Emit (OpCodes.Ldstr, prop.name.Value);
389                                 ig.Emit (OpCodes.Newobj, lb_type.GetConstructor (new Type [] { typeof (string)} ));
390                                 ig.Emit (OpCodes.Stloc, lateBinder);
391                                 ig.Emit (OpCodes.Ldloc, lateBinder);
392                                 ig.Emit (OpCodes.Dup);
393
394                                 Identifier obj_name = (Identifier) obj;
395
396                                 ig.Emit (OpCodes.Call, typeof (GlobalObject).GetProperty (obj_name.name.Value).GetGetMethod ());
397                                 ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
398                                 ig.Emit (OpCodes.Call, lb_type.GetMethod ("GetNonMissingValue"));
399
400                                 break;
401
402                         }
403                         emit_box (ig, minfo);
404                 }                       
405
406                 void emit_box (ILGenerator ig, MemberInfo info)
407                 {
408                         MemberTypes member_type = info.MemberType;
409                         Type type = null;
410
411                         switch (member_type) {
412                         case MemberTypes.Field:
413                                 type = ((FieldInfo) info).FieldType;
414                                 break;
415                         }
416                         if (type != null)
417                                 ig.Emit (OpCodes.Box, type);
418                 }
419
420                 private string FieldName (Type type)
421                 {
422                         if (type == typeof (RegExpConstructor))
423                                 return "RegExp";
424                         throw new NotImplementedException ();
425                 }
426
427                 void emit_late_binding (EmitContext ec)                 
428                 {
429                         LocalBuilder local_lb = init_late_binding (ec);
430                         emit_late_get_or_set (ec, local_lb);
431                 }
432
433                 LocalBuilder init_late_binding (EmitContext ec)
434                 {
435                         ILGenerator ig = ec.ig;
436                         Type lb_type = typeof (LateBinding);
437
438                         LocalBuilder local = ig.DeclareLocal (lb_type);
439                         
440                         string prop_name = (right as Identifier).name.Value;
441                         ig.Emit (OpCodes.Ldstr, prop_name);
442                         ig.Emit (OpCodes.Newobj, lb_type.GetConstructor (new Type [] {typeof (string)}));
443                         ig.Emit (OpCodes.Stloc, local);                 
444
445                         return local;
446                 }
447                 
448                 void emit_late_get_or_set (EmitContext ec, LocalBuilder lb_builder)
449                 {
450                         ILGenerator ig = ec.ig;
451                         LocalBuilder right_obj = ig.DeclareLocal (typeof (object));
452                         //
453                         // If right_side isn't supplied we take the new value from the stack.
454                         // This case is used by PostOrPrefixOperator.Emit when it encounters a
455                         // Binary node as its operand.
456                         //
457                         if (right_side == null && assign) {
458                                 ig.Emit (OpCodes.Box, typeof (object));
459                                 ig.Emit (OpCodes.Stloc, right_obj);
460                         }
461                         Type type = SemanticAnalyser.IsLiteral (left);
462
463                         if (type == null) {
464                                 ig.Emit (OpCodes.Ldloc, lb_builder);
465                                 ig.Emit (OpCodes.Dup);
466                         }                               
467                         left.Emit (ec);
468
469                         LocalBuilder local_literal = null;
470
471                         //
472                         // If the left hand side is as literal we must create a local
473                         // var where is kept for future use
474                         //
475                         if (type != null) {
476                                 local_literal = ig.DeclareLocal (type);
477                                 ig.Emit (OpCodes.Dup);
478                                 ig.Emit (OpCodes.Stloc, local_literal);
479                                 
480                                 ig.Emit (OpCodes.Ldloc, lb_builder);
481                                 ig.Emit (OpCodes.Dup);
482                                 ig.Emit (OpCodes.Ldloc, local_literal);
483                         } else {
484                                 CodeGenerator.load_engine (InFunction, ec.ig);
485                                 ig.Emit (OpCodes.Call , typeof (Convert).GetMethod ("ToObject"));
486                         }
487                         Type lb_type = typeof (LateBinding);
488                         ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
489                         
490                         if (assign) {
491                                 if (right_side != null)
492                                         right_side.Emit (ec);
493                                 else
494                                         ig.Emit (OpCodes.Ldloc, right_obj);
495                                 CodeGenerator.EmitBox (ig, right_side);
496                                 ig.Emit (OpCodes.Call, lb_type.GetMethod ("SetValue"));
497                         } else
498                                 ig.Emit (OpCodes.Call, lb_type.GetMethod ("GetNonMissingValue"));
499                 }
500                 
501                 internal void get_default_this (ILGenerator ig)
502                 {
503                         CodeGenerator.load_engine (InFunction, ig);
504                         ig.Emit (OpCodes.Call, typeof (Microsoft.JScript.Vsa.VsaEngine).GetMethod ("ScriptObjectStackTop"));
505                         Type iact_obj = typeof (IActivationObject);
506                         ig.Emit (OpCodes.Castclass, iact_obj);
507                         ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetDefaultThisObject"));
508                 }
509
510                 internal void emit_array_access (EmitContext ec)
511                 {
512                         ILGenerator ig = ec.ig;
513                         LocalBuilder right_obj = ig.DeclareLocal (typeof (object));
514                         if (right_side == null && assign) {
515                                 LocalBuilder val_obj = ig.DeclareLocal (typeof (object));
516                                 ig.Emit (OpCodes.Stloc, val_obj);
517                                 ig.Emit (OpCodes.Box, typeof (object));
518                                 ig.Emit (OpCodes.Stloc, right_obj);
519                                 ig.Emit (OpCodes.Ldloc, val_obj);
520                         }
521                         ig.Emit (OpCodes.Ldc_I4_1);
522                         ig.Emit (OpCodes.Newarr, typeof (object));
523                         ig.Emit (OpCodes.Dup);
524                         ig.Emit (OpCodes.Ldc_I4_0);
525                         if (right != null) {
526                                 right.Emit (ec);
527                                 CodeGenerator.EmitBox (ig, right);
528                         }
529                         ig.Emit (OpCodes.Stelem_Ref);                   
530
531                         if (assign) {
532                                 if (right_side != null) {
533                                         right_side.Emit (ec);
534                                         CodeGenerator.EmitBox (ig, right_side);
535                                 }
536                                 else
537                                         ig.Emit (OpCodes.Ldloc, right_obj);
538                                 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("SetIndexedPropertyValueStatic"));
539                         } else {
540                                 ig.Emit (OpCodes.Ldc_I4_0);
541                                 ig.Emit (OpCodes.Ldc_I4_1);
542                                 CodeGenerator.load_engine (InFunction, ig);
543                                 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
544                         }
545                 }
546
547                 internal void emit_op_eval (ILGenerator ig)
548                 {
549                         switch (op) {
550                         case JSToken.Plus:
551                                 ig.Emit (OpCodes.Callvirt, typeof (Plus).GetMethod ("EvaluatePlus"));
552                                 break;
553                         case JSToken.Minus:
554                         case JSToken.Divide:
555                         case JSToken.Modulo:
556                         case JSToken.Multiply:
557                                 ig.Emit (OpCodes.Call, typeof (NumericBinary).GetMethod ("EvaluateNumericBinary"));
558                                 break;
559                         case JSToken.BitwiseAnd:
560                         case JSToken.BitwiseXor:
561                         case JSToken.BitwiseOr:
562                         case JSToken.LeftShift:
563                         case JSToken.RightShift:
564                         case JSToken.UnsignedRightShift:
565                                 ig.Emit (OpCodes.Call, typeof (BitwiseBinary).GetMethod ("EvaluateBitwiseBinary"));
566                                 break;
567                         }
568                 }
569
570                 internal void emit_jumping_code (EmitContext ec)
571                 {
572                         ILGenerator ig = ec.ig;
573                         Type t = typeof (bool);
574                         Label false_label = ig.DefineLabel ();
575                         Label exit_label = ig.DefineLabel ();
576                         CodeGenerator.fall_true (ec, this, false_label);
577                         ig.Emit (OpCodes.Ldc_I4_1);     
578                         ig.Emit (OpCodes.Box, t);                       
579                         ig.Emit (OpCodes.Br, exit_label);
580                         ig.MarkLabel (false_label);
581                         ig.Emit (OpCodes.Ldc_I4_0);                     
582                         ig.Emit (OpCodes.Box, t);
583                         ig.MarkLabel (exit_label);
584                 }
585
586                 internal void emit_operator (ILGenerator ig)
587                 {
588                         LocalBuilder local_builder = null;
589                         Type t = null;
590                         
591                         if (op == JSToken.Plus) {
592                                 t = typeof (Plus);
593                                 local_builder = ig.DeclareLocal (t);                            
594                                 ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] {}));
595                                 ig.Emit (OpCodes.Stloc, local_builder);
596                                 ig.Emit (OpCodes.Ldloc, local_builder);
597                                 return;
598                         } else if (op == JSToken.Minus) {
599                                 t = typeof (NumericBinary);
600                                 local_builder = ig.DeclareLocal (t);
601                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 47);
602                         } else if (op == JSToken.LeftShift) {
603                                 t = typeof (BitwiseBinary);
604                                 local_builder = ig.DeclareLocal (t);
605                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 61);
606                         } else if (op == JSToken.RightShift) {
607                                 t = typeof (BitwiseBinary);
608                                 local_builder = ig.DeclareLocal (t);
609                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 62);
610                         } else if (op == JSToken.UnsignedRightShift) {
611                                 t = typeof (BitwiseBinary);
612                                 local_builder = ig.DeclareLocal (t);
613                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 63);
614                         } else if (op == JSToken.Multiply) {
615                                 t = typeof (NumericBinary);
616                                 local_builder = ig.DeclareLocal (t);
617                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 64);
618                         } else if (op == JSToken.Divide) {
619                                 t = typeof (NumericBinary);
620                                 local_builder = ig.DeclareLocal (t);
621                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 65);
622                         } else if (op == JSToken.Modulo) {
623                                 t = typeof (NumericBinary);
624                                 local_builder = ig.DeclareLocal (t);
625                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 66);
626                         } else if (op == JSToken.BitwiseOr) {
627                                 t = typeof (BitwiseBinary);
628                                 local_builder = ig.DeclareLocal (t);
629                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 50);
630                         } else if (op == JSToken.BitwiseXor) {
631                                 t = typeof (BitwiseBinary);
632                                 local_builder = ig.DeclareLocal (t);
633                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 51);                          
634                         } else if (op == JSToken.BitwiseAnd) {
635                                 t = typeof (BitwiseBinary);
636                                 local_builder = ig.DeclareLocal (t);
637                                 ig.Emit (OpCodes.Ldc_I4_S, (byte) 52);
638                         }
639                         ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] {typeof (int)}));
640                         ig.Emit (OpCodes.Stloc, local_builder);
641                         ig.Emit (OpCodes.Ldloc, local_builder);
642                 }
643
644                 internal bool IsDeletable (out bool isCtr)
645                 {
646                         if (left is Identifier && right is Identifier)
647                                 return SemanticAnalyser.IsDeletable ((Identifier) left, (Identifier) right, out isCtr);
648                         isCtr = false;
649                         return false;
650                 }
651         }
652
653         internal class Conditional : Exp {
654
655                 AST cond_exp, true_exp, false_exp;
656
657                 internal Conditional (AST parent, AST expr, AST  trueExpr, AST falseExpr, Location location)
658                         : base (parent, location)
659                 {
660                         this.cond_exp = expr;
661                         this.true_exp = trueExpr;
662                         this.false_exp = falseExpr;
663                 }
664                 
665                 public override string ToString ()
666                 {
667                         StringBuilder sb = new StringBuilder ();
668
669                         if (cond_exp != null)
670                                 sb.Append (cond_exp.ToString () + " ");
671                         if (true_exp != null)
672                                 sb.Append (true_exp.ToString () + " ");
673                         if (false_exp != null)
674                                 sb.Append (false_exp.ToString ());
675
676                         return sb.ToString ();
677                 }
678
679                 internal override bool Resolve (Environment env)
680                 {
681                         bool r = true;
682                         if (cond_exp != null)
683                                 r &= cond_exp.Resolve (env);
684                         if (true_exp != null)
685                                 r &= true_exp.Resolve (env);
686                         if (false_exp != null)
687                                 r &= false_exp.Resolve (env);
688                         return r;
689                 }
690
691                 internal override bool Resolve (Environment env, bool no_effect)
692                 {
693                         this.no_effect = no_effect;
694                         return Resolve (env);
695                 }
696
697                 internal override void Emit (EmitContext ec)
698                 {
699                         ILGenerator ig = ec.ig;
700                         Label false_label = ig.DefineLabel ();
701                         Label merge_label = ig.DefineLabel ();
702                         CodeGenerator.fall_true (ec, cond_exp, false_label);
703                         if (true_exp != null) {
704                                 true_exp.Emit (ec);
705                                 CodeGenerator.EmitBox (ig, true_exp);
706                         }
707                         ig.Emit (OpCodes.Br, merge_label);
708                         ig.MarkLabel (false_label);
709                         if (false_exp != null) {
710                                 false_exp.Emit (ec);
711                                 CodeGenerator.EmitBox (ig, false_exp);
712                         }
713                         ig.MarkLabel (merge_label);
714                         if (no_effect)
715                                 ig.Emit (OpCodes.Pop);
716                 }
717         }
718
719         internal interface ICallable {
720                 void AddArg (AST arg);
721         }
722         
723         internal class Call : Exp, ICallable {
724                 
725                 internal AST member_exp;                
726                 internal Args args;
727                 internal object binding;
728                 internal Type bind_type;
729                 private bool is_dynamic_function = false;
730                 private bool need_this = false;
731
732                 internal Call (AST parent, AST exp, Location location)
733                         : base (parent, location)
734                 {
735                         this.member_exp = exp;
736                         this.args = new Args (location);
737                 }
738                 
739                 public override string ToString ()
740                 {
741                         StringBuilder sb = new StringBuilder ();
742                         if (member_exp != null)
743                                 sb.Append (member_exp.ToString () + " ");
744                         if (args != null)
745                                 sb.Append (args.ToString ());
746                         return sb.ToString ();
747                 }
748
749                 public void AddArg (AST arg)
750                 {
751                         args.Add (arg);
752                 }
753
754                 internal override bool Resolve (Environment env)
755                 {
756                         bool r = true;
757
758                         if (member_exp != null) {
759                                 if (member_exp is Identifier) {
760                                         member_exp.Resolve (env);
761                                         binding = env.Get (String.Empty, (member_exp as Identifier).name);
762                                         bind_type = binding.GetType ();
763
764                                         if (bind_type == typeof (BuiltIn)) {
765                                                 BuiltIn built_in = binding as BuiltIn;
766                                                 if (!built_in.IsFunction)
767                                                         throw new Exception ("error JS5002 A: function expected.");
768                                                 if (IsGlobalObjectMethod (built_in)) {
769                                                         //
770                                                         // If a method contains an eval invocation
771                                                         // we must generate proper code for accessing 
772                                                         // the local vars in the StackFrame.
773                                                         //
774                                                         if (((Identifier) member_exp).name.Value == "eval") {
775                                                                 Function cont_func = GetContainerFunction;
776                                                                 if (cont_func != null)
777                                                                         SemanticAnalyser.AddMethodWithEval (cont_func.func_obj.name);
778                                                         }
779                                                 }
780                                         }
781                                 } else if (member_exp is Binary) {
782                                         member_exp.Resolve (env);
783                                         Binary bin = (Binary) member_exp;
784                                         if (bin.AccessField)
785                                                 binding = bin.Binding;
786                                         if (binding is MethodInfo)
787                                                 NeedThis ((MethodInfo) binding);
788                                 } else
789                                         r &= member_exp.Resolve (env);
790
791                                 args.BoundToMethod = binding;
792
793                                 if (args != null)
794                                         r &= args.Resolve (env);
795                         } else
796                                 throw new Exception ("Call.Resolve, member_exp can't be null");
797                         return r;
798                 }
799
800                 private void NeedThis (MethodInfo method)
801                 {
802                         need_this = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasThisObject, method);
803                 }
804
805                 internal override bool Resolve (Environment env, bool no_effect)
806                 {
807                         this.no_effect = no_effect;
808                         return Resolve (env);
809                 }
810
811                 internal override void Emit (EmitContext ec)
812                 {
813                         if (bind_type == typeof (BuiltIn)) {
814                                 BuiltIn b = binding as BuiltIn;
815                                 if (b.IsPrint) {
816                                         emit_print_stm (ec);
817                                         return;
818                                 } else if (IsGlobalObjectMethod (binding)) {
819                                         bool eval = IsEval (binding);
820                                         bool in_func = InFunction;
821                                         
822                                         if (eval && in_func)
823                                                 CodeGenerator.load_local_vars (ec.ig, in_func);
824                                         
825                                         args.Emit (ec);
826
827                                         if (eval) {
828 #if (!NET_1_0)
829                                                 ec.ig.Emit (OpCodes.Ldnull);
830 #endif
831                                                 CodeGenerator.load_engine (in_func, ec.ig);
832                                         }
833                                         member_exp.Emit (ec);
834                                         
835                                         if (eval && no_effect && in_func)
836                                                 ec.ig.Emit (OpCodes.Pop);
837
838                                         if (eval && in_func) {
839                                                 set_local_vars (ec.ig);
840                                                 return;
841                                         }
842                                 } else if (IsConstructorProperty (binding)) {
843                                         member_exp.Emit (ec);
844                                         EmitBuiltInArgs (ec);
845                                         EmitInvoke (ec);                                        
846                                 }
847                         } else if (bind_type == typeof (FunctionDeclaration) || bind_type == typeof (FunctionExpression)) {
848                                 Function function = binding as Function;
849                                 MethodBuilder method = (MethodBuilder) TypeManager.Get (function.func_obj.name);
850
851                                 if (SemanticAnalyser.MethodContainsEval (function.func_obj.name) ||
852                                     SemanticAnalyser.MethodReferenceOutterScopeVar (function.func_obj.name) ||
853                                     SemanticAnalyser.MethodVarsUsedNested (function.func_obj.name)) {
854                                         if (InFunction)
855                                                 CodeGenerator.load_local_vars (ec.ig, true);
856                                         emit_late_call (ec);
857                                         if (no_effect)
858                                                 ec.ig.Emit (OpCodes.Pop);
859                                         if (InFunction)
860                                                 set_local_vars (ec.ig);
861                                         return;
862                                 } else {
863                                         emit_func_call (method, ec);
864                                         return;
865                                 }
866                         } else if (binding is MemberInfo) {
867                                 MemberInfo minfo = (MemberInfo) binding;
868                                 MemberTypes member_type = minfo.MemberType;
869                                 ILGenerator ig = ec.ig;                         
870                                 
871                                 if (member_type == MemberTypes.Method) {
872                                         if (member_exp is Binary) {
873                                                 Binary bin = (Binary) member_exp;
874                                                 if (bin.left is ICanLookupPrototype && need_this ) {
875                                                         bin.left.Emit (ec);
876                                                         CodeGenerator.EmitBox (ig, bin.left);
877                                                 }
878                                         }                                               
879                                         args.Emit (ec);
880                                         MethodInfo method = (MethodInfo) minfo;
881                                         ig.Emit (OpCodes.Call, method);
882                                         Type return_type = method.ReturnType;
883                                         if (return_type != typeof (void) && return_type != typeof (string))
884                                                 ig.Emit (OpCodes.Box, return_type);
885                                 } else if (member_type == MemberTypes.Property) {
886                                         if (member_exp is Binary) {
887                                                 Binary bin = (Binary) member_exp;
888
889                                                 bin.left.Emit (ec);
890
891                                                 bool in_func = InFunction;
892                                                 CodeGenerator.load_engine (in_func, ig);
893                                                 ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToObject2"));
894
895                                                 if (bin.left is Identifier) {
896                                                         Type coerce_to = null;
897                                                         if (((Identifier) bin.left).name.Value == "Function")
898                                                                 coerce_to = typeof (FunctionConstructor);
899
900                                                         LocalBuilder ctr = null;
901
902                                                         if (coerce_to != null) {
903                                                                 ig.Emit (OpCodes.Castclass, coerce_to);
904                                                                 ctr = ig.DeclareLocal (coerce_to);
905                                                         }
906
907                                                         ig.Emit (OpCodes.Dup);
908                                                         ig.Emit (OpCodes.Stloc, ctr);
909                                                         bin.Emit (ec);
910
911                                                         ig.Emit (OpCodes.Ldc_I4, args.Size);
912                                                         ig.Emit (OpCodes.Newarr, typeof (object));
913
914                                                         ig.Emit (OpCodes.Ldc_I4_0);
915                                                         ig.Emit (OpCodes.Ldc_I4_0);
916
917                                                         CodeGenerator.load_engine (in_func, ig);
918
919                                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
920                                                 }
921                                         }
922                                 } else {
923                                         Console.WriteLine ("member_type = {0}", member_type);
924                                         Console.WriteLine ("member_exp = {0}", member_exp);
925                                         Console.WriteLine ("line_number = {0}", location.LineNumber);
926                                         throw new NotImplementedException ();
927                                 }
928                         } else
929                                 emit_late_call (ec);
930                         
931                         if (no_effect)
932                                 ec.ig.Emit (OpCodes.Pop);                       
933                 }
934
935                 internal void emit_print_stm (EmitContext ec)
936                 {
937                         ILGenerator ig = ec.ig;
938                         
939                         if (args == null || args.Size == 0) {
940                                 ig.Emit (OpCodes.Ldstr, "");
941                                 ig.Emit (OpCodes.Call, typeof (ScriptStream).GetMethod ("WriteLine"));
942                                 return;
943                         }
944
945                         Type script_stream = typeof (ScriptStream);
946                         MethodInfo write = script_stream.GetMethod ("Write");
947                         MethodInfo writeline = script_stream.GetMethod ("WriteLine");
948                         MethodInfo to_string = typeof (Convert).GetMethod ("ToString",
949                                                                            new Type [] { typeof (object), typeof (bool) });
950                         AST ast;
951                         int n = args.Size - 1;
952
953                         for (int i = 0; i <= n; i++) {
954                                 ast = args.get_element (i);
955
956                                 if (ast is Assign)
957                                         CodeGenerator.EmitAssignAsExp (ec, ast);
958                                 else
959                                         ast.Emit (ec);
960
961                                 if (ast is Relational) 
962                                         CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
963                                 else
964                                         CodeGenerator.EmitBox (ig, ast);
965
966                                 if (!(ast is StringLiteral)){
967                                         ig.Emit (OpCodes.Ldc_I4_1);
968                                         ig.Emit (OpCodes.Call, to_string);
969                                 }
970                                         
971                                 if (i == n)
972                                         ig.Emit (OpCodes.Call, writeline);
973                                 else
974                                         ig.Emit (OpCodes.Call, write);
975                         }
976                         
977                 }
978
979                 void emit_late_call (EmitContext ec)
980                 {
981                         ILGenerator ig = ec.ig;
982
983                         if (member_exp is Binary) {
984                                 Binary bin = member_exp as Binary;
985                                 if (SemanticAnalyser.IsLiteral (bin.left) != null) {
986                                         member_exp.Emit (ec);
987                                         CodeGenerator.EmitBox (ig, member_exp);
988                                         setup_late_call_args (ec);
989                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
990                                 } else if (bin.right is Identifier) {
991                                         Identifier rside = bin.right as Identifier;
992                                         Type lb_type = typeof (LateBinding);
993                                 
994                                         LocalBuilder lb = ig.DeclareLocal (lb_type);
995
996                                         ig.Emit (OpCodes.Ldstr, rside.name.Value);
997                                         ig.Emit (OpCodes.Newobj , lb_type.GetConstructor (new Type [] {typeof (string)}));
998                                         ig.Emit (OpCodes.Stloc, lb);
999                                         init_late_binding (ec, lb);
1000                                         setup_late_call_args (ec);
1001                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("Call"));
1002                                 } else {
1003                                         bin.left.Emit (ec);
1004                                         CodeGenerator.EmitBox (ig, bin.left);
1005
1006                                         member_exp.Emit (ec);
1007                                         CodeGenerator.EmitBox (ig, member_exp);
1008
1009                                         setup_late_call_args (ec);
1010                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
1011                                 }
1012                         } else {
1013                                 get_global_scope_or_this (ec.ig);
1014                                 member_exp.Emit (ec);
1015                                 CodeGenerator.EmitBox (ig, member_exp);
1016                                 setup_late_call_args (ec);
1017                                 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
1018                         }
1019                 }
1020
1021                 internal void get_global_scope_or_this (ILGenerator ig)
1022                 {
1023                         is_dynamic_function = parent is FunctionExpression && parent == member_exp;
1024
1025                         if (is_dynamic_function) {
1026                                 ig.Emit (OpCodes.Ldarg_0);
1027                                 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
1028                         } else
1029                                 CodeGenerator.load_engine (InFunction, ig);
1030                         ig.Emit (OpCodes.Call, typeof (Microsoft.JScript.Vsa.VsaEngine).GetMethod ("ScriptObjectStackTop"));
1031                         Type iact_obj = typeof (IActivationObject);
1032                         ig.Emit (OpCodes.Castclass, iact_obj);
1033
1034                         //
1035                         // FIXME: Find out the exact discrimination
1036                         // for: GetGlobalScope and GetDefaultThisObject.
1037                         // For example, in program: print (function () { return 1; } ());
1038                         // we invoke GetGlobalScope, in other cases GetDefaultThisObject 
1039                         //
1040                         if (member_exp is FunctionExpression)
1041                                 ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetGlobalScope"));
1042                         else
1043                                 ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetDefaultThisObject"));
1044                 }
1045
1046                 void init_late_binding (EmitContext ec, LocalBuilder local)
1047                 {
1048                         ILGenerator ig = ec.ig;
1049
1050                         ig.Emit (OpCodes.Ldloc, local);
1051                         ig.Emit (OpCodes.Dup);
1052                         
1053                         AST left = (member_exp as Binary).left;
1054                         left.Emit (ec);
1055
1056                         CodeGenerator.load_engine (InFunction, ig);
1057
1058                         ig.Emit (OpCodes.Call , typeof (Convert).GetMethod ("ToObject"));
1059
1060                         Type lb_type = typeof (LateBinding);
1061
1062                         ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
1063                 }
1064
1065                 void setup_late_call_args (EmitContext ec)
1066                 {
1067                         ILGenerator ig = ec.ig;
1068                         int n = args.Size;
1069                         AST ast = null;
1070
1071                         ig.Emit (OpCodes.Ldc_I4, n);
1072                         ig.Emit (OpCodes.Newarr, typeof (object));
1073                         
1074                         for (int i = 0; i < n; i++) {
1075                                 ig.Emit (OpCodes.Dup);
1076                                 ig.Emit (OpCodes.Ldc_I4, i);
1077                                 ast = args.get_element (i);
1078                                 ast.Emit (ec);
1079                                 CodeGenerator.EmitBox (ig, ast);
1080                                 ig.Emit (OpCodes.Stelem_Ref);
1081                         }
1082
1083                         ig.Emit (OpCodes.Ldc_I4_0);
1084                         ig.Emit (OpCodes.Ldc_I4_0);
1085
1086                         if (is_dynamic_function) {
1087                                 ig.Emit (OpCodes.Ldarg_0);
1088                                 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
1089                         } else
1090                                 CodeGenerator.load_engine (InFunction, ig);
1091                 }
1092
1093                 void emit_func_call (MethodBuilder mb, EmitContext ec)
1094                 {
1095                         ILGenerator ig = ec.ig;
1096                         CodeGenerator.load_engine (InFunction, ig);
1097                         ig.Emit (OpCodes.Call, typeof (VsaEngine).GetMethod ("ScriptObjectStackTop"));
1098                         Type iact_obj = typeof (IActivationObject);
1099                         ig.Emit (OpCodes.Castclass, iact_obj);
1100                         ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetDefaultThisObject"));
1101                         CodeGenerator.load_engine (InFunction, ig);
1102                         args.Emit (ec);
1103                         ig.Emit (OpCodes.Call, mb);
1104
1105                         if (!return_void (mb) && no_effect)
1106                                 ig.Emit (OpCodes.Pop);
1107                 }
1108
1109                 bool return_void (MethodBuilder mb)
1110                 {
1111                         return mb.ReturnType == typeof (void);
1112                 }
1113
1114                 void EmitBuiltInArgs (EmitContext ec)
1115                 {
1116                         if (member_exp.ToString () == "Date")
1117                                 return;
1118
1119                         ILGenerator ig = ec.ig;
1120                         int n = args.Size;
1121                         AST ast = null;
1122                         
1123                         if (n >= 1 && (member_exp.ToString () == "String" || member_exp.ToString () == "Boolean" || member_exp.ToString () == "Number")) {
1124                                 ast = args.get_element (0);
1125
1126                                 if (ast is Assign)
1127                                         CodeGenerator.EmitAssignAsExp (ec, ast);
1128                                 else {
1129                                         ast.Emit (ec);
1130                                         CodeGenerator.EmitBox (ig, ast);
1131                                 }
1132                                 return;
1133                         }
1134
1135                         ig.Emit (OpCodes.Ldc_I4, n);
1136                         ig.Emit (OpCodes.Newarr, typeof (object));
1137
1138                         for (int i = 0; i < n; i++) {
1139                                 ig.Emit (OpCodes.Dup);
1140                                 ig.Emit (OpCodes.Ldc_I4, i);
1141                                 ast = args.get_element (i);
1142
1143                                 if (ast is Assign)
1144                                         CodeGenerator.EmitAssignAsExp (ec, ast);
1145                                 else {
1146                                         ast.Emit (ec);
1147                                         CodeGenerator.EmitBox (ig, ast);
1148                                 }
1149
1150                                 ig.Emit (OpCodes.Stelem_Ref);
1151                         }
1152                 }
1153
1154                 void EmitInvoke (EmitContext ec)
1155                 {
1156                         ILGenerator ig = ec.ig;
1157                         string name = member_exp.ToString ();
1158                         Type type = null;
1159                         bool boolean = false;
1160                         bool number = false;
1161
1162                         switch (name) {
1163                         case "Object":
1164                                 type = typeof (ObjectConstructor);
1165                                 break;
1166                         case "Function":
1167                                 type = typeof (FunctionConstructor);
1168                                 break;
1169                         case "Array":
1170                                 type = typeof (ArrayConstructor);
1171                                 break;
1172                         case "String":
1173                                 type = typeof (StringConstructor);
1174                                 break;
1175                         case "Boolean":
1176                                 type = typeof (BooleanConstructor);
1177                                 boolean = true;
1178                                 break;
1179                         case "Number":
1180                                 type = typeof (NumberConstructor);
1181                                 number = true;
1182                                 break;
1183                         case "Date":
1184                                 type = typeof (DateConstructor);
1185                                 break;
1186                         case "RegExp":
1187                                 type = typeof (RegExpConstructor);
1188                                 break;
1189                         case "Error":
1190                         case "EvalError":
1191                         case "RangeError":
1192                         case "ReferenceError":
1193                         case "SyntaxError":
1194                         case "TypeError":
1195                         case "URIError":
1196                                 type = typeof (ErrorConstructor);
1197                                 break;
1198                         }
1199                         ig.Emit (OpCodes.Call, type.GetMethod ("Invoke"));
1200                         if (boolean)
1201                                 ig.Emit (OpCodes.Box, typeof (Boolean));
1202                         if (number)
1203                                 ig.Emit (OpCodes.Box, typeof (Double));
1204                 }
1205
1206                 bool IsConstructorProperty (object binding)
1207                 {
1208                         if (!(binding is BuiltIn))
1209                                 return false;
1210
1211                         string name = (binding as BuiltIn).Name;
1212                         
1213                         return (name == "Object" || name == "Function" || name == "Array" || name == "String" || name == "Boolean" || name == "Number" || name == "Date" || name == "RegExp" || name == "Error" || name == "EvalError" || name == "RangeError" || name == "ReferenceError" || name == "SyntaxError" || name == "TypeError" || name == "URIError");
1214                 }
1215
1216                 bool IsGlobalObjectMethod (object binding)
1217                 {
1218                         if (binding == null || binding.GetType () != typeof (BuiltIn))
1219                                 return false;
1220                         
1221                         BuiltIn bind = binding as BuiltIn;
1222                         switch (bind.Name) {
1223                         case "eval":
1224                         case "parseInt":
1225                         case "parseFloat":
1226                         case "isNaN":
1227                         case "isFinite":
1228                         case "decodeURI":
1229                         case "decodeURIComponent":
1230                         case "encodeURI":
1231                         case "encodeURIComponent":
1232                         case "escape":
1233                         case "unescape":
1234                                 return true;
1235                         default:
1236                                 return false;
1237                         }
1238                 }
1239
1240                 bool IsEval (object binding)
1241                 {
1242                         if (binding == null || binding.GetType () != typeof (BuiltIn))
1243                                 return false;
1244                         BuiltIn bind = (BuiltIn) binding;
1245                         return bind.Name == "eval";
1246                 }
1247
1248                 internal void set_local_vars (ILGenerator ig)
1249                 {
1250                         int n = 0;
1251                         Type stack_frame = typeof (StackFrame);
1252
1253                         CodeGenerator.load_engine (InFunction, ig);
1254
1255                         ig.Emit (OpCodes.Call, typeof (VsaEngine).GetMethod ("ScriptObjectStackTop"));
1256                         ig.Emit (OpCodes.Castclass, stack_frame);
1257                         ig.Emit (OpCodes.Ldfld, stack_frame.GetField ("localVars"));
1258
1259                         object [] locals = TypeManager.CurrentLocals;
1260                         n = locals != null ? locals.Length : 0;
1261                         object local = null;
1262
1263                         for (int i = 0; i < n; i++) {
1264                                 local = locals [i];
1265                                 if (local is LocalBuilder) {
1266                                         ig.Emit (OpCodes.Dup);
1267                                         ig.Emit (OpCodes.Ldc_I4, i);
1268                                         ig.Emit (OpCodes.Ldelem_Ref);
1269                                         ig.Emit (OpCodes.Stloc, (LocalBuilder) local);
1270                                 }
1271                         }
1272                         ig.Emit (OpCodes.Pop);
1273                 }
1274         }
1275
1276         interface IAccessible {
1277                 bool ResolveFieldAccess (AST parent);
1278         }
1279
1280         internal interface ICanLookupPrototype {
1281                 bool ResolveFieldAccess (AST parent);
1282         }
1283
1284         internal class Identifier : Exp, IAssignable, IAccessible {
1285                 
1286                 internal Symbol name;
1287                 internal AST binding;
1288                 internal bool assign;
1289                 AST right_side;
1290                 
1291                 int lexical_difference;
1292                 const int MINIMUM_DIFFERENCE = 1;
1293                 bool no_field;
1294                 LocalBuilder local_builder;
1295
1296                 private bool undeclared = false;
1297
1298                 internal Identifier (AST parent, string id, Location location)
1299                         : base (parent, location)
1300                 {
1301                         this.name = Symbol.CreateSymbol (id);
1302                 }
1303
1304                 bool NeedParents {
1305                         get { return lexical_difference >= MINIMUM_DIFFERENCE && no_field; }
1306                 }
1307
1308                 public override string ToString ()
1309                 {
1310                         return name.Value;
1311                 }
1312
1313                 internal override bool Resolve (Environment env)
1314                 {
1315                         bool contained = env.Contains (String.Empty, this.name);
1316                         if (contained) {
1317                                 binding = (AST) env.Get (String.Empty, this.name);
1318                                 if (binding is VariableDeclaration) {
1319                                         VariableDeclaration decl = (VariableDeclaration) binding;
1320                                         lexical_difference = env.Depth (String.Empty) - decl.lexical_depth;
1321                                         no_field = decl.lexical_depth != 0;
1322
1323                                         if (no_field && lexical_difference > 0 && !env.CatchScope (String.Empty)) {
1324                                                 Function container_func = GetContainerFunction;
1325                                                 SemanticAnalyser.AddMethodReferenceOutterScopeVar (container_func.func_obj.name, decl);
1326                                                 env.Enter (String.Empty, Symbol.CreateSymbol (decl.id), decl);
1327                                                 SemanticAnalyser.AddMethodVarsUsedNested (decl.GetContainerFunction.func_obj.name, decl);
1328                                         }
1329                                 }
1330                         } else if (SemanticAnalyser.NoFast) {
1331                                 undeclared = true;
1332                                 Console.WriteLine ("warning JS1135: Variable '" + name + "' has not been declared");
1333                         } else {
1334                                 //
1335                                 // Identifier not into stand-alone JScript, we'll search into 
1336                                 // referenced assemblies and namespaces 
1337                                 //
1338                                 throw new Exception (location.SourceName + "(" + location.LineNumber + 
1339                                              ",0) : error JS1135: Variable '" + name + "' has not been declared");
1340                         }
1341                         return true;
1342                 }
1343
1344                 internal override bool Resolve (Environment env, bool no_effect)
1345                 {
1346                         this.no_effect = no_effect;
1347                         return Resolve (env);
1348                 }
1349
1350                 public bool ResolveAssign (Environment env, AST right_side)
1351                 {
1352                         this.assign = true;
1353                         this.no_effect = false;
1354                         this.right_side = right_side;
1355                         if (name.Value != String.Empty)                 
1356                                 return Resolve (env);
1357                         return true;
1358                 }
1359
1360                 //
1361                 // Throws an exception if parent is a native object
1362                 // and does not contains name as member.
1363                 // Returns true if parent contains name as member. 
1364                 // Returns false if parent is not a native object,
1365                 // this indicate that late binding code must get generated.
1366                 //
1367                 public bool ResolveFieldAccess (AST parent)
1368                 {
1369                         if (parent is Identifier) {
1370                                 Identifier p = parent as Identifier;
1371                                 return is_static_property (p.name.Value, name.Value);
1372                         }
1373                         //
1374                         // Return false so late binding will take place
1375                         //
1376                         return false;
1377                 }
1378
1379                 //
1380                 // If obj_name is a native object, search in its
1381                 // constructor if contains a prop_name, otherwise return
1382                 // false letting late binding taking place
1383                 //
1384                 bool is_static_property (string obj_name, string prop_name)
1385                 {
1386                         bool native_obj = SemanticAnalyser.is_js_object (obj_name);
1387
1388                         if (!native_obj)
1389                                 return false;
1390
1391                         bool contains_method;
1392                         contains_method = SemanticAnalyser.object_contains (
1393                                            SemanticAnalyser.map_to_ctr (obj_name), LateBinding.MapToInternalName (prop_name));
1394                         if (!contains_method)
1395                                 throw new Exception ("error: JS0438: Object " + obj_name + " doesn't support this property or method:" + prop_name);
1396                         return true;
1397                 }
1398
1399                 internal override void Emit (EmitContext ec)
1400                 {
1401                         ILGenerator ig = ec.ig;
1402
1403                         if (assign && right_side != null && !undeclared) {
1404                                 right_side.Emit (ec);
1405                                 CodeGenerator.EmitBox (ig, right_side);
1406                         }
1407                         if (binding is FormalParam) {
1408                                 FormalParam f = binding as FormalParam;
1409                                 if (assign)
1410                                         ig.Emit (OpCodes.Starg, (short) f.pos);
1411                                 else
1412                                         ig.Emit (OpCodes.Ldarg_S, f.pos);
1413                         } else if (binding is VariableDeclaration || binding is Try || binding is Catch) {
1414                                 if (NeedParents) {
1415                                         CodeGenerator.emit_parents (InFunction, lexical_difference, ig);
1416                                         store_stack_frame_into_locals (ec.ig);
1417                                         if (this.local_builder != null)
1418                                                 if (assign)
1419                                                         ig.Emit (OpCodes.Stloc, local_builder);
1420                                                 else
1421                                                         ig.Emit (OpCodes.Ldloc, local_builder);
1422                                 } else {
1423                                         FieldInfo field_info = extract_field_info (binding);
1424                                         LocalBuilder local_builder = extract_local_builder (binding);
1425                                 
1426                                         if (field_info != null) {
1427                                                 if (assign)
1428                                                         ig.Emit (OpCodes.Stsfld, field_info);
1429                                                 else
1430                                                         ig.Emit (OpCodes.Ldsfld, field_info);
1431                                         } else if (local_builder != null) {
1432                                                 if (assign)
1433                                                         ig.Emit (OpCodes.Stloc, local_builder);
1434                                                 else
1435                                                         ig.Emit (OpCodes.Ldloc, local_builder);
1436                                         }
1437                                 }
1438                         } else if (binding is BuiltIn)
1439                                 binding.Emit (ec);
1440                         else if (binding is FunctionDeclaration)
1441                                 load_script_func (ec, (FunctionDeclaration) binding);
1442                         else if (binding == null) { // it got referenced before was declared and initialized
1443                                 if (undeclared) {
1444                                         if (assign)
1445                                                 emit_undeclared_assignment (ec);
1446                                         else
1447                                                 emit_undeclared_use (ig);
1448                                 }
1449                         } else
1450                                 Console.WriteLine ("Identifier.Emit, binding.GetType = {0}", binding.GetType ());
1451
1452                         if (!assign && no_effect && !undeclared)
1453                                 ig.Emit (OpCodes.Pop);
1454                 }
1455   
1456                 private void emit_undeclared_assignment (EmitContext ec)
1457                 {
1458                         ILGenerator ig = ec.ig;
1459                         string name = this.name.Value;
1460                         Type lb_type = typeof (LateBinding);
1461                         bool in_function = InFunction;
1462
1463                         MethodInfo script_object_stack_top = typeof (VsaEngine).GetMethod ("ScriptObjectStackTop");
1464                         Type iactivation_obj = typeof (IActivationObject);
1465
1466                         Label label_no_field = ig.DefineLabel ();
1467                         Label label_end = ig.DefineLabel ();
1468
1469                         LocalBuilder lb_local = ig.DeclareLocal (lb_type);
1470                         LocalBuilder field_builder = ig.DeclareLocal (typeof (FieldInfo));
1471                         LocalBuilder tmp_helper = ig.DeclareLocal (typeof (object));
1472
1473                         ig.Emit (OpCodes.Ldstr, name);
1474                         CodeGenerator.load_engine (in_function, ig);
1475                         ig.Emit (OpCodes.Call, script_object_stack_top);
1476                         ig.Emit (OpCodes.Newobj, lb_type.GetConstructor (new Type [] { typeof (string), typeof (object) }));
1477                         ig.Emit (OpCodes.Stloc, lb_local);
1478                         CodeGenerator.load_engine (in_function, ig);
1479                         ig.Emit (OpCodes.Call, script_object_stack_top);
1480                         ig.Emit (OpCodes.Castclass, iactivation_obj);
1481                         ig.Emit (OpCodes.Ldstr, name);
1482
1483                         // FIXME: compute the needed lexical level, for now is hardcoded
1484                         ig.Emit (OpCodes.Ldc_I4_0);
1485                         ig.Emit (OpCodes.Callvirt, iactivation_obj.GetMethod ("GetField"));
1486                         ig.Emit (OpCodes.Stloc, field_builder);
1487
1488                         ig.Emit (OpCodes.Ldloc, lb_local);
1489
1490                         right_side.Emit (ec);
1491                         CodeGenerator.EmitBox (ec.ig, right_side);
1492
1493                         ig.Emit (OpCodes.Ldloc, field_builder);         
1494                         ig.Emit (OpCodes.Ldnull);
1495                         ig.Emit (OpCodes.Beq_S, label_no_field);
1496
1497                         ig.Emit (OpCodes.Stloc, tmp_helper); // Store value
1498                         ig.Emit (OpCodes.Pop); // Pop local builder
1499                         
1500                         ig.Emit (OpCodes.Ldloc, field_builder);
1501                         ig.Emit (OpCodes.Ldstr, name);
1502                         ig.Emit (OpCodes.Ldloc, tmp_helper);
1503                         ig.Emit (OpCodes.Callvirt, typeof (FieldInfo).GetMethod ("SetValue", new Type [] { typeof (object), typeof (object) }));
1504                         
1505                         ig.Emit (OpCodes.Br_S, label_end);
1506
1507                         ig.MarkLabel (label_no_field);
1508                         ig.Emit (OpCodes.Call, lb_type.GetMethod ("SetValue"));
1509                         ig.MarkLabel (label_end);
1510                 }
1511
1512                 private void emit_undeclared_use (ILGenerator ig)
1513                 {
1514                         Label merge = ig.DefineLabel ();
1515
1516                         string name = this.name.Value;
1517                         Type lb_type = typeof (LateBinding);
1518                         LocalBuilder lb_local = ig.DeclareLocal (lb_type);
1519                         bool in_function = InFunction;
1520                         MethodInfo script_object_stack_top = typeof (VsaEngine).GetMethod ("ScriptObjectStackTop");
1521                         Type iactivation_obj = typeof (IActivationObject);
1522
1523                         ig.Emit (OpCodes.Ldstr, name);
1524                         CodeGenerator.load_engine (in_function, ig);
1525                         ig.Emit (OpCodes.Call, script_object_stack_top);
1526                         ig.Emit (OpCodes.Newobj, lb_type.GetConstructor (new Type [] { typeof (string), typeof (object) }));
1527                         ig.Emit (OpCodes.Stloc, lb_local);
1528                         CodeGenerator.load_engine (in_function, ig);
1529                         ig.Emit (OpCodes.Call, script_object_stack_top);
1530                         ig.Emit (OpCodes.Castclass, iactivation_obj);
1531                         ig.Emit (OpCodes.Ldstr, name);
1532
1533                         // FIXME: compute the needed lexical level, for now is hardcoded
1534                         ig.Emit (OpCodes.Ldc_I4_0);
1535
1536                         ig.Emit (OpCodes.Callvirt, iactivation_obj.GetMethod ("GetMemberValue"));
1537                         ig.Emit (OpCodes.Dup);
1538                         ig.Emit (OpCodes.Call, typeof (Binding).GetMethod ("IsMissing"));
1539
1540                         ig.Emit (OpCodes.Brfalse, merge);
1541
1542                         ig.Emit (OpCodes.Pop);
1543
1544                         ig.Emit (OpCodes.Ldloc, lb_local);
1545                         ig.Emit (OpCodes.Call, lb_type.GetMethod ("GetValue2"));
1546                         ig.MarkLabel (merge);
1547                 }
1548
1549                 internal void EmitStore (EmitContext ec)
1550                 {
1551                         ILGenerator ig = ec.ig;
1552
1553                         if (binding is FormalParam) {
1554                                 FormalParam f = binding as FormalParam;
1555                                 ig.Emit (OpCodes.Starg, (short) f.pos);
1556                         } else if (binding is VariableDeclaration || binding is Try) {
1557                                 FieldInfo fb = extract_field_info (binding);
1558                                 LocalBuilder local = extract_local_builder (binding);
1559                                 if (fb == null)
1560                                         ig.Emit (OpCodes.Stloc, local);
1561                                 else
1562                                         ig.Emit (OpCodes.Stsfld, fb);                                   
1563                         }
1564                 }
1565
1566                 internal void EmitLoad (EmitContext ec)
1567                 {
1568                         ILGenerator ig = ec.ig;
1569
1570                         if (binding is FormalParam) {
1571                                 FormalParam f = binding as FormalParam;
1572                                 ig.Emit (OpCodes.Ldarg_S, f.pos);
1573                         } else if (binding is VariableDeclaration || binding is Try) {
1574                                 FieldInfo fb = extract_field_info (binding);
1575                                 LocalBuilder local = extract_local_builder (binding);
1576                                 if (fb == null)
1577                                         ig.Emit (OpCodes.Ldloc, local);
1578                                 else
1579                                         ig.Emit (OpCodes.Ldsfld, fb);
1580                         }
1581                 }
1582
1583                 void load_script_func (EmitContext ec, FunctionDeclaration binding)
1584                 {
1585                         object bind = TypeManager.Get (binding.func_obj.name);
1586                                                        
1587                         if (bind != null) {
1588                                 if (bind is MethodBuilder) {
1589                                         TypeBuilder type = ec.type_builder;
1590                                         if (binding.InFunction) {
1591                                                 LocalBuilder local_meth = (LocalBuilder) TypeManager.GetLocalScriptFunction (binding.func_obj.name);
1592                                                 ec.ig.Emit (OpCodes.Ldloc, local_meth);
1593                                         } else {
1594                                                 FieldInfo method = type.GetField (binding.func_obj.name);
1595                                                 ec.ig.Emit (OpCodes.Ldsfld, method);
1596                                         }
1597                                 } else if (bind is LocalBuilder)
1598                                         ec.ig.Emit (OpCodes.Ldloc, (LocalBuilder) bind);
1599                                 else throw new Exception ("load_script_func");
1600                         }
1601                 }
1602
1603                 internal FieldInfo extract_field_info (AST a)
1604                 {
1605                         FieldInfo r = null;
1606
1607                         if (a is VariableDeclaration)
1608                                 r = ((VariableDeclaration) a).field_info;
1609                         else if (a is Try)
1610                                 r = ((Try) a).field_info;
1611                         else if (a is Catch)
1612                                 r = ((Catch) a).field_info;
1613                         return r;
1614                 }
1615                 
1616                 internal LocalBuilder extract_local_builder (AST a)
1617                 {
1618                         LocalBuilder r = null;
1619                         if (a is VariableDeclaration)
1620                                 r = ((VariableDeclaration) a).local_builder;
1621                         else if (a is Try)
1622                                 r = ((Try) a).local_builder;
1623                         else if (a is Catch)
1624                                 r = ((Catch) a).local_builder;
1625                         return r;
1626                 }
1627                 
1628                 //
1629                 // FIXME: Only must store the extern variables which are used.
1630                 //
1631                 internal void store_stack_frame_into_locals (ILGenerator ig)
1632                 {
1633                         ig.Emit (OpCodes.Dup);
1634
1635                         Type stack_frame = typeof (StackFrame);
1636                         ig.Emit (OpCodes.Castclass, stack_frame);
1637                         ig.Emit (OpCodes.Ldfld, stack_frame.GetField ("localVars"));
1638                         
1639                         DictionaryEntry [] locals = TypeManager.LocalsAtDepth (((VariableDeclaration) binding).lexical_depth);
1640
1641                         int i = 0;
1642                         LocalBuilder local = null;
1643
1644                         foreach (DictionaryEntry entry in locals) {
1645                                 if (entry.Value is LocalBuilder) {
1646                                         local = ig.DeclareLocal (typeof (object));
1647                                         if (entry.Key == name.Value)
1648                                                 this.local_builder = local;
1649                                         ig.Emit (OpCodes.Dup);
1650                                         ig.Emit (OpCodes.Ldc_I4, i++);
1651                                         ig.Emit (OpCodes.Ldelem_Ref);
1652                                         ig.Emit (OpCodes.Stloc, (LocalBuilder) local);
1653                                 }
1654                         }
1655                         ig.Emit (OpCodes.Pop);
1656
1657                         //
1658                         // FIXME: what does it determine this?
1659                         //
1660                         ig.Emit (OpCodes.Call, typeof (ScriptObject).GetMethod ("GetParent"));
1661                         ig.Emit (OpCodes.Pop);                  
1662                 }
1663         }
1664
1665         internal class Args : AST {
1666
1667                 private ArrayList elems;
1668
1669                 //
1670                 // BoundToMethod can be of type:
1671                 // - Function (when we have a function expression or declaration)
1672                 // - MethodInfo (prototype's method invoked through a
1673                 //   literal or access to a method from any built-in
1674                 // object.
1675                 // - BuiltIn for methods from the GlobalObject
1676                 //
1677                 internal object BoundToMethod;
1678
1679                 private bool BoundToDeclaredFunction {
1680                         get { return BoundToMethod is Function; }
1681                 }
1682
1683                 private bool in_new = false;
1684                 internal bool InNew {
1685                         set { in_new = value; }
1686                         get { return in_new; }
1687                 }
1688
1689                 private int expected_args = 0;
1690                 private bool has_this = false;
1691                 private bool var_args = false;
1692                 private bool has_engine = false;
1693
1694                 internal Args (Location location)
1695                         : base (null, location)
1696                 {
1697                         elems = new ArrayList ();
1698                 }
1699
1700                 internal void Add (AST e)
1701                 {
1702                         elems.Add (e);
1703                 }
1704
1705                 internal AST get_element (int i)
1706                 {
1707                         if (0 <= i && i < elems.Count)
1708                                 return (AST) elems [i];
1709                         return null;
1710                 }
1711
1712                 internal int Size {
1713                         get {
1714                                 if (elems == null)
1715                                         return 0;
1716                                 return elems.Count;
1717                         }
1718                 }
1719
1720                 internal override bool Resolve (Environment env)
1721                 {
1722                         AST tmp;
1723                         bool r = true;
1724
1725                         if (BoundToMethod is Function)
1726                                 expected_args = ((Function) BoundToMethod).NumOfArgs;
1727                         if (BoundToMethod is MethodInfo) {
1728                                 MethodInfo method = (MethodInfo) BoundToMethod;
1729                                 has_this = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasThisObject, method);
1730                                 var_args = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasVarArgs, method);
1731                                 has_engine = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasEngine, method);
1732                                 expected_args = method.GetParameters ().Length;
1733                         } else if (BoundToMethod is BuiltIn) {
1734                                 BuiltIn built_in = (BuiltIn) BoundToMethod;
1735                                 if (built_in.IsConstructor || InNew)
1736                                         expected_args = (elems == null) ? 0 : elems.Count;
1737                                 else
1738                                         expected_args = ((BuiltIn) BoundToMethod).NumOfArgs;
1739                         }
1740
1741                         if (elems == null)
1742                                 return true;
1743                         
1744                         int n = elems.Count;
1745
1746                         for (int i = 0; i < n; i++) {
1747                                 tmp = (AST) elems [i];
1748                                 if (tmp != null)
1749                                         if (tmp is Exp)
1750                                                 r &= ((Exp) tmp).Resolve (env, false);
1751                                         else
1752                                                 r &= tmp.Resolve (env);
1753                         }
1754                         return r;
1755                 }
1756
1757                 internal override void Emit (EmitContext ec)
1758                 {
1759                         bool strong_type = BoundToMethod is MethodInfo;
1760                         ParameterInfo [] parameters = null;
1761
1762                         if (!BoundToDeclaredFunction) {
1763                                 if (has_this)
1764                                         expected_args--;
1765                                 if (has_engine)
1766                                         expected_args--;
1767                                 if (var_args)
1768                                         expected_args--;
1769                         }
1770
1771                         if (expected_args < 0) {
1772                                 if (BoundToDeclaredFunction)
1773                                         expected_args = ((Function) BoundToMethod).NumOfArgs;
1774                                 else
1775                                         throw new Exception ("expected_args can't be negative");
1776                         }
1777
1778                         //
1779                         // When BoundToMethod is null and the semantic
1780                         // analysis passed means that the method is 'print'
1781                         //
1782                         // This should be on Resolve but it's here as
1783                         // a work around of the various passes that
1784                         // get performed of Resolve that affect the
1785                         // state of expected_args.
1786                         //
1787                         // When the fix for calling just one time
1788                         // Resolve is applied, this must be moved back
1789                         // to Resolve.
1790                         //
1791                         if (BoundToMethod != null && !var_args) {
1792                                 if (elems.Count > expected_args) {
1793                                         Console.WriteLine (
1794                                            location.SourceName + "(" + location.LineNumber + ",0) : " +
1795                                            "warning JS1148: There are too many arguments. The extra arguments will be ignored");
1796                                 }
1797                                 if (elems.Count < expected_args) {
1798                                         string name = String.Empty;
1799
1800                                         if (BoundToMethod is MethodInfo)
1801                                                 name = ((MethodInfo) BoundToMethod).Name;
1802                                         else if (BoundToDeclaredFunction)
1803                                                 name = ((Function) BoundToMethod).func_obj.name;
1804
1805                                         Console.WriteLine (location.SourceName + "(" + location.LineNumber + ",0) : " +
1806                                                    "warning JS1204: Not all required arguments have been supplied" + 
1807                                                    " to method " + name);
1808                                 }
1809                         }
1810
1811                         if (BoundToMethod is MethodInfo)
1812                                 parameters = ((MethodInfo) BoundToMethod).GetParameters ();
1813
1814                         if (has_engine)
1815                                 CodeGenerator.load_engine (InFunction, ec.ig);
1816
1817                         if (var_args) {
1818                                 if (expected_args > 1)
1819                                         emit_default_args_case (ec, expected_args, strong_type, parameters);
1820                                 
1821                                 ILGenerator ig = ec.ig;
1822
1823                                 int remains = elems.Count - expected_args;
1824                                 
1825                                 if (remains >= 0)
1826                                         ig.Emit (OpCodes.Ldc_I4, remains);
1827                                 else
1828                                         ig.Emit (OpCodes.Ldc_I4_0);
1829
1830                                 ig.Emit (OpCodes.Newarr, typeof (object));
1831
1832                                 int n = elems.Count;
1833                                 AST ast = null;
1834
1835                                 for (int j = expected_args, k = 0; j < n; j++, k++) {
1836                                         ast = get_element (j);
1837                                         if (ast != null) {
1838                                                 ig.Emit (OpCodes.Dup);
1839                                                 ig.Emit (OpCodes.Ldc_I4, k);
1840                                                 if (ast is Assign)
1841                                                         CodeGenerator.EmitAssignAsExp (ec, ast);
1842                                                 else
1843                                                         ast.Emit (ec);
1844
1845                                                 if (ast is Relational)
1846                                                         CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
1847                                                 else
1848                                                         CodeGenerator.EmitBox (ig, ast);
1849
1850                                                 ig.Emit (OpCodes.Stelem_Ref);
1851                                         }
1852                                 }
1853                         } else
1854                                 emit_default_args_case (ec, expected_args, strong_type, parameters);
1855                 }
1856
1857                 internal void emit_default_args_case (EmitContext ec, int n, bool strong_type,
1858                                               ParameterInfo [] parameters)
1859                 {
1860                         AST ast = null;
1861                         ILGenerator ig = ec.ig;
1862
1863                         // tracks the proper index of the formal params
1864                         // from the strong typed method
1865                         int j = 0;
1866
1867                         if (!BoundToDeclaredFunction) {
1868                                 if (has_this)
1869                                         j++;
1870                                 if (has_engine)
1871                                         j++;
1872                         }
1873
1874                         for (int i = 0; i < n; i++, j++) {
1875                                 ast = get_element (i);
1876                                 if (ast != null) {
1877                                         if (ast is Assign) {
1878                                                 CodeGenerator.EmitAssignAsExp (ec, ast);
1879                                                 continue;
1880                                         } else
1881                                                 ast.Emit (ec);
1882
1883                                         if (ast is Relational)
1884                                                 CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
1885                                         else if (strong_type)
1886                                                 force_strong_type (ig, ast, parameters [j]);
1887                                         else
1888                                                 CodeGenerator.EmitBox (ig, ast);
1889                                 } else {
1890                                         //
1891                                         // ast was null and we need
1892                                         // to provide a parameter
1893                                         //
1894                                         if (strong_type)
1895                                                 CodeGenerator.emit_default_value (ig, parameters [j]);
1896                                         else
1897                                                 ig.Emit (OpCodes.Ldsfld, typeof (Missing).GetField ("Value"));
1898                                 }
1899                         }
1900                 }
1901
1902                 internal void force_strong_type (ILGenerator ig, AST ast, object obj)
1903                 {
1904                         Type param_type = null;
1905                         if (obj is ParameterInfo)
1906                                 param_type = ((ParameterInfo) obj).ParameterType;
1907                         else
1908                                 param_type = obj.GetType ();
1909
1910                         if (SemanticAnalyser.IsNumericConstant (ast)) {
1911                                 if (param_type == typeof (double))
1912                                         CodeGenerator.EmitConv (ig, param_type);
1913                                 else if (param_type == typeof (object))
1914                                         CodeGenerator.EmitBox (ig, ast);
1915                                 else
1916                                         throw new NotImplementedException ();
1917                         } else {
1918                                 if (ast is Unary) {
1919                                         Unary unary = (Unary) ast;
1920                                         force_strong_type (ig, unary.operand, obj);
1921                                 } else if (param_type == typeof (double))
1922                                         ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToNumber",
1923                                                                                    new Type [] { typeof (object) }));
1924                         }
1925                 }
1926         }
1927
1928         internal class Expression : Exp {
1929
1930                 internal ArrayList exprs;
1931
1932                 internal int Size {
1933                         get { return exprs.Count; }
1934                 }
1935
1936                 internal Expression (AST parent, Location location)
1937                         : base (parent, location)
1938                 {
1939                         exprs = new ArrayList ();
1940                 }
1941
1942                 internal void Add (AST a)
1943                 {
1944                         exprs.Add (a);
1945                 }
1946
1947                 internal AST Last {
1948                         get { return (AST) exprs [Size - 1]; }
1949                 }
1950
1951                 public override string ToString ()
1952                 {
1953                         int size = exprs.Count;         
1954
1955                         if (size > 0) {
1956                                 int i;
1957                                 StringBuilder sb = new StringBuilder ();
1958
1959                                 for (i = 0; i < size; i++)
1960                                         sb.Append (exprs [i].ToString ());
1961                                 return sb.ToString ();
1962                         } else return String.Empty;
1963                 }
1964
1965                 internal override bool Resolve (Environment env)
1966                 {
1967                         int i, n;
1968                         object e;
1969                         bool r = true;
1970                         
1971                         n = exprs.Count - 1;
1972
1973                         for (i = 0; i < n; i++) {
1974                                 e = exprs [i];
1975                                 if (e is Exp)
1976                                         if (e is Assign)
1977                                                 r &= ((Assign) e).Resolve (env);
1978                                         else
1979                                                 r &= ((Exp) e).Resolve (env, true);
1980                         }
1981                         e = exprs [n];
1982                         if (e is Exp)
1983                                 if (e is Assign)
1984                                         r &= ((Assign) e).Resolve (env);
1985                                 else
1986                                         r &= ((Exp) e).Resolve (env, no_effect);
1987                         else 
1988                                 ((AST) e).Resolve (env);
1989
1990                         return r;
1991                 }
1992
1993                 internal override bool Resolve (Environment env, bool no_effect)
1994                 {
1995                         this.no_effect = no_effect;
1996                         return Resolve (env);
1997                 }
1998
1999                 internal override void Emit (EmitContext ec)
2000                 {
2001                         int i, n = exprs.Count;
2002                         AST exp;
2003
2004                         for (i = 0; i < n; i++) {
2005                                 exp = (AST) exprs [i];
2006                                 exp.Emit (ec);
2007                                 CodeGenerator.EmitBox (ec.ig, exp);
2008                         }
2009                 }
2010         }
2011
2012         internal class Assign : BinaryOp {
2013
2014                 internal bool is_embedded;
2015
2016                 internal Assign (AST parent, JSToken op, Location location)
2017                         : base (parent, null, null, op, location)
2018                 {
2019                 }
2020
2021                 internal void Init (AST left, AST right, bool is_embedded)
2022                 {
2023                         this.left = left;
2024                         this.right = right;
2025                         this.is_embedded = is_embedded;
2026                 }
2027
2028                 //
2029                 // after calling Resolve, left contains all the 
2030                 // information about the assignment
2031                 //
2032                 internal override bool Resolve (Environment env)
2033                 {
2034                         bool r;
2035
2036                         if (left is IAssignable)
2037                                 r = ((IAssignable) left).ResolveAssign (env, right);
2038                         else
2039                                 throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
2040                         if (right is Exp)
2041                                 r &=((Exp) right).Resolve (env, false);
2042                         else
2043                                 r &= right.Resolve (env);
2044                         return r;
2045                 }
2046
2047                 internal override bool Resolve (Environment env, bool no_effect)
2048                 {
2049                         this.no_effect = no_effect;
2050                         return Resolve (env);
2051                 }
2052
2053                 internal LocalBuilder EmitAndReturnBuilder (EmitContext ec)
2054                 {
2055                         ILGenerator ig = ec.ig;
2056                         LocalBuilder builder = ig.DeclareLocal (typeof (object));
2057                         Emit (ec);
2058                         right.Emit (ec);
2059                         CodeGenerator.EmitBox (ig, right);
2060                         ig.Emit (OpCodes.Stloc, builder);
2061                         return builder;
2062                 }
2063
2064                 internal override void Emit (EmitContext ec)
2065                 {
2066                         if (op == JSToken.Assign) {
2067                                 if (is_embedded) {
2068                                         Console.WriteLine ("embedded assignments not supported yet");
2069                                         System.Environment.Exit (-1);
2070                                 } 
2071                                 left.Emit (ec);
2072                         } else {
2073                                 ILGenerator ig = ec.ig;
2074                                 Type type = null;
2075                                 LocalBuilder local = null;
2076                                 LocalBuilder aux = ig.DeclareLocal (typeof (object));
2077                                 
2078                                 switch (op) {
2079                                 case JSToken.PlusAssign:
2080                                         type = typeof (Plus);
2081                                         local = ig.DeclareLocal (type);
2082                                         ig.Emit (OpCodes.Newobj, type.GetConstructor (new Type [] {}));
2083                                         ig.Emit (OpCodes.Stloc, local);
2084                                         if (left is Identifier)
2085                                                 ((Identifier) left).EmitLoad (ec);
2086                                         ig.Emit (OpCodes.Stloc, aux);
2087                                         ig.Emit (OpCodes.Ldloc, local);
2088                                         ig.Emit (OpCodes.Ldloc, aux);
2089                                         if (right != null) {
2090                                                 right.Emit (ec);
2091                                                 CodeGenerator.EmitBox (ig, right);
2092                                         }
2093                                         ig.Emit (OpCodes.Call, type.GetMethod ("EvaluatePlus"));
2094                                         if (left is Identifier)
2095                                                 ((Identifier) left).EmitStore (ec);
2096                                         return;
2097                                 case JSToken.MinusAssign:
2098                                 case JSToken.MultiplyAssign:
2099                                 case JSToken.DivideAssign:
2100                                 case JSToken.ModuloAssign:
2101                                         type = typeof (NumericBinary);
2102                                         break;
2103                                 case JSToken.BitwiseAndAssign:
2104                                 case JSToken.BitwiseOrAssign:
2105                                 case JSToken.BitwiseXorAssign:
2106                                 case JSToken.LeftShiftAssign:
2107                                 case JSToken.RightShiftAssign:
2108                                 case JSToken.UnsignedRightShiftAssign:
2109                                         type = typeof (BitwiseBinary);
2110                                         break;                         
2111                                 }
2112                                 local = ig.DeclareLocal (type);
2113                                 load_parameter (ig, op);
2114
2115                                 ig.Emit (OpCodes.Newobj, type.GetConstructor (new Type [] {typeof (int)}));
2116                                 ig.Emit (OpCodes.Stloc, local);
2117
2118                                 if (left is Identifier)
2119                                         ((Identifier) left).EmitLoad (ec);
2120
2121                                 ig.Emit (OpCodes.Stloc, aux);
2122                                 ig.Emit (OpCodes.Ldloc, local);
2123                                 ig.Emit (OpCodes.Ldloc, aux);
2124
2125                                 if (right != null) {
2126                                         right.Emit (ec);
2127                                         CodeGenerator.EmitBox (ig, right);
2128                                 }
2129
2130                                 emit_evaluation (op, type, ig);
2131                                 
2132                                 if (left is Identifier)
2133                                         ((Identifier) left).EmitStore (ec);
2134                         }
2135                 }
2136
2137                 void load_parameter (ILGenerator ig, JSToken op)
2138                 {
2139                         switch (op) {
2140                         case JSToken.MinusAssign: 
2141                                 ig.Emit (OpCodes.Ldc_I4_S, 47);
2142                                 break;
2143                         case JSToken.BitwiseOrAssign:
2144                                 ig.Emit (OpCodes.Ldc_I4_S, 50);
2145                                 break;
2146                         case JSToken.BitwiseXorAssign:
2147                                 ig.Emit (OpCodes.Ldc_I4_S, 51);
2148                                 break;
2149                         case JSToken.BitwiseAndAssign:
2150                                 ig.Emit (OpCodes.Ldc_I4_S, 52);
2151                                 break;
2152                         case JSToken.LeftShiftAssign:
2153                                 ig.Emit (OpCodes.Ldc_I4_S, 61);
2154                                 break;
2155                         case JSToken.RightShiftAssign:
2156                                 ig.Emit (OpCodes.Ldc_I4_S, 62);
2157                                 break;                          
2158                         case JSToken.UnsignedRightShiftAssign:
2159                                 ig.Emit (OpCodes.Ldc_I4_S, 63);
2160                                 break;
2161                         case JSToken.MultiplyAssign:
2162                                 ig.Emit (OpCodes.Ldc_I4_S, 64);
2163                                 break;
2164                         case JSToken.DivideAssign:
2165                                 ig.Emit (OpCodes.Ldc_I4_S, 65);
2166                                 break;
2167                         case JSToken.ModuloAssign:
2168                                 ig.Emit (OpCodes.Ldc_I4_S, 66);
2169                                 break;
2170                         default:
2171                                 throw new NotImplementedException ();
2172                         }
2173                 }
2174
2175                 void emit_evaluation (JSToken op, Type type, ILGenerator ig)
2176                 {
2177                         switch (op) {
2178                         case JSToken.MinusAssign:
2179                         case JSToken.MultiplyAssign:
2180                         case JSToken.DivideAssign:
2181                         case JSToken.ModuloAssign:
2182                                 ig.Emit (OpCodes.Call, type.GetMethod ("EvaluateNumericBinary"));
2183                                 break;
2184                         case JSToken.BitwiseAndAssign:
2185                         case JSToken.BitwiseOrAssign:
2186                         case JSToken.BitwiseXorAssign:
2187                         case JSToken.LeftShiftAssign:
2188                         case JSToken.RightShiftAssign:
2189                         case JSToken.UnsignedRightShiftAssign:
2190                                 ig.Emit (OpCodes.Call, type.GetMethod ("EvaluateBitwiseBinary"));
2191                                 break;
2192                         default:
2193                                 throw new NotImplementedException ();
2194                         }
2195
2196                 }
2197
2198                 public override string ToString ()
2199                 {
2200                         string l = left.ToString ();
2201                         string r = right.ToString ();
2202                         return l + " " + op.ToString () + " " + r;
2203                 }
2204         }
2205
2206         internal class New : AST, ICallable {
2207
2208                 AST exp;
2209                 Args args;
2210                 bool late_bind = false;
2211
2212                 internal New (AST parent, AST exp, Location location)
2213                         : base (parent, location)
2214                 {
2215                         this.exp = exp;
2216                         this.args = new Args (location);
2217                 }
2218
2219                 public void AddArg (AST arg)
2220                 {
2221                         args.Add (arg);
2222                 }
2223                 
2224                 internal override bool Resolve (Environment env)
2225                 {
2226                         bool r = true;
2227
2228                         if (exp != null && exp.GetType () == typeof (Identifier)) {
2229                                 Identifier id = (Identifier) exp;
2230                                 late_bind = !SemanticAnalyser.is_js_object (id.name.Value);
2231                         } 
2232                         exp.Resolve (env);
2233
2234                         if (args != null) {
2235                                 args.InNew = true;
2236                                 r &= args.Resolve (env);
2237                         }
2238                         return r;
2239                 }
2240
2241                 internal override void Emit (EmitContext ec)
2242                 {
2243                         ILGenerator ig = ec.ig;
2244
2245                         if (exp != null) {
2246                                 if (late_bind) {
2247                                         AST ast = null;
2248                                         CodeGenerator.emit_get_default_this (ec.ig, InFunction);
2249                                         exp.Emit (ec);
2250
2251                                         ig.Emit (OpCodes.Ldc_I4, args.Size);
2252                                         ig.Emit (OpCodes.Newarr, typeof (object));
2253
2254                                         for (int i = 0; i < args.Size; i++) {
2255                                                 ig.Emit (OpCodes.Dup);
2256                                                 ig.Emit (OpCodes.Ldc_I4, i);
2257                                                 ast = args.get_element (i);
2258
2259                                                 if (ast is Assign)
2260                                                         CodeGenerator.EmitAssignAsExp (ec, ast);
2261                                                 else {
2262                                                         ast.Emit (ec);
2263                                                         CodeGenerator.EmitBox (ig, ast);
2264                                                 }
2265                                                 ig.Emit (OpCodes.Stelem_Ref);
2266                                         }
2267
2268                                         ig.Emit (OpCodes.Ldc_I4_1);
2269                                         ig.Emit (OpCodes.Ldc_I4_0);
2270
2271                                         CodeGenerator.load_engine (InFunction, ig);
2272
2273                                         ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
2274                                 } else {
2275                                         if (exp != null)
2276                                                 exp.Emit (ec);
2277                                         if (args != null)
2278                                                 emit_args (ec);
2279                                         emit_create_instance (ec);
2280                                 }
2281                         }
2282                 }
2283                 
2284                 void emit_create_instance (EmitContext ec)
2285                 {
2286                         if (exp is Identifier) {
2287                                 ILGenerator ig = ec.ig;
2288                                 Type type = null;
2289                                 switch ((exp as Identifier).name.Value) {
2290                                 case "Array":                                   
2291                                         type = typeof (ArrayConstructor);
2292                                         break;
2293                                 case "Date":
2294                                         type = typeof (DateConstructor);
2295                                         break;
2296                                 case "Number":
2297                                         type = typeof (NumberConstructor);
2298                                         break;
2299                                 case "Object":
2300                                         type = typeof (ObjectConstructor);
2301                                         break;
2302                                 case "RegExp":
2303                                         type = typeof (RegExpConstructor);
2304                                         break;
2305                                 case "String":
2306                                         type = typeof (StringConstructor);
2307                                         break;
2308                                 case "Boolean":
2309                                         type = typeof (BooleanConstructor);
2310                                         break;
2311                                 case "Function":
2312                                         type = typeof (FunctionConstructor);
2313                                         break;
2314                                 }
2315                                 if (type != null)
2316                                         ig.Emit (OpCodes.Call, type.GetMethod ("CreateInstance"));
2317                                 else
2318                                         throw new NotImplementedException (String.Format (
2319                                                 "Should emit LateBinding.CallValue logic for unknown constructor {0}",
2320                                                 (exp as Identifier).name.Value));
2321                         }
2322                 }
2323                 
2324                 void emit_args (EmitContext ec)
2325                 {
2326                         ILGenerator ig = ec.ig;
2327                         int n = args.Size;
2328                         ig.Emit (OpCodes.Ldc_I4, args.Size);
2329                         ig.Emit (OpCodes.Newarr, typeof (object));
2330
2331                         AST ast = null;
2332
2333                         for (int i = 0; i < n; i++) {
2334                                 ig.Emit (OpCodes.Dup);
2335                                 ig.Emit (OpCodes.Ldc_I4, i);
2336                                 ast = args.get_element (i);
2337
2338                                 if (ast is Assign)
2339                                         CodeGenerator.EmitAssignAsExp (ec, ast);
2340                                 else {
2341                                         ast.Emit (ec);
2342                                         CodeGenerator.EmitBox (ig, ast);
2343                                 }
2344                                 ig.Emit (OpCodes.Stelem_Ref);
2345                         }
2346                 }
2347         }
2348         
2349         internal interface IAssignable {
2350                 bool ResolveAssign (Environment env, AST right_side);
2351         }
2352
2353         internal class BuiltIn : AST {
2354                 string name;
2355                 bool allowed_as_ctr;
2356                 bool allowed_as_func;
2357
2358                 internal BuiltIn (string name, bool allowed_as_ctr, bool allowed_as_func)
2359                         : base (null, null)
2360                 {
2361                         this.name = name;
2362                         this.allowed_as_ctr = allowed_as_ctr;
2363                         this.allowed_as_func = allowed_as_func;
2364                 }
2365
2366                 internal override bool Resolve (Environment env)
2367                 {
2368                         return true;
2369                 }
2370                 
2371                 internal string Name {
2372                         get { return name; }
2373                 }
2374                 
2375                 internal bool IsConstructor {
2376                         get { return allowed_as_ctr; }
2377                 }
2378
2379                 internal bool IsFunction {
2380                         get { return allowed_as_func; }
2381                 }
2382                 
2383                 internal bool IsPrint {
2384                         get { return String.Equals (name, "print"); }
2385                 }
2386                 internal int NumOfArgs {
2387                         get {
2388                                 if (name == "print")
2389                                         return -1;
2390
2391                                 Type global_object = typeof (GlobalObject);
2392                                 MethodInfo method = global_object.GetMethod (name);
2393                                 return method.GetParameters ().Length;
2394                         }
2395                 }
2396
2397                 internal ParameterInfo [] Parameters {
2398                         get {
2399                                 Type global_obj = typeof (GlobalObject);
2400                                 return global_obj.GetMethod (name).GetParameters ();
2401                         }
2402                 }
2403
2404                 internal override void Emit (EmitContext ec)
2405                 {
2406                         ILGenerator ig = ec.ig;
2407                         Type go = typeof (GlobalObject);
2408                         switch (name) {
2409                         /* value properties of the Global Object */
2410                         case "NaN":
2411                                 ig.Emit (OpCodes.Ldc_R8, Double.NaN);
2412                                 break;                          
2413
2414                         case "Infinity":
2415                                 ig.Emit (OpCodes.Ldc_R8, Double.PositiveInfinity);
2416                                 break;
2417
2418                         case "undefined":
2419                                 ig.Emit (OpCodes.Ldnull);
2420                                 break;
2421
2422                         case "null":
2423                                 ig.Emit (OpCodes.Ldsfld, typeof (DBNull).GetField ("Value"));
2424                                 break;
2425                                 
2426                         /* function properties of the Global Object */
2427                         case "eval":
2428                                 Type [] method_args = null;
2429 #if NET_1_0
2430                                 method_args = new Type [] {typeof (object), typeof (VsaEngine)};
2431 #else
2432                                 method_args = new Type [] {typeof (object), typeof (object), typeof (VsaEngine)};
2433 #endif
2434                                 ig.Emit (OpCodes.Call, typeof (Eval).GetMethod ("JScriptEvaluate", method_args));
2435                                 break;
2436
2437                         case "parseInt":                                
2438                                 ig.Emit (OpCodes.Call, go.GetMethod ("parseInt"));
2439                                 ig.Emit (OpCodes.Box, typeof (Double));
2440                                 break;
2441
2442                         case "parseFloat":
2443                                 ig.Emit (OpCodes.Call, go.GetMethod ("parseFloat"));
2444                                 ig.Emit (OpCodes.Box, typeof (Double));
2445                                 break;
2446
2447                         case "isNaN":
2448                                 ig.Emit (OpCodes.Call, go.GetMethod ("isNaN"));
2449                                 ig.Emit (OpCodes.Box, typeof (bool));
2450                                 break;
2451
2452                         case "isFinite":
2453                                 ig.Emit (OpCodes.Call, go.GetMethod ("isFinite"));
2454                                 ig.Emit (OpCodes.Box, typeof (bool));
2455                                 break;
2456
2457                         case "decodeURI":
2458                                 ig.Emit (OpCodes.Call, go.GetMethod ("decodeURI"));
2459                                 break;
2460
2461                         case "decodeURIComponent":
2462                                 ig.Emit (OpCodes.Call, go.GetMethod ("decodeURIComponent"));
2463                                 break;
2464
2465                         case "encodeURI":
2466                                 ig.Emit (OpCodes.Call, go.GetMethod ("encodeURI"));
2467                                 break;
2468
2469                         case "encodeURIComponent":
2470                                 ig.Emit (OpCodes.Call, go.GetMethod ("encodeURIComponent"));
2471                                 break;
2472
2473                         case "escape":
2474                                 ig.Emit (OpCodes.Call, go.GetMethod ("escape"));
2475                                 break;
2476
2477                         case "unescape":
2478                                 ig.Emit (OpCodes.Call, go.GetMethod ("unescape"));
2479                                 break;
2480
2481                         /* constructor properties of the Global object */
2482                         case "Object":
2483                                 ig.Emit (OpCodes.Call, go.GetProperty ("Object").GetGetMethod ());
2484                                 break;
2485
2486                         case "Function":
2487                                 ig.Emit (OpCodes.Call, go.GetProperty ("Function").GetGetMethod ());
2488                                 break;
2489
2490                         case "Array":
2491                                 ig.Emit (OpCodes.Call, go.GetProperty ("Array").GetGetMethod ());
2492                                 break;
2493
2494                         case "String":
2495                                 ig.Emit (OpCodes.Call, go.GetProperty ("String").GetGetMethod ());
2496                                 break;
2497
2498                         case "Boolean":
2499                                 ig.Emit (OpCodes.Call, go.GetProperty ("Boolean").GetGetMethod ());
2500                                 break;
2501
2502                         case "Number":
2503                                 ig.Emit (OpCodes.Call, go.GetProperty ("Number").GetGetMethod ());
2504                                 break;
2505
2506                         case "Date":
2507                                 ig.Emit (OpCodes.Call, go.GetProperty ("Date").GetGetMethod ());
2508                                 break;
2509
2510                         case "RegExp":
2511                                 ig.Emit (OpCodes.Call, go.GetProperty ("RegExp").GetGetMethod ());
2512                                 break;
2513
2514                         case "Error":
2515                                 ig.Emit (OpCodes.Call, go.GetProperty ("Error").GetGetMethod ());
2516                                 break;
2517
2518                         case "EvalError":
2519                                 ig.Emit (OpCodes.Call, go.GetProperty ("EvalError").GetGetMethod ());
2520                                 break;
2521
2522                         case "RangeError":
2523                                 ig.Emit (OpCodes.Call, go.GetProperty ("RangeError").GetGetMethod ());
2524                                 break;
2525
2526                         case "ReferenceError":
2527                                 ig.Emit (OpCodes.Call, go.GetProperty ("ReferenceError").GetGetMethod ());
2528                                 break;
2529
2530                         case "SyntaxError":
2531                                 ig.Emit (OpCodes.Call, go.GetProperty ("SyntaxError").GetGetMethod ());
2532                                 break;
2533
2534                         case "TypeError":
2535                                 ig.Emit (OpCodes.Call, go.GetProperty ("TypeError").GetGetMethod ());
2536                                 break;
2537
2538                         case "URIError":
2539                                 ig.Emit (OpCodes.Call, go.GetProperty ("URIError").GetGetMethod ());
2540                                 break;
2541                         /* other properties of the Global object */
2542                         case "Math":
2543                                 ig.Emit (OpCodes.Call, go.GetProperty ("Math").GetGetMethod ());
2544                                 break;
2545                         default:
2546                                 throw new Exception ("This is BuiltIn " + name);
2547                         }
2548                 }
2549         }
2550 }