From 75fc23c810b9cb9a721ace9e6f17083910c54d45 Mon Sep 17 00:00:00 2001 From: xermicus Date: Sat, 28 Jun 2025 12:01:34 +0200 Subject: [PATCH] add the missing memset builtin (#353) Closes #350 - Add the missing `memset` builtin which was accidentally deleted in a previous PR. - Add a compilation test to ensure the `memset` builtin is present. --------- Signed-off-by: Cyrill Leutwiler --- CHANGELOG.md | 1 + .../cli-tests/src/contracts/yul/memset.yul | 22 +++++++++++++++++++ .../src/tests/cli-tests/src/entities.ts | 6 +++++ .../src/tests/cli-tests/tests/memset.test.ts | 18 +++++++++++++++ crates/runtime-api/src/polkavm_imports.c | 7 ++++++ 5 files changed, 54 insertions(+) create mode 100644 crates/resolc/src/tests/cli-tests/src/contracts/yul/memset.yul create mode 100644 crates/resolc/src/tests/cli-tests/tests/memset.test.ts diff --git a/CHANGELOG.md b/CHANGELOG.md index 9cfa5e2..96c2afb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ Supported `polkadot-sdk` rev: `2503.0.1` ### Fixed - llvm-context: Bugfix the SAR YUL builtin translation. +- runtime-api: Add the missing `memset` builtin. - npm package: Bugfix the exports field defined in the `package.json`. diff --git a/crates/resolc/src/tests/cli-tests/src/contracts/yul/memset.yul b/crates/resolc/src/tests/cli-tests/src/contracts/yul/memset.yul new file mode 100644 index 0000000..af1f642 --- /dev/null +++ b/crates/resolc/src/tests/cli-tests/src/contracts/yul/memset.yul @@ -0,0 +1,22 @@ +object "Test" { + code { + function allocate(size) -> ptr { + ptr := mload(0x40) + if iszero(ptr) { ptr := 0x60 } + mstore(0x40, add(ptr, size)) + } + let size := datasize("Test_deployed") + let offset := allocate(size) + datacopy(offset, dataoffset("Test_deployed"), size) + return(offset, size) + } + object "Test_deployed" { + code { +{ + let test:=0x5 + mstore(2,signextend(0x8,0x0)) + mstore(8,lt(0xc,test)) +} + + return(0, 65536) +}}} diff --git a/crates/resolc/src/tests/cli-tests/src/entities.ts b/crates/resolc/src/tests/cli-tests/src/entities.ts index d2f9f45..b0a795e 100644 --- a/crates/resolc/src/tests/cli-tests/src/entities.ts +++ b/crates/resolc/src/tests/cli-tests/src/entities.ts @@ -15,6 +15,11 @@ const pathToBasicYulContract = path.join( 'yul', contractYulFilename ) +const pathToMemsetYulContract = path.join( + pathToContracts, + 'yul', + 'memset.yul' +) const pathToBasicSolContract = path.join( pathToContracts, 'solidity', @@ -42,6 +47,7 @@ export const paths = { pathToContracts: pathToContracts, pathToBasicSolContract: pathToBasicSolContract, pathToBasicYulContract: pathToBasicYulContract, + pathToMemsetYulContract: pathToMemsetYulContract, pathToSolBinOutputFile: pathToSolBinOutputFile, pathToSolAsmOutputFile: pathToSolAsmOutputFile, } diff --git a/crates/resolc/src/tests/cli-tests/tests/memset.test.ts b/crates/resolc/src/tests/cli-tests/tests/memset.test.ts new file mode 100644 index 0000000..c1a956c --- /dev/null +++ b/crates/resolc/src/tests/cli-tests/tests/memset.test.ts @@ -0,0 +1,18 @@ +import { executeCommand } from '../src/helper' +import { paths } from '../src/entities' + +describe('tests for the memset builtin to be present', () => { + // -O3 is required to reproduce. + const command = `resolc ${paths.pathToMemsetYulContract} --yul -O3` + const result = executeCommand(command) + + it('Valid command exit code = 0', () => { + expect(result.exitCode).toBe(0) + }) + + it('--yul output is presented', () => { + expect(result.output).toMatch(/(Compiler run successful)/i) + expect(result.output).toMatch(/(No output requested)/i) + }) + +}) diff --git a/crates/runtime-api/src/polkavm_imports.c b/crates/runtime-api/src/polkavm_imports.c index 91d4e36..10f974d 100644 --- a/crates/runtime-api/src/polkavm_imports.c +++ b/crates/runtime-api/src/polkavm_imports.c @@ -30,6 +30,13 @@ void * memmove(void *dst, const void *src, size_t n) { return dst; } +void * memset(void *b, int c, size_t len) { + uint8_t *dest = b; + uint8_t val = (uint8_t)c; + while (len-- > 0) *dest++ = val; + return b; +} + // Imports POLKAVM_IMPORT(void, address, uint32_t)