Example #1
0
        public void ToInteger_Test()
        {
            var function = new ToInteger();

            var result = function.Evaluate("01");

            Assert.AreEqual(1, result);
        }
Example #2
0
        public static InstructionCollection Parse(Stream input, long instructionsPosition)
        {
            var instructions = new SortedList <int, InstructionBase>();

            using (var helper = new InstructionParseHelper(input, instructionsPosition))
            {
                var reader = helper.GetReader();
                while (helper.CanParse(instructions))
                {
                    //now reader the instructions
                    var instructionPosition = helper.CurrentPosition;
                    var type             = reader.ReadByteAsEnum <InstructionType>();
                    var requireAlignment = InstructionAlignment.IsAligned(type);

                    if (requireAlignment)
                    {
                        reader.Align(4);
                    }

                    InstructionBase instruction = null;
                    var             parameters  = new List <Value>();

                    switch (type)
                    {
                    case InstructionType.ToNumber:
                        instruction = new ToNumber();
                        break;

                    case InstructionType.NextFrame:
                        instruction = new NextFrame();
                        break;

                    case InstructionType.Play:
                        instruction = new Play();
                        break;

                    case InstructionType.Stop:
                        instruction = new Stop();
                        break;

                    case InstructionType.Add:
                        instruction = new Add();
                        break;

                    case InstructionType.Subtract:
                        instruction = new Subtract();
                        break;

                    case InstructionType.Multiply:
                        instruction = new Multiply();
                        break;

                    case InstructionType.Divide:
                        instruction = new Divide();
                        break;

                    case InstructionType.Not:
                        instruction = new Not();
                        break;

                    case InstructionType.StringEquals:
                        instruction = new StringEquals();
                        break;

                    case InstructionType.Pop:
                        instruction = new Pop();
                        break;

                    case InstructionType.ToInteger:
                        instruction = new ToInteger();
                        break;

                    case InstructionType.GetVariable:
                        instruction = new GetVariable();
                        break;

                    case InstructionType.SetVariable:
                        instruction = new SetVariable();
                        break;

                    case InstructionType.StringConcat:
                        instruction = new StringConcat();
                        break;

                    case InstructionType.GetProperty:
                        instruction = new GetProperty();
                        break;

                    case InstructionType.SetProperty:
                        instruction = new SetProperty();
                        break;

                    case InstructionType.Trace:
                        instruction = new Trace();
                        break;

                    case InstructionType.Random:
                        instruction = new RandomNumber();
                        break;

                    case InstructionType.Delete:
                        instruction = new Delete();
                        break;

                    case InstructionType.Delete2:
                        instruction = new Delete2();
                        break;

                    case InstructionType.DefineLocal:
                        instruction = new DefineLocal();
                        break;

                    case InstructionType.CallFunction:
                        instruction = new CallFunction();
                        break;

                    case InstructionType.Return:
                        instruction = new Return();
                        break;

                    case InstructionType.Modulo:
                        instruction = new Modulo();
                        break;

                    case InstructionType.NewObject:
                        instruction = new NewObject();
                        break;

                    case InstructionType.InitArray:
                        instruction = new InitArray();
                        break;

                    case InstructionType.InitObject:
                        instruction = new InitObject();
                        break;

                    case InstructionType.TypeOf:
                        instruction = new TypeOf();
                        break;

                    case InstructionType.Add2:
                        instruction = new Add2();
                        break;

                    case InstructionType.LessThan2:
                        instruction = new LessThan2();
                        break;

                    case InstructionType.Equals2:
                        instruction = new Equals2();
                        break;

                    case InstructionType.ToString:
                        instruction = new ToString();
                        break;

                    case InstructionType.PushDuplicate:
                        instruction = new PushDuplicate();
                        break;

                    case InstructionType.GetMember:
                        instruction = new GetMember();
                        break;

                    case InstructionType.SetMember:
                        instruction = new SetMember();
                        break;

                    case InstructionType.Increment:
                        instruction = new Increment();
                        break;

                    case InstructionType.Decrement:
                        instruction = new Decrement();
                        break;

                    case InstructionType.CallMethod:
                        instruction = new CallMethod();
                        break;

                    case InstructionType.Enumerate2:
                        instruction = new Enumerate2();
                        break;

                    case InstructionType.EA_PushThis:
                        instruction = new PushThis();
                        break;

                    case InstructionType.EA_PushZero:
                        instruction = new PushZero();
                        break;

                    case InstructionType.EA_PushOne:
                        instruction = new PushOne();
                        break;

                    case InstructionType.EA_CallFunc:
                        instruction = new CallFunc();
                        break;

                    case InstructionType.EA_CallMethodPop:
                        instruction = new CallMethodPop();
                        break;

                    case InstructionType.BitwiseXOr:
                        instruction = new BitwiseXOr();
                        break;

                    case InstructionType.Greater:
                        instruction = new Greater();
                        break;

                    case InstructionType.EA_PushThisVar:
                        instruction = new PushThisVar();
                        break;

                    case InstructionType.EA_PushGlobalVar:
                        instruction = new PushGlobalVar();
                        break;

                    case InstructionType.EA_ZeroVar:
                        instruction = new ZeroVar();
                        break;

                    case InstructionType.EA_PushTrue:
                        instruction = new PushTrue();
                        break;

                    case InstructionType.EA_PushFalse:
                        instruction = new PushFalse();
                        break;

                    case InstructionType.EA_PushNull:
                        instruction = new PushNull();
                        break;

                    case InstructionType.EA_PushUndefined:
                        instruction = new PushUndefined();
                        break;

                    case InstructionType.GotoFrame:
                        instruction = new GotoFrame();
                        parameters.Add(Value.FromInteger(reader.ReadInt32()));
                        break;

                    case InstructionType.GetURL:
                        instruction = new GetUrl();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.SetRegister:
                        instruction = new SetRegister();
                        parameters.Add(Value.FromInteger(reader.ReadInt32()));
                        break;

                    case InstructionType.ConstantPool:
                    {
                        instruction = new ConstantPool();
                        var count     = reader.ReadUInt32();
                        var constants = reader.ReadFixedSizeArrayAtOffset <uint>(() => reader.ReadUInt32(), count);

                        foreach (var constant in constants)
                        {
                            parameters.Add(Value.FromConstant(constant));
                        }
                    }
                    break;

                    case InstructionType.GotoLabel:
                        instruction = new GotoLabel();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.DefineFunction2:
                    {
                        instruction = new DefineFunction2();
                        var name       = reader.ReadStringAtOffset();
                        var nParams    = reader.ReadUInt32();
                        var nRegisters = reader.ReadByte();
                        var flags      = reader.ReadUInt24();

                        //list of parameter strings
                        var paramList = reader.ReadFixedSizeListAtOffset <FunctionArgument>(() => new FunctionArgument()
                            {
                                Register  = reader.ReadInt32(),
                                Parameter = reader.ReadStringAtOffset(),
                            }, nParams);

                        parameters.Add(Value.FromString(name));
                        parameters.Add(Value.FromInteger((int)nParams));
                        parameters.Add(Value.FromInteger((int)nRegisters));
                        parameters.Add(Value.FromInteger((int)flags));
                        foreach (var param in paramList)
                        {
                            parameters.Add(Value.FromInteger(param.Register));
                            parameters.Add(Value.FromString(param.Parameter));
                        }
                        //body size of the function
                        parameters.Add(Value.FromInteger(reader.ReadInt32()));
                        //skip 8 bytes
                        reader.ReadUInt64();
                    }
                    break;

                    case InstructionType.PushData:
                    {
                        instruction = new PushData();

                        var count     = reader.ReadUInt32();
                        var constants = reader.ReadFixedSizeArrayAtOffset <uint>(() => reader.ReadUInt32(), count);

                        foreach (var constant in constants)
                        {
                            parameters.Add(Value.FromConstant(constant));
                        }
                    }
                    break;

                    case InstructionType.BranchAlways:
                    {
                        instruction = new BranchAlways();
                        var offset = reader.ReadInt32();
                        parameters.Add(Value.FromInteger(offset));
                        helper.ReportBranchOffset(offset);
                    }
                    break;

                    case InstructionType.GetURL2:
                        instruction = new GetUrl2();
                        break;

                    case InstructionType.DefineFunction:
                    {
                        instruction = new DefineFunction();
                        var name = reader.ReadStringAtOffset();
                        //list of parameter strings
                        var paramList = reader.ReadListAtOffset <string>(() => reader.ReadStringAtOffset());

                        parameters.Add(Value.FromString(name));
                        parameters.Add(Value.FromInteger(paramList.Count));
                        foreach (var param in paramList)
                        {
                            parameters.Add(Value.FromString(param));
                        }
                        //body size of the function
                        parameters.Add(Value.FromInteger(reader.ReadInt32()));
                        //skip 8 bytes
                        reader.ReadUInt64();
                    }
                    break;

                    case InstructionType.BranchIfTrue:
                    {
                        instruction = new BranchIfTrue();
                        var offset = reader.ReadInt32();
                        parameters.Add(Value.FromInteger(offset));
                        helper.ReportBranchOffset(offset);
                    }
                    break;

                    case InstructionType.GotoFrame2:
                        instruction = new GotoFrame2();
                        parameters.Add(Value.FromInteger(reader.ReadInt32()));
                        break;

                    case InstructionType.EA_PushString:
                        instruction = new PushString();
                        //the constant id that should be pushed
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.EA_PushConstantByte:
                        instruction = new PushConstantByte();
                        //the constant id that should be pushed
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_GetStringVar:
                        instruction = new GetStringVar();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.EA_SetStringVar:
                        instruction = new SetStringVar();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.EA_GetStringMember:
                        instruction = new GetStringMember();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.EA_SetStringMember:
                        instruction = new SetStringMember();
                        parameters.Add(Value.FromString(reader.ReadStringAtOffset()));
                        break;

                    case InstructionType.EA_PushValueOfVar:
                        instruction = new PushValueOfVar();
                        //the constant id that should be pushed
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_GetNamedMember:
                        instruction = new GetNamedMember();
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_CallNamedFuncPop:
                        instruction = new CallNamedFuncPop();
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_CallNamedFunc:
                        instruction = new CallNamedFunc();
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_CallNamedMethodPop:
                        instruction = new CallNamedMethodPop();
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.EA_PushFloat:
                        instruction = new PushFloat();
                        parameters.Add(Value.FromFloat(reader.ReadSingle()));
                        break;

                    case InstructionType.EA_PushByte:
                        instruction = new PushByte();
                        parameters.Add(Value.FromInteger(reader.ReadByte()));
                        break;

                    case InstructionType.EA_PushShort:
                        instruction = new PushShort();
                        parameters.Add(Value.FromInteger(reader.ReadUInt16()));
                        break;

                    case InstructionType.End:
                        instruction = new End();
                        break;

                    case InstructionType.EA_CallNamedMethod:
                        instruction = new CallNamedMethod();
                        parameters.Add(Value.FromConstant(reader.ReadByte()));
                        break;

                    case InstructionType.Var:
                        instruction = new Var();
                        break;

                    case InstructionType.EA_PushRegister:
                        instruction = new PushRegister();
                        parameters.Add(Value.FromInteger(reader.ReadByte()));
                        break;

                    case InstructionType.EA_PushConstantWord:
                        instruction = new PushConstantWord();
                        parameters.Add(Value.FromConstant(reader.ReadUInt16()));
                        break;

                    case InstructionType.EA_CallFuncPop:
                        instruction = new CallFunctionPop();
                        break;

                    case InstructionType.StrictEqual:
                        instruction = new StrictEquals();
                        break;

                    default:
                        throw new InvalidDataException("Unimplemented bytecode instruction:" + type.ToString());
                    }

                    if (instruction != null)
                    {
                        instruction.Parameters = parameters;
                        instructions.Add(instructionPosition, instruction);
                    }
                }
            }

            return(new InstructionCollection(instructions));
        }
Example #3
0
        public void Parse()
        {
            var current = _reader.BaseStream.Position;

            _reader.BaseStream.Seek(_offset, SeekOrigin.Begin);
            bool parsing     = true;
            bool branched    = false;
            int  branchBytes = 0;

            while (parsing)
            {
                //now reader the instructions
                var type    = _reader.ReadByteAsEnum <InstructionType>();
                var aligned = InstructionAlignment.IsAligned(type);

                if (aligned)
                {
                    var padding = _reader.Align(4);
                    if (padding > 0)
                    {
                        Items.Add(new Padding(padding));
                        if (branched)
                        {
                            branchBytes -= (int)padding;

                            if (branchBytes <= 0)
                            {
                                branched    = false;
                                branchBytes = 0;
                            }
                        }
                    }
                }

                InstructionBase instruction = null;
                List <Value>    parameters  = new List <Value>();

                switch (type)
                {
                case InstructionType.ToNumber:
                    instruction = new ToNumber();
                    break;

                case InstructionType.NextFrame:
                    instruction = new NextFrame();
                    break;

                case InstructionType.Play:
                    instruction = new Play();
                    break;

                case InstructionType.Stop:
                    instruction = new Stop();
                    break;

                case InstructionType.Add:
                    instruction = new Add();
                    break;

                case InstructionType.Subtract:
                    instruction = new Subtract();
                    break;

                case InstructionType.Multiply:
                    instruction = new Multiply();
                    break;

                case InstructionType.Divide:
                    instruction = new Divide();
                    break;

                case InstructionType.Not:
                    instruction = new Not();
                    break;

                case InstructionType.StringEquals:
                    instruction = new StringEquals();
                    break;

                case InstructionType.Pop:
                    instruction = new Pop();
                    break;

                case InstructionType.ToInteger:
                    instruction = new ToInteger();
                    break;

                case InstructionType.GetVariable:
                    instruction = new GetVariable();
                    break;

                case InstructionType.SetVariable:
                    instruction = new SetVariable();
                    break;

                case InstructionType.StringConcat:
                    instruction = new StringConcat();
                    break;

                case InstructionType.GetProperty:
                    instruction = new GetProperty();
                    break;

                case InstructionType.SetProperty:
                    instruction = new SetProperty();
                    break;

                case InstructionType.Trace:
                    instruction = new Trace();
                    break;

                case InstructionType.Delete:
                    instruction = new Delete();
                    break;

                case InstructionType.Delete2:
                    instruction = new Delete2();
                    break;

                case InstructionType.DefineLocal:
                    instruction = new DefineLocal();
                    break;

                case InstructionType.CallFunction:
                    instruction = new CallFunction();
                    break;

                case InstructionType.Return:
                    instruction = new Return();
                    break;

                case InstructionType.NewObject:
                    instruction = new NewObject();
                    break;

                case InstructionType.InitArray:
                    instruction = new InitArray();
                    break;

                case InstructionType.InitObject:
                    instruction = new InitObject();
                    break;

                case InstructionType.TypeOf:
                    instruction = new InitObject();
                    break;

                case InstructionType.Add2:
                    instruction = new Add2();
                    break;

                case InstructionType.LessThan2:
                    instruction = new LessThan2();
                    break;

                case InstructionType.Equals2:
                    instruction = new Equals2();
                    break;

                case InstructionType.ToString:
                    instruction = new ToString();
                    break;

                case InstructionType.PushDuplicate:
                    instruction = new PushDuplicate();
                    break;

                case InstructionType.GetMember:
                    instruction = new GetMember();
                    break;

                case InstructionType.SetMember:
                    instruction = new SetMember();
                    break;

                case InstructionType.Increment:
                    instruction = new Increment();
                    break;

                case InstructionType.Decrement:
                    instruction = new Decrement();
                    break;

                case InstructionType.CallMethod:
                    instruction = new CallMethod();
                    break;

                case InstructionType.Enumerate2:
                    instruction = new Enumerate2();
                    break;

                case InstructionType.EA_PushThis:
                    instruction = new PushThis();
                    break;

                case InstructionType.EA_PushZero:
                    instruction = new PushZero();
                    break;

                case InstructionType.EA_PushOne:
                    instruction = new PushOne();
                    break;

                case InstructionType.EA_CallFunc:
                    instruction = new CallFunc();
                    break;

                case InstructionType.EA_CallMethodPop:
                    instruction = new CallMethodPop();
                    break;

                case InstructionType.BitwiseXOr:
                    instruction = new BitwiseXOr();
                    break;

                case InstructionType.Greater:
                    instruction = new Greater();
                    break;

                case InstructionType.EA_PushThisVar:
                    instruction = new PushThisVar();
                    break;

                case InstructionType.EA_PushGlobalVar:
                    instruction = new PushGlobalVar();
                    break;

                case InstructionType.EA_ZeroVar:
                    instruction = new ZeroVar();
                    break;

                case InstructionType.EA_PushTrue:
                    instruction = new PushTrue();
                    break;

                case InstructionType.EA_PushFalse:
                    instruction = new PushFalse();
                    break;

                case InstructionType.EA_PushNull:
                    instruction = new PushNull();
                    break;

                case InstructionType.EA_PushUndefined:
                    instruction = new PushUndefined();
                    break;

                case InstructionType.GotoFrame:
                    instruction = new GotoFrame();
                    parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    break;

                case InstructionType.GetURL:
                    instruction = new GetUrl();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.SetRegister:
                    instruction = new SetRegister();
                    parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    break;

                case InstructionType.ConstantPool:
                {
                    instruction = new ConstantPool();
                    var count     = _reader.ReadUInt32();
                    var constants = _reader.ReadFixedSizeArrayAtOffset <uint>(() => _reader.ReadUInt32(), count);

                    foreach (var constant in constants)
                    {
                        parameters.Add(Value.FromConstant(constant));
                    }
                }
                break;

                case InstructionType.GotoLabel:
                    instruction = new GotoLabel();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.DefineFunction2:
                {
                    instruction = new DefineFunction2();
                    var name       = _reader.ReadStringAtOffset();
                    var nParams    = _reader.ReadUInt32();
                    var nRegisters = _reader.ReadByte();
                    var flags      = _reader.ReadUInt24();

                    //list of parameter strings
                    var paramList = _reader.ReadFixedSizeListAtOffset <FunctionArgument>(() => new FunctionArgument()
                        {
                            Register  = _reader.ReadInt32(),
                            Parameter = _reader.ReadStringAtOffset(),
                        }, nParams);

                    parameters.Add(Value.FromString(name));
                    parameters.Add(Value.FromInteger((int)nParams));
                    parameters.Add(Value.FromInteger((int)nRegisters));
                    parameters.Add(Value.FromInteger((int)flags));
                    foreach (var param in paramList)
                    {
                        parameters.Add(Value.FromInteger(param.Register));
                        parameters.Add(Value.FromString(param.Parameter));
                    }
                    //body size of the function
                    parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    //skip 8 bytes
                    _reader.ReadUInt64();
                }
                break;

                case InstructionType.PushData:
                {
                    instruction = new PushData();

                    var count     = _reader.ReadUInt32();
                    var constants = _reader.ReadFixedSizeArrayAtOffset <uint>(() => _reader.ReadUInt32(), count);

                    foreach (var constant in constants)
                    {
                        parameters.Add(Value.FromConstant(constant));
                    }
                }
                break;

                case InstructionType.BranchAlways:
                    instruction = new BranchAlways();
                    if (!branched)
                    {
                        branchBytes = _reader.ReadInt32();
                        parameters.Add(Value.FromInteger(branchBytes));

                        if (branchBytes > 0)
                        {
                            branchBytes += (int)instruction.Size + 1;
                            branched     = true;
                        }
                    }
                    else
                    {
                        parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    }
                    break;

                case InstructionType.GetURL2:
                    instruction = new GetUrl2();
                    break;

                case InstructionType.DefineFunction:
                {
                    instruction = new DefineFunction();
                    var name = _reader.ReadStringAtOffset();
                    //list of parameter strings
                    var paramList = _reader.ReadListAtOffset <string>(() => _reader.ReadStringAtOffset());

                    parameters.Add(Value.FromString(name));
                    parameters.Add(Value.FromInteger(paramList.Count));
                    foreach (var param in paramList)
                    {
                        parameters.Add(Value.FromString(param));
                    }
                    //body size of the function
                    parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    //skip 8 bytes
                    _reader.ReadUInt64();
                }
                break;

                case InstructionType.BranchIfTrue:
                    instruction = new BranchIfTrue();
                    if (!branched)
                    {
                        branchBytes = _reader.ReadInt32();
                        parameters.Add(Value.FromInteger(branchBytes));

                        if (branchBytes > 0)
                        {
                            branchBytes += (int)instruction.Size + 1;
                            branched     = true;
                        }
                    }
                    else
                    {
                        parameters.Add(Value.FromInteger(_reader.ReadInt32()));
                    }
                    break;

                case InstructionType.GotoFrame2:
                    instruction = new GotoFrame2();
                    parameters.Add(Value.FromInteger(_reader.ReadByte()));
                    break;

                case InstructionType.EA_PushString:
                    instruction = new PushString();
                    //the constant id that should be pushed
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.EA_PushConstantByte:
                    instruction = new PushConstantByte();
                    //the constant id that should be pushed
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_GetStringVar:
                    instruction = new GetStringVar();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.EA_SetStringVar:
                    instruction = new SetStringMember();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.EA_GetStringMember:
                    instruction = new GetStringMember();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.EA_SetStringMember:
                    instruction = new SetStringMember();
                    parameters.Add(Value.FromString(_reader.ReadStringAtOffset()));
                    break;

                case InstructionType.EA_PushValueOfVar:
                    instruction = new PushValueOfVar();
                    //the constant id that should be pushed
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_GetNamedMember:
                    instruction = new GetNamedMember();
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_CallNamedFuncPop:
                    instruction = new CallNamedFuncPop();
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_CallNamedFunc:
                    instruction = new CallNamedFunc();
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_CallNamedMethodPop:
                    instruction = new CallNamedMethodPop();
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.EA_PushFloat:
                    instruction = new PushFloat();
                    parameters.Add(Value.FromFloat(_reader.ReadSingle()));
                    break;

                case InstructionType.EA_PushByte:
                    instruction = new PushByte();
                    parameters.Add(Value.FromInteger(_reader.ReadByte()));
                    break;

                case InstructionType.EA_PushShort:
                    instruction = new PushShort();
                    parameters.Add(Value.FromInteger(_reader.ReadUInt16()));
                    break;

                case InstructionType.End:
                    instruction = new End();

                    if (!branched)
                    {
                        parsing = false;
                    }
                    break;

                case InstructionType.EA_CallNamedMethod:
                    instruction = new CallNamedMethod();
                    parameters.Add(Value.FromConstant(_reader.ReadByte()));
                    break;

                case InstructionType.Var:
                    instruction = new Var();

                    break;

                default:
                    throw new InvalidDataException("Unimplemented bytecode instruction:" + type.ToString());
                }

                if (instruction != null)
                {
                    instruction.Parameters = parameters;
                    Items.Add(instruction);
                }

                if (branched)
                {
                    branchBytes -= (int)instruction.Size + 1;

                    if (branchBytes <= 0)
                    {
                        branched = false;
                    }
                }
            }
            _reader.BaseStream.Seek(current, SeekOrigin.Begin);
        }
