Skip to content

feat(vm): implement TIP-7939 CLZ opcode#6656

Open
yanghang8612 wants to merge 1 commit intotronprotocol:developfrom
yanghang8612:implement-tip-7939
Open

feat(vm): implement TIP-7939 CLZ opcode#6656
yanghang8612 wants to merge 1 commit intotronprotocol:developfrom
yanghang8612:implement-tip-7939

Conversation

@yanghang8612
Copy link
Copy Markdown
Collaborator

Summary

Implement TIP-7939 CLZ opcode (0x1e), gated behind the existing allowTvmOsaka flag.

  • New opcode: pops 1 value, pushes the number of leading zero bits (256 if zero)
  • Gas cost: 5 (LOW_TIER, matching MUL)
  • Added TRON_V1_5 version with appendOsakaOperations to support Osaka opcodes
  • Test cases cover all TIP test vectors and energy cost verification

Related: tronprotocol/tips#838

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
DataWord word = program.stackPop();
int clz = numberOfLeadingZeros(word.getData());
if (clz == 256) {
program.stackPush(new DataWord(256));
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not define 256 as a static constant, so that whenever word is 0, it is pushed directly onto the stack?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Even if a 256 DataWord constant is defined, it still needs to be cloned when pushed onto the stack. The overhead involved is nearly equivalent to creating a new instance from scratch, so the constant approach was not adopted.

@halibobo1205 halibobo1205 added the topic:vm VM, smart contract label Apr 9, 2026
if (clz == 256) {
program.stackPush(new DataWord(256));
} else {
program.stackPush(DataWord.of((byte) clz));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work overall! One minor suggestion: since DataWord.of(byte num) directly assigns bb[31] = num, casting clz to (byte) when it's in [128, 255] introduces a subtle signed/unsigned ambiguity. Would it be worth simplifying both branches into one using new DataWord(int), which handles the full range cleanly?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

topic:vm VM, smart contract

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants