All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.qbicc.object.ModuleSection Maven / Gradle / Ivy

There is a newer version: 0.77.0
Show newest version
package org.qbicc.object;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import io.smallrye.common.constraint.Assert;
import org.qbicc.context.CompilationContext;
import org.qbicc.graph.Value;
import org.qbicc.type.FunctionType;
import org.qbicc.type.TypeUtil;
import org.qbicc.type.ValueType;
import org.qbicc.type.definition.element.ExecutableElement;
import org.qbicc.type.definition.element.MemberElement;

/**
 * A section in a program module.
 * 

* A section has a simple name, which is translated into a target-specific form. For example, some * targets might requires sections to begin with a leading period ({@code .}) character. *

* Sections are loaded into {@linkplain Segment segments}. Segments are predefined program areas that the * linker handles in a specific manner. */ public final class ModuleSection extends ProgramObject implements Comparable { final ProgramModule programModule; final Section section; // the list of section objects, unindexed (see ProgramModule#moduleObjects), in order // protected by programModule final List objects = new ArrayList<>(); // protected by programModule long offset; ModuleSection(final Section section, final ValueType valueType, final ProgramModule programModule) { super(section.getName(), valueType); this.section = section; this.programModule = programModule; if (section.isDataOnly()) { offset = 0; } else { offset = -1; } } public Data addData(MemberElement originalElement, String name, Value value) { Data obj = new Data(originalElement, this, Assert.checkNotNullParam("name", name), Assert.checkNotNullParam("value", value).getType(), value ); Map definedObjects = programModule.moduleObjects; synchronized (programModule) { ProgramObject existing = definedObjects.get(name); long offset = TypeUtil.alignUp(this.offset, obj.getValueType().getAlign()); if (existing == null) { if (offset != -1) { // todo: max(obj align, type align) obj.initOffset(offset); this.offset = offset + obj.getSize(); } objects.add(obj); definedObjects.put(name, obj); } else { if (existing instanceof DataDeclaration decl) { if (! decl.getValueType().equals(obj.getValueType())) { programModule.clash(originalElement, name); } else { obj.initDeclaration(decl); if (offset != -1) { // todo: max(obj align, type align) obj.initOffset(offset); this.offset = offset + obj.getSize(); } objects.add(obj); definedObjects.replace(name, decl, obj); } } else { twice(originalElement, name); } } } return obj; } /** * Get the current data offset of this module section. * Each new data object will increase this offset based on its size and alignment. * * @return the current offset * @throws IllegalArgumentException if the section is not data-only */ public long getCurrentOffset() { long offset; synchronized (programModule) { offset = this.offset; } if (offset == -1) { throw new IllegalArgumentException("Not a data-only section"); } return offset; } private void twice(MemberElement originalElement, final String name) { CompilationContext ctxt = programModule.getTypeDefinition().getContext().getCompilationContext(); if (originalElement != null) { ctxt.error(originalElement, "Object '%s' defined twice", name); } else { ctxt.error("Synthetic object '%s' defined twice", name); } } public Function addFunction(ExecutableElement originalElement, String name, FunctionType type) { if (section.isDataOnly()) { throw dataOnlyException(); } Function obj = new Function(originalElement, this, Assert.checkNotNullParam("name", name), Assert.checkNotNullParam("type", type), Function.getFunctionFlags(originalElement) ); Map definedObjects = programModule.moduleObjects; synchronized (programModule) { ProgramObject existing = definedObjects.get(name); if (existing == null) { objects.add(obj); definedObjects.put(name, obj); } else { if (existing instanceof FunctionDeclaration decl) { if (! decl.getSymbolType().equals(obj.getSymbolType())) { programModule.clash(originalElement, name); } else { obj.initDeclaration(decl); objects.add(obj); definedObjects.replace(name, existing, obj); } } else if (existing instanceof Function) { twice(originalElement, name); } else { programModule.clash(originalElement, name); } } } return obj; } public Iterable contents() { synchronized (programModule) { return List.copyOf(objects); } } @Override public ProgramModule getProgramModule() { return programModule; } @Override public DataDeclaration getDeclaration() { return section.getSegmentStartDeclaration(programModule); } @Override public int compareTo(ModuleSection o) { return section.compareTo(o.section); } private static IllegalArgumentException dataOnlyException() { return new IllegalArgumentException("Cannot add function to data-only section"); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy