-
Notifications
You must be signed in to change notification settings - Fork 344
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ encodeURIComponent #1098
✨ encodeURIComponent #1098
Conversation
* Feature: URI Component encoding * run forge fmt * add contact * add doc link * remove author
Gas Snapshot Comparison Report
|
Happy to have contributed! Thanks for the help @Vectorized |
} | ||
|
||
// Original implementation of `_encodeURIComponentOriginal` | ||
// credit to John Shankman aka White Lights - [email protected] (whitelights.eth). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<3
function encodeURIComponent(string memory s) internal pure returns (string memory result) { | ||
/// @solidity memory-safe-assembly | ||
assembly { | ||
result := mload(0x40) | ||
// Store "0123456789ABCDEF" in scratch space. | ||
// Uppercased to be consistent with JavaScript's implementation. | ||
mstore(0x0f, 0x30313233343536373839414243444546) | ||
let o := add(result, 0x20) | ||
for { let end := add(s, mload(s)) } iszero(eq(s, end)) {} { | ||
s := add(s, 1) | ||
let c := and(mload(s), 0xff) | ||
// If not in `[0-9A-Z-a-z-.!~*'()]`. | ||
if iszero(and(1, shr(c, 0x47fffffe07fffffe03ff678200000000))) { | ||
mstore8(o, 0x25) // '%'. | ||
mstore8(add(o, 1), mload(and(shr(4, c), 15))) | ||
mstore8(add(o, 2), mload(and(c, 15))) | ||
o := add(o, 3) | ||
continue | ||
} | ||
mstore8(o, c) | ||
o := add(o, 1) | ||
} | ||
mstore(result, sub(o, add(result, 0x20))) // Store the length. | ||
mstore(o, 0) // Zeroize the slot after the string. | ||
mstore(0x40, add(o, 0x20)) // Allocate memory. | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Vectorized where can i learn more about how you optimized this? really impressive. even putting the lookup table in scratch space with mstore, that's pretty dang cool. never would've thought of that.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Opcodes are like the movements of martial arts and fingerstyle guitar.
Study, practice, experiment.
Then combine them to create art.
Marcin is a great inspiration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
big thank you. this truly seems like a whole different mindset. once you have a working implementation, it's then about breaking it down into pieces of byte-wise memory and trying to optimize on the mload/mstore level.
this is fun cause now i have a little test. if i can manage to optimize my original function the same way you have (or similarly) i'll know i'm starting to get the hang of it.
thank you vec!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@johnnyshankman, may I know why you included _
in this encoding method? According to the documentation, it should be excluded.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good spot.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Description
Continued from #1097.
Checklist
Ensure you completed all of the steps below before submitting your pull request:
forge fmt
?forge test
?Pull requests with an incomplete checklist will be thrown out.