示例#1
0
        public void Generate(Generator generator)
        {
            generator.AllocateAssembler();
            functionPointer = generator.Assembler.Region.BaseLocation;
            Assembler a       = generator.Assembler;
            int       thisidx = a.AddParameter(); // this;
            int       typeidx = a.AddParameter(); // type

            generator.Symbols.Source(a.Region.CurrentLocation, definition);
            a.StartFunction();
            //TODO: a binary searchtree would be fun
            foreach (KeyValuePair <int, DefinitionTypeReference> titrkvp in definition.GetSupportedTypesMap())
            {
                a.RetrieveVariable(typeidx);
                a.PushValue();
                a.SetOnlyValue(titrkvp.Value.Id);
                a.IntegerEquals();
                JumpToken noMatch = a.CreateJumpToken();
                a.JumpIfFalse(noMatch);
                a.RetrieveVariable(thisidx);
                a.SetTypePart(definition.RuntimeStruct);
                if (titrkvp.Key != -1)
                {
                    a.TypeConversionNotNull(titrkvp.Key);
                }
                a.StopFunction();
                a.SetDestination(noMatch);
            }
            a.Empty();
            a.StopFunction();
            generator.Symbols.Source(a.Region.CurrentLocation, definition, SourceMark.EndSequence);
            generator.Symbols.WriteData(a.Region.BaseLocation, a.Region.Length, "dcf:" + definition.Name.Data);
        }
示例#2
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            if (statement.IsEmptyStatement())
            {
                throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody));
            }
            generator.Resolver.EnterContext();
            JumpToken loopToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.SetDestination(loopToken);
            expression.Prepare(generator, null); // boolean
            expression.Generate(generator);
            generator.Resolver.EnterContext();
            JumpToken skipToken = generator.Assembler.CreateJumpToken();

            generator.Resolver.RegisterGoto("@continue", loopToken);
            generator.Resolver.RegisterGoto("@break", skipToken);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(skipToken);
            statement.Generate(generator, returnType);
            generator.Assembler.Jump(loopToken);
            generator.Assembler.SetDestination(skipToken);
            generator.Resolver.LeaveContext();
            generator.Resolver.LeaveContext();
            breaks = skipToken.JumpCount > 1;
        }
示例#3
0
        /// <summary>
        /// Inserts an unconditional jump to the location described by the jump token.
        /// This may be a forward or backward jump, but should be local to the Assembler.
        /// </summary>
        public override void Jump(Compiler.JumpToken token)
        {
            JumpToken t = (JumpToken)token;

            t.SetKind(JumpTokenKind.Relative);
            region.WriteByte(0xe9); // relative offset next instruction
            t.SetJumpSite(region.InsertIntToken());
        }
示例#4
0
 /// <summary>
 /// Conditional version of Jump().
 /// Reads a boolean value from the accumulator
 /// </summary>
 public override void JumpIfFalse(JumpToken token)
 {
     token.SetKind(JumpTokenKind.Relative);
     region.Write(new byte[] {
         0x48, 0x21, 0xc0, // and rax, rax
         0x0f, 0x84        // jz
     });
     token.SetJumpSite(region.InsertIntToken());
 }
示例#5
0
 /// <summary>
 /// Conditional version of Jump().
 /// Takes the jump if the type part of the accumulator is empty
 /// </summary>
 public override void JumpIfUnassigned(JumpToken token)
 {
     token.SetKind(JumpTokenKind.Relative);
     region.Write(new byte[] {
         0x48, 0x21, 0xd2, // and rdx, rdx
         0x0f, 0x84        // jz
     });
     token.SetJumpSite(region.InsertIntToken());
 }
示例#6
0
 public override void Generate(Generator generator)
 {
     if (getStatement != null)
     {
         generator.Resolver.EnterContext();
         generator.Resolver.SetContextParameters(getParameters);
         generator.Resolver.CurrentFieldName = name.Data + ":get";
         generator.AllocateAssembler();
         getParameters.Generate(generator);
         ParameterMetadata thisParam = getParameters.Find("this");
         generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
         getStatement.Prepare(generator);
         generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
         generator.Assembler.StartFunction();
         JumpToken returnToken = generator.Assembler.CreateJumpToken();
         generator.Resolver.RegisterGoto("@return", returnToken);
         JumpToken recurToken = generator.Assembler.CreateJumpToken();
         generator.Assembler.SetDestination(recurToken);
         generator.Resolver.RegisterGoto("@recur", recurToken);
         getStatement.Generate(generator, type);
         if (!getStatement.Returns())
         {
             throw new CompilerException(getStatement, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue));
         }
         generator.Assembler.SetDestination(returnToken);
         generator.Assembler.StopFunction();
         generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
         generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "getter:" + ParentDefinition.Name.Data + "." + name.Data);
         getStatementPointer = generator.Assembler.Region.BaseLocation;
         generator.Resolver.LeaveContext();
     }
     if (setStatement != null)
     {
         generator.Resolver.EnterContext();
         generator.Resolver.SetContextParameters(setParameters);
         generator.Resolver.CurrentFieldName = name.Data + ":set";
         generator.AllocateAssembler();
         setParameters.Generate(generator);
         ParameterMetadata thisParam = setParameters.Find("this");
         generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
         setStatement.Prepare(generator);
         generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
         generator.Assembler.StartFunction();
         JumpToken returnToken = generator.Assembler.CreateJumpToken();
         generator.Resolver.RegisterGoto("@return", returnToken);
         JumpToken recurToken = generator.Assembler.CreateJumpToken();
         generator.Assembler.SetDestination(recurToken);
         generator.Resolver.RegisterGoto("@recur", recurToken);
         setStatement.Generate(generator, null);
         generator.Assembler.SetDestination(returnToken);
         generator.Assembler.StopFunction();
         generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
         generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "setter:" + ParentDefinition.Name.Data + "." + name.Data);
         setStatementPointer = generator.Assembler.Region.BaseLocation;
         generator.Resolver.LeaveContext();
     }
 }
