Skip to content

Commit fd3500a

Browse files
Merge pull request #358 from rainlanguage/2025-07-13-min
2025 07 13 min
2 parents e8d94fb + 1a69344 commit fd3500a

7 files changed

Lines changed: 630 additions & 576 deletions

File tree

.gas-snapshot

Lines changed: 418 additions & 394 deletions
Large diffs are not rendered by default.

src/generated/Rainterpreter.pointers.sol

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
pragma solidity =0.8.25;
1111

1212
/// @dev Hash of the known bytecode.
13-
bytes32 constant BYTECODE_HASH = bytes32(0xe67bfbe2d8ebe116b64bcb02d5e29330d9ade17c1c3367def6883adee4d399e7);
13+
bytes32 constant BYTECODE_HASH = bytes32(0x201dec199626b955935bb8907110beb3f69aeb86c149be19adf8adb5a01ec361);
1414

1515
/// @dev The function pointers known to the interpreter for dynamic dispatch.
1616
/// By setting these as a constant they can be inlined into the interpreter
1717
/// and loaded at eval time for very low gas (~100) due to the compiler
1818
/// optimising it to a single `codecopy` to build the in memory bytes array.
1919
bytes constant OPCODE_FUNCTION_POINTERS =
20-
hex"07120744076808f409bd09cf09e109fa0a1e0a520a630a740b160b350be40c680c790c8a0c8a0c9b0d280d410d550d6e0d870d9a0dfc0e4a0e7b0ec90f170ffe";
20+
hex"071c074e077208fe09c709d909eb0a040a280a5c0a6d0a7e0b200b3f0bee0c720c830c940c940ca50d320d4b0d5f0d780d910da40e060e540e850ed30f210f6f1056";

src/generated/RainterpreterExpressionDeployer.pointers.sol

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
pragma solidity =0.8.25;
1111

1212
/// @dev Hash of the known bytecode.
13-
bytes32 constant BYTECODE_HASH = bytes32(0x84daba4ae586abd5a30c407378175e919ea82b291b9bff08604debfa5e59d183);
13+
bytes32 constant BYTECODE_HASH = bytes32(0x32ce28951182ae67a8783f6c482e3433eda8756bab71349543b7c621816c6c92);
1414

1515
/// @dev The hash of the meta that describes the contract.
16-
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0x53bf9fadcc5583af0b446b3d62f227146b09d4476ca6f3998e21c1410fe04965);
16+
bytes32 constant DESCRIBED_BY_META_HASH = bytes32(0x5aaf62fc2ee9a61ce7f262226c5142750dd5f7fc3eaed156ae0ef88e03a44d38);
1717

1818
/// @dev The function pointers for the integrity check fns.
1919
bytes constant INTEGRITY_FUNCTION_POINTERS =
20-
hex"0db80e360e9a1014101e101e10281031104c10f210f2114e11c6101e1028101410141014101411d3101e101e101e101e101411dd1205101412051205102811d3";
20+
hex"0dc00e3e0ea2101c1026102610301039105410fa10fa115611ce10261030101c101c101c101c11db1026102610261026101c11e5120d101c11e5120d120d103011db";

src/generated/RainterpreterParser.pointers.sol

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
pragma solidity =0.8.25;
1111

1212
/// @dev Hash of the known bytecode.
13-
bytes32 constant BYTECODE_HASH = bytes32(0xd292c1e12f252b9afbe785ce00e0c8980c99b3469982fc5ffdab15e8017acd83);
13+
bytes32 constant BYTECODE_HASH = bytes32(0xe37800b673d2b3028fae1ac8509130acb9670683fe9888cd58d2ccebab7d0a02);
1414

