2 // expression.cs: Everything related to expressions
5 // Cesar Lopez Nataren (cesar@ciencias.unam.mx)
7 // (C) 2003, 2004 Cesar Lopez Nataren
8 // (C) 2005, Novell Inc. (http://novell.com)
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:
20 // The above copyright notice and this permission notice shall be
21 // included in all copies or substantial portions of the Software.
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.
34 using System.Collections;
35 using System.Reflection;
36 using System.Reflection.Emit;
37 using Microsoft.JScript.Vsa;
39 namespace Microsoft.JScript {
41 public abstract class Exp : AST {
42 internal bool no_effect;
43 internal abstract bool Resolve (Environment env, bool no_effect);
45 internal Exp (AST parent, Location location)
46 : base (parent, location)
51 internal class Unary : UnaryOp {
53 private bool deletable = false;
54 private bool isCtr = false;
56 internal Unary (AST parent, JSToken oper, Location location)
57 : base (parent, location)
62 public override string ToString ()
64 StringBuilder sb = new StringBuilder ();
66 if (oper != JSToken.None)
67 sb.Append (oper + " ");
70 sb.Append (operand.ToString ());
72 return sb.ToString ();
75 internal override bool Resolve (Environment env)
79 if (operand is Binary) {
80 Binary bin = (Binary) operand;
81 if (oper == JSToken.Delete && bin.AccessField)
82 this.deletable = bin.IsDeletable (out isCtr);
84 } else if (operand is Exp) {
85 if (oper != JSToken.Increment && oper != JSToken.Decrement)
86 r = ((Exp) operand).Resolve (env, no_effect);
88 r = operand.Resolve (env);
92 internal override bool Resolve (Environment env, bool no_effect)
94 this.no_effect = no_effect;
98 internal override void Emit (EmitContext ec)
100 ILGenerator ig = ec.ig;
105 ig.Emit (OpCodes.Pop);
106 ig.Emit (OpCodes.Ldnull);
111 CodeGenerator.EmitBox (ig, operand);
112 ig.Emit (OpCodes.Call, typeof (Typeof).GetMethod ("JScriptTypeof"));
116 Expression exp = operand as Expression;
118 operand = exp.exprs [exp.exprs.Count - 1] as AST;
120 Binary arg = operand as Binary;
122 if (arg.op == JSToken.LeftBracket || arg.op == JSToken.AccessField ) {
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) }));
133 Console.WriteLine ("{0}({1},0) : warning: " +
134 "JS1164: '{2}' is not deletable",
135 location.SourceName, location.LineNumber, arg.ToString ());
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;
141 Type lb_type = typeof (LateBinding);
142 LocalBuilder lb = ig.DeclareLocal (lb_type);
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);
150 ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
151 ig.Emit (OpCodes.Call, lb_type.GetMethod ("Delete"));
155 Console.WriteLine ("emit_unary_op: Delete: unknown operand type {0}", arg.op);
156 throw new NotImplementedException ();
159 Console.WriteLine ("emit_unary_op: Delete: unknown operand {0} ({1})", operand, operand.GetType ());
160 throw new NotImplementedException ();
165 ig.Emit (OpCodes.Pop);
170 ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToNumber", new Type [] { typeof (object) }));
172 // FIXME: investigate the real
173 // discriminate for generating this
176 ig.Emit (OpCodes.Box, typeof (double));
180 if (SemanticAnalyser.IsNumericConstant (operand)) {
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);
187 emit_non_numeric_unary (ec, operand, (byte) 47);
190 case JSToken.BitwiseNot:
191 if (SemanticAnalyser.IsNumericConstant (operand)) {
193 ig.Emit (OpCodes.Not);
195 emit_non_numeric_unary (ec, operand, (byte) 40);
198 case JSToken.LogicalNot:
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) }));
206 ig.Emit (OpCodes.Ldc_I4_0);
207 ig.Emit (OpCodes.Ceq);
211 Console.WriteLine ("Unimplemented Unary Op: {0}", oper);
212 throw new NotImplementedException ();
216 private void emit_non_numeric_unary (EmitContext ec, AST operand, byte oper)
218 ILGenerator ig = ec.ig;
220 Type unary_type = typeof (NumericUnary);
221 LocalBuilder unary_builder = ig.DeclareLocal (unary_type);
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);
230 ig.Emit (OpCodes.Call, unary_type.GetMethod ("EvaluateUnary"));
234 internal class Binary : BinaryOp, IAssignable {
236 internal bool assign, late_bind = false;
237 internal AST right_side;
239 internal Binary (AST parent, AST left, JSToken op, Location location)
240 : this (parent, left, null, op, location)
244 internal Binary (AST parent, AST left, AST right, JSToken op, Location location)
245 : base (parent, left, right, op, location)
249 public override string ToString ()
251 StringBuilder sb = new StringBuilder ();
252 sb.Append (left.ToString ());
254 if (op == JSToken.AccessField)
259 sb.Append (right.ToString ());
261 return sb.ToString ();
264 internal bool AccessField {
265 get { return op == JSToken.AccessField; }
268 internal bool LateBinding {
269 get { return late_bind; }
272 internal override bool Resolve (Environment env)
277 if (op == JSToken.AccessField && left is ICanLookupPrototype) {
278 found &= ((ICanLookupPrototype) left).ResolveFieldAccess (right);
282 found &= left.Resolve (env);
284 if (op == JSToken.AccessField && right is IAccessible) {
285 found &= ((IAccessible) right).ResolveFieldAccess (left);
289 found &= right.Resolve (env);
293 internal override bool Resolve (Environment env, bool no_effect)
295 this.no_effect = no_effect;
296 return Resolve (env);
299 public bool ResolveAssign (Environment env, AST right_side)
301 if (op == JSToken.LeftBracket || op == JSToken.AccessField) {
302 this.no_effect = false;
304 this.right_side = right_side;
305 return Resolve (env);
307 throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
310 internal MemberInfo Binding {
312 return SemanticAnalyser.get_member (left, right);
316 internal override void Emit (EmitContext ec)
318 ILGenerator ig = ec.ig;
319 if (op == JSToken.None) {
322 } else if (op == JSToken.LogicalAnd || op == JSToken.LogicalOr)
323 emit_jumping_code (ec);
324 else if (op == JSToken.LeftBracket) {
326 get_default_this (ig);
329 emit_array_access (ec);
330 } else if (op == JSToken.AccessField) {
332 emit_late_binding (ec);
334 emit_access (left, right, ec);
339 CodeGenerator.EmitBox (ig, left);
343 CodeGenerator.EmitBox (ig, right);
348 ig.Emit (OpCodes.Pop);
351 void emit_access (AST obj, AST prop_name, EmitContext ec)
353 MemberInfo minfo = SemanticAnalyser.get_member (obj, prop_name);
354 ILGenerator ig = ec.ig;
355 MemberTypes minfo_type = minfo.MemberType;
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);
365 case MemberTypes.Property:
366 PropertyInfo property = (PropertyInfo) minfo;
367 Type decl_type = property.DeclaringType;
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 ());
381 ig.Emit (OpCodes.Call, decl_type.GetProperty (property.Name).GetGetMethod ());
384 Type lb_type = typeof (LateBinding);
385 LocalBuilder lateBinder = ig.DeclareLocal (lb_type);
386 Identifier prop = (Identifier) prop_name;
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);
394 Identifier obj_name = (Identifier) obj;
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"));
403 emit_box (ig, minfo);
406 void emit_box (ILGenerator ig, MemberInfo info)
408 MemberTypes member_type = info.MemberType;
411 switch (member_type) {
412 case MemberTypes.Field:
413 type = ((FieldInfo) info).FieldType;
417 ig.Emit (OpCodes.Box, type);
420 private string FieldName (Type type)
422 if (type == typeof (RegExpConstructor))
424 throw new NotImplementedException ();
427 void emit_late_binding (EmitContext ec)
429 LocalBuilder local_lb = init_late_binding (ec);
430 emit_late_get_or_set (ec, local_lb);
433 LocalBuilder init_late_binding (EmitContext ec)
435 ILGenerator ig = ec.ig;
436 Type lb_type = typeof (LateBinding);
438 LocalBuilder local = ig.DeclareLocal (lb_type);
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);
448 void emit_late_get_or_set (EmitContext ec, LocalBuilder lb_builder)
450 ILGenerator ig = ec.ig;
451 LocalBuilder right_obj = ig.DeclareLocal (typeof (object));
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.
457 if (right_side == null && assign) {
458 ig.Emit (OpCodes.Box, typeof (object));
459 ig.Emit (OpCodes.Stloc, right_obj);
461 Type type = SemanticAnalyser.IsLiteral (left);
464 ig.Emit (OpCodes.Ldloc, lb_builder);
465 ig.Emit (OpCodes.Dup);
469 LocalBuilder local_literal = null;
472 // If the left hand side is as literal we must create a local
473 // var where is kept for future use
476 local_literal = ig.DeclareLocal (type);
477 ig.Emit (OpCodes.Dup);
478 ig.Emit (OpCodes.Stloc, local_literal);
480 ig.Emit (OpCodes.Ldloc, lb_builder);
481 ig.Emit (OpCodes.Dup);
482 ig.Emit (OpCodes.Ldloc, local_literal);
484 CodeGenerator.load_engine (InFunction, ec.ig);
485 ig.Emit (OpCodes.Call , typeof (Convert).GetMethod ("ToObject"));
487 Type lb_type = typeof (LateBinding);
488 ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
491 if (right_side != null)
492 right_side.Emit (ec);
494 ig.Emit (OpCodes.Ldloc, right_obj);
495 CodeGenerator.EmitBox (ig, right_side);
496 ig.Emit (OpCodes.Call, lb_type.GetMethod ("SetValue"));
498 ig.Emit (OpCodes.Call, lb_type.GetMethod ("GetNonMissingValue"));
501 internal void get_default_this (ILGenerator ig)
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"));
510 internal void emit_array_access (EmitContext ec)
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);
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);
527 CodeGenerator.EmitBox (ig, right);
529 ig.Emit (OpCodes.Stelem_Ref);
532 if (right_side != null) {
533 right_side.Emit (ec);
534 CodeGenerator.EmitBox (ig, right_side);
537 ig.Emit (OpCodes.Ldloc, right_obj);
538 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("SetIndexedPropertyValueStatic"));
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"));
547 internal void emit_op_eval (ILGenerator ig)
551 ig.Emit (OpCodes.Callvirt, typeof (Plus).GetMethod ("EvaluatePlus"));
556 case JSToken.Multiply:
557 ig.Emit (OpCodes.Call, typeof (NumericBinary).GetMethod ("EvaluateNumericBinary"));
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"));
570 internal void emit_jumping_code (EmitContext ec)
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);
586 internal void emit_operator (ILGenerator ig)
588 LocalBuilder local_builder = null;
591 if (op == JSToken.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);
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);
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);
644 internal bool IsDeletable (out bool isCtr)
646 if (left is Identifier && right is Identifier)
647 return SemanticAnalyser.IsDeletable ((Identifier) left, (Identifier) right, out isCtr);
653 internal class Conditional : Exp {
655 AST cond_exp, true_exp, false_exp;
657 internal Conditional (AST parent, AST expr, AST trueExpr, AST falseExpr, Location location)
658 : base (parent, location)
660 this.cond_exp = expr;
661 this.true_exp = trueExpr;
662 this.false_exp = falseExpr;
665 public override string ToString ()
667 StringBuilder sb = new StringBuilder ();
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 ());
676 return sb.ToString ();
679 internal override bool Resolve (Environment env)
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);
691 internal override bool Resolve (Environment env, bool no_effect)
693 this.no_effect = no_effect;
694 return Resolve (env);
697 internal override void Emit (EmitContext ec)
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) {
705 CodeGenerator.EmitBox (ig, true_exp);
707 ig.Emit (OpCodes.Br, merge_label);
708 ig.MarkLabel (false_label);
709 if (false_exp != null) {
711 CodeGenerator.EmitBox (ig, false_exp);
713 ig.MarkLabel (merge_label);
715 ig.Emit (OpCodes.Pop);
719 internal interface ICallable {
720 void AddArg (AST arg);
723 internal class Call : Exp, ICallable {
725 internal AST member_exp;
727 internal object binding;
728 internal Type bind_type;
729 private bool is_dynamic_function = false;
730 private bool need_this = false;
732 internal Call (AST parent, AST exp, Location location)
733 : base (parent, location)
735 this.member_exp = exp;
736 this.args = new Args (location);
739 public override string ToString ()
741 StringBuilder sb = new StringBuilder ();
742 if (member_exp != null)
743 sb.Append (member_exp.ToString () + " ");
745 sb.Append (args.ToString ());
746 return sb.ToString ();
749 public void AddArg (AST arg)
754 internal override bool Resolve (Environment env)
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 ();
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)) {
770 // If a method contains an eval invocation
771 // we must generate proper code for accessing
772 // the local vars in the StackFrame.
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);
781 } else if (member_exp is Binary) {
782 member_exp.Resolve (env);
783 Binary bin = (Binary) member_exp;
785 binding = bin.Binding;
786 if (binding is MethodInfo)
787 NeedThis ((MethodInfo) binding);
789 r &= member_exp.Resolve (env);
791 args.BoundToMethod = binding;
794 r &= args.Resolve (env);
796 throw new Exception ("Call.Resolve, member_exp can't be null");
800 private void NeedThis (MethodInfo method)
802 need_this = SemanticAnalyser.Needs (JSFunctionAttributeEnum.HasThisObject, method);
805 internal override bool Resolve (Environment env, bool no_effect)
807 this.no_effect = no_effect;
808 return Resolve (env);
811 internal override void Emit (EmitContext ec)
813 if (bind_type == typeof (BuiltIn)) {
814 BuiltIn b = binding as BuiltIn;
818 } else if (IsGlobalObjectMethod (binding)) {
819 bool eval = IsEval (binding);
820 bool in_func = InFunction;
823 CodeGenerator.load_local_vars (ec.ig, in_func);
829 ec.ig.Emit (OpCodes.Ldnull);
831 CodeGenerator.load_engine (in_func, ec.ig);
833 member_exp.Emit (ec);
835 if (eval && no_effect && in_func)
836 ec.ig.Emit (OpCodes.Pop);
838 if (eval && in_func) {
839 set_local_vars (ec.ig);
842 } else if (IsConstructorProperty (binding)) {
843 member_exp.Emit (ec);
844 EmitBuiltInArgs (ec);
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);
851 if (SemanticAnalyser.MethodContainsEval (function.func_obj.name) ||
852 SemanticAnalyser.MethodReferenceOutterScopeVar (function.func_obj.name) ||
853 SemanticAnalyser.MethodVarsUsedNested (function.func_obj.name)) {
855 CodeGenerator.load_local_vars (ec.ig, true);
858 ec.ig.Emit (OpCodes.Pop);
860 set_local_vars (ec.ig);
863 emit_func_call (method, ec);
866 } else if (binding is MemberInfo) {
867 MemberInfo minfo = (MemberInfo) binding;
868 MemberTypes member_type = minfo.MemberType;
869 ILGenerator ig = ec.ig;
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 ) {
876 CodeGenerator.EmitBox (ig, bin.left);
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;
891 bool in_func = InFunction;
892 CodeGenerator.load_engine (in_func, ig);
893 ig.Emit (OpCodes.Call, typeof (Convert).GetMethod ("ToObject2"));
895 if (bin.left is Identifier) {
896 Type coerce_to = null;
897 if (((Identifier) bin.left).name.Value == "Function")
898 coerce_to = typeof (FunctionConstructor);
900 LocalBuilder ctr = null;
902 if (coerce_to != null) {
903 ig.Emit (OpCodes.Castclass, coerce_to);
904 ctr = ig.DeclareLocal (coerce_to);
907 ig.Emit (OpCodes.Dup);
908 ig.Emit (OpCodes.Stloc, ctr);
911 ig.Emit (OpCodes.Ldc_I4, args.Size);
912 ig.Emit (OpCodes.Newarr, typeof (object));
914 ig.Emit (OpCodes.Ldc_I4_0);
915 ig.Emit (OpCodes.Ldc_I4_0);
917 CodeGenerator.load_engine (in_func, ig);
919 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
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 ();
932 ec.ig.Emit (OpCodes.Pop);
935 internal void emit_print_stm (EmitContext ec)
937 ILGenerator ig = ec.ig;
939 if (args == null || args.Size == 0) {
940 ig.Emit (OpCodes.Ldstr, "");
941 ig.Emit (OpCodes.Call, typeof (ScriptStream).GetMethod ("WriteLine"));
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) });
951 int n = args.Size - 1;
953 for (int i = 0; i <= n; i++) {
954 ast = args.get_element (i);
957 CodeGenerator.EmitAssignAsExp (ec, ast);
961 if (ast is Relational)
962 CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
964 CodeGenerator.EmitBox (ig, ast);
966 if (!(ast is StringLiteral)){
967 ig.Emit (OpCodes.Ldc_I4_1);
968 ig.Emit (OpCodes.Call, to_string);
972 ig.Emit (OpCodes.Call, writeline);
974 ig.Emit (OpCodes.Call, write);
979 void emit_late_call (EmitContext ec)
981 ILGenerator ig = ec.ig;
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);
994 LocalBuilder lb = ig.DeclareLocal (lb_type);
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"));
1004 CodeGenerator.EmitBox (ig, bin.left);
1006 member_exp.Emit (ec);
1007 CodeGenerator.EmitBox (ig, member_exp);
1009 setup_late_call_args (ec);
1010 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
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"));
1021 internal void get_global_scope_or_this (ILGenerator ig)
1023 is_dynamic_function = parent is FunctionExpression && parent == member_exp;
1025 if (is_dynamic_function) {
1026 ig.Emit (OpCodes.Ldarg_0);
1027 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
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);
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
1040 if (member_exp is FunctionExpression)
1041 ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetGlobalScope"));
1043 ig.Emit (OpCodes.Callvirt, iact_obj.GetMethod ("GetDefaultThisObject"));
1046 void init_late_binding (EmitContext ec, LocalBuilder local)
1048 ILGenerator ig = ec.ig;
1050 ig.Emit (OpCodes.Ldloc, local);
1051 ig.Emit (OpCodes.Dup);
1053 AST left = (member_exp as Binary).left;
1056 CodeGenerator.load_engine (InFunction, ig);
1058 ig.Emit (OpCodes.Call , typeof (Convert).GetMethod ("ToObject"));
1060 Type lb_type = typeof (LateBinding);
1062 ig.Emit (OpCodes.Stfld, lb_type.GetField ("obj"));
1065 void setup_late_call_args (EmitContext ec)
1067 ILGenerator ig = ec.ig;
1071 ig.Emit (OpCodes.Ldc_I4, n);
1072 ig.Emit (OpCodes.Newarr, typeof (object));
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);
1079 CodeGenerator.EmitBox (ig, ast);
1080 ig.Emit (OpCodes.Stelem_Ref);
1083 ig.Emit (OpCodes.Ldc_I4_0);
1084 ig.Emit (OpCodes.Ldc_I4_0);
1086 if (is_dynamic_function) {
1087 ig.Emit (OpCodes.Ldarg_0);
1088 ig.Emit (OpCodes.Ldfld, typeof (ScriptObject).GetField ("engine"));
1090 CodeGenerator.load_engine (InFunction, ig);
1093 void emit_func_call (MethodBuilder mb, EmitContext ec)
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);
1103 ig.Emit (OpCodes.Call, mb);
1105 if (!return_void (mb) && no_effect)
1106 ig.Emit (OpCodes.Pop);
1109 bool return_void (MethodBuilder mb)
1111 return mb.ReturnType == typeof (void);
1114 void EmitBuiltInArgs (EmitContext ec)
1116 if (member_exp.ToString () == "Date")
1119 ILGenerator ig = ec.ig;
1123 if (n >= 1 && (member_exp.ToString () == "String" || member_exp.ToString () == "Boolean" || member_exp.ToString () == "Number")) {
1124 ast = args.get_element (0);
1127 CodeGenerator.EmitAssignAsExp (ec, ast);
1130 CodeGenerator.EmitBox (ig, ast);
1135 ig.Emit (OpCodes.Ldc_I4, n);
1136 ig.Emit (OpCodes.Newarr, typeof (object));
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);
1144 CodeGenerator.EmitAssignAsExp (ec, ast);
1147 CodeGenerator.EmitBox (ig, ast);
1150 ig.Emit (OpCodes.Stelem_Ref);
1154 void EmitInvoke (EmitContext ec)
1156 ILGenerator ig = ec.ig;
1157 string name = member_exp.ToString ();
1159 bool boolean = false;
1160 bool number = false;
1164 type = typeof (ObjectConstructor);
1167 type = typeof (FunctionConstructor);
1170 type = typeof (ArrayConstructor);
1173 type = typeof (StringConstructor);
1176 type = typeof (BooleanConstructor);
1180 type = typeof (NumberConstructor);
1184 type = typeof (DateConstructor);
1187 type = typeof (RegExpConstructor);
1192 case "ReferenceError":
1196 type = typeof (ErrorConstructor);
1199 ig.Emit (OpCodes.Call, type.GetMethod ("Invoke"));
1201 ig.Emit (OpCodes.Box, typeof (Boolean));
1203 ig.Emit (OpCodes.Box, typeof (Double));
1206 bool IsConstructorProperty (object binding)
1208 if (!(binding is BuiltIn))
1211 string name = (binding as BuiltIn).Name;
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");
1216 bool IsGlobalObjectMethod (object binding)
1218 if (binding == null || binding.GetType () != typeof (BuiltIn))
1221 BuiltIn bind = binding as BuiltIn;
1222 switch (bind.Name) {
1229 case "decodeURIComponent":
1231 case "encodeURIComponent":
1240 bool IsEval (object binding)
1242 if (binding == null || binding.GetType () != typeof (BuiltIn))
1244 BuiltIn bind = (BuiltIn) binding;
1245 return bind.Name == "eval";
1248 internal void set_local_vars (ILGenerator ig)
1251 Type stack_frame = typeof (StackFrame);
1253 CodeGenerator.load_engine (InFunction, ig);
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"));
1259 object [] locals = TypeManager.CurrentLocals;
1260 n = locals != null ? locals.Length : 0;
1261 object local = null;
1263 for (int i = 0; i < n; 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);
1272 ig.Emit (OpCodes.Pop);
1276 interface IAccessible {
1277 bool ResolveFieldAccess (AST parent);
1280 internal interface ICanLookupPrototype {
1281 bool ResolveFieldAccess (AST parent);
1284 internal class Identifier : Exp, IAssignable, IAccessible {
1286 internal Symbol name;
1287 internal AST binding;
1288 internal bool assign;
1291 int lexical_difference;
1292 const int MINIMUM_DIFFERENCE = 1;
1294 LocalBuilder local_builder;
1296 private bool undeclared = false;
1298 internal Identifier (AST parent, string id, Location location)
1299 : base (parent, location)
1301 this.name = Symbol.CreateSymbol (id);
1305 get { return lexical_difference >= MINIMUM_DIFFERENCE && no_field; }
1308 public override string ToString ()
1313 internal override bool Resolve (Environment env)
1315 bool contained = env.Contains (String.Empty, this.name);
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;
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);
1330 } else if (SemanticAnalyser.NoFast) {
1332 Console.WriteLine ("warning JS1135: Variable '" + name + "' has not been declared");
1335 // Identifier not into stand-alone JScript, we'll search into
1336 // referenced assemblies and namespaces
1338 throw new Exception (location.SourceName + "(" + location.LineNumber +
1339 ",0) : error JS1135: Variable '" + name + "' has not been declared");
1344 internal override bool Resolve (Environment env, bool no_effect)
1346 this.no_effect = no_effect;
1347 return Resolve (env);
1350 public bool ResolveAssign (Environment env, AST right_side)
1353 this.no_effect = false;
1354 this.right_side = right_side;
1355 if (name.Value != String.Empty)
1356 return Resolve (env);
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.
1367 public bool ResolveFieldAccess (AST parent)
1369 if (parent is Identifier) {
1370 Identifier p = parent as Identifier;
1371 return is_static_property (p.name.Value, name.Value);
1374 // Return false so late binding will take place
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
1384 bool is_static_property (string obj_name, string prop_name)
1386 bool native_obj = SemanticAnalyser.is_js_object (obj_name);
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);
1399 internal override void Emit (EmitContext ec)
1401 ILGenerator ig = ec.ig;
1403 if (assign && right_side != null && !undeclared) {
1404 right_side.Emit (ec);
1405 CodeGenerator.EmitBox (ig, right_side);
1407 if (binding is FormalParam) {
1408 FormalParam f = binding as FormalParam;
1410 ig.Emit (OpCodes.Starg, (short) f.pos);
1412 ig.Emit (OpCodes.Ldarg_S, f.pos);
1413 } else if (binding is VariableDeclaration || binding is Try || binding is Catch) {
1415 CodeGenerator.emit_parents (InFunction, lexical_difference, ig);
1416 store_stack_frame_into_locals (ec.ig);
1417 if (this.local_builder != null)
1419 ig.Emit (OpCodes.Stloc, local_builder);
1421 ig.Emit (OpCodes.Ldloc, local_builder);
1423 FieldInfo field_info = extract_field_info (binding);
1424 LocalBuilder local_builder = extract_local_builder (binding);
1426 if (field_info != null) {
1428 ig.Emit (OpCodes.Stsfld, field_info);
1430 ig.Emit (OpCodes.Ldsfld, field_info);
1431 } else if (local_builder != null) {
1433 ig.Emit (OpCodes.Stloc, local_builder);
1435 ig.Emit (OpCodes.Ldloc, local_builder);
1438 } else if (binding is BuiltIn)
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
1445 emit_undeclared_assignment (ec);
1447 emit_undeclared_use (ig);
1450 Console.WriteLine ("Identifier.Emit, binding.GetType = {0}", binding.GetType ());
1452 if (!assign && no_effect && !undeclared)
1453 ig.Emit (OpCodes.Pop);
1456 private void emit_undeclared_assignment (EmitContext ec)
1458 ILGenerator ig = ec.ig;
1459 string name = this.name.Value;
1460 Type lb_type = typeof (LateBinding);
1461 bool in_function = InFunction;
1463 MethodInfo script_object_stack_top = typeof (VsaEngine).GetMethod ("ScriptObjectStackTop");
1464 Type iactivation_obj = typeof (IActivationObject);
1466 Label label_no_field = ig.DefineLabel ();
1467 Label label_end = ig.DefineLabel ();
1469 LocalBuilder lb_local = ig.DeclareLocal (lb_type);
1470 LocalBuilder field_builder = ig.DeclareLocal (typeof (FieldInfo));
1471 LocalBuilder tmp_helper = ig.DeclareLocal (typeof (object));
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);
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);
1488 ig.Emit (OpCodes.Ldloc, lb_local);
1490 right_side.Emit (ec);
1491 CodeGenerator.EmitBox (ec.ig, right_side);
1493 ig.Emit (OpCodes.Ldloc, field_builder);
1494 ig.Emit (OpCodes.Ldnull);
1495 ig.Emit (OpCodes.Beq_S, label_no_field);
1497 ig.Emit (OpCodes.Stloc, tmp_helper); // Store value
1498 ig.Emit (OpCodes.Pop); // Pop local builder
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) }));
1505 ig.Emit (OpCodes.Br_S, label_end);
1507 ig.MarkLabel (label_no_field);
1508 ig.Emit (OpCodes.Call, lb_type.GetMethod ("SetValue"));
1509 ig.MarkLabel (label_end);
1512 private void emit_undeclared_use (ILGenerator ig)
1514 Label merge = ig.DefineLabel ();
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);
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);
1533 // FIXME: compute the needed lexical level, for now is hardcoded
1534 ig.Emit (OpCodes.Ldc_I4_0);
1536 ig.Emit (OpCodes.Callvirt, iactivation_obj.GetMethod ("GetMemberValue"));
1537 ig.Emit (OpCodes.Dup);
1538 ig.Emit (OpCodes.Call, typeof (Binding).GetMethod ("IsMissing"));
1540 ig.Emit (OpCodes.Brfalse, merge);
1542 ig.Emit (OpCodes.Pop);
1544 ig.Emit (OpCodes.Ldloc, lb_local);
1545 ig.Emit (OpCodes.Call, lb_type.GetMethod ("GetValue2"));
1546 ig.MarkLabel (merge);
1549 internal void EmitStore (EmitContext ec)
1551 ILGenerator ig = ec.ig;
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);
1560 ig.Emit (OpCodes.Stloc, local);
1562 ig.Emit (OpCodes.Stsfld, fb);
1566 internal void EmitLoad (EmitContext ec)
1568 ILGenerator ig = ec.ig;
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);
1577 ig.Emit (OpCodes.Ldloc, local);
1579 ig.Emit (OpCodes.Ldsfld, fb);
1583 void load_script_func (EmitContext ec, FunctionDeclaration binding)
1585 object bind = TypeManager.Get (binding.func_obj.name);
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);
1594 FieldInfo method = type.GetField (binding.func_obj.name);
1595 ec.ig.Emit (OpCodes.Ldsfld, method);
1597 } else if (bind is LocalBuilder)
1598 ec.ig.Emit (OpCodes.Ldloc, (LocalBuilder) bind);
1599 else throw new Exception ("load_script_func");
1603 internal FieldInfo extract_field_info (AST a)
1607 if (a is VariableDeclaration)
1608 r = ((VariableDeclaration) a).field_info;
1610 r = ((Try) a).field_info;
1611 else if (a is Catch)
1612 r = ((Catch) a).field_info;
1616 internal LocalBuilder extract_local_builder (AST a)
1618 LocalBuilder r = null;
1619 if (a is VariableDeclaration)
1620 r = ((VariableDeclaration) a).local_builder;
1622 r = ((Try) a).local_builder;
1623 else if (a is Catch)
1624 r = ((Catch) a).local_builder;
1629 // FIXME: Only must store the extern variables which are used.
1631 internal void store_stack_frame_into_locals (ILGenerator ig)
1633 ig.Emit (OpCodes.Dup);
1635 Type stack_frame = typeof (StackFrame);
1636 ig.Emit (OpCodes.Castclass, stack_frame);
1637 ig.Emit (OpCodes.Ldfld, stack_frame.GetField ("localVars"));
1639 DictionaryEntry [] locals = TypeManager.LocalsAtDepth (((VariableDeclaration) binding).lexical_depth);
1642 LocalBuilder local = null;
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);
1655 ig.Emit (OpCodes.Pop);
1658 // FIXME: what does it determine this?
1660 ig.Emit (OpCodes.Call, typeof (ScriptObject).GetMethod ("GetParent"));
1661 ig.Emit (OpCodes.Pop);
1665 internal class Args : AST {
1667 private ArrayList elems;
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
1675 // - BuiltIn for methods from the GlobalObject
1677 internal object BoundToMethod;
1679 private bool BoundToDeclaredFunction {
1680 get { return BoundToMethod is Function; }
1683 private bool in_new = false;
1684 internal bool InNew {
1685 set { in_new = value; }
1686 get { return in_new; }
1689 private int expected_args = 0;
1690 private bool has_this = false;
1691 private bool var_args = false;
1692 private bool has_engine = false;
1694 internal Args (Location location)
1695 : base (null, location)
1697 elems = new ArrayList ();
1700 internal void Add (AST e)
1705 internal AST get_element (int i)
1707 if (0 <= i && i < elems.Count)
1708 return (AST) elems [i];
1720 internal override bool Resolve (Environment env)
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;
1738 expected_args = ((BuiltIn) BoundToMethod).NumOfArgs;
1744 int n = elems.Count;
1746 for (int i = 0; i < n; i++) {
1747 tmp = (AST) elems [i];
1750 r &= ((Exp) tmp).Resolve (env, false);
1752 r &= tmp.Resolve (env);
1757 internal override void Emit (EmitContext ec)
1759 bool strong_type = BoundToMethod is MethodInfo;
1760 ParameterInfo [] parameters = null;
1762 if (!BoundToDeclaredFunction) {
1771 if (expected_args < 0) {
1772 if (BoundToDeclaredFunction)
1773 expected_args = ((Function) BoundToMethod).NumOfArgs;
1775 throw new Exception ("expected_args can't be negative");
1779 // When BoundToMethod is null and the semantic
1780 // analysis passed means that the method is 'print'
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.
1787 // When the fix for calling just one time
1788 // Resolve is applied, this must be moved back
1791 if (BoundToMethod != null && !var_args) {
1792 if (elems.Count > expected_args) {
1794 location.SourceName + "(" + location.LineNumber + ",0) : " +
1795 "warning JS1148: There are too many arguments. The extra arguments will be ignored");
1797 if (elems.Count < expected_args) {
1798 string name = String.Empty;
1800 if (BoundToMethod is MethodInfo)
1801 name = ((MethodInfo) BoundToMethod).Name;
1802 else if (BoundToDeclaredFunction)
1803 name = ((Function) BoundToMethod).func_obj.name;
1805 Console.WriteLine (location.SourceName + "(" + location.LineNumber + ",0) : " +
1806 "warning JS1204: Not all required arguments have been supplied" +
1807 " to method " + name);
1811 if (BoundToMethod is MethodInfo)
1812 parameters = ((MethodInfo) BoundToMethod).GetParameters ();
1815 CodeGenerator.load_engine (InFunction, ec.ig);
1818 if (expected_args > 1)
1819 emit_default_args_case (ec, expected_args, strong_type, parameters);
1821 ILGenerator ig = ec.ig;
1823 int remains = elems.Count - expected_args;
1826 ig.Emit (OpCodes.Ldc_I4, remains);
1828 ig.Emit (OpCodes.Ldc_I4_0);
1830 ig.Emit (OpCodes.Newarr, typeof (object));
1832 int n = elems.Count;
1835 for (int j = expected_args, k = 0; j < n; j++, k++) {
1836 ast = get_element (j);
1838 ig.Emit (OpCodes.Dup);
1839 ig.Emit (OpCodes.Ldc_I4, k);
1841 CodeGenerator.EmitAssignAsExp (ec, ast);
1845 if (ast is Relational)
1846 CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
1848 CodeGenerator.EmitBox (ig, ast);
1850 ig.Emit (OpCodes.Stelem_Ref);
1854 emit_default_args_case (ec, expected_args, strong_type, parameters);
1857 internal void emit_default_args_case (EmitContext ec, int n, bool strong_type,
1858 ParameterInfo [] parameters)
1861 ILGenerator ig = ec.ig;
1863 // tracks the proper index of the formal params
1864 // from the strong typed method
1867 if (!BoundToDeclaredFunction) {
1874 for (int i = 0; i < n; i++, j++) {
1875 ast = get_element (i);
1877 if (ast is Assign) {
1878 CodeGenerator.EmitAssignAsExp (ec, ast);
1883 if (ast is Relational)
1884 CodeGenerator.EmitRelationalComp (ig, (Relational) ast);
1885 else if (strong_type)
1886 force_strong_type (ig, ast, parameters [j]);
1888 CodeGenerator.EmitBox (ig, ast);
1891 // ast was null and we need
1892 // to provide a parameter
1895 CodeGenerator.emit_default_value (ig, parameters [j]);
1897 ig.Emit (OpCodes.Ldsfld, typeof (Missing).GetField ("Value"));
1902 internal void force_strong_type (ILGenerator ig, AST ast, object obj)
1904 Type param_type = null;
1905 if (obj is ParameterInfo)
1906 param_type = ((ParameterInfo) obj).ParameterType;
1908 param_type = obj.GetType ();
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);
1916 throw new NotImplementedException ();
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) }));
1928 internal class Expression : Exp {
1930 internal ArrayList exprs;
1933 get { return exprs.Count; }
1936 internal Expression (AST parent, Location location)
1937 : base (parent, location)
1939 exprs = new ArrayList ();
1942 internal void Add (AST a)
1948 get { return (AST) exprs [Size - 1]; }
1951 public override string ToString ()
1953 int size = exprs.Count;
1957 StringBuilder sb = new StringBuilder ();
1959 for (i = 0; i < size; i++)
1960 sb.Append (exprs [i].ToString ());
1961 return sb.ToString ();
1962 } else return String.Empty;
1965 internal override bool Resolve (Environment env)
1971 n = exprs.Count - 1;
1973 for (i = 0; i < n; i++) {
1977 r &= ((Assign) e).Resolve (env);
1979 r &= ((Exp) e).Resolve (env, true);
1984 r &= ((Assign) e).Resolve (env);
1986 r &= ((Exp) e).Resolve (env, no_effect);
1988 ((AST) e).Resolve (env);
1993 internal override bool Resolve (Environment env, bool no_effect)
1995 this.no_effect = no_effect;
1996 return Resolve (env);
1999 internal override void Emit (EmitContext ec)
2001 int i, n = exprs.Count;
2004 for (i = 0; i < n; i++) {
2005 exp = (AST) exprs [i];
2007 CodeGenerator.EmitBox (ec.ig, exp);
2012 internal class Assign : BinaryOp {
2014 internal bool is_embedded;
2016 internal Assign (AST parent, JSToken op, Location location)
2017 : base (parent, null, null, op, location)
2021 internal void Init (AST left, AST right, bool is_embedded)
2025 this.is_embedded = is_embedded;
2029 // after calling Resolve, left contains all the
2030 // information about the assignment
2032 internal override bool Resolve (Environment env)
2036 if (left is IAssignable)
2037 r = ((IAssignable) left).ResolveAssign (env, right);
2039 throw new Exception (location.SourceName + " (" + location.LineNumber + ",0): error JS5008: Illegal assignment");
2041 r &=((Exp) right).Resolve (env, false);
2043 r &= right.Resolve (env);
2047 internal override bool Resolve (Environment env, bool no_effect)
2049 this.no_effect = no_effect;
2050 return Resolve (env);
2053 internal LocalBuilder EmitAndReturnBuilder (EmitContext ec)
2055 ILGenerator ig = ec.ig;
2056 LocalBuilder builder = ig.DeclareLocal (typeof (object));
2059 CodeGenerator.EmitBox (ig, right);
2060 ig.Emit (OpCodes.Stloc, builder);
2064 internal override void Emit (EmitContext ec)
2066 if (op == JSToken.Assign) {
2068 Console.WriteLine ("embedded assignments not supported yet");
2069 System.Environment.Exit (-1);
2073 ILGenerator ig = ec.ig;
2075 LocalBuilder local = null;
2076 LocalBuilder aux = ig.DeclareLocal (typeof (object));
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) {
2091 CodeGenerator.EmitBox (ig, right);
2093 ig.Emit (OpCodes.Call, type.GetMethod ("EvaluatePlus"));
2094 if (left is Identifier)
2095 ((Identifier) left).EmitStore (ec);
2097 case JSToken.MinusAssign:
2098 case JSToken.MultiplyAssign:
2099 case JSToken.DivideAssign:
2100 case JSToken.ModuloAssign:
2101 type = typeof (NumericBinary);
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);
2112 local = ig.DeclareLocal (type);
2113 load_parameter (ig, op);
2115 ig.Emit (OpCodes.Newobj, type.GetConstructor (new Type [] {typeof (int)}));
2116 ig.Emit (OpCodes.Stloc, local);
2118 if (left is Identifier)
2119 ((Identifier) left).EmitLoad (ec);
2121 ig.Emit (OpCodes.Stloc, aux);
2122 ig.Emit (OpCodes.Ldloc, local);
2123 ig.Emit (OpCodes.Ldloc, aux);
2125 if (right != null) {
2127 CodeGenerator.EmitBox (ig, right);
2130 emit_evaluation (op, type, ig);
2132 if (left is Identifier)
2133 ((Identifier) left).EmitStore (ec);
2137 void load_parameter (ILGenerator ig, JSToken op)
2140 case JSToken.MinusAssign:
2141 ig.Emit (OpCodes.Ldc_I4_S, 47);
2143 case JSToken.BitwiseOrAssign:
2144 ig.Emit (OpCodes.Ldc_I4_S, 50);
2146 case JSToken.BitwiseXorAssign:
2147 ig.Emit (OpCodes.Ldc_I4_S, 51);
2149 case JSToken.BitwiseAndAssign:
2150 ig.Emit (OpCodes.Ldc_I4_S, 52);
2152 case JSToken.LeftShiftAssign:
2153 ig.Emit (OpCodes.Ldc_I4_S, 61);
2155 case JSToken.RightShiftAssign:
2156 ig.Emit (OpCodes.Ldc_I4_S, 62);
2158 case JSToken.UnsignedRightShiftAssign:
2159 ig.Emit (OpCodes.Ldc_I4_S, 63);
2161 case JSToken.MultiplyAssign:
2162 ig.Emit (OpCodes.Ldc_I4_S, 64);
2164 case JSToken.DivideAssign:
2165 ig.Emit (OpCodes.Ldc_I4_S, 65);
2167 case JSToken.ModuloAssign:
2168 ig.Emit (OpCodes.Ldc_I4_S, 66);
2171 throw new NotImplementedException ();
2175 void emit_evaluation (JSToken op, Type type, ILGenerator ig)
2178 case JSToken.MinusAssign:
2179 case JSToken.MultiplyAssign:
2180 case JSToken.DivideAssign:
2181 case JSToken.ModuloAssign:
2182 ig.Emit (OpCodes.Call, type.GetMethod ("EvaluateNumericBinary"));
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"));
2193 throw new NotImplementedException ();
2198 public override string ToString ()
2200 string l = left.ToString ();
2201 string r = right.ToString ();
2202 return l + " " + op.ToString () + " " + r;
2206 internal class New : AST, ICallable {
2210 bool late_bind = false;
2212 internal New (AST parent, AST exp, Location location)
2213 : base (parent, location)
2216 this.args = new Args (location);
2219 public void AddArg (AST arg)
2224 internal override bool Resolve (Environment env)
2228 if (exp != null && exp.GetType () == typeof (Identifier)) {
2229 Identifier id = (Identifier) exp;
2230 late_bind = !SemanticAnalyser.is_js_object (id.name.Value);
2236 r &= args.Resolve (env);
2241 internal override void Emit (EmitContext ec)
2243 ILGenerator ig = ec.ig;
2248 CodeGenerator.emit_get_default_this (ec.ig, InFunction);
2251 ig.Emit (OpCodes.Ldc_I4, args.Size);
2252 ig.Emit (OpCodes.Newarr, typeof (object));
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);
2260 CodeGenerator.EmitAssignAsExp (ec, ast);
2263 CodeGenerator.EmitBox (ig, ast);
2265 ig.Emit (OpCodes.Stelem_Ref);
2268 ig.Emit (OpCodes.Ldc_I4_1);
2269 ig.Emit (OpCodes.Ldc_I4_0);
2271 CodeGenerator.load_engine (InFunction, ig);
2273 ig.Emit (OpCodes.Call, typeof (LateBinding).GetMethod ("CallValue"));
2279 emit_create_instance (ec);
2284 void emit_create_instance (EmitContext ec)
2286 if (exp is Identifier) {
2287 ILGenerator ig = ec.ig;
2289 switch ((exp as Identifier).name.Value) {
2291 type = typeof (ArrayConstructor);
2294 type = typeof (DateConstructor);
2297 type = typeof (NumberConstructor);
2300 type = typeof (ObjectConstructor);
2303 type = typeof (RegExpConstructor);
2306 type = typeof (StringConstructor);
2309 type = typeof (BooleanConstructor);
2312 type = typeof (FunctionConstructor);
2316 ig.Emit (OpCodes.Call, type.GetMethod ("CreateInstance"));
2318 throw new NotImplementedException (String.Format (
2319 "Should emit LateBinding.CallValue logic for unknown constructor {0}",
2320 (exp as Identifier).name.Value));
2324 void emit_args (EmitContext ec)
2326 ILGenerator ig = ec.ig;
2328 ig.Emit (OpCodes.Ldc_I4, args.Size);
2329 ig.Emit (OpCodes.Newarr, typeof (object));
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);
2339 CodeGenerator.EmitAssignAsExp (ec, ast);
2342 CodeGenerator.EmitBox (ig, ast);
2344 ig.Emit (OpCodes.Stelem_Ref);
2349 internal interface IAssignable {
2350 bool ResolveAssign (Environment env, AST right_side);
2353 internal class BuiltIn : AST {
2355 bool allowed_as_ctr;
2356 bool allowed_as_func;
2358 internal BuiltIn (string name, bool allowed_as_ctr, bool allowed_as_func)
2362 this.allowed_as_ctr = allowed_as_ctr;
2363 this.allowed_as_func = allowed_as_func;
2366 internal override bool Resolve (Environment env)
2371 internal string Name {
2372 get { return name; }
2375 internal bool IsConstructor {
2376 get { return allowed_as_ctr; }
2379 internal bool IsFunction {
2380 get { return allowed_as_func; }
2383 internal bool IsPrint {
2384 get { return String.Equals (name, "print"); }
2386 internal int NumOfArgs {
2388 if (name == "print")
2391 Type global_object = typeof (GlobalObject);
2392 MethodInfo method = global_object.GetMethod (name);
2393 return method.GetParameters ().Length;
2397 internal ParameterInfo [] Parameters {
2399 Type global_obj = typeof (GlobalObject);
2400 return global_obj.GetMethod (name).GetParameters ();
2404 internal override void Emit (EmitContext ec)
2406 ILGenerator ig = ec.ig;
2407 Type go = typeof (GlobalObject);
2409 /* value properties of the Global Object */
2411 ig.Emit (OpCodes.Ldc_R8, Double.NaN);
2415 ig.Emit (OpCodes.Ldc_R8, Double.PositiveInfinity);
2419 ig.Emit (OpCodes.Ldnull);
2423 ig.Emit (OpCodes.Ldsfld, typeof (DBNull).GetField ("Value"));
2426 /* function properties of the Global Object */
2428 Type [] method_args = null;
2430 method_args = new Type [] {typeof (object), typeof (VsaEngine)};
2432 method_args = new Type [] {typeof (object), typeof (object), typeof (VsaEngine)};
2434 ig.Emit (OpCodes.Call, typeof (Eval).GetMethod ("JScriptEvaluate", method_args));
2438 ig.Emit (OpCodes.Call, go.GetMethod ("parseInt"));
2439 ig.Emit (OpCodes.Box, typeof (Double));
2443 ig.Emit (OpCodes.Call, go.GetMethod ("parseFloat"));
2444 ig.Emit (OpCodes.Box, typeof (Double));
2448 ig.Emit (OpCodes.Call, go.GetMethod ("isNaN"));
2449 ig.Emit (OpCodes.Box, typeof (bool));
2453 ig.Emit (OpCodes.Call, go.GetMethod ("isFinite"));
2454 ig.Emit (OpCodes.Box, typeof (bool));
2458 ig.Emit (OpCodes.Call, go.GetMethod ("decodeURI"));
2461 case "decodeURIComponent":
2462 ig.Emit (OpCodes.Call, go.GetMethod ("decodeURIComponent"));
2466 ig.Emit (OpCodes.Call, go.GetMethod ("encodeURI"));
2469 case "encodeURIComponent":
2470 ig.Emit (OpCodes.Call, go.GetMethod ("encodeURIComponent"));
2474 ig.Emit (OpCodes.Call, go.GetMethod ("escape"));
2478 ig.Emit (OpCodes.Call, go.GetMethod ("unescape"));
2481 /* constructor properties of the Global object */
2483 ig.Emit (OpCodes.Call, go.GetProperty ("Object").GetGetMethod ());
2487 ig.Emit (OpCodes.Call, go.GetProperty ("Function").GetGetMethod ());
2491 ig.Emit (OpCodes.Call, go.GetProperty ("Array").GetGetMethod ());
2495 ig.Emit (OpCodes.Call, go.GetProperty ("String").GetGetMethod ());
2499 ig.Emit (OpCodes.Call, go.GetProperty ("Boolean").GetGetMethod ());
2503 ig.Emit (OpCodes.Call, go.GetProperty ("Number").GetGetMethod ());
2507 ig.Emit (OpCodes.Call, go.GetProperty ("Date").GetGetMethod ());
2511 ig.Emit (OpCodes.Call, go.GetProperty ("RegExp").GetGetMethod ());
2515 ig.Emit (OpCodes.Call, go.GetProperty ("Error").GetGetMethod ());
2519 ig.Emit (OpCodes.Call, go.GetProperty ("EvalError").GetGetMethod ());
2523 ig.Emit (OpCodes.Call, go.GetProperty ("RangeError").GetGetMethod ());
2526 case "ReferenceError":
2527 ig.Emit (OpCodes.Call, go.GetProperty ("ReferenceError").GetGetMethod ());
2531 ig.Emit (OpCodes.Call, go.GetProperty ("SyntaxError").GetGetMethod ());
2535 ig.Emit (OpCodes.Call, go.GetProperty ("TypeError").GetGetMethod ());
2539 ig.Emit (OpCodes.Call, go.GetProperty ("URIError").GetGetMethod ());
2541 /* other properties of the Global object */
2543 ig.Emit (OpCodes.Call, go.GetProperty ("Math").GetGetMethod ());
2546 throw new Exception ("This is BuiltIn " + name);