dev/studio-frame-composer-syscall-and-sprite-alignment #5

Merged
bquarkz merged 7 commits from dev/studio-frame-composer-syscall-and-sprite-alignment into master 2026-04-18 16:33:53 +00:00
2 changed files with 77 additions and 7 deletions
Showing only changes of commit a17dfde481 - Show all commits

View File

@ -85,13 +85,14 @@ class PbsGateUSdkInterfaceConformanceTest {
tempDir.resolve("gate-u-reserved-import-positive"),
"""
import { Color } from @core:color;
import { Composer } from @sdk:composer;
import { Gfx } from @sdk:gfx;
import { Input, InputPad, InputButton } from @sdk:input;
import { Assets } from @sdk:asset;
import { Log } from @sdk:log;
declare contract Renderer {
fn render(gfx: Gfx, color: Color, input: Input, pad: InputPad, button: InputButton, assets: Assets, log: Log) -> void;
fn render(composer: Composer, gfx: Gfx, color: Color, input: Input, pad: InputPad, button: InputButton, assets: Assets, log: Log) -> void;
}
""",
"pub contract Renderer;",
@ -115,6 +116,11 @@ class PbsGateUSdkInterfaceConformanceTest {
&& h.abiModule().equals("gfx")
&& h.abiMethod().equals("clear")
&& h.abiVersion() == 1));
assertTrue(positive.irBackend().getReservedMetadata().hostMethodBindings().stream()
.anyMatch(h -> h.ownerName().equals("LowComposer")
&& h.abiModule().equals("composer")
&& h.abiMethod().equals("emit_sprite")
&& h.abiVersion() == 1));
assertTrue(positive.irBackend().getReservedMetadata().hostMethodBindings().stream()
.anyMatch(h -> h.ownerName().equals("LowLog")
&& h.abiModule().equals("log")

View File

@ -1006,8 +1006,72 @@ class PBSFrontendPhaseServiceTest {
}
@Test
void shouldLowerSdkGfxSetSpriteFacadeUsingBankIdContract() throws IOException {
final var projectRoot = tempDir.resolve("project-bootstrap-sdk-gfx-set-sprite");
void shouldLowerSdkComposerEmitSpriteFacadeUsingCanonicalComposerContract() throws IOException {
final var projectRoot = tempDir.resolve("project-bootstrap-sdk-composer-emit-sprite");
final var sourceRoot = projectRoot.resolve("src");
final var modulePath = sourceRoot.resolve("app");
Files.createDirectories(modulePath);
final var sourceFile = modulePath.resolve("source.pbs");
final var modBarrel = modulePath.resolve("mod.barrel");
Files.writeString(sourceFile, """
import { Composer } from @sdk:composer;
fn render() -> int
{
return Composer.emit_sprite(7, 3, 12, 18, 0, 2, false, true, 1);
}
[Frame]
fn frame() -> void
{
render();
return;
}
""");
Files.writeString(modBarrel, """
pub fn render() -> int;
pub fn frame() -> void;
""");
final var projectTable = new ProjectTable();
final var fileTable = new FileTable(1);
final var projectId = projectTable.register(ProjectDescriptor.builder()
.rootPath(projectRoot)
.name("app")
.version("1.0.0")
.sourceRoots(ReadOnlyList.wrap(List.of(sourceRoot)))
.build());
registerFile(projectId, projectRoot, sourceFile, fileTable);
registerFile(projectId, projectRoot, modBarrel, fileTable);
final var ctx = new FrontendPhaseContext(
projectTable,
fileTable,
new BuildStack(ReadOnlyList.wrap(List.of(projectId))),
1);
final var diagnostics = DiagnosticSink.empty();
final var irBackend = new PBSFrontendPhaseService().compile(
ctx,
diagnostics,
LogAggregator.empty(),
BuildingIssueSink.empty());
assertTrue(diagnostics.stream().noneMatch(d ->
d.getCode().equals(PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name())));
assertTrue(irBackend.getExecutableFunctions().stream().anyMatch(function -> "frame".equals(function.callableName())));
assertTrue(irBackend.getReservedMetadata().hostMethodBindings().stream()
.anyMatch(h -> h.ownerName().equals("LowComposer")
&& h.sourceMethodName().equals("emit_sprite")
&& h.abiModule().equals("composer")
&& h.abiMethod().equals("emit_sprite")));
}
@Test
void shouldRejectLegacyGfxSetSpriteAfterComposerMigration() throws IOException {
final var projectRoot = tempDir.resolve("project-bootstrap-sdk-gfx-set-sprite-removed");
final var sourceRoot = projectRoot.resolve("src");
final var modulePath = sourceRoot.resolve("app");
Files.createDirectories(modulePath);
@ -1059,10 +1123,10 @@ class PBSFrontendPhaseServiceTest {
LogAggregator.empty(),
BuildingIssueSink.empty());
assertTrue(diagnostics.stream().noneMatch(d ->
d.getCode().equals(PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name())));
assertTrue(irBackend.getExecutableFunctions().stream().anyMatch(function -> "frame".equals(function.callableName())));
assertTrue(irBackend.getReservedMetadata().hostMethodBindings().stream()
assertTrue(diagnostics.stream().anyMatch(d ->
d.getCode().equals(PbsSemanticsErrors.E_SEM_INVALID_MEMBER_ACCESS.name())
|| d.getCode().equals(PbsSemanticsErrors.E_SEM_EXEC_LOWERING_UNRESOLVED_CALLEE.name())));
assertFalse(irBackend.getReservedMetadata().hostMethodBindings().stream()
.anyMatch(h -> h.ownerName().equals("LowGfx") && h.sourceMethodName().equals("set_sprite")));
}