1515
/// @dev The parse meta that is used to lookup word definitions.
1616
/// The structure of the parse meta is:
@@ -29,7 +29,7 @@ bytes32 constant BYTECODE_HASH = bytes32(0xd292c1e12f252b9afbe785ce00e0c8980c99b
2929
/// bit count of the previous bloom filter. If we reach the end of the bloom
3030
/// filters then we have a miss.
3131
bytes constant PARSE_META =
32-
hex"01092404940810009008201088000400e0010080000800001028010100080900090002cd70471e14fbe61685cf8700f861d11ad0e20c0e8be82d1f7c7f8004e5ab37194d06d00d67df8415fedd510602c61f08bcae760bcd088610f1c17805ac4b9f0a09bc09180ce432091ef7b011dfb72601a91367121faf890c2b9f481ce804c11bbd68ce14811fdb1726c459034a067c0fffb07907743c4a1d15024513edf10f";
32+
hex"01092404940810009008201088000400e0010080000800001028010100080902090002cd70471f14fbe61c85bda21685cf8700f861d11ad0e20c0e8be82d207c7f8004e5ab37194d06d00d67df8415fedd510602c61f08bcae760bcd088610f1c17805ac4b9f0a09bc09180ce432091ef7b011dfb72601a91367121faf890c2b9f481de804c11bbd68ce14811fdb1726c459034a067c0fffb07907743c4a1e15024513edf10f";
3333

3434
/// @dev The build depth of the parser meta.
3535

@@ -39,11 +39,11 @@ uint8 constant PARSE_META_BUILD_DEPTH = 2;
3939
/// These positional indexes all map to the same indexes looked up in the parse
4040
/// meta.
4141
bytes constant OPERAND_HANDLER_FUNCTION_POINTERS =
42-
hex"199a199a199a1a6f1b861b861b861a6f1a6f199a199a199a1b861b861b861b861b861b861b861b861b861b861b861b861b861b861b861b861b86199a1b861b86";
42+
hex"19a219a219a21a771b8e1b8e1b8e1a771a7719a219a219a21b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e1b8e19a21b8e1b8e";
4343

4444
/// @dev Every two bytes is a function pointer for a literal parser.
4545
/// Literal dispatches are determined by the first byte(s) of the literal
4646
/// rather than a full word lookup, and are done with simple conditional
4747
/// jumps as the possibilities are limited compared to the number of words we
4848
/// have.
49-
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"14e21714175717f5";
49+
bytes constant LITERAL_PARSER_FUNCTION_POINTERS = hex"14ea171c175f17fd";

src/lib/op/LibAllStandardOps.sol

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ import {LibParseLiteralHex} from "../parse/literal/LibParseLiteralHex.sol";
105105
import {LibParseLiteralSubParseable} from "../parse/literal/LibParseLiteralSubParseable.sol";
106106

107107
/// @dev Number of ops currently provided by `AllStandardOps`.
108-
uint256 constant ALL_STANDARD_OPS_LENGTH = 32;
108+
uint256 constant ALL_STANDARD_OPS_LENGTH = 33;
109109

110110
/// @title LibAllStandardOps
111111
/// @notice Every opcode available from the core repository laid out as a single
@@ -269,7 +269,7 @@ library LibAllStandardOps {
269269
"max-value",
270270
"The maximum representable float value. This is so large that it is effectively infinity (it has ~2.1 billion zero digits). Almost all numbers that you could possibly subtract from it will be ignored as a rounding error."
271271
),
272-
// AuthoringMetaV2("min", "Finds the minimum number from all inputs."),
272+
AuthoringMetaV2("min", "Finds the minimum number from all inputs."),
273273
// AuthoringMetaV2("mod", "Modulos the first number by all other numbers. Errors if any divisor is zero."),
274274
AuthoringMetaV2("mul", "Multiplies all numbers together."),
275275
// AuthoringMetaV2(
@@ -481,8 +481,8 @@ library LibAllStandardOps {
481481
// LibParseOperand.handleOperandDisallowed,
482482
// max-value
483483
LibParseOperand.handleOperandDisallowed,
484-
// // min
485-
// LibParseOperand.handleOperandDisallowed,
484+
// min
485+
LibParseOperand.handleOperandDisallowed,
486486
// // mod
487487
// LibParseOperand.handleOperandDisallowed,
488488
// mul
@@ -603,7 +603,7 @@ library LibAllStandardOps {
603603
// LibOpLog10.integrity,
604604
// LibOpMax.integrity,
605605
LibOpMaxValue.integrity,
606-
// LibOpMin.integrity,
606+
LibOpMin.integrity,
607607
// LibOpMod.integrity,
608608
LibOpMul.integrity,
609609
// LibOpPow.integrity,
@@ -715,7 +715,7 @@ library LibAllStandardOps {
715715
// LibOpLog10.run,
716716
// LibOpMax.run,
717717
LibOpMaxValue.run,
718-
// LibOpMin.run,
718+
LibOpMin.run,
719719
// LibOpMod.run,
720720
LibOpMul.run,
721721
// LibOpPow.run,

src/lib/op/math/LibOpMin.sol

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,8 @@ import {OperandV2} from "rain.interpreter.interface/interface/unstable/IInterpre
55
import {Pointer} from "rain.solmem/lib/LibPointer.sol";
66
import {InterpreterState} from "../../state/LibInterpreterState.sol";
77
import {IntegrityCheckState} from "../../integrity/LibIntegrityCheck.sol";
8+
import {Float, LibDecimalFloat} from "rain.math.float/lib/LibDecimalFloat.sol";
9+
import {StackItem} from "rain.interpreter.interface/interface/unstable/IInterpreterV4.sol";
810

911
/// @title LibOpMin
1012
/// @notice Opcode to find the min from N integers.
@@ -19,16 +21,14 @@ library LibOpMin {
1921
/// min
2022
/// Finds the minimum value from N integers.
2123
function run(InterpreterState memory, OperandV2 operand, Pointer stackTop) internal pure returns (Pointer) {
22-
uint256 a;
23-
uint256 b;
24+
Float a;
25+
Float b;
2426
assembly ("memory-safe") {
2527
a := mload(stackTop)
2628
b := mload(add(stackTop, 0x20))
2729
stackTop := add(stackTop, 0x40)
2830
}
29-
if (a > b) {
30-
a = b;
31-
}
31+
a = LibDecimalFloat.min(a, b);
3232

3333
{
3434
uint256 inputs = uint256((OperandV2.unwrap(operand) >> 0x10) & bytes32(uint256(0x0F)));
@@ -38,9 +38,8 @@ library LibOpMin {
3838
b := mload(stackTop)
3939
stackTop := add(stackTop, 0x20)
4040
}
41-
if (a > b) {
42-
a = b;
43-
}
41+
a = LibDecimalFloat.min(a, b);
42+
4443
unchecked {
4544
i++;
4645
}
@@ -55,20 +54,20 @@ library LibOpMin {
5554
}
5655

5756
/// Gas intensive reference implementation of minimum for testing.
58-
function referenceFn(InterpreterState memory, OperandV2, uint256[] memory inputs)
57+
function referenceFn(InterpreterState memory, OperandV2, StackItem[] memory inputs)
5958
internal
6059
pure
61-
returns (uint256[] memory outputs)
60+
returns (StackItem[] memory outputs)
6261
{
6362
// Unchecked so that when we assert that an overflow error is thrown, we
6463
// see the revert from the real function and not the reference function.
6564
unchecked {
66-
uint256 acc = inputs[0];
65+
Float acc = Float.wrap(StackItem.unwrap(inputs[0]));
6766
for (uint256 i = 1; i < inputs.length; i++) {
68-
acc = acc > inputs[i] ? inputs[i] : acc;
67+
acc = LibDecimalFloat.min(acc, Float.wrap(StackItem.unwrap(inputs[i])));
6968
}
70-
outputs = new uint256[](1);
71-
outputs[0] = acc;
69+
outputs = new StackItem[](1);
70+
outputs[0] = StackItem.wrap(Float.unwrap(acc));
7271
}
7372
}
7473
}

0 commit comments

Comments
 (0)