Example #4
0
 public override void Visit(ToInteger node)
 {
     Visit((ConversionExpression)node);
 }
Example #5
0
 public override void Visit(ToInteger node)
 {
     unfinishedClone = new ToInteger(GetCloneOf(node.Expression));
     base.Visit(node);
 }
 public override void Visit(ToInteger node)
 {
     throw new InterpretException("TODO");
 }
Example #7
0
 public override void Visit(ToInteger node)
 {
     UpdateType(node, TypeCalculator.GetType(node));
 }
Example #8
0
        public static IEnumerable <TestCaseData> GetTestCases()
        {
            var MAX_OF     = new Max();
            var MIN_OF     = new Min();
            var ABS_OF     = new Abs();
            var TO_INTEGER = new ToInteger();
            var TO_DOUBLE  = new ToDouble();
            var TO_LONG    = new ToLong();

            var INT_SUM_OF    = new IntSum();
            var DOUBLE_SUM_OF = new DoubleSum();
            var LONG_SUM_OF   = new LongSum();

            var INT_SUBTRACT_OF    = new IntSubtract();
            var DOUBLE_SUBTRACT_OF = new DoubleSubtract();
            var LONG_SUBTRACT_OF   = new LongSubtract();

            var DIV_OF           = new Divide();
            var DIV_AND_ROUND_OF = new DivideAndRound();

            object[][] tests = new object[][] {
                new object[] { "max-empty-array", MAX_OF, new JArray(), null },
                new object[] { "max-null", MAX_OF, null, null },
                new object[] { "max-object", MAX_OF, new JArray(new JObject()), null },

                new object[] { "max-single-int-array", MAX_OF, new JArray(1), new JValue(1) },
                new object[] { "max-single-long-array", MAX_OF, new JArray(1L), new JValue(1L) },
                new object[] { "max-single-double-array", MAX_OF, new JArray(1.0), new JValue(1.0) },

                new object[] { "max-single-int-list", MAX_OF, new JArray(1), new JValue(1) },
                new object[] { "max-single-long-list", MAX_OF, new JArray(1L), new JValue(1L) },
                new object[] { "max-single-double-list", MAX_OF, new JArray(1.0), new JValue(1.0) },

                new object[] { "max-single-int-array-extra-arg", MAX_OF, new JArray(1, "a"), new JValue(1) },
                new object[] { "max-single-long-array-extra-arg", MAX_OF, new JArray(1L, "a"), new JValue(1L) },
                new object[] { "max-single-double-array-extra-arg", MAX_OF, new JArray(1.0, "a"), new JValue(1.0) },

                new object[] { "max-single-int-list-extra-arg", MAX_OF, new JArray(1, "a"), new JValue(1) },
                new object[] { "max-single-long-list-extra-arg", MAX_OF, new JArray(1L, "a"), new JValue(1L) },
                new object[] { "max-single-double-list-extra-arg", MAX_OF, new JArray(1.0, "a"), new JValue(1.0) },

                new object[] { "max-multi-int-array", MAX_OF, new JArray(1, 3, 2, 5), new JValue(5) },
                new object[] { "max-multi-long-array", MAX_OF, new JArray(1L, 3L, 2L, 5L), new JValue(5L) },
                new object[] { "max-multi-double-array", MAX_OF, new JArray(1.0, 3.0, 2.0, 5.0), new JValue(5.0) },

                new object[] { "max-multi-int-list", MAX_OF, new JArray(1, 3, 2, 5), new JValue(5) },
                new object[] { "max-multi-long-list", MAX_OF, new JArray(1L, 3L, 2L, 5L), new JValue(5L) },
                new object[] { "max-multi-double-list", MAX_OF, new JArray(1.0, 3.0, 2.0, 5.0), new JValue(5.0) },

                new object[] { "max-combo-int-array", MAX_OF, new JArray(1.0, 3L, null, 5), new JValue(5) },
                new object[] { "max-combo-long-array", MAX_OF, new JArray(1.0, 3L, null, 5L), new JValue(5L) },
                new object[] { "max-combo-double-array", MAX_OF, new JArray(1.0, 3L, null, 5.0), new JValue(5.0) },

                new object[] { "max-combo-int-list", MAX_OF, new JArray(1.0, 3L, null, 5), new JValue(5) },
                new object[] { "max-combo-long-list", MAX_OF, new JArray(1.0, 3L, null, 5L), new JValue(5L) },
                new object[] { "max-combo-double-list", MAX_OF, new JArray(1.0, 3L, null, 5.0), new JValue(5.0) },

                new object[] { "max-NaN", MAX_OF, new JArray(1.0, Double.NaN), new JValue(Double.NaN) },
                new object[] { "max-positive-infinity", MAX_OF, new JArray(1.0, Double.PositiveInfinity), new JValue(Double.PositiveInfinity) },
                new object[] { "max-NaN-positive-infinity", MAX_OF, new JArray(1.0, Double.NaN, Double.PositiveInfinity), new JValue(Double.NaN) },

                new object[] { "min-empty-array", MIN_OF, new JArray(), null },
                new object[] { "min-null", MIN_OF, null, null },
                new object[] { "min-object", MIN_OF, new JObject(), null },

                new object[] { "min-single-int-array", MIN_OF, new JArray(1), new JValue(1) },
                new object[] { "min-single-long-array", MIN_OF, new JArray(1L), new JValue(1L) },
                new object[] { "min-single-double-array", MIN_OF, new JArray(1.0), new JValue(1.0) },

                new object[] { "min-single-int-list", MIN_OF, new JArray(1), new JValue(1) },
                new object[] { "min-single-long-list", MIN_OF, new JArray(1L), new JValue(1L) },
                new object[] { "min-single-double-list", MIN_OF, new JArray(1.0), new JValue(1.0) },

                new object[] { "min-single-int-array-extra-arg", MIN_OF, new JArray(1, "a"), new JValue(1) },
                new object[] { "min-single-long-array-extra-arg", MIN_OF, new JArray(1L, "a"), new JValue(1L) },
                new object[] { "min-single-double-array-extra-arg", MIN_OF, new JArray(1.0, "a"), new JValue(1.0) },

                new object[] { "min-single-int-list-extra-arg", MIN_OF, new JArray(1, "a"), new JValue(1) },
                new object[] { "min-single-long-list-extra-arg", MIN_OF, new JArray(1L, "a"), new JValue(1L) },
                new object[] { "min-single-double-list-extra-arg", MIN_OF, new JArray(1.0, "a"), new JValue(1.0) },

                new object[] { "min-multi-int-array", MIN_OF, new JArray(1, 3, 2, 5), new JValue(1) },
                new object[] { "min-multi-long-array", MIN_OF, new JArray(1L, 3L, 2L, 5L), new JValue(1L) },
                new object[] { "min-multi-double-array", MIN_OF, new JArray(1.0, 3.0, 2.0, 5.0), new JValue(1.0) },

                new object[] { "min-multi-int-list", MIN_OF, new JArray(1, 3, 2, 5), new JValue(1) },
                new object[] { "min-multi-long-list", MIN_OF, new JArray(1L, 3L, 2L, 5L), new JValue(1L) },
                new object[] { "min-multi-double-list", MIN_OF, new JArray(1.0, 3.0, 2.0, 5.0), new JValue(1.0) },

                new object[] { "min-combo-int-array", MIN_OF, new JArray(1, 3L, null, 5.0), new JValue(1) },
                new object[] { "min-combo-long-array", MIN_OF, new JArray(1L, 3, null, 5.0), new JValue(1L) },
                new object[] { "min-combo-double-array", MIN_OF, new JArray(1.0, 3L, null, 5), new JValue(1.0) },

                new object[] { "min-combo-int-list", MIN_OF, new JArray(1, 3L, null, 5.0), new JValue(1) },
                new object[] { "min-combo-long-list", MIN_OF, new JArray(1L, 3, null, 5.0), new JValue(1L) },
                new object[] { "min-combo-double-list", MIN_OF, new JArray(1.0, 3L, null, 5), new JValue(1.0) },

                new object[] { "min-NaN", MIN_OF, new JArray(-1.0, Double.NaN), new JValue(Double.NaN) },
                new object[] { "min-negative-Infinity", MIN_OF, new JArray(-1.0, Double.NegativeInfinity), new JValue(Double.NegativeInfinity) },
                new object[] { "min-NaN-positive-infinity", MIN_OF, new JArray(-1.0, Double.NaN, Double.NegativeInfinity), new JValue(Double.NaN) },


                new object[] { "abs-null", ABS_OF, null, null },
                new object[] { "abs-invalid", ABS_OF, new JObject(), null },
                new object[] { "abs-empty-array", ABS_OF, new JArray(), null },

                new object[] { "abs-single-negative-int", ABS_OF, new JValue(-1), new JValue(1) },
                new object[] { "abs-single-negative-long", ABS_OF, new JValue(-1L), new JValue(1L) },
                new object[] { "abs-single-negative-double", ABS_OF, new JValue(-1.0), new JValue(1.0) },
                new object[] { "abs-single-positive-int", ABS_OF, new JValue(1), new JValue(1) },
                new object[] { "abs-single-positive-long", ABS_OF, new JValue(1L), new JValue(1L) },
                new object[] { "abs-single-positive-double", ABS_OF, new JValue(1.0), new JValue(1.0) },

                new object[] { "abs-list", ABS_OF, new JArray(-1, -1L, -1.0), new JArray(1, 1L, 1.0) },
                new object[] { "abs-array", ABS_OF, new JArray(-1, -1L, -1.0), new JArray(1, 1L, 1.0) },

                new object[] { "abs-Nan", ABS_OF, new JValue(Double.NaN), new JValue(Double.NaN) },
                new object[] { "abs-PosInfinity", ABS_OF, new JValue(Double.PositiveInfinity), new JValue(Double.PositiveInfinity) },
                new object[] { "abs-NefInfinity", ABS_OF, new JValue(Double.NegativeInfinity), new JValue(Double.PositiveInfinity) },


                new object[] { "toInt-null", TO_INTEGER, null, null },
                new object[] { "toInt-invalid", TO_INTEGER, new JObject(), null },
                new object[] { "toInt-empty-array", TO_INTEGER, new JArray(), null },

                new object[] { "toInt-single-positive-string", TO_INTEGER, new JValue("1"), new JValue(1) },
                new object[] { "toInt-single-negative-string", TO_INTEGER, new JValue("-1"), new JValue(-1) },
                new object[] { "toInt-single-positive-int", TO_INTEGER, new JValue(1), new JValue(1) },
                new object[] { "toInt-single-negative-int", TO_INTEGER, new JValue(-1), new JValue(-1) },
                new object[] { "toInt-single-positive-long", TO_INTEGER, new JValue(1L), new JValue(1) },
                new object[] { "toInt-single-negative-long", TO_INTEGER, new JValue(-1L), new JValue(-1) },
                new object[] { "toInt-single-positive-double", TO_INTEGER, new JValue(1.0), new JValue(1) },
                new object[] { "toInt-single-negative-double", TO_INTEGER, new JValue(-1.0), new JValue(-1) },

                new object[] { "toInt-single-positive-string-list", TO_INTEGER, new JArray("1", "2"), new JArray(1, 2) },
                new object[] { "toInt-single-negative-string-array", TO_INTEGER, new JArray("-1", "-2"), new JArray(-1, -2) },
                new object[] { "toInt-single-positive-int-list", TO_INTEGER, new JArray(1, 2), new JArray(1, 2) },
                new object[] { "toInt-single-negative-int-array", TO_INTEGER, new JArray(-1, -2), new JArray(-1, -2) },
                new object[] { "toInt-single-positive-long-list", TO_INTEGER, new JArray(1L, 2L), new JArray(1, 2) },
                new object[] { "toInt-single-negative-long-array", TO_INTEGER, new JArray(-1L, -2L), new JArray(-1, -2) },
                new object[] { "toInt-single-positive-double-list", TO_INTEGER, new JArray(1.0, 2.0), new JArray(1, 2) },
                new object[] { "toInt-single-negative-double-array", TO_INTEGER, new JArray(-1.0, -2.0), new JArray(-1, -2) },

                new object[] { "toDouble-null", TO_DOUBLE, null, null },
                new object[] { "toDouble-invalid", TO_DOUBLE, new JObject(), null },
                new object[] { "toDouble-empty-array", TO_DOUBLE, new JArray(), null },

                new object[] { "toDouble-single-positive-string", TO_DOUBLE, new JValue("1"), new JValue(1.0) },
                new object[] { "toDouble-single-negative-string", TO_DOUBLE, new JValue("-1"), new JValue(-1.0) },
                new object[] { "toDouble-single-positive-int", TO_DOUBLE, new JValue(1), new JValue(1.0) },
                new object[] { "toDouble-single-negative-int", TO_DOUBLE, new JValue(-1), new JValue(-1.0) },
                new object[] { "toDouble-single-positive-long", TO_DOUBLE, new JValue(1L), new JValue(1.0) },
                new object[] { "toDouble-single-negative-long", TO_DOUBLE, new JValue(-1L), new JValue(-1.0) },
                new object[] { "toDouble-single-positive-double", TO_DOUBLE, new JValue(1.0), new JValue(1.0) },
                new object[] { "toDouble-single-negative-double", TO_DOUBLE, new JValue(-1.0), new JValue(-1.0) },

                new object[] { "toDouble-single-positive-string-list", TO_DOUBLE, new JArray("1", "2"), new JArray(1.0, 2.0) },
                new object[] { "toDouble-single-negative-string-array", TO_DOUBLE, new JArray("-1", "-2"), new JArray(-1.0, -2.0) },
                new object[] { "toDouble-single-positive-int-list", TO_DOUBLE, new JArray(1, 2), new JArray(1.0, 2.0) },
                new object[] { "toDouble-single-negative-int-array", TO_DOUBLE, new JArray(-1, -2), new JArray(-1.0, -2.0) },
                new object[] { "toDouble-single-positive-long-list", TO_DOUBLE, new JArray(1L, 2L), new JArray(1.0, 2.0) },
                new object[] { "toDouble-single-negative-long-array", TO_DOUBLE, new JArray(-1L, -2L), new JArray(-1.0, -2.0) },
                new object[] { "toDouble-single-positive-double-list", TO_DOUBLE, new JArray(1.0, 2.0), new JArray(1.0, 2.0) },
                new object[] { "toDouble-single-negative-double-array", TO_DOUBLE, new JArray(-1.0, -2.0), new JArray(-1.0, -2.0) },

                new object[] { "toLong-null", TO_LONG, null, null },
                new object[] { "toLong-invalid", TO_LONG, new JObject(), null },
                new object[] { "toLong-empty-array", TO_LONG, new JArray(), null },

                new object[] { "toLong-single-positive-string", TO_LONG, new JValue("1"), new JValue(1L) },
                new object[] { "toLong-single-negative-string", TO_LONG, new JValue("-1"), new JValue(-1L) },
                new object[] { "toLong-single-positive-int", TO_LONG, new JValue(1), new JValue(1L) },
                new object[] { "toLong-single-negative-int", TO_LONG, new JValue(-1), new JValue(-1L) },
                new object[] { "toLong-single-positive-long", TO_LONG, new JValue(1L), new JValue(1L) },
                new object[] { "toLong-single-negative-long", TO_LONG, new JValue(-1L), new JValue(-1L) },
                new object[] { "toLong-single-positive-double", TO_LONG, new JValue(1L), new JValue(1L) },
                new object[] { "toLong-single-negative-double", TO_LONG, new JValue(-1L), new JValue(-1L) },

                new object[] { "toLong-single-positive-string-list", TO_LONG, new JArray("1", "2"), new JArray(1L, 2L) },
                new object[] { "toLong-single-negative-string-array", TO_LONG, new JArray("-1", "-2"), new JArray(-1L, -2L) },
                new object[] { "toLong-single-positive-int-list", TO_LONG, new JArray(1, 2), new JArray(1L, 2L) },
                new object[] { "toLong-single-negative-int-array", TO_LONG, new JArray(-1, -2), new JArray(-1L, -2L) },
                new object[] { "toLong-single-positive-long-list", TO_LONG, new JArray(1L, 2L), new JArray(1L, 2L) },
                new object[] { "toLong-single-negative-long-array", TO_LONG, new JArray(-1L, -2L), new JArray(-1L, -2L) },
                new object[] { "toLong-single-positive-double-list", TO_LONG, new JArray(1L, 2L), new JArray(1L, 2L) },
                new object[] { "toLong-single-negative-double-array", TO_LONG, new JArray(-1L, -2L), new JArray(-1L, -2L) },

                new object[] { "toInteger-combo-string-array", TO_INTEGER, new JArray("-1", 2, -3L, 4.0), new JArray(-1, 2, -3, 4) },
                new object[] { "toLong-combo-int-array", TO_LONG, new JArray("-1", 2, -3L, 4.0), new JArray(-1L, 2L, -3L, 4L) },
                new object[] { "toDouble-combo-long-array", TO_DOUBLE, new JArray("-1", 2, -3L, 4.0), new JArray(-1.0, 2.0, -3.0, 4.0) },

                new object[] { "intsum-combo-string-array", INT_SUM_OF, new JArray(1, 2.0, "random", 0), new JValue(3) },
                new object[] { "intsum-single-value", INT_SUM_OF, new JValue(2), null },
                new object[] { "intsum-combo-intstring-array", INT_SUM_OF, new JArray(1L, 2, "-3.0", 0), new JValue(0) },

                new object[] { "doublesum-combo-string-array", DOUBLE_SUM_OF, new JArray(1, 2.0, "random", 0), new JValue(3.0) },
                new object[] { "doublesum-single-value", DOUBLE_SUM_OF, new JValue(2), null },
                new object[] { "doublesum-combo-intstring-array", DOUBLE_SUM_OF, new JArray(1L, 2, "-3.0", 0), new JValue(0.0) },

                new object[] { "longsum-combo-string-array", LONG_SUM_OF, new JArray(1, 2.0, "random", 0), new JValue(3L) },
                new object[] { "longsum-single-value", LONG_SUM_OF, new JValue(2), null },
                new object[] { "longsum-combo-intstring-array", LONG_SUM_OF, new JArray(1L, 2, "-3.0", 0), new JValue(0L) },

                new object[] { "intsubtract-happy-path", INT_SUBTRACT_OF, new JArray(4, 1), new JValue(3) },
                new object[] { "intsubtract-single-value", INT_SUBTRACT_OF, new JValue(2), null },
                new object[] { "intsubtract-wrong-type", INT_SUBTRACT_OF, new JArray(4.0, 1), null },

                new object[] { "doublesubtract-happy-path", DOUBLE_SUBTRACT_OF, new JArray(4.0, 1.0), new JValue(3.0) },
                new object[] { "doublesubtract-single-value", DOUBLE_SUBTRACT_OF, new JValue(2.0), null },
                new object[] { "doublesubtract-wrong-type", DOUBLE_SUBTRACT_OF, new JArray(4L, 1), null },

                new object[] { "longsubtract-happy-path", LONG_SUBTRACT_OF, new JArray(4L, 1L), new JValue(3L) },
                new object[] { "longsubtract-single-value", LONG_SUBTRACT_OF, new JValue(2L), null },
                new object[] { "longsubtract-wrong-type", LONG_SUBTRACT_OF, new JArray(4.0, 1), null },

                // Test to make sure "div" only uses the first and second element in the array and ignores the rest.
                new object[] { "div-combo-array", DIV_OF, new JArray(10L, 5.0, 2), null },
                new object[] { "div-combo-string-array", DIV_OF, new JArray(10L, "5", 2), null },
                new object[] { "div-single-element-array", DIV_OF, new JArray("5"), null },
                new object[] { "div-single-element", DIV_OF, new JValue("10"), null },

                // Dividing by 0 returns an empty result.
                new object[] { "div-combo-invalid-array", DIV_OF, new JArray(10L, 0, 2), null },

                // Dividing 0 by any number returns 0.0(double)
                new object[] { "div-combo-valid-array", DIV_OF, new JArray(0.0, 10), new JValue(0.0) },

                new object[] { "divAndRound-single-precision-array", DIV_AND_ROUND_OF, new JArray(1, 5.0, 2), new JValue(2.5) },
                new object[] { "divAndRound-double-precision-array", DIV_AND_ROUND_OF, new JArray(2, 5.0, 2), new JValue(2.50) },
                new object[] { "divAndRound-trailing-precision-array", DIV_AND_ROUND_OF, new JArray(3, 5.0, 2), new JValue(2.500) },
                new object[] { "divAndRound-no-precision-array", DIV_AND_ROUND_OF, new JArray(0, 5.0, 2), new JValue(3.0) },          // Round up as >= 0.5
                new object[] { "divAndRound-no-precision-array", DIV_AND_ROUND_OF, new JArray(0, 4.8, 2), new JValue(2.0) },          // Round down as < 0.5
            };

            foreach (var test in tests)
            {
                yield return(new TestCaseData(test.Skip(1).ToArray())
                {
                    TestName = $"RunTest({test[0]})"
                });
            }
        }
Example #9
0
 public override void Visit(ToInteger node)
 {
     AssignToImplicitReturn(node);
 }