Skip to content

chore: Refactor GPU function call mechanism - #2919

Merged
iwoplaza merged 3 commits into
mainfrom
chore/refactor-fn-calls
Nov 5, 2026
Merged

iwoplaza merged 3 commits into
mainfrom
chore/refactor-fn-calls

Conversation

@iwoplaza

@iwoplaza iwoplaza commented Aug 25, 2026 •

Copy link
Copy Markdown
Collaborator

Changes:

  • Struct and array schemas now take care of what happens when somebody calls them.
  • Struct instantiations now have the constant origin where applicable.
  • Separated the $gpuCallable object into just having the method be on the symbol, and strictSignature be a separate symbol: $gpuCallableStrictSignature. This was done so that the method can live on the class prototype and refer to properties of the instance.
  • Generating argument snippets out of tinyest nodes is now a seperate step from actually calling a function. This allows other parts of the generator to call helper functions without needing to reach into the deep internals via symbols (helpful in GLSL generation as well as the future matrix std function rewrites)

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from ae39d1b to 08937bf Compare August 25, 2026 11:46
@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Resolution Time Benchmark

---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Random Branching (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.83, 1.72, 3.91, 6.23, 6.49, 10.43, 21.63, 20.80]
  line [0.83, 1.71, 3.79, 5.98, 7.48, 12.31, 22.42, 25.37]
  line [1.09, 2.08, 4.78, 7.51, 8.64, 14.66, 27.26, 29.80]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Linear Recursion (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.20, 0.40, 0.55, 0.66, 0.90, 1.03, 1.23, 1.28]
  line [0.24, 0.45, 0.60, 0.74, 0.97, 1.02, 1.15, 1.29]
  line [0.29, 0.53, 0.77, 0.93, 1.17, 1.29, 1.51, 1.73]
Loading
---
config:
  themeVariables:
    xyChart:
      plotColorPalette: "#E63946, #3B82F6, #059669"
---
xychart
  title "Full Tree (🔴 PR | 🔵 main | 🟢 release)"
  x-axis "max depth" [1, 2, 3, 4, 5, 6, 7, 8]
  y-axis "time (ms)"
  line [0.77, 2.06, 3.79, 6.96, 12.69, 23.07, 50.99, 101.57]
  line [0.80, 2.07, 3.49, 6.71, 11.36, 24.90, 50.67, 105.94]
  line [0.95, 2.56, 4.04, 8.54, 15.28, 30.82, 61.87, 129.17]
Loading

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 08937bf to 2c95c24 Compare August 25, 2026 12:46
@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

pkg.pr.new

packages
Ready to be installed by your favorite package manager ⬇️

https://pkg.pr.new/software-mansion/TypeGPU/tgpu-gen@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/typegpu@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/cli@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/color@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/gl@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/@typegpu/radiance-cascades@fca6640dceb19c83d3d64c52d84fda40fdc23983
https://pkg.pr.new/software-mansion/TypeGPU/unplugin-typegpu@fca6640dceb19c83d3d64c52d84fda40fdc23983

benchmark
view benchmark

commit
view commit

@github-actions

github-actions Bot commented Aug 25, 2026 •

Copy link
Copy Markdown

Bundle size comparison (import * as ... in PR vs import * as ... in target):

🟢 Decreased ➖ Unchanged 🔴 Increased (max 497.51%) ❔ Unknown
0 3 353 0

import * as ... in PR vs import * as ... in target (did bundle size increase?):

