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); }
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; }
/// <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()); }
/// <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()); }
/// <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()); }
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(); } }
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()); }
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()); }
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); }
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()); }
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); }
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; }
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); }
/// <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); }
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); }
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); } }
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); } }
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); } }
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); }
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); } } }
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); }
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; }
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(); }
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(); }