규칙 11.10
11장, 대상과 오라클 테스트
A compiled program’s manifest, what packModule() returns and what the default export of a module’s host import is, must be one JSON object that carries its schema (schema, 1) and the package version that wrote it (compiler); each binding with its group and slot, its resource in reflect()’s vocabulary, the stages that reach it, and a buffer’s byte layout with every offset, size and stride under the rule of its space (Rule 6.8), the _fp64 guard the emit adds among them; each entry with its stage, its workgroup size, its inputs and outputs with their locations, builtins and interpolation, the bindings it reaches and which it writes, a vertex entry’s vertex buffer, and its line; the overrides and the WebGPU features; with console, the recorded variant, its WGSL, its log table and its bindings; with ir, the program as portable IR and the package version that wrote it, which emitted again gives every other field byte for byte; and what the WebGL2 tier uses, each full-screen fragment entry’s GLSL ES 3.00 program, block names and texture-sampler pairs, and each storage array’s data texture.
A sampled texture’s resource must carry its sampleType, the word its bind group layout takes, from its element and the calls that read it: depth for a depth texture, uint or sint for an integer one, float for an f32 texture that a call of an entry, or of a function an entry calls, pairs with a sampler (a textureSample of any form or a textureGather, through a helper’s parameters or a const of the texture as well), and unfilterable-float for every other f32 texture: one the entries only load, measure or count, one no entry reaches, and a multisampled one, which no sampler reads.
A module with no entry is read whole, since a host writes its entries over it, and one with a raw statement in what its entries reach, whose text no analysis reads, has each f32 texture but a multisampled one float; reflect() reports the same word, and the WebGL2 tier’s texture-sampler pairs are read from the same calls.
A manifest packed under emit options (packModule(m, { emit }): an optimization level, parens, fp64Flavor and plugins) must hold the WGSL, the recorded variant’s WGSL, the GLSL (each WebGL2 draw’s program among it) and the bindings those options emit, the _fp64 guard of a module that emulates f64 among the bindings under the float flavor and none under the integer one; the GLSL writer has no level, so level is the WGSL’s alone.
It must record the level and the two named options, emit, so that the IR emitted again is emitted under them and gives every other field byte for byte.
A plugin is a function, which a manifest cannot record: ir with a plugin must be a TypeError that says the load-time emitter could not emit the program again, and a word an option does not take, which a writer reads as another, must be a TypeError that names what the option takes.
It is built from the IR alone, with no TypeScript, so every producer builds the same one; a reader must refuse a schema it does not know, naming both.
규칙 본문과 그 아래 항목은 설계 문서에 적힌 컴파일러 원문이라 한국어 페이지에서도 영어로 둡니다.
근거
a host that runs a program needed reflect() for its offsets, parsed type strings for its resources, and re-derived what the call layer computed privately; a stored program with no version cannot say which runtime reads it, which an engine’s shader cache needs; a texture’s sample type follows from the calls that read it, which only the compiler has, and a wrong one is a pipeline WebGPU refuses: float for an r32float texture the program only loads (#404), unfilterable-float for one a filtering sampler reads; a host that shows or ships a program under other emit options (an application’s WGSL tab) must run that program and not the default one, whose bindings the flavor changes (the guard), and a manifest that did not record how it was emitted could not be emitted again to agree with itself.
출처
changes 0025 (section 1) and 0028 (sections 2 and 4) in changes/; issues #335 (principle 4) and #404; Rule 6.8; measured on Dawn (Chromium 153 on SwiftShader): a texture laid out unfilterable-float beside a filtering sampler is refused when a textureSample, a textureSampleLevel, a textureGather, a helper’s parameters or a let pair them, and accepted when the texture is only loaded.
검증 방식
테스트로 확인합니다. 테스트나 게이트 스크립트, CI 워크플로가 이 규칙을 가리키고, 아래 파일 가운데 하나라도 규칙을 더는 가리키지 않으면 추적 검사가 실패합니다.
컴파일러가 이 규칙을 적용하는 곳을 규칙이 직접 적은 내용입니다.
buildManifest in src/core/manifest.ts, which packModule in src/compiler/ts/pack.ts and hostFace in src/compiler/ts/host-face.ts call, and which checks the emit options and hands the writers theirs, the level to emitModule in src/core/emit.ts; the sample type by reflect() in src/core/reflect.ts over the pairs texturePairs in src/core/passes/texture-pairs.ts reads; pinned by src/core/manifest.test.ts, over every example (schema, version, JSON round trip, slots, entries, offsets, vertex layout, the recorded variant, a data texture’s format against the GLSL, the call layer’s layouts, each texture’s sample type against the calls in its WGSL, and for each level and flavor the WGSL, the GLSL, the bindings, the recorded variant and the WebGL2 draws those options emit and repack giving the manifest back byte for byte, with each refusal’s sentence), by src/core/passes/texture-pairs.test.ts (each way a call pairs a texture with a sampler, and each it does not), and by src/vite.test.ts, which imports a module’s default export through the plugin and bundles it alone with no CPU tier.
커밋 c66579bf에서 이 규칙을 확인하는 파일입니다. 파일마다 규칙을 처음 가리키는 줄로 연결했습니다.
설명하는 절
커밋 c66579bf의 표면 문서에서 이 규칙을 설명하는 절입니다.
함께 보기
소스
커밋 c66579bf의 규칙 원문:
docs/language-design.md:1213(설계 문서)reqs/rules/RULE-1110.md(추적 항목)