Inheritance: BinaryOp
Example #1
0
        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);
        }
Example #2
0
            // 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));
            }
Example #3
0
        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));
        }
Example #4
0
        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);
        }
Example #5
0
 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;
 }
Example #6
0
        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);
        }
Example #7
0
        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);
        }
Example #8
0
        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));
        }
Example #9
0
        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;
        }