static void ff_emit_relational(EmitContext ec, AST ast, Label lbl) { ILGenerator ig = ec.ig; Relational r = ast as Relational; r.Emit(ec); OpCode opcode; switch (r.op) { case JSToken.LessThan: opcode = OpCodes.Blt; break; case JSToken.GreaterThan: opcode = OpCodes.Bgt; break; case JSToken.LessThanEqual: opcode = OpCodes.Ble; break; case JSToken.GreaterThanEqual: opcode = OpCodes.Bge; break; default: throw new Exception("unexpected token"); } ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Conv_R8); ig.Emit(opcode, lbl); }
// Uses a built-in compare function internal static sbyte nativeCompare(Hashtable elems, bool b1, object o1_, uint i2) { bool b2 = !elems.ContainsKey(i2); if (b1 && b2) { return(0); } else if (b1) { return(1); } else if (b2) { return(-1); } IComparable o1 = o1_ as IComparable; IComparable o2 = elems [i2] as IComparable; if (o1 == null && o2 == null) { return(0); } if (o1 == null) { return(1); } else if (o2 == null) { return(-1); } return((sbyte)Relational.JScriptCompare(o1, o2)); }
internal static void EmitRelationalComp(ILGenerator ig, Relational re) { JSToken op = re.op; if (op == JSToken.Instanceof) { return; } else if (op == JSToken.In) { ig.Emit(OpCodes.Box, typeof(bool)); return; } Label true_case = ig.DefineLabel(); Label box_to_bool = ig.DefineLabel(); ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Conv_R8); OpCode opcode; switch (op) { case JSToken.LessThan: opcode = OpCodes.Blt; break; case JSToken.LessThanEqual: opcode = OpCodes.Ble; break; case JSToken.GreaterThan: opcode = OpCodes.Bgt; break; case JSToken.GreaterThanEqual: opcode = OpCodes.Bge; break; default: Console.WriteLine(re.Location.LineNumber); throw new NotImplementedException(); } ig.Emit(opcode, true_case); ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Br, box_to_bool); ig.MarkLabel(true_case); ig.Emit(OpCodes.Ldc_I4_1); ig.MarkLabel(box_to_bool); ig.Emit(OpCodes.Box, typeof(bool)); }
static void ft_emit_relational(EmitContext ec, Relational re, Label lbl) { ILGenerator ig = ec.ig; re.Emit(ec); JSToken op = re.op; OpCode opcode; switch (op) { case JSToken.LessThan: opcode = OpCodes.Bge_Un; break; case JSToken.GreaterThan: opcode = OpCodes.Ble_Un; break; case JSToken.LessThanEqual: opcode = OpCodes.Bgt_Un; break; case JSToken.GreaterThanEqual: opcode = OpCodes.Blt_Un; break; default: Console.WriteLine(re.Location.LineNumber); throw new NotImplementedException(); } ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Conv_R8); ig.Emit(opcode, lbl); }
AST RelExpr(AST parent, bool in_for_init) { AST pn = ShiftExpr (parent); for (;;) { int tt = ts.PeekToken (); if (tt == Token.IN) { if (in_for_init) break; else { ts.GetToken (); decompiler.AddToken (tt); pn = new Relational (parent, pn, ShiftExpr (parent), ToJSToken (tt), new Location (ts.SourceName, ts.LineNumber)); continue; } } else if (tt == Token.INSTANCEOF || tt == Token.LE || tt == Token.LT || tt == Token.GE || tt == Token.GT) { ts.GetToken (); decompiler.AddToken (tt); pn = new Relational (parent, pn, ShiftExpr (parent), ToJSToken (tt), new Location (ts.SourceName, ts.LineNumber)); continue; } break; } return pn; }
private static Type GetBoxType(object obj) { if (obj is ByteConstant || obj is ShortConstant || obj is IntConstant) { return(typeof(int)); } else if (obj is LongConstant) { return(typeof(long)); } else if (obj is FloatConstant || obj is DoubleConstant) { return(typeof(double)); } else if (obj is BooleanConstant || obj is StrictEquality || obj is Equality) { return(typeof(bool)); } else if (obj is Unary) { Unary unary = (Unary)obj; JSToken oper = unary.oper; AST operand = unary.operand; if (oper == JSToken.Minus || oper == JSToken.Plus || oper == JSToken.Increment || oper == JSToken.Decrement || oper == JSToken.BitwiseNot) { return(GetBoxType(operand)); } else if (oper == JSToken.LogicalNot || oper == JSToken.Delete) { return(typeof(bool)); } } else if (obj is Identifier) { Identifier id = (Identifier)obj; string name = id.name.Value; if (name == "NaN" || name == "Infinity") { return(typeof(double)); } } else if (obj is Binary) { Binary bin = obj as Binary; if (bin.AccessField && !bin.LateBinding) { MemberInfo binding = bin.Binding; MemberTypes member_type = binding.MemberType; if (member_type == MemberTypes.Property) { return(((PropertyInfo)binding).PropertyType); } } } else if (obj is Relational) { Relational re = (Relational)obj; if (re.op == JSToken.In) { return(typeof(bool)); } } return(null); }
static void ft_emit_relational(EmitContext ec, Relational re, Label lbl) { ILGenerator ig = ec.ig; re.Emit (ec); JSToken op = re.op; OpCode opcode; switch (op) { case JSToken.LessThan: opcode = OpCodes.Bge_Un; break; case JSToken.GreaterThan: opcode = OpCodes.Ble_Un; break; case JSToken.LessThanEqual: opcode = OpCodes.Bgt_Un; break; case JSToken.GreaterThanEqual: opcode = OpCodes.Blt_Un; break; default: Console.WriteLine (re.Location.LineNumber); throw new NotImplementedException (); } ig.Emit (OpCodes.Ldc_I4_0); ig.Emit (OpCodes.Conv_R8); ig.Emit (opcode, lbl); }
internal static void EmitRelationalComp(ILGenerator ig, Relational re) { JSToken op = re.op; if (op == JSToken.Instanceof) return; else if (op == JSToken.In) { ig.Emit (OpCodes.Box, typeof (bool)); return; } Label true_case = ig.DefineLabel (); Label box_to_bool = ig.DefineLabel (); ig.Emit (OpCodes.Ldc_I4_0); ig.Emit (OpCodes.Conv_R8); OpCode opcode; switch (op) { case JSToken.LessThan: opcode = OpCodes.Blt; break; case JSToken.LessThanEqual: opcode = OpCodes.Ble; break; case JSToken.GreaterThan: opcode = OpCodes.Bgt; break; case JSToken.GreaterThanEqual: opcode = OpCodes.Bge; break; default: Console.WriteLine (re.Location.LineNumber); throw new NotImplementedException (); } ig.Emit (opcode, true_case); ig.Emit (OpCodes.Ldc_I4_0); ig.Emit (OpCodes.Br, box_to_bool); ig.MarkLabel (true_case); ig.Emit (OpCodes.Ldc_I4_1); ig.MarkLabel (box_to_bool); ig.Emit (OpCodes.Box, typeof (bool)); }
internal override void Emit(EmitContext ec) { AST tmp; ILGenerator ig = ec.ig; Label old_begin = ec.LoopBegin; Label old_end = ec.LoopEnd; Label back = ig.DefineLabel(); Label forward = ig.DefineLabel(); /* emit init expr */ tmp = exprs [0]; if (tmp != null) { tmp.Emit(ec); } ec.LoopBegin = ig.DefineLabel(); ec.LoopEnd = ig.DefineLabel(); ig.MarkLabel(back); ig.MarkLabel(ec.LoopBegin); /* emit condition */ tmp = exprs [1]; if (tmp != null) { tmp.Emit(ec); } if (tmp != null && tmp is Expression) { ArrayList t = ((Expression)tmp).exprs; AST a = (AST)t [t.Count - 1]; if (a is Equality) { ig.Emit(OpCodes.Brfalse, forward); } else if (a is Relational) { Relational rel = (Relational)a; ig.Emit(OpCodes.Ldc_I4_0); ig.Emit(OpCodes.Conv_R8); if (rel.op == JSToken.GreaterThan) { ig.Emit(OpCodes.Ble, forward); } else { ig.Emit(OpCodes.Bge, forward); } } } /* emit stms */ if (stms != null) { stms.Emit(ec); } if (parent.GetType() == typeof(Labelled)) { ig.MarkLabel((parent as Labelled).InitAddrs); } tmp = exprs [2]; /* emit increment */ if (tmp != null) { tmp.Emit(ec); } ig.Emit(OpCodes.Br, back); ig.MarkLabel(forward); ig.MarkLabel(ec.LoopEnd); ec.LoopBegin = old_begin; ec.LoopEnd = old_end; }