diff --git a/src/cairoWriter/writers/cairoContractWriter.ts b/src/cairoWriter/writers/cairoContractWriter.ts index 58df6093f..2b14111bd 100644 --- a/src/cairoWriter/writers/cairoContractWriter.ts +++ b/src/cairoWriter/writers/cairoContractWriter.ts @@ -24,17 +24,17 @@ export class CairoContractWriter extends CairoASTNodeWriter { `// This contract may be abstract, it may not implement an abstract parent's methods\n// completely or it may not invoke an inherited contract's constructor correctly.\n`, ]; - const dynamicVariables = [...node.dynamicStorageAllocations.entries()].map( + const staticVariables = [...node.staticStorageAllocations.entries()].map( ([decl, loc]) => `const ${decl.name}: felt252 = ${loc};`, ); - const staticVariables = [...node.staticStorageAllocations.entries()].map( + const dynamicVariables = [...node.dynamicStorageAllocations.entries()].map( ([decl, loc]) => `const ${decl.name}: felt252 = ${loc};`, ); const variables = [ - `// Dynamic variables - Arrays and Maps`, - ...dynamicVariables, - `// Static variables`, + staticVariables.length > 0 ? '// Static variables' : '', ...staticVariables, + dynamicVariables.length > 0 ? '// Dynamic variables - Arrays and Maps' : '', + ...dynamicVariables, ]; let documentation = getDocumentation(node.documentation, writer); diff --git a/src/cairoWriter/writers/sourceUnitWriter.ts b/src/cairoWriter/writers/sourceUnitWriter.ts index 50ac26cc8..fcedeb660 100644 --- a/src/cairoWriter/writers/sourceUnitWriter.ts +++ b/src/cairoWriter/writers/sourceUnitWriter.ts @@ -16,12 +16,12 @@ export class SourceUnitWriter extends CairoASTNodeWriter { this.generateInterfaceNameMappings(node); // Every sourceUnit should only define a single contract - const mainContract_ = + const mainContracts = node.vContracts.length >= 2 ? node.vContracts.filter((cd) => !cd.name.endsWith(TEMP_INTERFACE_SUFFIX)) : node.vContracts; - assert(mainContract_.length <= 1, 'Every SourceUnit should only define a single contract'); + assert(mainContracts.length <= 1, 'Every SourceUnit should only define a single contract'); structRemappings = new Map(); diff --git a/src/passes/cairoUtilImporter.ts b/src/passes/cairoUtilImporter.ts index 838c320d8..2e0a3a810 100644 --- a/src/passes/cairoUtilImporter.ts +++ b/src/passes/cairoUtilImporter.ts @@ -12,6 +12,7 @@ import { } from 'solc-typed-ast'; import { AST } from '../ast/ast'; import { ASTMapper } from '../ast/mapper'; +import { CairoFunctionDefinition } from '../export'; import { requireNonNullish } from '../export'; import { createImport } from '../utils/importFuncGenerator'; import { @@ -19,6 +20,8 @@ import { U256_FROM_FELTS, U128_FROM_FELT, CONTRACT_ADDRESS, + WARP_MEMORY, + WM_INIT, CUTOFF_DOWNCAST, WARPLIB_INTEGER, } from '../utils/importPaths'; @@ -31,16 +34,27 @@ import { getContainingSourceUnit, primitiveTypeToCairo } from '../utils/utils'; the warplib maths functions as they are added to the code, but for determining if Uint256 needs to be imported, it's easier to do it here */ - export class CairoUtilImporter extends ASTMapper { private dummySourceUnit: SourceUnit | undefined; // Function to add passes that should have been run before this pass addInitialPassPrerequisites(): void { - const passKeys: Set = new Set([]); + // It requires the AnnotateImplicits (An) because we need to know if any functions + // uses WarpMemory + // It requires Function Prunner (Fp) for it not to delete any of these newly added + // imports + const passKeys: Set = new Set(['An', 'Fp']); passKeys.forEach((key) => this.addPassPrerequisite(key)); } + visitCairoFunctionDefinition(node: CairoFunctionDefinition, ast: AST): void { + if (node.implicits.has('warp_memory')) { + createImport(...WARP_MEMORY, this.dummySourceUnit ?? node, ast); + createImport(...WM_INIT, this.dummySourceUnit ?? node, ast); + } + this.commonVisit(node, ast); + } + visitElementaryTypeName(node: ElementaryTypeName, ast: AST): void { const cairoType = primitiveTypeToCairo(node.name); if (cairoType === 'u256') { @@ -63,7 +77,7 @@ export class CairoUtilImporter extends ASTMapper { visitLiteral(node: Literal, ast: AST): void { const type = safeGetNodeType(node, ast.inference); - if (type instanceof IntType && type.nBits > 251) { + if (type instanceof IntType && type.nBits === 256) { createImport(...U256_FROM_FELTS, this.dummySourceUnit ?? node, ast); } diff --git a/src/passes/references/memoryAllocations.ts b/src/passes/references/memoryAllocations.ts index a49e20b8a..afdfb8594 100644 --- a/src/passes/references/memoryAllocations.ts +++ b/src/passes/references/memoryAllocations.ts @@ -17,9 +17,13 @@ import { printNode } from '../../utils/astPrinter'; import { CairoType, TypeConversionContext } from '../../utils/cairoTypeSystem'; import { NotSupportedYetError } from '../../utils/errors'; import { createCallToFunction } from '../../utils/functionGeneration'; -import { createNumberLiteral, createUint256TypeName } from '../../utils/nodeTemplates'; +import { + createFeltTypeName, + createNumberLiteral, + createUint256TypeName, +} from '../../utils/nodeTemplates'; import { getElementType, safeGetNodeType } from '../../utils/nodeTypeProcessing'; -import { WM_NEW } from '../../utils/importPaths'; +import { U256_TO_FELT252, WM_NEW } from '../../utils/importPaths'; /* Handles expressions that directly insert data into memory: struct constructors, news, and inline arrays @@ -83,8 +87,8 @@ export class MemoryAllocations extends ReferenceSubPass { node, ...WM_NEW, [ - ['len', createUint256TypeName(ast)], - ['elemWidth', createUint256TypeName(ast)], + ['len', createFeltTypeName(ast)], + ['elem_size', createFeltTypeName(ast)], ], [['loc', node.vExpression.vTypeName, DataLocation.Memory]], ); @@ -102,9 +106,21 @@ export class MemoryAllocations extends ReferenceSubPass { TypeConversionContext.Ref, ); + const uint256ToFeltDef = ast.registerImport( + node, + ...U256_TO_FELT252, + [['x_256', createUint256TypeName(ast)]], + [['x_252', createFeltTypeName(ast)]], + ); + const uint256ToFeltConversion = createCallToFunction( + uint256ToFeltDef, + [node.vArguments[0]], + ast, + ); + const call = createCallToFunction( funcImport, - [node.vArguments[0], createNumberLiteral(elementCairoType.width, ast, 'uint256')], + [uint256ToFeltConversion, createNumberLiteral(elementCairoType.width, ast, 'uint252')], ast, ); diff --git a/src/utils/cairoTypeSystem.ts b/src/utils/cairoTypeSystem.ts index ba2bdfb8a..7fe12e8c9 100644 --- a/src/utils/cairoTypeSystem.ts +++ b/src/utils/cairoTypeSystem.ts @@ -96,7 +96,7 @@ export abstract class CairoType { } else if (tp instanceof FunctionType) { throw new NotSupportedYetError('Serialising FunctionType not supported yet'); } else if (tp instanceof IntType) { - return new CairoUint(tp.nBits); + return tp.nBits === 252 ? new CairoFelt() : new CairoUint(tp.nBits); } else if (tp instanceof MappingType) { return new WarpLocation(); } else if (tp instanceof PointerType) { diff --git a/src/utils/importFuncGenerator.ts b/src/utils/importFuncGenerator.ts index 9c20fc4f0..67f0c533f 100644 --- a/src/utils/importFuncGenerator.ts +++ b/src/utils/importFuncGenerator.ts @@ -91,23 +91,6 @@ const FUNCTION_IMPORTS = [ Paths.BOOL_INTO_FELT252, Paths.FELT252_INTO_BOOL, Paths.WARPLIB_INTEGER, - Paths.WARP_MEMORY, - Paths.WM_NEW, - Paths.WM_READ, - Paths.WM_ALLOC, - Paths.WM_STORE, - Paths.WM_WRITE, - Paths.WM_CREATE, - Paths.WM_GET_ID, - Paths.WM_RETRIEVE, - Paths.WM_INDEX_DYN, - Paths.WM_UNSAFE_READ, - Paths.WM_INDEX_STATIC, - Paths.WM_UNSAFE_ALLOC, - Paths.WM_UNSAFE_WRITE, - Paths.WM_READ_MULTIPLE, - Paths.WM_WRITE_MULTIPLE, - Paths.WM_DYN_ARRAY_LENGTH, ]; export function createImport( @@ -175,7 +158,7 @@ export function createImport( return createFuncImport(); } - throw new TranspileFailedError(`Import ${name} from ${path} is not defined.`); + throw new TranspileFailedError(`Import ${name} from ${path.join('::')} is not defined.`); } function findExistingImport( diff --git a/src/utils/importPaths.ts b/src/utils/importPaths.ts index fd0f67711..af8e437f6 100644 --- a/src/utils/importPaths.ts +++ b/src/utils/importPaths.ts @@ -245,6 +245,8 @@ const MEMORY_MODULE = ['warplib', 'warp_memory']; export const WARP_MEMORY: [string[], string] = [MEMORY_MODULE, 'WarpMemory']; const WARP_MEMORY_TRAIT: string[] = [...MEMORY_MODULE, 'WarpMemoryTrait']; + +export const WM_INIT: [string[], string] = [WARP_MEMORY_TRAIT, 'warp_memory.initialize']; export const WM_READ: [string[], string] = [WARP_MEMORY_TRAIT, 'warp_memory.read']; export const WM_WRITE: [string[], string] = [WARP_MEMORY_TRAIT, 'warp_memory.write']; export const WM_ALLOC: [string[], string] = [WARP_MEMORY_TRAIT, 'warp_memory.alloc']; @@ -261,7 +263,7 @@ export const WM_UNSAFE_ALLOC: [string[], string] = [ 'warp_memory.unsafe_alloc', ]; -const WARP_MEMORY_ARRAYS_TRAIT: string[] = [...MEMORY_MODULE, 'WarpMemoryArraysTrait']; +const WARP_MEMORY_ARRAYS_TRAIT: string[] = [...MEMORY_MODULE, 'arrays', 'WarpMemoryArraysTrait']; export const WM_DYN_ARRAY_LENGTH: [string[], string] = [ WARP_MEMORY_ARRAYS_TRAIT, 'warp_memory.length_dyn', @@ -280,7 +282,11 @@ export const WM_GET_ID: [string[], string] = [ 'warp_memory.get_or_create_id', ]; -const MULTICELL_ACCESSOR_TRAIT: string[] = [...MEMORY_MODULE, 'WarpMemoryMultiCellAccessorTrait']; +const MULTICELL_ACCESSOR_TRAIT: string[] = [ + ...MEMORY_MODULE, + 'accessors', + 'WarpMemoryMultiCellAccessorTrait', +]; export const WM_WRITE_MULTIPLE: [string[], string] = [ MULTICELL_ACCESSOR_TRAIT, 'warp_memory.write_multiple', diff --git a/src/warplib/gatherWarplibImports.ts b/src/warplib/gatherWarplibImports.ts index 8069abf80..a62153007 100644 --- a/src/warplib/gatherWarplibImports.ts +++ b/src/warplib/gatherWarplibImports.ts @@ -3,6 +3,7 @@ import { Implicits } from '../utils/utils'; import { parseMultipleRawCairoFunctions } from '../utils/cairoParsing'; import { glob } from 'glob'; import path from 'path'; +import assert from 'assert'; import { WARP_ROOT } from '../config'; @@ -18,6 +19,23 @@ export const warplibImportInfo = glob .slice('warplib/src/'.length, -'.cairo'.length) .split(path.sep), ]; + + // Handle WarpMemory function gathering differently + if (importPath.includes('warp_memory')) { + // Hardcode WarpMemory struct + if (pathToFile.endsWith('warp_memory.cairo')) { + warplibMap.set(importPath.join('/'), new Map([['WarpMemory', []]])); + } + gatherWarpMemoryFuncs(rawCairoCode, importPath, warplibMap); + return warplibMap; + } + + if (importPath[importPath.length - 1] === 'integer') { + console.log('Gather int conversion'); + gatherIntegerConversion(rawCairoCode, importPath, warplibMap); + return warplibMap; + } + // TODO: Add encodePath here. Importing encodePath cause circular // dependency error. Suggested solution is to relocate all import // related scripts (including this, and the ones in src/utils) @@ -32,3 +50,91 @@ export const warplibImportInfo = glob ); return warplibMap; }, new Map>()); + +function gatherIntegerConversion( + rawCairoCode: string, + importPath: string[], + warplibMap: Map>, +) { + const integerTraitInfo = traitFunctionExtractor(rawCairoCode); + console.log(integerTraitInfo); + + integerTraitInfo.forEach(({ trait, code }) => { + const traitImportPath = [...importPath, trait]; + const key = traitImportPath.join('/'); + + const fileMap: Map = warplibMap.get(key) ?? new Map(); + if (!warplibMap.has(key)) { + warplibMap.set(key, fileMap); + } + + parseMultipleRawCairoFunctions(code).forEach((cairoFunc) => fileMap.set(cairoFunc.name, [])); + }); +} + +// Functions that stored warp memory functions accordingly +function gatherWarpMemoryFuncs( + rawCairoCode: string, + importPath: string[], + warplibMap: Map>, +) { + // Get the body for each trait + const warpMemoryTraitInfo = traitFunctionExtractor(rawCairoCode); + + // Store each trait import path with each function prefixed with "warp_memory." + warpMemoryTraitInfo.forEach(({ trait, code }) => { + const traitImportPath = [...importPath, trait]; + const key = traitImportPath.join('/'); + + const fileMap: Map = warplibMap.get(key) ?? new Map(); + if (!warplibMap.has(key)) { + warplibMap.set(key, fileMap); + } + + parseMultipleRawCairoFunctions(code).forEach((cairoFunc) => + fileMap.set(`warp_memory.${cairoFunc.name}`, ['warp_memory']), + ); + }); +} + +type TraitInfo = { trait: string; code: string }; +function traitFunctionExtractor(rawCairoCode: string): TraitInfo[] { + const warpMemoryInfo: TraitInfo[] = []; + let currentTrait = ''; + let currentBody = ''; + rawCairoCode + .split('\n') + .filter((l) => !l.match('^[ ]*$')) + .forEach((l) => { + if (l.trim().startsWith('trait')) { + if (currentTrait !== '') { + warpMemoryInfo.push({ trait: currentTrait, code: currentBody }); + } + currentTrait = extractName('trait', l); + currentBody = ''; + return; + } + if (l.trim().startsWith('impl')) { + if (currentTrait !== '') { + warpMemoryInfo.push({ trait: currentTrait, code: currentBody }); + } + currentTrait = ''; + currentBody = ''; + return; + } + currentBody += '\n' + l.trim(); + }); + + return warpMemoryInfo; +} + +function extractName(keyword: string, line: string) { + const regex = new RegExp(`${keyword}[ ]+(?\\w+)`); + const m = line.match(regex); + assert( + m !== null && m.groups !== undefined, + `Error extracting name for ${keyword} in line:\n"${line}"`, + ); + + return m.groups.name; +} diff --git a/tests/compilation/compilation.test.ts b/tests/compilation/compilation.test.ts index 63079e962..75dc4b417 100644 --- a/tests/compilation/compilation.test.ts +++ b/tests/compilation/compilation.test.ts @@ -10,7 +10,6 @@ import { passingContracts } from './passingContracts'; const expectedResults = new Map( [ - ['arrayLength.sol', 'Success'], ['ERC20.sol', 'Success'], ['ERC20Storage.sol', 'Success'], ['address/8/160NotAllowed.sol', 'SolCompileFailed'], @@ -136,21 +135,15 @@ const expectedResults = new Map( ['namedArgs/constructor.sol', 'Success'], ['namedArgs/eventsAndErrors.sol', 'Success'], ['namedArgs/function.sol', 'Success'], - ['nestedStaticArrayStruct.sol', 'Success'], - ['nestedStructStaticArray.sol', 'Success'], - ['nestedStructs.sol', 'Success'], - ['nestedTuple.sol', 'WillNotSupport'], ['oldCodeGenErr.sol', 'WillNotSupport'], ['oldCodeGenErr7.sol', 'WillNotSupport'], ['payableFunction.sol', 'Success'], ['pureFunction.sol', 'Success'], ['rejectNaming.sol', 'WillNotSupport'], ['removeUnreachableFunctions.sol', 'Success'], - ['returnDynArray.sol', 'Success'], ['returnVarCapturing.sol', 'Success'], ['returndatasize.sol', 'WillNotSupport'], ['returnInserter.sol', 'Success'], - ['simpleStorageVar.sol', 'Success'], ['sstoreSload.sol', 'WillNotSupport'], ['stateVariables/scalars.sol', 'Success'], ['stateVariables/enums.sol', 'Success'], @@ -160,7 +153,6 @@ const expectedResults = new Map( ['stateVariables/structs.sol', 'Success'], ['stateVariables/structsNested.sol', 'Success'], ['stateVariables/misc.sol', 'Success'], - ['structs.sol', 'Success'], ['thisMethodsCall.sol', 'Success'], ['tryCatch.sol', 'WillNotSupport'], ['tupleAssignment7.sol', 'Success'], @@ -173,7 +165,6 @@ const expectedResults = new Map( ['typeConversion/toAddressConversion.sol', 'Success'], ['typeConversion/unusedArrayConversion.sol', 'Success'], ['typeMinMax.sol', 'Success'], - ['uint256StaticArrayCasting.sol', 'Success'], ['typestrings/basicArrays.sol', 'Success'], ['typestrings/scalars.sol', 'Success'], ['typestrings/structArrays.sol', 'Success'], @@ -214,6 +205,16 @@ const expectedResults = new Map( ['thisAtConstructor/externalFunctionCallAtConstruction.sol', 'WillNotSupport'], ['thisAtConstructor/multipleExternalFunctionCallsAtConstruction.sol', 'WillNotSupport'], ['thisAtConstructor/validThisUseAtConstructor.sol', 'Success'], + ['warpMemorySystems/arrayLength.sol', 'Success'], + ['warpMemorySystems/implicitPropagation.sol', 'Success'], + ['warpMemorySystems/nestedStaticArrayStruct.sol', 'Success'], + ['warpMemorySystems/nestedStructStaticArray.sol', 'Success'], + ['warpMemorySystems/nestedStructs.sol', 'Success'], + ['warpMemorySystems/nestedTuple.sol', 'WillNotSupport'], + ['warpMemorySystems/returnDynArray.sol', 'Success'], + ['warpMemorySystems/simpleStorageVar.sol', 'Success'], + ['warpMemorySystems/structs.sol', 'Success'], + ['warpMemorySystems/uint256StaticArrayCasting.sol', 'Success'], ].map(([key, result]) => { return [path.join(WARP_TEST_FOLDER, key), result] as [string, ResultType]; }), diff --git a/tests/compilation/contracts/returnDynArray.sol b/tests/compilation/contracts/returnDynArray.sol deleted file mode 100644 index a6f0130b5..000000000 --- a/tests/compilation/contracts/returnDynArray.sol +++ /dev/null @@ -1,12 +0,0 @@ -pragma solidity ^0.8.11; - -//SPDX-License-Identifier: MIT - -contract WARP { - uint8[] x; - - function getArray() public view returns (uint8[] memory) { - return x; - } - -} diff --git a/tests/compilation/contracts/arrayLength.sol b/tests/compilation/contracts/warpMemorySystems/arrayLength.sol similarity index 100% rename from tests/compilation/contracts/arrayLength.sol rename to tests/compilation/contracts/warpMemorySystems/arrayLength.sol diff --git a/tests/compilation/contracts/warpMemorySystems/implicitPropagation.sol b/tests/compilation/contracts/warpMemorySystems/implicitPropagation.sol new file mode 100644 index 000000000..be0ef4b6f --- /dev/null +++ b/tests/compilation/contracts/warpMemorySystems/implicitPropagation.sol @@ -0,0 +1,12 @@ +pragma solidity ^0.8.6; + +contract WARP { + function internalUsesMemory() internal pure returns (uint8[] memory) { + uint8[] memory y = new uint8[](3); + return y; + } + + function callD() external pure { + internalUsesMemory(); + } +} diff --git a/tests/compilation/contracts/nestedStaticArrayStruct.sol b/tests/compilation/contracts/warpMemorySystems/nestedStaticArrayStruct.sol similarity index 100% rename from tests/compilation/contracts/nestedStaticArrayStruct.sol rename to tests/compilation/contracts/warpMemorySystems/nestedStaticArrayStruct.sol diff --git a/tests/compilation/contracts/nestedStructStaticArray.sol b/tests/compilation/contracts/warpMemorySystems/nestedStructStaticArray.sol similarity index 100% rename from tests/compilation/contracts/nestedStructStaticArray.sol rename to tests/compilation/contracts/warpMemorySystems/nestedStructStaticArray.sol diff --git a/tests/compilation/contracts/nestedStructs.sol b/tests/compilation/contracts/warpMemorySystems/nestedStructs.sol similarity index 100% rename from tests/compilation/contracts/nestedStructs.sol rename to tests/compilation/contracts/warpMemorySystems/nestedStructs.sol diff --git a/tests/compilation/contracts/nestedTuple.sol b/tests/compilation/contracts/warpMemorySystems/nestedTuple.sol similarity index 100% rename from tests/compilation/contracts/nestedTuple.sol rename to tests/compilation/contracts/warpMemorySystems/nestedTuple.sol diff --git a/tests/compilation/contracts/warpMemorySystems/returnDynArray.sol b/tests/compilation/contracts/warpMemorySystems/returnDynArray.sol new file mode 100644 index 000000000..74ceb57ba --- /dev/null +++ b/tests/compilation/contracts/warpMemorySystems/returnDynArray.sol @@ -0,0 +1,16 @@ +pragma solidity ^0.8.11; + +//SPDX-License-Identifier: MIT + +contract WARP { + uint8[] x; + + function returnStorageArray() public view returns (uint8[] memory) { + return x; + } + + function returnMemoryArray(uint128[] memory) public view returns (uint128[] memory) { + uint128[] memory y = new uint128[](10); + return y; + } +} diff --git a/tests/compilation/contracts/simpleStorageVar.sol b/tests/compilation/contracts/warpMemorySystems/simpleStorageVar.sol similarity index 100% rename from tests/compilation/contracts/simpleStorageVar.sol rename to tests/compilation/contracts/warpMemorySystems/simpleStorageVar.sol diff --git a/tests/compilation/contracts/structs.sol b/tests/compilation/contracts/warpMemorySystems/structs.sol similarity index 100% rename from tests/compilation/contracts/structs.sol rename to tests/compilation/contracts/warpMemorySystems/structs.sol diff --git a/tests/compilation/contracts/uint256StaticArrayCasting.sol b/tests/compilation/contracts/warpMemorySystems/uint256StaticArrayCasting.sol similarity index 100% rename from tests/compilation/contracts/uint256StaticArrayCasting.sol rename to tests/compilation/contracts/warpMemorySystems/uint256StaticArrayCasting.sol diff --git a/tests/compilation/passingContracts.ts b/tests/compilation/passingContracts.ts index 8b373c8d1..fbbdd0707 100644 --- a/tests/compilation/passingContracts.ts +++ b/tests/compilation/passingContracts.ts @@ -14,7 +14,7 @@ export const passingContracts = [ 'tests/compilation/contracts/address/8/maxPrimeExplicit.sol', 'tests/compilation/contracts/address/8/padding.sol', 'tests/compilation/contracts/address/8/primeField.sol', - // 'tests/compilation/contracts/arrayLength.sol', + // 'tests/compilation/contracts/warpMemorySystems/arrayLength.sol', // 'tests/compilation/contracts/boolOpNoSideEffects.sol', // 'tests/compilation/contracts/boolOpSideEffects.sol', // 'tests/compilation/contracts/bytesXAccess.sol', @@ -139,11 +139,11 @@ export const passingContracts = [ // 'tests/compilation/contracts/rejectedTerms/contractNameLib.sol', // 'tests/compilation/contracts/rejectedTerms/reservedContract.sol', // 'tests/compilation/contracts/removeUnreachableFunctions.sol', - // 'tests/compilation/contracts/returnDynArray.sol', + // 'tests/compilation/contracts/warpMemorySystems/returnDynArray.sol', // 'tests/compilation/contracts/returnInserter.sol', // 'tests/compilation/contracts/returnVarCapturing.sol', // 'tests/compilation/contracts/returndatasize.sol', - 'tests/compilation/contracts/simpleStorageVar.sol', + 'tests/compilation/contracts/warpMemorySystems/simpleStorageVar.sol', // 'tests/compilation/contracts/sstoreSload.sol', // 'tests/compilation/contracts/stateVariables/arrays.sol', // 'tests/compilation/contracts/stateVariables/arraysInit.sol', @@ -151,7 +151,7 @@ export const passingContracts = [ // 'tests/compilation/contracts/stateVariables/mappings.sol', // 'tests/compilation/contracts/stateVariables/misc.sol', // 'tests/compilation/contracts/stateVariables/scalars.sol', - // 'tests/compilation/contracts/stateVariables/structs.sol', + // 'tests/compilation/contracts/stateVariables/warpMemorySystems/structs.sol', // 'tests/compilation/contracts/stateVariables/structsNested.sol', 'tests/compilation/contracts/structs.sol', // 'tests/compilation/contracts/thisAtConstructor/externalFunctionCallAtConstruction.sol', @@ -174,7 +174,7 @@ export const passingContracts = [ // 'tests/compilation/contracts/typestrings/scalars.sol', // 'tests/compilation/contracts/typestrings/structArrays.sol', // 'tests/compilation/contracts/typestrings/structs.sol', - // 'tests/compilation/contracts/uint256StaticArrayCasting.sol', + // 'tests/compilation/contracts/warpMemorySystems/uint256StaticArrayCasting.sol', // 'tests/compilation/contracts/units.sol', // 'tests/compilation/contracts/unsupportedFunctions/abi.sol', // 'tests/compilation/contracts/unsupportedFunctions/addmod.sol', @@ -198,4 +198,5 @@ export const passingContracts = [ // 'tests/compilation/contracts/usingReturnValues.sol', // 'tests/compilation/contracts/variableDeclarations.sol', // 'tests/compilation/contracts/viewFunction.sol', + 'tests/compilation/contracts/warpMemorySystems/implicitPropagation.sol', ]; diff --git a/warplib/src/conversions/integer_conversions.cairo b/warplib/src/conversions/integer_conversions.cairo index 26e3b0231..de237eec2 100644 --- a/warplib/src/conversions/integer_conversions.cairo +++ b/warplib/src/conversions/integer_conversions.cairo @@ -5,6 +5,7 @@ use starknet::ContractAddress; use traits::{Into, TryInto}; use warplib::integer::{bitnot, Integer}; +use integer::{u256_from_felt252, u128_to_felt252}; fn u256_from_felts(low_felt: felt252, high_felt: felt252) -> u256 { let low_u128: u128 = get_u128_try_from_felt_result(low_felt); @@ -12,6 +13,15 @@ fn u256_from_felts(low_felt: felt252, high_felt: felt252) -> u256 { return u256 { low: low_u128, high: high_u128 }; } +fn u256_to_felt252(x: u256) -> felt252 { + let MAX_FELT = u256_from_felt252(-1); + if x > MAX_FELT { + panic_with_felt252('Overflow in u256_to_felt252') + } + // hex is 2**128 + u128_to_felt252(x.low) + 0x100000000000000000000000000000000 * u128_to_felt252(x.high) +} + fn get_u128_try_from_felt_result(value: felt252) -> u128 { let resp = u128_try_from_felt252(value); assert(resp.is_some(), 'Felts too large for u256');