Click to reveal the results table (65 entries).
Test tsdown
d_struct.ts 23.18 kB ($${\color{red}+497.5\%}$$)
d_Void.ts 850 B ($${\color{red}+6.4\%}$$)
d_sampler.ts 858 B ($${\color{red}+6.3\%}$$)
d_isPtr.ts 868 B ($${\color{red}+6.2\%}$$)
d_comparisonSampler.ts 869 B ($${\color{red}+6.2\%}$$)
d_isSizeAttrib.ts 870 B ($${\color{red}+6.2\%}$$)
d_isWgslArray.ts 870 B ($${\color{red}+6.2\%}$$)
d_isAlignAttrib.ts 871 B ($${\color{red}+6.2\%}$$)
d_isAtomic.ts 871 B ($${\color{red}+6.2\%}$$)
d_isWgslStruct.ts 871 B ($${\color{red}+6.2\%}$$)
d_isBuiltinAttrib.ts 873 B ($${\color{red}+6.2\%}$$)
d_isDecorated.ts 874 B ($${\color{red}+6.2\%}$$)
d_isLocationAttrib.ts 874 B ($${\color{red}+6.2\%}$$)
d_isInvariantAttrib.ts 875 B ($${\color{red}+6.2\%}$$)
d_isInterpolateAttrib.ts 877 B ($${\color{red}+6.2\%}$$)
d_atomic.ts 895 B ($${\color{red}+6.0\%}$$)
d_ptrHandle.ts 967 B ($${\color{red}+5.6\%}$$)
d_ptrUniform.ts 968 B ($${\color{red}+5.6\%}$$)
d_ptrStorage.ts 972 B ($${\color{red}+5.5\%}$$)
d_ptrPrivate.ts 974 B ($${\color{red}+5.5\%}$$)
d_ptrFn.ts 975 B ($${\color{red}+5.5\%}$$)
d_ptrWorkgroup.ts 976 B ($${\color{red}+5.5\%}$$)
d_textureExternal.ts 989 B ($${\color{red}+5.4\%}$$)
d_textureStorage1d.ts 1.13 kB ($${\color{red}+4.6\%}$$)
d_textureStorage2d.ts 1.13 kB ($${\color{red}+4.6\%}$$)
d_textureStorage3d.ts 1.13 kB ($${\color{red}+4.6\%}$$)
d_textureStorage2dArray.ts 1.14 kB ($${\color{red}+4.6\%}$$)
d_isDisarray.ts 1.23 kB ($${\color{red}+4.2\%}$$)
d_isUnstruct.ts 1.23 kB ($${\color{red}+4.2\%}$$)
d_isLooseDecorated.ts 1.23 kB ($${\color{red}+4.2\%}$$)
d_isLooseData.ts 1.27 kB ($${\color{red}+4.1\%}$$)
d_isWgslData.ts 1.42 kB ($${\color{red}+3.6\%}$$)
d_arrayOf.ts 34.97 kB ($${\color{red}+3.3\%}$$)
d_builtin.ts 37.49 kB ($${\color{red}+3.1\%}$$)
common_fullScreenTriangle.ts 50.50 kB ($${\color{red}+2.9\%}$$)
d_unstruct.ts 1.78 kB ($${\color{red}+2.9\%}$$)
tgpu_slot.ts 1.79 kB ($${\color{red}+2.9\%}$$)
d_isData.ts 1.92 kB ($${\color{red}+2.7\%}$$)
STATIC_common.ts 58.71 kB ($${\color{red}+2.5\%}$$)
STATIC_d.ts 73.27 kB ($${\color{red}+2.0\%}$$)
std_atomicCompareExchangeWeak.ts 24.64 kB ($${\color{red}+1.5\%}$$)
tgpu_unroll.ts 2.46 kB ($${\color{red}+1.5\%}$$)
std_frexp.ts 39.13 kB ($${\color{red}+1.3\%}$$)
std_modf.ts 39.26 kB ($${\color{red}+1.3\%}$$)
tgpu_accessor.ts 69.85 kB ($${\color{red}+1.3\%}$$)
tgpu_mutableAccessor.ts 69.85 kB ($${\color{red}+1.3\%}$$)
tgpu_computeFn.ts 47.03 kB ($${\color{red}+1.1\%}$$)
tgpu_vertexFn.ts 47.58 kB ($${\color{red}+1.1\%}$$)
tgpu_fragmentFn.ts 47.76 kB ($${\color{red}+1.1\%}$$)
common_writeChannels.ts 5.58 kB ($${\color{red}+0.9\%}$$)
tgpu_lazy.ts 64.14 kB ($${\color{red}+0.8\%}$$)
tgpu_const.ts 64.34 kB ($${\color{red}+0.8\%}$$)
tgpu_workgroupVar.ts 64.92 kB ($${\color{red}+0.8\%}$$)
tgpu_privateVar.ts 64.93 kB ($${\color{red}+0.8\%}$$)
tgpu_bindGroupLayout.ts 71.58 kB ($${\color{red}+0.7\%}$$)
tgpu_comptime.ts 21.73 kB ($${\color{red}+0.6\%}$$)
std_extensionEnabled.ts 21.94 kB ($${\color{red}+0.6\%}$$)
std_range.ts 22.21 kB ($${\color{red}+0.6\%}$$)
d_disarrayOf.ts 22.43 kB ($${\color{red}+0.6\%}$$)
d_deepEqual.ts 23.08 kB ($${\color{red}+0.6\%}$$)
d_schemasEqualNominally.ts 23.08 kB ($${\color{red}+0.6\%}$$)
d_schemasEqualStructurally.ts 23.08 kB ($${\color{red}+0.6\%}$$)
std_isBeingTranspiled.ts 22.24 kB ($${\color{red}+0.5\%}$$)
std_getShaderStage.ts 22.29 kB ($${\color{red}+0.5\%}$$)
std_getTargetShaderLanguage.ts 22.30 kB ($${\color{red}+0.5\%}$$)