示例#7
0
        public override void JumpIfUnassigned(Compiler.JumpToken token)
        {
            JumpToken t = (JumpToken)token;

            t.SetKind(JumpTokenKind.Relative);
            region.Write(new byte[] {
                0x21, 0xd2, // and edx, edx
                0x0f, 0x84  // jz
            });
            t.SetJumpSite(region.InsertIntToken());
        }
示例#8
0
        public override void JumpIfTrue(Compiler.JumpToken token)
        {
            JumpToken t = (JumpToken)token;

            t.SetKind(JumpTokenKind.Relative);
            region.Write(new byte[] {
                0x21, 0xc0, // and eax, eax
                0x0f, 0x85  // jnz
            });
            t.SetJumpSite(region.InsertIntToken());
        }
示例#9
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            left.Generate(generator);
            JumpToken skip = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfAssigned(skip);
            right.Generate(generator);
            right.TypeReference.GenerateConversion(this, generator, left.TypeReference);
            generator.Assembler.SetDestination(skip);
        }
示例#10
0
        public override void JumpIfNotMarked(Compiler.JumpToken token)
        {
            region.Write(new byte[] {
                0x48, 0xF7, 0xC2, 0x01, 0x00, 0x00, 0x00 // test rdx, 1
            });
            JumpToken t = (JumpToken)token;

            t.SetKind(JumpTokenKind.Relative);
            region.Write(new byte[] {
                0x0f, 0x84  // jz
            });
            t.SetJumpSite(region.InsertIntToken());
        }
示例#11
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            Parameters scopeParameters = generator.Resolver.CurrentContextParameters();

            Require.Assigned(scopeParameters);
            if (scopeParameters.ParameterList.Count != this.parameters.Count)
            {
                throw new CompilerException(this, string.Format(Resource.Culture,
                                                                Resource.FunctionCallParameterCountMismatch, ParameterListString(scopeParameters.ParameterList), this.parameters.Count));
            }

            int i = 0;

            foreach (Expression parameter in this.parameters)
            {
                TypeReference tr = scopeParameters.ParameterList[i].TypeReference;
                parameter.Prepare(generator, tr);
                i++;
            }
            i = 0;
            foreach (Expression parameter in this.parameters)
            {
                TypeReference tr = scopeParameters.ParameterList[i].TypeReference;
                parameter.Generate(generator);
                tr.GenerateConversion(this, generator, parameter.TypeReference);
                i++;
                generator.Assembler.PushValue();
            }
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            //store in local slots
            List <ParameterMetadata> p = new List <ParameterMetadata>(scopeParameters.ParameterList);

            p.Reverse();
            foreach (ParameterMetadata parameter in p)
            {
                generator.Assembler.PopValue();
                generator.Assembler.StoreVariable(parameter.Slot);
            }

            bool      tryContext;
            JumpToken gotoToken = generator.Resolver.FindGoto("@recur", out tryContext);

            if ((gotoToken == null) || tryContext)
            {
                throw new CompilerException(this, string.Format(Resource.Culture, Resource.UnsupportedJumpOutOfTry));
            }
            generator.Assembler.Jump(gotoToken);
        }
示例#12
0
        void GenerateLambda(Generator generator)
        {
            Assembler oldAssembler = generator.Assembler;

            offset = oldAssembler.SlotCount();
            generator.AllocateAssembler();
            Assembler inner = generator.Assembler;

            generator.Assembler = new LambdaAssembler(this, generator.Assembler);
            generator.Resolver.EnterContextParentReadOnly();
            closureSlot = offset;
            localSlots.Add(closureSlot, inner.AddParameter()); // closure, or nothing if no fields
            Parameters p = new Parameters();

            for (int i = 0; i < parameters.Count; ++i)
            {
                int s  = inner.AddParameter();
                int ex = offset + localSlots.Count;
                localSlots.Add(ex, s);
                generator.Resolver.AddVariable(parameters[i], parameterTypes[i], ex, true);
                generator.Resolver.AssignSlot(ex);
                generator.Resolver.RetrieveSlot(this, ex, false); // todo: make warning: treat function arguments as used
                ParameterMetadata pm = p.AddParameter(parameters[i], parameterTypes[i], parameters[i]);
                pm.Bind(ex);
            }
            generator.Resolver.SetContextParameters(p);

            statement.Prepare(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.StartFunction();
            JumpToken returnToken = generator.Assembler.CreateJumpToken();

            generator.Resolver.RegisterGoto("@return", returnToken);
            JumpToken recurToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.SetDestination(recurToken);
            generator.Resolver.RegisterGoto("@recur", recurToken);
            statement.Generate(generator, returnType);
            generator.Assembler.SetDestination(returnToken);
            generator.Assembler.StopFunction();
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
            generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "lambda:");

            functionPointer = generator.Assembler.Region.BaseLocation;

            generator.Resolver.LeaveContext();
            generator.Assembler = oldAssembler;
        }
