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 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) { rootConstructorNode.GenerateFunction(generator); generator.Resolver.EnterContext(); generator.Resolver.CurrentFieldName = ConstructorName(); generator.AllocateAssembler(); parametersMetadata.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this); generator.Assembler.StartFunction(); generator.Assembler.CallAllocator(generator.Allocator, ParentDefinition.InstanceSize, ParentDefinition.RuntimeStruct); int thisslot = generator.Resolver.ResolveSlotOffset(new Identifier(this, "this")); generator.Resolver.IncompleteSlot(thisslot, false); generator.Assembler.StoreVariable(thisslot); generator.Assembler.SetTypePart(rootConstructorNode.RuntimeStruct); generator.Assembler.PushValue(); foreach (ParameterMetadata p in parametersMetadata.ParameterList) { generator.Assembler.RetrieveVariable(p.Slot); generator.Assembler.PushValue(); } Placeholder retSite = generator.Assembler.CallFromStack(parametersMetadata.ParameterList.Count); generator.AddCallTraceEntry(retSite, this, generator.Resolver.CurrentDefinition.Name.DataModifierLess, generator.Resolver.CurrentFieldName); generator.Resolver.LeaveContext(); generator.Assembler.RetrieveVariable(thisslot); generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, this, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "constructor:" + ParentDefinition.TypeReference.TypeName.Data + ".constructor"); functionPointer = generator.Assembler.Region.BaseLocation; castFunction = new CallableCastFunction(this); castFunction.Generate(generator); if (ParentDefinition.GarbageCollectable) { runtimeStruct.WriteNumber(1); } else { runtimeStruct.WriteNumber(0); } runtimeStruct.WritePlaceholder(castFunction.FunctionPointer); runtimeStruct.WriteNumber(0); runtimeStruct.WriteNumber(0); runtimeStruct.WritePlaceholder(functionPointer); runtimeStruct.WritePlaceholder(ParentDefinition.RuntimeStruct); generator.Symbols.WriteData(runtimeStruct.BaseLocation, runtimeStruct.Length, "ms:" + ParentDefinition.TypeReference.TypeName.Data + ".constructor"); }
public void Generate(Generator generator) { generator.AllocateAssembler(); functionPointer = generator.Assembler.Region.BaseLocation; Assembler a = generator.Assembler; generator.Symbols.Source(a.Region.BaseLocation, location); a.StartFunction(); //TODO: implementation ? a.Empty(); // the current type supports nothing, not even its own type... a.StopFunction(); generator.Symbols.Source(a.Region.CurrentLocation, location, SourceMark.EndSequence); generator.Symbols.WriteData(a.Region.BaseLocation, a.Region.Length, "ccf"); }
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 Placeholder Generate(Generator generator, Identifier primaryContextName, Identifier methodName, TypeReference returnType, Parameters parametersMetadata) { if (string.IsNullOrEmpty(xml)) { generator.AllocateAssembler(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName); generator.Assembler.CallNative(generator.Importer.FetchImport(primaryContextName.Namespace, primaryContextName.Data, methodName.Data), 0, false, true); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data); return(generator.Assembler.Region.BaseLocation); } else { generator.AllocateAssembler(); parametersMetadata.Generate(generator); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName); generator.Assembler.StartFunction(); if (parametersMetadata.ParameterList.Count != parameters.Count) { throw new ExternException(this, "Parameter count mismatch."); } string word = "int32"; if (Program.Linux_x86_64 || Program.Windows_x86_64) { word = "int64"; } generator.Assembler.SetupNativeReturnSpace(); for (int i = parameters.Count - 1; i >= 0; --i) { string type = parameters[i]; if (type == word) { generator.Assembler.RetrieveVariable(parametersMetadata.ParameterList[i].Slot); generator.Assembler.PushValuePart(); } else { throw new ExternException(this, "Unsupported type."); } } if (string.IsNullOrEmpty(library)) { throw new ExternException(this, "No library specified"); } if (string.IsNullOrEmpty(entrypoint)) { throw new ExternException(this, "No entrypoint specified"); } generator.Assembler.CallNative(generator.Importer.FetchImportAsPointer(library, entrypoint), parameters.Count, false, false); if (returns == word) { generator.Assembler.SetTypePart(intType.RuntimeStruct); returnType.GenerateConversion(this, generator, intType); } else if (returns == "void") { voidType.GenerateConversion(this, generator, returnType); generator.Assembler.Empty(); } else { throw new ExternException(this, "Unsupported return type."); } generator.Assembler.StopFunction(); generator.Symbols.Source(generator.Assembler.Region.CurrentLocation, methodName, SourceMark.EndSequence); generator.Symbols.WriteCode(generator.Assembler.Region.BaseLocation, generator.Assembler.Region.Length, "extern:" + primaryContextName.Data + "." + methodName.Data); return(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(); }