If you wish to run a comparison for other, slower bundlers, run the 'Tree-shake test' from the GitHub Actions menu.

@iwoplaza
iwoplaza marked this pull request as ready for review August 25, 2026 19:56
Copilot AI lite review requested due to automatic review settings August 25, 2026 19:56

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Refactors TypeGPU’s GPU-callable invocation model by moving call behavior onto schemas/functions themselves and separating strict signature metadata from the call implementation, with WGSL generation updated to route all calls through a unified ShaderGenerator.call(...) path.

Changes:

  • Replace the $gpuCallable object-with-.call(...) pattern with a direct callable symbol function and introduce $gpuCallableStrictSignature for strict signature metadata.
  • Centralize call handling in WgslGenerator.call(...), including strict-signature-based argument conversion and improved argument count diagnostics.
  • Update schemas (struct/array) and standard library helpers to implement the new calling convention; adjust tests to match updated error messages and typing behavior.

Reviewed changes

Copilot reviewed 24 out of 24 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
packages/typegpu/tests/tgsl/wgslGenerator.test.ts Updates inline snapshot for new strict-signature argument count error message.
packages/typegpu/tests/struct.test.ts Updates snapshot message and removes non-null assertions to match new call/type behavior.
packages/typegpu/tests/bindGroupLayout.test.ts Removes non-null assertion in schema call usage.
packages/typegpu/tests/array.test.ts Updates inline snapshot for new strict-signature argument count error message.
packages/typegpu/src/types.ts Introduces GPUCallableStrictSignature, reshapes GPUCallable, and tightens generateLog args type to readonly.
packages/typegpu/src/tgsl/wgslGenerator.ts Adds centralized call(...) method and refactors call-expression generation to use it.
packages/typegpu/src/tgsl/shaderGenerator.ts Adds call(callee, args) to the ShaderGenerator interface.
packages/typegpu/src/tgsl/forOfUtils.ts Updates arrayLength GPU-callable invocation to the new $gpuCallable(ctx, args) form.
packages/typegpu/src/std/numeric.ts Adjusts variadic helper typing to accept readonly tuples.
packages/typegpu/src/std/matrix.ts Updates std matrix wrappers to bind the new $gpuCallable function directly.
packages/typegpu/src/std/environment.ts Converts $gpuCallable implementation to a direct function.
packages/typegpu/src/shared/symbols.ts Adds $gpuCallableStrictSignature symbol.
packages/typegpu/src/data/wgslTypes.ts Refactors WgslStruct/WgslArray types to extend DualFn for unified call typing.
packages/typegpu/src/data/vertexFormatData.ts Converts $gpuCallable implementation to a direct function.
packages/typegpu/src/data/struct.ts Moves struct schema call behavior into $gpuCallable and provides strict signature metadata.
packages/typegpu/src/data/snippet.ts Makes MapValueToSnippet<T> readonly to better align with readonly argument flows.
packages/typegpu/src/data/schemaCallWrapper.ts Updates schema GPU-call wrapper to use $gpuCallable(ctx, args) form.
packages/typegpu/src/data/ref.ts Converts _ref GPU-callable implementation to a direct function.
packages/typegpu/src/data/array.ts Moves array schema call behavior into $gpuCallable and provides strict signature metadata.
packages/typegpu/src/core/unroll/tgpuUnroll.ts Converts unroll GPU-callable implementation to a direct function.
packages/typegpu/src/core/slot/accessor.ts Updates GPU-callable accessors to use $gpuCallable(ctx, []).
packages/typegpu/src/core/function/dualImpl.ts Splits strict signature metadata onto $gpuCallableStrictSignature and updates $gpuCallable to a direct function.
packages/typegpu/src/core/function/createCallableSchema.ts Converts callable schema GPU-callable implementation to a direct function.
packages/typegpu/src/core/function/comptime.ts Moves comptime GPU-callable behavior onto a shared prototype and updates internal metadata shape.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment thread packages/typegpu/src/types.ts Resolved
Comment thread packages/typegpu/src/shared/symbols.ts Resolved

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — single commit 2c95c245 ("chore: Refactor GPU function call mechanism"): struct and array schemas now own their call semantics through $gpuCallable, the $gpuCallable symbol changed shape (callable (ctx, args) => Snippet plus a separate $gpuCallableStrictSignature), and argument-snippet generation was split out of call resolution into a new WgslGenerator.call(callee, args) funnel that _expression and generators can share.