示例#13
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            bool      tryContext;
            JumpToken gotoToken = generator.Resolver.FindGoto(token, out tryContext);

            if (gotoToken == null)
            {
                throw new CompilerException(this, string.Format(Resource.Culture, Resource.NoEnclosingLoop));
            }
            if (tryContext)
            {
                throw new CompilerException(this, string.Format(Resource.Culture, Resource.UnsupportedJumpOutOfTry));
            }
            generator.Assembler.Jump(gotoToken);
        }
示例#14
0
        /// <summary>
        /// Tests the content of the accumulator for nullness and puts the result as a boolean in the accumulator.
        /// Note: the type part of the boolean is missing.
        /// </summary>
        public override void IsNotNull()
        {
            JumpToken zeroJump = new JumpToken();

            zeroJump.SetKind(JumpTokenKind.Relative);
            region.Write(new byte[] {
                0x48, 0x31, 0xC0, // xor rax, rax
                0x48, 0x21, 0xd2, // and rdx, rdx
                0x0f, 0x84        // jz
            });
            zeroJump.SetJumpSite(region.InsertIntToken());
            region.Write(new byte[] {
                0x48, 0x83, 0xf0, 0x01 // xor rax, 1
            });
            zeroJump.SetDestination(region.CurrentLocation);
        }
示例#15
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            condition.Generate(generator); // boolean
            boolType.GenerateConversion(this, generator, condition.TypeReference);
            JumpToken elseToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(elseToken);
            left.Generate(generator);
            resultType.GenerateConversion(this, generator, left.TypeReference);
            JumpToken skipElseToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.Jump(skipElseToken);
            generator.Assembler.SetDestination(elseToken);
            right.Generate(generator);
            resultType.GenerateConversion(this, generator, right.TypeReference);
            generator.Assembler.SetDestination(skipElseToken);
        }
示例#16
0
        public static void DoReturn(ILocation location, Generator generator)
        {
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location);
            bool      tryContext;
            JumpToken gotoToken = generator.Resolver.FindGoto("@return", out tryContext);

            if (tryContext)
            {
                generator.Assembler.MarkType();
                generator.Assembler.ExceptionHandlerInvoke();
            }
            else
            {
                if (gotoToken == null)
                {
                    throw new CompilerException(location, string.Format(Resource.Culture, Resource.UnsupportedJumpOutOfTry));
                }
                generator.Assembler.Jump(gotoToken);
            }
        }
示例#17
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            left.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);

            TypeReference leftType = left.TypeReference;

            if (call == null)
            {
                JumpToken skip = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfTrue(skip);
                right.Generate(generator);
                leftType.GenerateConversion(this, generator, right.TypeReference);
                generator.Assembler.SetDestination(skip);
            }
            else
            {
                call.Generate(generator);
            }
        }
示例#18
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            parent.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            TypeReference ptr = parent.TypeReference;
            TypeReference str = returnType;

            if (str.SupportsImplicit(ptr))
            {
                returnType.GenerateConversion(this, generator, parent.TypeReference);
            }
            else
            {
                JumpToken jtNull = null;
                jtNull = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(jtNull);
                generator.Assembler.TypeConversionDynamicNotNull(resolvedType.Id);
                generator.Assembler.SetDestination(jtNull);
            }
        }
示例#19
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            expression.Prepare(generator, null); // boolean
            expression.Generate(generator);      // boolean
            boolType.GenerateConversion(this, generator, expression.TypeReference);
            JumpToken elseToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(elseToken);
            generator.Resolver.EnterContext();
            if (statement.IsEmptyBlock())
            {
                throw new CompilerException(statement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty));
            }
            statement.Generate(generator, returnType);
            Resolver.Context trueContext = generator.Resolver.LeaveContextAcquire();
            if (elseStatement != null)
            {
                if (elseStatement.IsEmptyBlock())
                {
                    throw new CompilerException(elseStatement, string.Format(Resource.Culture, Resource.IfBranchIsEmpty));
                }
                JumpToken skipElseToken = generator.Assembler.CreateJumpToken();
                generator.Assembler.Jump(skipElseToken);
                generator.Assembler.SetDestination(elseToken);
                generator.Resolver.EnterContext();
                elseStatement.Generate(generator, returnType);
                returns = statement.Returns() && elseStatement.Returns();
                Resolver.Context falseContext = generator.Resolver.LeaveContextAcquire();
                generator.Resolver.IntersectContexts(trueContext, falseContext);
                generator.Resolver.ReleaseContext(falseContext);
                generator.Assembler.SetDestination(skipElseToken);
            }
            else
            {
                generator.Assembler.SetDestination(elseToken);
            }
            generator.Resolver.ReleaseContext(trueContext);
        }
示例#20
0
        public override void Generate(Generator generator)
        {
            base.Generate(generator);
            parent.Generate(generator);
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            TypeReference ptr       = parent.TypeReference;
            bool          allowNull = ptr.IsNullable && !typeReference.IsNullable;

            if (!allowNull)
            {
                generator.Assembler.CrashIfNull();
            }
            TypeReference str = typeReference;

            if (str.SupportsImplicit(ptr))
            {
                typeReference.GenerateConversion(this, generator, parent.TypeReference);
            }
            else
            {
                JumpToken jtNull = null;
                if (allowNull)
                {
                    jtNull = generator.Assembler.CreateJumpToken();
                    generator.Assembler.JumpIfUnassigned(jtNull);
                }
                generator.Assembler.TypeConversionDynamicNotNull(str.Id);
                JumpToken jtOk = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfAssigned(jtOk);
                throwCastException.Generate(generator, null);
                generator.Assembler.SetDestination(jtOk);
                if (allowNull)
                {
                    generator.Assembler.SetDestination(jtNull);
                }
            }
        }
示例#21
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            //
            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            PlaceholderRef fonCatchJump = null;

            if (finallyStatement != null)
            {
                fonCatchJump = new PlaceholderRef();
                generator.Assembler.ExceptionHandlerSetup(fonCatchJump);
                generator.Resolver.EnterContext();
                generator.Resolver.RegisterTryContext();
            }
            PlaceholderRef onCatchJump = null;

            if (catches.Count > 0)
            {
                onCatchJump = new PlaceholderRef();
                generator.Assembler.ExceptionHandlerSetup(onCatchJump);
            }
            generator.Resolver.EnterContext();
            generator.Resolver.RegisterTryContext();
            statement.Generate(generator, returnType);
            returns = statement.Returns();
            Resolver.Context statementContext = generator.Resolver.LeaveContextAcquire();
            if (catches.Count > 0)
            {
                generator.Assembler.ExceptionHandlerRemove();
                JumpToken noExceptionJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.Jump(noExceptionJump);
                generator.Assembler.SetDestination(onCatchJump);

                JumpToken noReturnJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfNotMarked(noReturnJump);
                generator.Assembler.UnmarkType();
                ReturnStatement.DoReturn(this, generator);
                generator.Assembler.SetDestination(noReturnJump);

                generator.Assembler.StoreVariable(valueSlot);

                List <JumpToken> escape = new List <JumpToken>();

                foreach (Catch c in catches)
                {
                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, c);
                    generator.Assembler.RetrieveVariable(valueSlot);
                    JumpToken noMatch = generator.Assembler.CreateJumpToken();
                    generator.Assembler.TypeConversionDynamicNotNull(c.type.Id);
                    generator.Assembler.JumpIfUnassigned(noMatch);
                    generator.Assembler.StoreVariable(valueSlot);
                    generator.Resolver.EnterContext();
                    generator.Resolver.AddVariable(c.identifier, c.type, valueSlot, true);
                    generator.Resolver.AssignSlot(valueSlot);
                    c.statement.Generate(generator, returnType);
                    returns = returns && c.statement.Returns();
                    generator.Resolver.LeaveContext();
                    JumpToken jt = generator.Assembler.CreateJumpToken();
                    escape.Add(jt);
                    generator.Assembler.Jump(jt);
                    generator.Assembler.SetDestination(noMatch);
                }
                //unhandled, rethrow
                generator.Assembler.RetrieveVariable(valueSlot);
                generator.Assembler.ExceptionHandlerInvoke();
                foreach (JumpToken jt in escape)
                {
                    generator.Assembler.SetDestination(jt);
                }
                generator.Assembler.SetDestination(noExceptionJump);
            }
            if (finallyStatement != null)
            {
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, finallyLocation);
                generator.Resolver.LeaveContext();
                generator.Assembler.ExceptionHandlerRemove();
                generator.Assembler.Empty();
                generator.Assembler.SetDestination(fonCatchJump);
                JumpToken fnoReturnJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfNotMarked(fnoReturnJump);
                generator.Assembler.UnmarkType();
                generator.Assembler.StoreVariable(returnSlot);
                generator.Assembler.SetDestination(fnoReturnJump);
                generator.Assembler.StoreVariable(valueSlot);
                generator.Resolver.EnterContext();
                finallyStatement.Generate(generator, returnType);
                generator.Resolver.LeaveAndMergeContext();
                if (catches.Count == 0) // if there are no catches we can be sure the whole try part completed and so we can use the variables initialized by it.
                {
                    generator.Resolver.MergeContext(statementContext);
                }

                generator.Assembler.RetrieveVariable(returnSlot);
                JumpToken fonExceptionFinallyJump = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(fonExceptionFinallyJump);
                ReturnStatement.DoReturn(this, generator);
                generator.Assembler.SetDestination(fonExceptionFinallyJump);

                generator.Assembler.RetrieveVariable(valueSlot);
                JumpToken fnoException = generator.Assembler.CreateJumpToken();
                generator.Assembler.JumpIfUnassigned(fnoException);
                generator.Assembler.ExceptionHandlerInvoke();
                generator.Assembler.SetDestination(fnoException);
            }
            generator.Resolver.ReleaseContext(statementContext);
        }
示例#22
0
            private Token DeserializeNext( byte tokenCode = Byte.MaxValue )
            {
                var tokenPosition = CodePosition;
                if( tokenCode == Byte.MaxValue )
                {
                    tokenCode = FixToken( Buffer.ReadByte() );
                    AlignSize( sizeof(byte) );
                }

                Token tokenItem = null;
                if( tokenCode >= (byte)ExprToken.FirstNative )
                {
                    tokenItem = FindNativeTable( tokenCode );
                }
                else if( tokenCode >= (byte)ExprToken.ExtendedNative )
                {
                    tokenItem = FindNativeTable( (tokenCode - (byte)ExprToken.ExtendedNative) << 8 | Buffer.ReadByte() );
                    AlignSize( sizeof(byte) );
                }
                else switch( tokenCode )
                {
                    #region Cast
                    case (byte)ExprToken.DynamicCast:
                        tokenItem = new DynamicCastToken();
                        break;

                    case (byte)ExprToken.MetaCast:
                        tokenItem = new MetaCastToken();
                        break;

                    case (byte)ExprToken.InterfaceCast:
                        if( Buffer.Version < PrimitveCastVersion )      // UE1
                        {
                            tokenItem = new IntToStringToken();
                        }
                        else
                        {
                            tokenItem = new InterfaceCastToken();
                        }
                        break;

                    // Redefined, can be RotatorToVector!(UE1)
                    case (byte)ExprToken.PrimitiveCast:
                        if( Buffer.Version < PrimitveCastVersion )      // UE1
                        {
                            tokenItem = new RotatorToVectorToken();
                        }
                        else                                            // UE2+
                        {
                            // Next byte represents the CastToken!
                            tokenCode = Buffer.ReadByte();
                            AlignSize( sizeof(byte) );

                            tokenItem = DeserializeCastToken( tokenCode );
                            //tokenitem = new PrimitiveCastToken();
                        }
                        break;
                    #endregion

                    #region Context
                    case (byte)ExprToken.ClassContext:
                        tokenItem = new ClassContextToken();
                        break;

                    case (byte)ExprToken.InterfaceContext:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new ByteToStringToken();
                        }
                        else
                        {
                            tokenItem = new InterfaceContextToken();
                        }
                        break;

                    case (byte)ExprToken.Context:
                        tokenItem = new ContextToken();
                        break;

                    case (byte)ExprToken.StructMember:
                        tokenItem = new StructMemberToken();
                        break;
                    #endregion

                    #region Assigns
                    case (byte)ExprToken.Let:
                        tokenItem = new LetToken();
                        break;

                    case (byte)ExprToken.LetBool:
                        tokenItem = new LetBoolToken();
                        break;

                    case (byte)ExprToken.EndParmValue:
                        tokenItem = new EndParmValueToken();
                        break;

                    // Redefined, can be FloatToBool!(UE1)
                    case (byte)ExprToken.LetDelegate:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new FloatToBoolToken();
                        }
                        else
                        {
                            tokenItem = new LetDelegateToken();
                        }
                        break;

                    // Redefined, can be NameToBool!(UE1)
                    case (byte)ExprToken.Conditional:
                        tokenItem = new ConditionalToken();
                        break;

                    case (byte)ExprToken.Eval: // case (byte)ExprToken.DynArrayFindStruct: case (byte)ExprToken.Conditional:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new NameToBoolToken();
                        }
                        else if( Buffer.Version >= 300 )
                        {
                            tokenItem = new DynamicArrayFindStructToken();
                        }
                        else
                        {
                            tokenItem = new ConditionalToken();
                        }
                        break;
                    #endregion

                    #region Jumps
                    case (byte)ExprToken.Return:
                        tokenItem = new ReturnToken();
                        break;

                    case (byte)ExprToken.ReturnNothing:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new ByteToIntToken();
                        }
                            // Definitely existed since GoW(490)
                        else if( Buffer.Version > 420 && (DeserializedTokens.Count > 0 && !(DeserializedTokens[DeserializedTokens.Count - 1] is ReturnToken)) ) // Should only be done if the last token wasn't Return
                        {
                            tokenItem = new DynamicArrayInsertToken();
                        }
                        else
                        {
                            tokenItem = new ReturnNothingToken();
                        }
                        break;

                    case (byte)ExprToken.GotoLabel:
                        tokenItem = new GoToLabelToken();
                        break;

                    case (byte)ExprToken.Jump:
                        tokenItem = new JumpToken();
                        break;

                    case (byte)ExprToken.JumpIfNot:
                        tokenItem = new JumpIfNotToken();
                        break;

                    case (byte)ExprToken.Switch:
                        tokenItem = new SwitchToken();
                        break;

                    case (byte)ExprToken.Case:
                        tokenItem = new CaseToken();
                        break;

                    case (byte)ExprToken.DynArrayIterator:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new RotatorToStringToken();
                        }
                        else
                        {
                            tokenItem = new ArrayIteratorToken();
                        }
                        break;

                    case (byte)ExprToken.Iterator:
                        tokenItem = new IteratorToken();
                        break;

                    case (byte)ExprToken.IteratorNext:
                        tokenItem = new IteratorNextToken();
                        break;

                    case (byte)ExprToken.IteratorPop:
                        tokenItem = new IteratorPopToken();
                        break;

                    case (byte)ExprToken.FilterEditorOnly:
                        tokenItem = new FilterEditorOnlyToken();
                        break;

                    #endregion

                    #region Variables
                    case (byte)ExprToken.NativeParm:
                        tokenItem = new NativeParameterToken();
                        break;

                    // Referenced variables that are from this function e.g. Local and params
                    case (byte)ExprToken.InstanceVariable:
                        tokenItem = new InstanceVariableToken();
                        break;

                    case (byte)ExprToken.LocalVariable:
                        tokenItem = new LocalVariableToken();
                        break;

                    case (byte)ExprToken.StateVariable:
                        tokenItem = new StateVariableToken();
                        break;

                    // Referenced variables that are default
                    case (byte)ExprToken.UndefinedVariable:
                        #if BORDERLANDS2
                            if( _Container.Package.Build == UnrealPackage.GameBuild.BuildName.Borderlands2 )
                            {
                                tokenItem = new DynamicVariableToken();
                                break;
                            }
                        #endif
                        tokenItem = new UndefinedVariableToken();
                        break;

                    case (byte)ExprToken.DefaultVariable:
                        tokenItem = new DefaultVariableToken();
                        break;

                    // UE3+
                    case (byte)ExprToken.OutVariable:
                        tokenItem = new OutVariableToken();
                        break;

                    case (byte)ExprToken.BoolVariable:
                        tokenItem = new BoolVariableToken();
                        break;

                    // Redefined, can be FloatToInt!(UE1)
                    case (byte)ExprToken.DelegateProperty:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new FloatToIntToken();
                        }
                        else
                        {
                            tokenItem = new DelegatePropertyToken();
                        }
                        break;

                    case (byte)ExprToken.DefaultParmValue:
                        if( Buffer.Version < PrimitveCastVersion )   // StringToInt
                        {
                            tokenItem = new StringToIntToken();
                        }
                        else
                        {
                            tokenItem = new DefaultParameterToken();
                        }
                        break;
                    #endregion

                    #region Misc
                    // Redefined, can be BoolToFloat!(UE1)
                    case (byte)ExprToken.DebugInfo:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new BoolToFloatToken();
                        }
                        else
                        {
                            tokenItem = new DebugInfoToken();
                        }
                        break;

                    case (byte)ExprToken.Nothing:
                        tokenItem = new NothingToken();
                        break;

                    case (byte)ExprToken.EndFunctionParms:
                        tokenItem = new EndFunctionParmsToken();
                        break;

                    case (byte)ExprToken.IntZero:
                        tokenItem = new IntZeroToken();
                        break;

                    case (byte)ExprToken.IntOne:
                        tokenItem = new IntOneToken();
                        break;

                    case (byte)ExprToken.True:
                        tokenItem = new TrueToken();
                        break;

                    case (byte)ExprToken.False:
                        tokenItem = new FalseToken();
                        break;

                    case (byte)ExprToken.NoDelegate:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new IntToFloatToken();
                        }
                        else
                        {
                            tokenItem = new NoDelegateToken();
                        }
                        break;

                        // No value passed to an optional parameter.
                    case (byte)ExprToken.NoParm:
                        tokenItem = new NoParmToken();
                        break;

                    case (byte)ExprToken.NoObject:
                        tokenItem = new NoObjectToken();
                        break;

                    case (byte)ExprToken.Self:
                        tokenItem = new SelfToken();
                        break;

                    // End of state code.
                    case (byte)ExprToken.Stop:
                        tokenItem = new StopToken();
                        break;

                    case (byte)ExprToken.Assert:
                        tokenItem = new AssertToken();
                        break;

                    case (byte)ExprToken.LabelTable:
                        tokenItem = new LabelTableToken();
                        break;

                    case (byte)ExprToken.EndOfScript:   //CastToken.BoolToString:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new BoolToStringToken();
                        }
                        else
                        {
                            tokenItem = new EndOfScriptToken();
                        }
                        break;

                    case (byte)ExprToken.Skip:
                        tokenItem = new SkipToken();
                        break;

                    case (byte)ExprToken.StructCmpEq:
                        tokenItem = new StructCmpEqToken();
                        break;

                    case (byte)ExprToken.StructCmpNE:
                        tokenItem = new StructCmpNeToken();
                        break;

                    case (byte)ExprToken.DelegateCmpEq:
                        tokenItem = new DelegateCmpEqToken();
                        break;

                    case (byte)ExprToken.DelegateFunctionCmpEq:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new IntToBoolToken();
                        }
                        else
                        {
                            tokenItem = new DelegateFunctionCmpEqToken();
                        }
                        break;

                    case (byte)ExprToken.DelegateCmpNE:
                        tokenItem = new DelegateCmpNEToken();
                        break;

                    case (byte)ExprToken.DelegateFunctionCmpNE:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new IntToBoolToken();
                        }
                        else
                        {
                            tokenItem = new DelegateFunctionCmpNEToken();
                        }
                        break;

                    case (byte)ExprToken.InstanceDelegate:
                        tokenItem = new InstanceDelegateToken();
                        break;

                    case (byte)ExprToken.EatString:
                        tokenItem = new EatStringToken();
                        break;

                    case (byte)ExprToken.New:
                        tokenItem = new NewToken();
                        break;

                    case (byte)ExprToken.FunctionEnd: // case (byte)ExprToken.DynArrayFind:
                        if( Buffer.Version < 300 )
                        {
                            tokenItem = new EndOfScriptToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayFindToken();
                        }
                        break;

                    case (byte)ExprToken.VarInt:
                    case (byte)ExprToken.VarFloat:
                    case (byte)ExprToken.VarByte:
                    case (byte)ExprToken.VarBool:
                    //case (byte)ExprToken.VarObject:   // See UndefinedVariable
                        if (_Container.Package.Build == UnrealPackage.GameBuild.BuildName.Mass_Effect)
                        {
                            // Don't know what this op code is for.... just know it takes two bytes.
                            tokenItem = new MassEffectUnknownToken();
                        }
                        else
                        {
                            tokenItem = new DynamicVariableToken();
                        }
                        break;
                    #endregion

                    #region Constants
                    case (byte)ExprToken.IntConst:
                        tokenItem = new IntConstToken();
                        break;

                    case (byte)ExprToken.ByteConst:
                        tokenItem = new ByteConstToken();
                        break;

                    case (byte)ExprToken.IntConstByte:
                        tokenItem = new IntConstByteToken();
                        break;

                    case (byte)ExprToken.FloatConst:
                        tokenItem = new FloatConstToken();
                        break;

                    // ClassConst?
                    case (byte)ExprToken.ObjectConst:
                        tokenItem = new ObjectConstToken();
                        break;

                    case (byte)ExprToken.NameConst:
                        tokenItem = new NameConstToken();
                        break;

                    case (byte)ExprToken.StringConst:
                        tokenItem = new StringConstToken();
                        break;

                    case (byte)ExprToken.UniStringConst:
                        tokenItem = new UniStringConstToken();
                        break;

                    case (byte)ExprToken.RotatorConst:
                        tokenItem = new RotatorConstToken();
                        break;

                    case (byte)ExprToken.VectorConst:
                        tokenItem = new VectorConstToken();
                        break;
                    #endregion

                    #region Functions
                    case (byte)ExprToken.FinalFunction:
                        tokenItem = new FinalFunctionToken();
                        break;

                    case (byte)ExprToken.VirtualFunction:
                        tokenItem = new VirtualFunctionToken();
                        break;

                    case (byte)ExprToken.GlobalFunction:
                        tokenItem = new GlobalFunctionToken();
                        break;

                    // Redefined, can be FloatToByte!(UE1)
                    case (byte)ExprToken.DelegateFunction:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new FloatToByteToken();
                        }
                        else
                        {
                            tokenItem = new DelegateFunctionToken();
                        }
                        break;
                    #endregion

                    #region Arrays
                    case (byte)ExprToken.ArrayElement:
                        tokenItem = new ArrayElementToken();
                        break;

                    case (byte)ExprToken.DynArrayElement:
                        tokenItem = new DynamicArrayElementToken();
                        break;

                    case (byte)ExprToken.DynArrayLength:
                        tokenItem = new DynamicArrayLengthToken();
                        break;

                    case (byte)ExprToken.DynArrayInsert:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new BoolToByteToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayInsertToken();
                        }
                        break;

                    case (byte)ExprToken.DynArrayInsertItem:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new VectorToStringToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayInsertItemToken();
                        }
                        break;

                    // Redefined, can be BoolToInt!(UE1)
                    case (byte)ExprToken.DynArrayRemove:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new BoolToIntToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayRemoveToken();
                        }
                        break;

                    case (byte)ExprToken.DynArrayRemoveItem:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new NameToStringToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayRemoveItemToken();
                        }
                        break;

                    case (byte)ExprToken.DynArrayAdd:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new FloatToStringToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayAddToken();
                        }
                        break;

                    case (byte)ExprToken.DynArrayAddItem:
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            tokenItem = new ObjectToStringToken();
                        }
                        else
                        {
                            tokenItem = new DynamicArrayAddItemToken();
                        }
                        break;

                    case (byte)ExprToken.DynArraySort:
                        tokenItem = new DynamicArraySortToken();
                        break;

                    // See FunctionEnd and Eval
                    /*case (byte)ExprToken.DynArrayFind:
                        break;

                    case (byte)ExprToken.DynArrayFindStruct:
                        break;*/

                    #endregion

                    default:
                    {
                        #region Casts
                        if( Buffer.Version < PrimitveCastVersion )
                        {
                            // No other token was matched. Check if it matches any of the CastTokens
                            // We don't just use PrimitiveCast detection due compatible with UE1 games
                            tokenItem = DeserializeCastToken( tokenCode );
                        }
                        break;
                        #endregion
                    }
                }

                if( tokenItem == null )
                {
                    tokenItem = new UnknownExprToken();
                }

                Console.Out.WriteLine("Token is: "+ tokenCode.ToString("X") + " type: " + tokenItem.GetType().Name + " pos: " + Buffer.Position);

                tokenItem.Decompiler = this;
                tokenItem.RepresentToken = tokenCode;
                tokenItem.Position = tokenPosition;// + (uint)Owner._ScriptOffset;
                tokenItem.StoragePosition = (uint)Buffer.Position - (uint)_Container.ScriptOffset - 1;
                // IMPORTANT:Add before deserialize, due the possibility that the tokenitem might deserialize other tokens as well.
                DeserializedTokens.Add( tokenItem );
                tokenItem.Deserialize( Buffer );
                // Includes all sizes of followed tokens as well! e.g. i = i + 1; is summed here but not i = i +1; (not>>)i ++;
                tokenItem.Size = (ushort)(CodePosition - tokenPosition);
                tokenItem.StorageSize = (ushort)((uint)Buffer.Position - (uint)_Container.ScriptOffset - tokenItem.StoragePosition);
                tokenItem.PostDeserialized();
                return tokenItem;
            }
示例#23
0
        public override void Generate(Generator generator)
        {
            Require.False(generated);
            Require.True(prepared);
            generated    = true;
            castFunction = new CallableCastFunction(this);
            castFunction.Generate(generator);

            generator.Resolver.EnterContext();
            generator.Resolver.SetContextParameters(parametersMetadata);
            generator.Resolver.CurrentFieldName = name.Data + "()";

            if (modifiers.Extern)
            {
                string className = ParentDefinition.Name.PrimaryName.Data;
                if (className == "pluk.base.Array")
                {
                    string s = ParentDefinition.Name.Data;
                    if (s == "pluk.base.Array<pluk.base.Int>")
                    {
                        className = "pluk.base.Array..pluk.base.Int";
                    }
                    else if (s == "pluk.base.Array<pluk.base.Bool>")
                    {
                        className = "pluk.base.Array..pluk.base.Bool";
                    }
                    else if (s == "pluk.base.Array<pluk.base.Byte>")
                    {
                        className = "pluk.base.Array..pluk.base.Byte";
                    }
                }
                string fieldName = name.Data;
                if (modifiers.ExternMetadata == null)
                {
                    string namespaceName = ParentDefinition.Name.PrimaryName.Namespace;
                    generator.AllocateAssembler();
                    parametersMetadata.Generate(generator);
                    ParameterMetadata thisParam = parametersMetadata.Find("this");
                    generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);

                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                    generator.Assembler.StartFunction();
                    generator.Assembler.SetupNativeReturnSpace();
                    int count = parametersMetadata.NativeArgumentCount();
                    generator.Assembler.SetupNativeStackFrameArgument(count);
                    parametersMetadata.WriteNative(generator.Assembler);
                    generator.Assembler.CallNative(generator.Importer.FetchImport(namespaceName, className, fieldName), count * 2, true, false);
                    generator.Assembler.StopFunction();
                    generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
                    generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "method-externed:" + ParentDefinition.Name.Data + "." + name.Data);
                    functionPointer = generator.Assembler.Region.BaseLocation;
                }
                else
                {
                    functionPointer = modifiers.ExternMetadata.Generate(generator, ParentDefinition.Name.PrimaryName, name, returnType, parametersMetadata);
                }
            }
            else
            {
                generator.AllocateAssembler();
                parametersMetadata.Generate(generator);
                ParameterMetadata thisParam = parametersMetadata.Find("this");
                if (modifiers.Static)
                {
                    Require.True(thisParam.TypeReference.IsStatic);
                }
                generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference);
                statementMetadata.Prepare(generator);
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
                generator.Assembler.StartFunction();
                JumpToken returnToken = generator.Assembler.CreateJumpToken();
                generator.Resolver.RegisterGoto("@return", returnToken);
                JumpToken recurToken = generator.Assembler.CreateJumpToken();
                generator.Assembler.SetDestination(recurToken);
                generator.Resolver.RegisterGoto("@recur", recurToken);
                statementMetadata.Generate(generator, returnType);
                if (modifiers.Abstract)
                {
                    generator.Assembler.Empty();
                    generator.Assembler.CrashIfNull();
                }
                else
                if ((returnType != null) && (!returnType.IsVoid) && (!statementMetadata.Returns()))
                {
                    throw new CompilerException(statementMetadata, string.Format(Resource.Culture, Resource.NotAllCodePathsReturnAValue));
                }
                generator.Assembler.SetDestination(returnToken);
                generator.Assembler.StopFunction();
                generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence);
                generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "method:" + ParentDefinition.Name.Data + "." + name.Data);
                functionPointer = generator.Assembler.Region.BaseLocation;
            }

            generator.Resolver.LeaveContext();
        }
