@@ -237,6 +237,36 @@ func (m *Machine[T]) evalBuiltinAppWithArg(
237237 return m .evalBuiltinAppReady (fn , forces , argCount , & finalArgs )
238238}
239239
240+ type oneArgCost struct {
241+ mem OneArgument
242+ cpu OneArgument
243+ constant bool
244+ }
245+
246+ func newOneArgCostCache (
247+ costs BuiltinCosts ,
248+ ) [builtin .TotalBuiltinCount ]oneArgCost {
249+ var ret [builtin .TotalBuiltinCount ]oneArgCost
250+ for i , model := range costs {
251+ if model == nil {
252+ continue
253+ }
254+
255+ mem , memOK := model .mem .(OneArgument )
256+ cpu , cpuOK := model .cpu .(OneArgument )
257+ if ! memOK || ! cpuOK {
258+ continue
259+ }
260+
261+ ret [i ] = oneArgCost {
262+ mem : mem ,
263+ cpu : cpu ,
264+ constant : mem .HasConstants ()[0 ] && cpu .HasConstants ()[0 ],
265+ }
266+ }
267+ return ret
268+ }
269+
240270type twoArgCost struct {
241271 mem TwoArgument
242272 cpu TwoArgument
@@ -275,6 +305,48 @@ func newTwoArgCostCache(
275305 return ret
276306}
277307
308+ type threeArgCost struct {
309+ mem ThreeArgument
310+ cpu ThreeArgument
311+ memConstX bool
312+ memConstY bool
313+ memConstZ bool
314+ cpuConstX bool
315+ cpuConstY bool
316+ cpuConstZ bool
317+ }
318+
319+ func newThreeArgCostCache (
320+ costs BuiltinCosts ,
321+ ) [builtin .TotalBuiltinCount ]threeArgCost {
322+ var ret [builtin .TotalBuiltinCount ]threeArgCost
323+ for i , model := range costs {
324+ if model == nil {
325+ continue
326+ }
327+
328+ mem , memOK := model .mem .(ThreeArgument )
329+ cpu , cpuOK := model .cpu .(ThreeArgument )
330+ if ! memOK || ! cpuOK {
331+ continue
332+ }
333+
334+ memConstants := mem .HasConstants ()
335+ cpuConstants := cpu .HasConstants ()
336+ ret [i ] = threeArgCost {
337+ mem : mem ,
338+ cpu : cpu ,
339+ memConstX : memConstants [0 ],
340+ memConstY : memConstants [1 ],
341+ memConstZ : memConstants [2 ],
342+ cpuConstX : cpuConstants [0 ],
343+ cpuConstY : cpuConstants [1 ],
344+ cpuConstZ : cpuConstants [2 ],
345+ }
346+ }
347+ return ret
348+ }
349+
278350// plutusVersionName returns a human-readable name for the Plutus version
279351func plutusVersionName (v builtin.PlutusVersion ) string {
280352 switch v {
@@ -294,18 +366,26 @@ func plutusVersionName(v builtin.PlutusVersion) string {
294366}
295367
296368func (m * Machine [T ]) CostOne (b * builtin.DefaultFunction , x func () ExMem ) error {
297- model := m .costs .builtinCosts [* b ]
298-
299- mem := model .mem .(OneArgument )
300- cpu := model .cpu .(OneArgument )
301-
302- cf := CostingFunc [OneArgument ]{
303- mem : mem ,
304- cpu : cpu ,
369+ model := & m .oneArgCosts [* b ]
370+ mem := model .mem
371+ cpu := model .cpu
372+ if mem == nil || cpu == nil {
373+ fallbackModel := m .costs .builtinCosts [* b ]
374+ mem = fallbackModel .mem .(OneArgument )
375+ cpu = fallbackModel .cpu .(OneArgument )
376+ model .mem = mem
377+ model .cpu = cpu
378+ model .constant = mem .HasConstants ()[0 ] && cpu .HasConstants ()[0 ]
305379 }
306380
307- cost := CostSingle (cf , x )
308- return m .spendBudget (cost )
381+ xMem := ExMem (0 )
382+ if ! model .constant {
383+ xMem = x ()
384+ }
385+ return m .spendBudget (ExBudget {
386+ Mem : int64 (mem .Cost (xMem )),
387+ Cpu : int64 (cpu .Cost (xMem )),
388+ })
309389}
310390
311391func (m * Machine [T ]) CostTwo (
@@ -365,18 +445,41 @@ func (m *Machine[T]) CostThree(
365445 b * builtin.DefaultFunction ,
366446 x , y , z func () ExMem ,
367447) error {
368- model := m .costs .builtinCosts [* b ]
369-
370- mem := model .mem .(ThreeArgument )
371- cpu := model .cpu .(ThreeArgument )
372-
373- cf := CostingFunc [ThreeArgument ]{
374- mem : mem ,
375- cpu : cpu ,
448+ model := & m .threeArgCosts [* b ]
449+ mem := model .mem
450+ cpu := model .cpu
451+ if mem == nil || cpu == nil {
452+ fallbackModel := m .costs .builtinCosts [* b ]
453+ mem = fallbackModel .mem .(ThreeArgument )
454+ cpu = fallbackModel .cpu .(ThreeArgument )
455+ model .mem = mem
456+ model .cpu = cpu
457+ memConstants := mem .HasConstants ()
458+ cpuConstants := cpu .HasConstants ()
459+ model .memConstX = memConstants [0 ]
460+ model .memConstY = memConstants [1 ]
461+ model .memConstZ = memConstants [2 ]
462+ model .cpuConstX = cpuConstants [0 ]
463+ model .cpuConstY = cpuConstants [1 ]
464+ model .cpuConstZ = cpuConstants [2 ]
376465 }
377466
378- cost := CostTriple (cf , x , y , z )
379- return m .spendBudget (cost )
467+ xMem := ExMem (0 )
468+ if ! model .memConstX || ! model .cpuConstX {
469+ xMem = x ()
470+ }
471+ yMem := ExMem (0 )
472+ if ! model .memConstY || ! model .cpuConstY {
473+ yMem = y ()
474+ }
475+ zMem := ExMem (0 )
476+ if ! model .memConstZ || ! model .cpuConstZ {
477+ zMem = z ()
478+ }
479+ return m .spendBudget (ExBudget {
480+ Mem : int64 (mem .CostThree (xMem , yMem , zMem )),
481+ Cpu : int64 (cpu .CostThree (xMem , yMem , zMem )),
482+ })
380483}
381484
382485func (m * Machine [T ]) CostThreeExMem (
0 commit comments