Verified end-to-end: the full packages/typegpu suite (176 files / 2362 tests) and @typegpu/gl (58 tests) pass, and test:types is green on both packages. The struct/array codegen that moved out of _expression into the schema impls maps onto typeInstantiation with identical output for the WGSL generator and the GLSL GlslGenerator override (verified by tracing the array/struct paths through typeInstantiation), so downstream behavior is unchanged. The rewritten over-arity error messages have their snapshots updated in all four touched tests. No leftover consumers of the old object-shaped $gpuCallable anywhere, and no other package implements the symbol.

ℹ️ Redundant second conversion of strict-signature arguments

On AST-backed calls to a strict-signature callable, argument snippets are converted twice: once in the _expression branch via _typedExpression(arg, argType) (which also sets ctx.expectedType, needed for literal typing) and again inside WgslGenerator.call at the isGPUCallable/strict-signature branch. The second pass is a type-preserving no-op (tryConvertSnippet short-circuits on target === dataType), and the schema impls re-run tryConvertSnippet a third time on the already-typed value, so the behavior is correct — just redundant. This includes the pre-existing arrangement, so it is not a regression, but since call() is now the documented funnel for generators, it is worth deciding where conversion is owned once.

Technical details
# Strict-signature argument conversion happens three times

## Affected sites
- packages/typegpu/src/tgsl/wgslGenerator.ts:819-836 (_expression strict-signature branch) — converts via `_typedExpression`
- packages/typegpu/src/tgsl/wgslGenerator.ts:461-471 (call()'s strict-signature branch) — converts via `tryConvertSnippet`
- packages/typegpu/src/data/array.ts:137 and packages/typegpu/src/data/struct.ts:100 — schema impls convert a third time

## Required outcome
- No behavior change; evaluate whether the second and third conversions can be removed without losing the `expectedType` hint that `_typedExpression` provides.

ℹ️ Naming: call sits ambiguously next to emitCall

The new ShaderGenerator.call(callee, args) (returns a Snippet) reads confusingly against the existing emitCall(name, templateParams, args) (returns a string that emits the resolved call text), which std codegenImpls and GlslGenerator override. Since ShaderGenerator is already marked unstable, a more distinct name for the invoke-and-resolve path (e.g. callGpu/resolveCall) would spare downstream generator authors a footgun.

Technical details
# Naming ambiguity: `call` vs `emitCall`

## Affected sites
- packages/typegpu/src/tgsl/shaderGenerator.ts:126 — `call(callee: AnyFn, args: readonly Snippet[]): Snippet`
- packages/typegpu/src/tgsl/shaderGenerator.ts:127 — `emitCall(name: string, templateParams: readonly Snippet[], args: readonly Snippet[]): string`

## Required outcome
- Decide on a name for `call` that does not collide conceptually with `emitCall`; renames only touch the unstable interface and the typegpu-gl generator, which inherits from WgslGenerator.

Also nice touch: dropping the now-unnecessary ! non-null assertions in the two struct/bind-group tests under the new DualFn-based WgslArray typing.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 2c95c24 to 8a1f015 Compare August 26, 2026 09:45

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

Reviewed changes — incremental delta (2c95c24 → 8a1f0151) on this force-pushed single-commit branch:

  • Split WgslGenerator._typedExpression into _expressionWithTypeSuggestion (sets ctx.expectedType, evaluates, no conversion) and _expressionWithTypeConversion (suggestion then tryConvertSnippet, preserving the AutoStruct skip). All conversion call sites renamed accordingly across wgslGenerator, glslGenerator, and parseResolved.
  • The tinyest NODE.call strict-signature branch now evaluates args via _expressionWithTypeSuggestion only, moving the single conversion into WgslGenerator.call()'s strict-signature branch. This eliminates the redundant double/triple conversion flagged in the prior review — behavior is preserved (suggestion+convert semantics identical at every call site, AutoStruct handling intact).
  • Made generateLog's args param readonly in the ResolutionCtx, LogGenerator, and GPUCallable types (implementation keeps a mutable signature, valid under method bivariance), and adjusted the std variadic readonly tuple typing.
  • Added emitBinaryOp to the ShaderGenerator interface (already implemented in WgslGenerator and overridden in GlslGenerator) and documented the call vs emit* split — addressing the prior naming-ambiguity note via docs rather than a rename, which is a reasonable call.

I verified the split is behavior-preserving at each call site and ran the green checks: typegpu 198 tests, tgsl 406, @typegpu/gl 58, and test:types on typegpu. Both prior informational concerns are cleanly addressed; no new issues found.

Pullfrog  | View workflow run | Using DeepSeek Flash (free via Pullfrog for OSS) | 𝕏

@aleksanderkatan

Copy link
Copy Markdown
Member

Hey, is this reviewable?

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 8a1f015 to 976ae30 Compare October 26, 2026 12:41

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦)

Avast! I re-boarded this here PR, compared the latest commit with the prior review, and checked the new diagnostics, source-node handlin', and rebase adaptations. The whole fleet o' typegpu tests passed, so I be approvin' this voyage.

Reviewed changes — incremental delta (8a1f0151 → 976ae308) since the previous pullfrog review:

  • Rebased the refactor onto current main, dropping the branch-local isKnownAtComptime in favor of upstream asComptime across the comptime fast paths (comptime, dualImpl, callableSchema, generator eval sites), and adapting to isStoredInMemory and the immediate origin.
  • WgslGenerator.call() now accepts the callee's source snippet and re-attaches source nodes to strict-signature-converted arguments, restoring descriptive Function 'fns[0]' is not marked with the 'use gpu' directive diagnostics now that call() no longer receives a callee snippet.
  • Over-arity diagnostics now report the signature's maximum arity (expected at most N argument(s)), with snapshots updated in the array, struct, and generator tests; removed the dead duplicate "not marked with 'use gpu'" throw in the AST call branch.
  • Boid().pos member-access snapshot origin changed runtime → constant because zero-arg struct construction now resolves through typeInstantiation (empty args are constant), which is behavior-neutral.

Verified: full typegpu suite (200 files, 2980 tests), @typegpu/gl (154 passed, 2 skipped), and tsc --noEmit for both packages are green. Both prior informational concerns remain resolved; no new actionable issues.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦)

Aye, a fresh commit sailed in while I were writin' the last review. I inspected it close: it be a tidy fix to the comptime prototype chain, and the new test guards it. Shipshape, says I.

Reviewed changes — incremental delta (976ae308 → 646f147) since the previous pullfrog review:

  • Restored Function.prototype at the end of the comptime prototype chain (Object.setPrototypeOf(ComptimePrototype, Function.prototype)), so tgpu.comptime results keep call/apply/bind and satisfy instanceof Function after impl's prototype was replaced by the plain ComptimePrototype object. The existing toString override still reports 'comptime'.
  • Added a regression test in tests/tgsl/comptime.test.ts covering instanceof Function, call, apply, bind, and String(double).

Verified at 646f147: full typegpu suite (200 files, 2981 tests) and tsc --noEmit are green. The fix is correct and targets exactly the gap it describes; no new actionable issues.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 646f147 to d54b257 Compare October 26, 2026 17:56

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

✅ ( ◦°^°◦)

Avast! I re-boarded this here PR, compared the fresh commit against the last review, and spied naught but a tidy prototype reshuffle below deck. The whole typegpu fleet still sails green, so I be approvin' this voyage.

Reviewed changes — incremental delta (646f147 → d54b257) since the previous pullfrog review:

  • Vertex-format schemas moved to a prototype $gpuCallable — TgpuVertexFormatDataImpl now implements [$gpuCallable](ctx, [v]) as a prototype method rather than assigning a per-instance arrow property in its constructor, and relocates the [$internal] marker from an own field to the prototype via a static {} initializer. This matches the existing WgslStructImpl/WgslArrayImpl prototype pattern.
  • Behavior-preserving — every call site (schemaCallWrapperGPU) invokes it as schema[$gpuCallable](...), so this.type stays correctly bound; host-side [$cast] and the isPackedData/isMarkedInternal checks resolve the same through the prototype chain.
  • The comptime Function.prototype fix and its regression test are unchanged from 646f147 and were already reviewed.

Verified at d54b257: full typegpu suite (200 files / 2981 tests) and tsc --noEmit are green.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

( ◦°^°◦) ✅

Avast! I re-boarded PR #2919, spied the fresh commits, and found the only new cargo be the cap'n's rebase onto a newer main — nary a line o' the refactor itself changed. I re-checked the seams and the tests sail green, so I be approvin' again.

✅ No new issues found.

Reviewed changes — incremental delta (d54b257 → e98f49b) since the previous pullfrog review:

  • Pure rebase — no authored changes. A direct tree diff (git diff-tree d54b257 e98f49b) shows the PR's own files are byte-identical to the previously reviewed d54b257; the branch is now squashed to two commits on current main (0069f48).
  • #3279 arrived via the rebase — adds Object.setPrototypeOf(<Impl>, Function.prototype) to WgslArrayImpl/WgslStructImpl/DisarrayImpl/UnstructImpl plus tests/schemaPrototype.test.ts. Already merged upstream, so these sit as context (not + lines) in the PR diff.
  • #3252 arrived via the rebase — attribute() now replaces a same-type attribute (withAttribute/WithoutAttribute) and schemasEqual compares the exact deduped attrib list; tests/attributes.test.ts.
  • Refactor + comptime fix unchanged — the $gpuCallable/$gpuCallableStrictSignature shape, the WgslGenerator.call funnel, the struct/array schema impls, and the comptime Function.prototype fix with its regression test are all identical to the previously approved state.

Verified at e98f49b: tests/array, tests/struct, tests/attributes, tests/schemaPrototype, tests/bindGroupLayout, and tests/tgsl are green (29 files / 662 tests), and tsc --noEmit for packages/typegpu is clean. All prior pullfrog reviews carry zero open threads.

Pullfrog  | Fix it ➔ | View workflow run | Using deepseek-v4.1-flash (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from e98f49b to 6bcd630 Compare October 27, 2026 12:17
Comment thread packages/typegpu/src/data/struct.ts Resolved
// we can use internally to work with generic arrays.
export interface WgslArray<out TElement extends BaseData = BaseData> extends BaseData {
export interface WgslArray<out TElement extends BaseData = BaseData>
extends BaseData, GPUCallable<[elements?: Infer<TElement>[]]> {

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a reason why array extends GPUCallable but struct extends DualFn?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To keep it consistent, I moved both to use GPUCallable, I think it's cleaner anyway

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 6bcd630 to d280a66 Compare November 4, 2026 06:51

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦) 🏴‍☠️

Avast! I re-boarded this here PR, spied the fresh "Review fixes" commit, and found naught but two tidy repairs to the cap'n's review — shipshape and all hands green.

Reviewed changes — incremental delta (d280a66 → 8bfb92d) since the previous pullfrog review:

  • Restored this === undefined for non-arrow comptime functions — ComptimePrototype[$gpuCallable] now invokes the wrapped function via .apply(undefined, args) instead of this[$internal].func(...args), which had bound this to the callable object. This matches the pre-refactor closure call, and the host-side impl(...) wrapper already behaved this way.
  • Struct copy origin now falls through from its argument — WgslStructImpl[$gpuCallable] uses fallthroughCopyOrigin(arg.origin) instead of a hard-coded 'runtime', matching array.ts and WgslGenerator.typeInstantiation. The only behavioral delta is Struct(<constant snippet>) now yielding a 'constant' snippet; object-literal arguments stay 'runtime' (the objectExpr branch always produces 'runtime') and tgpu.const reads stay 'constant-immutable-def' → 'runtime'.

Both are fixes for the open human review feedback on struct copy origin and comptime this binding. Verified at 8bfb92d: full typegpu suite green (206 files / 3084 tests), @typegpu/gl green (154 passed, 2 skipped), and tsc --noEmit for packages/typegpu clean.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 8bfb92d to 57c05ae Compare November 4, 2026 07:04

@pullfrog pullfrog Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ No new issues found.

( ◦°^°◦) 🏴‍☠️

Avast! I re-boarded this here PR, spied the fresh "Review fixes" commit, and found naught but a tidy type alignment — shipshape and all hands green.

Reviewed changes — incremental delta (8bfb92d → 57c05ae9) since the previous pullfrog review:

  • WgslStruct switched from DualFn to GPUCallable — it now extends BaseData, TgpuNamable, GPUCallable<[props?: Prettify<InferRecord<TProps>>]> with one explicit (props?: ...): ... signature, so struct and array schemas express their call type the same way. This resolves the open human review question on wgslTypes.ts.
  • Structurally identical to the previous declaration — DualFn<T> = T & GPUCallable<Parameters<T>>, and the old (props) / () overloads collapse into a single optional-param signature, so there is no runtime, codegen, or diagnostic change. test:types (tsc --noEmit) for packages/typegpu is green.

Pullfrog  | View workflow run | Using deepseek-v4.1-flash-1017 (free via Pullfrog for OSS) | 𝕏

@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from 57c05ae to b5ca2aa Compare November 4, 2026 07:22
@iwoplaza
iwoplaza requested a review from cieplypolar November 4, 2026 07:23
@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from b5ca2aa to d6224cd Compare November 5, 2026 13:54
@iwoplaza
iwoplaza enabled auto-merge (squash) November 5, 2026 13:55
@iwoplaza
iwoplaza force-pushed the chore/refactor-fn-calls branch from d6224cd to fca6640 Compare November 5, 2026 15:19
@iwoplaza
iwoplaza disabled auto-merge November 5, 2026 15:26
@iwoplaza
iwoplaza merged commit c918968 into main Nov 5, 2026
9 checks passed
@iwoplaza
iwoplaza deleted the chore/refactor-fn-calls branch November 5, 2026 15:26
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants