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 Generate(Generator generator, TypeReference returnType) { base.Generate(generator, returnType); expression.Prepare(generator, null); expression.Generate(generator); generator.Assembler.StoreVariable(slot); generator.Resolver.EnterContext(); generator.Resolver.AddVariable(new Identifier(this, Guid.NewGuid().ToString("B")), expression.TypeReference, slot, true); if (!expression.TypeReference.IsDefinition && !expression.TypeReference.IsStatic) { throw new CompilerException(this, Resource.CanOnlyUseWithOnNotNullClassInstances); } generator.Resolver.SetImplicitFields(slot, expression.TypeReference); statement.Generate(generator, returnType); returns = statement.Returns(); generator.Resolver.LeaveAndMergeContext(); }
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, 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); }
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(); }