示例#24
0
        public override void Generate(Generator generator, TypeReference returnType)
        {
            base.Generate(generator, returnType);
            if (statement.IsEmptyStatement())
            {
                throw new CompilerException(statement, string.Format(Resource.Culture, Resource.LoopStatementHasNoBody));
            }

            generator.Resolver.EnterContext();

            expression.Prepare(generator, null);
            expression.Generate(generator); // Iterator<slot> ?
            // create the field, and the hidden enumerator
            if (enumeratorType == null)
            {
                enumeratorType = expression.TypeReference;
            }
            else
            {
                enumeratorType.GenerateConversion(expression, generator, expression.TypeReference);
            }
            generator.Resolver.AddVariable(enumeratorName, enumeratorType, enumeratorSlot, true);
            generator.Resolver.AssignSlot(enumeratorSlot);
            // get the enumerator from the expression
            generator.Assembler.StoreVariable(enumeratorSlot);
            // start of the loop
            JumpToken loopToken = generator.Assembler.CreateJumpToken();

            generator.Assembler.SetDestination(loopToken);
            // move the enumerator and check if something is available
            move.Prepare(generator, null);
            move.Generate(generator);
            boolType.GenerateConversion(this, generator, move.TypeReference);
            JumpToken skipToken = generator.Assembler.CreateJumpToken();

            generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this);
            generator.Assembler.JumpIfFalse(skipToken);
            // something is available so put it in the field
            current.Prepare(generator, null);
            current.Generate(generator);
            if (type == null)
            {
                type = current.TypeReference;
            }
            if (name != null)
            {
                generator.Resolver.AddVariable(name, type, slot, true);
                type.GenerateConversion(this, generator, current.TypeReference);
                generator.Resolver.AssignSlot(slot);
                generator.Assembler.StoreVariable(slot);
            }
            // for body
            generator.Resolver.EnterContext();
            generator.Resolver.RegisterGoto("@continue", loopToken);
            generator.Resolver.RegisterGoto("@break", skipToken);
            statement.Generate(generator, returnType);
            generator.Resolver.LeaveContext();
            generator.Assembler.Jump(loopToken);
            generator.Assembler.SetDestination(skipToken);
            generator.Resolver.LeaveContext();
        }