public override void Prepare(Generator generator, Set <TypeReference> dependsUpon) { Require.False(prepared); Require.True(resolved); prepared = true; ParameterMetadata thisParam = parametersMetadata.Find("this"); if (modifiers.Static) { Require.True(thisParam.TypeReference.IsStatic); } dependsUpon.Put(ReturnType); Parameters.DependsUpon(dependsUpon); }
public ParameterMetadata AddParameter(ILocation location, TypeReference type, Identifier name) { if (name == null) { throw new ArgumentNullException("name"); } foreach (ParameterMetadata param in parameters) { Require.False(param.Name == name.Data); } ParameterMetadata pm = new ParameterMetadata(location, type, name); parameters.Add(pm); return(pm); }
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 void GenerateFunction(Generator generator) { Require.False(generated); generated = true; if (redirect != null) { redirect.node.GenerateFunction(generator); } else { foreach (ConstructorNodeInvocation i in inherit) { i.node.GenerateFunction(generator); } } generator.Resolver.EnterContext(); generator.Resolver.EnterFakeContext(definition); StringBuilder sb = new StringBuilder(); //sb.Append(parentDefinition.TypeReference.TypeName.Data); sb.Append("this"); //sb.Append(definition.TypeReference.TypeName.Data); parameters.PrettyPrint(sb); string name = sb.ToString(); generator.Resolver.CurrentFieldName = name; generator.AllocateAssembler(); parameters.Generate(generator); ParameterMetadata thisParam = parameters.Find("this"); generator.Resolver.SetImplicitFields(thisParam.Slot, thisParam.TypeReference); int thisslot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this")); generator.Resolver.IncompleteSlot(thisslot, false); statement.Prepare(generator); if (redirect == null) { definition.PrepareInitializer(generator); } generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location); generator.Assembler.StartFunction(); if (redirect != null) { redirect.Call(generator); } else { foreach (ConstructorNodeInvocation i in inherit) { i.Call(generator); } definition.GenerateInitializer(generator); } statement.Generate(generator, null); int slot = generator.Resolver.ResolveSlotOffset(new Identifier(location, "this")); generator.Resolver.RetrieveSlot(location, slot, false); foreach (Field field in definition.Fields) { if (generator.Resolver.IsFieldAssigned(field)) { assignedFields.Add(field); } } generator.Resolver.LeaveFakeContext(); generator.Resolver.LeaveContext(); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, location, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "constructor:" + parentDefinition.TypeReference.TypeName.Data + "." + name); functionPointer = generator.Assembler.Region.BaseLocation; }
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(); }