Skip to content

Commit

Permalink
add javadoc
Browse files Browse the repository at this point in the history
Signed-off-by: Karim Taam <[email protected]>
  • Loading branch information
matkt committed Feb 13, 2025
1 parent e1f6b8d commit adf9301
Show file tree
Hide file tree
Showing 3 changed files with 205 additions and 4 deletions.
81 changes: 80 additions & 1 deletion evm/src/main/java/org/hyperledger/besu/evm/code/Bytecode.java
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,18 @@
import org.apache.tuweni.bytes.AbstractBytes;
import org.apache.tuweni.bytes.MutableBytes;

/**
* An abstract class representing bytecode . This class provides common methods for working with
* bytecode, including slicing and copying the bytecode.
*/
public abstract class Bytecode extends AbstractBytes {

/**
* Creates a sliced version of the bytecode starting at the given index.
*
* @param i the index to start slicing from
* @return a new Bytecode object representing the sliced portion
*/
@Override
public Bytecode slice(final int i) {
if (i == 0) {
Expand All @@ -31,51 +41,120 @@ public Bytecode slice(final int i) {
}
}

/**
* Creates a sliced version of the bytecode starting at the given index and with the specified
* length.
*
* @param i the index to start slicing from
* @param length the length of the slice
* @return a new Bytecode object representing the sliced portion
*/
@Override
public abstract Bytecode slice(int i, int length);

/**
* Returns the raw bytecode as a RawByteArray.
*
* @return the raw bytecode as a RawByteArray
*/
public abstract RawByteArray getRawByteArray();

/**
* Creates a copy of the current bytecode.
*
* @return a new Bytecode object that is a copy of the current bytecode
*/
@Override
public abstract Bytecode copy();

/**
* Throws an UnsupportedOperationException since bytecode cannot have a mutable copy.
*
* @throws UnsupportedOperationException if called
*/
@Override
public MutableBytes mutableCopy() {
throw new UnsupportedOperationException("cannot create a mutable copy of bytecode");
}

/**
* A helper class that wraps raw bytecode as an array of bytes, providing methods to access raw
* bytecode.
*/
public static class RawByteArray {
byte[] rawBytecode;
private final byte[] rawBytecode;

/**
* Constructs a RawByteArray with the given raw bytecode array.
*
* @param rawBytecode the byte array representing the raw bytecode
*/
public RawByteArray(final byte[] rawBytecode) {
this.rawBytecode = rawBytecode;
}

/**
* Gets the byte at the specified offset.
*
* @param offset the offset at which to retrieve the byte
* @return the byte at the specified offset
*/
public byte get(final int offset) {
return rawBytecode[offset];
}

/**
* Gets a subarray of bytes from the specified offset and length.
*
* @param offset the starting offset
* @param length the number of bytes to retrieve
* @return a byte array containing the requested bytes
*/
public byte[] get(final int offset, final int length) {
return get(offset, length, length);
}

/**
* Gets a subarray of bytes from the specified offset and length.
*
* @param offset the starting offset
* @param length the number of bytes to retrieve
* @param arraySize the size of the array to return
* @return a byte array containing the requested bytes
*/
public byte[] get(final int offset, final int length, final int arraySize) {
var bytecodeLocal = new byte[arraySize];
System.arraycopy(rawBytecode, offset, bytecodeLocal, 0, length);
return bytecodeLocal;
}

/**
* Returns the size of the raw bytecode array.
*
* @return the size of the raw bytecode
*/
public int size() {
return rawBytecode.length;
}

/**
* Checks if two RawByteArray objects are equal by comparing their byte arrays.
*
* @param o the object to compare to
* @return true if the objects are equal, false otherwise
*/
@Override
public boolean equals(final Object o) {
if (o == null || getClass() != o.getClass()) return false;
RawByteArray that = (RawByteArray) o;
return Arrays.equals(rawBytecode, that.rawBytecode);
}

/**
* Returns the hash code for this RawByteArray.
*
* @return the hash code of the raw bytecode array
*/
@Override
public int hashCode() {
return Arrays.hashCode(rawBytecode);
Expand Down
75 changes: 75 additions & 0 deletions evm/src/main/java/org/hyperledger/besu/evm/code/FullBytecode.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,61 +16,136 @@

import org.apache.tuweni.bytes.Bytes;

/**
* Represents a full bytecode. This class provides methods for accessing the bytecode, slicing it,
* and converting it from various formats.
*/
public class FullBytecode extends Bytecode {

/** Constant representing an empty bytecode . */
public static final FullBytecode EMPTY = new FullBytecode(Bytes.EMPTY);

private final Bytes bytes;

/**
* Constructs a FullBytecode object from Bytes .
*
* @param bytes the Bytes object containing the bytecode data
*/
public FullBytecode(final Bytes bytes) {
this.bytes = bytes;
}

/**
* Constructs a FullBytecode from a byte array.
*
* @param bytes the byte array containing the bytecode data
*/
public FullBytecode(final byte[] bytes) {
this.bytes = Bytes.wrap(bytes);
}

/**
* Returns a RawByteArray representation of the bytecode.
*
* @return the RawByteArray representation of the bytecode
*/
@Override
public RawByteArray getRawByteArray() {
return new RawByteArray(bytes.toArrayUnsafe());
}

/**
* Returns the size of the bytecode.
*
* @return the size of the bytecode
*/
@Override
public int size() {
return bytes.size();
}

/**
* Returns the byte at the specified index in the bytecode.
*
* @param i the index of the byte to retrieve
* @return the byte at the specified index
* @throws IndexOutOfBoundsException if the index is out of bounds
*/
@Override
public byte get(final int i) {
return bytes.get(i);
}

/**
* Creates a copy of the FullBytecode object.
*
* @return a new FullBytecode object with the same bytecode data
*/
@Override
public Bytecode copy() {
return new FullBytecode(bytes.copy());
}

/**
* Slices the bytecode from a specified index and length.
*
* @param i the starting index of the slice
* @param length the length of the slice
* @return a new SlicedBytecode object representing the sliced portion
*/
@Override
public Bytecode slice(final int i, final int length) {
return new SlicedBytecode(this, i, length);
}

/**
* Converts a hex string representation of bytecode into a FullBytecode object.
*
* @param hex the hex string representing the bytecode
* @return a FullBytecode object containing the bytecode represented by the hex string
*/
public static Bytecode fromHexString(final String hex) {
return new FullBytecode(Bytes.fromHexString(hex));
}

/**
* Creates a FullBytecode object from a sequence of integers, where each integer represents a
* byte.
*
* @param bytes the sequence of integers representing the bytecode
* @return a FullBytecode object containing the bytecode
*/
public static Bytecode of(final int... bytes) {
return new FullBytecode(Bytes.of(bytes));
}

/**
* Creates a FullBytecode object from a sequence of bytes.
*
* @param bytes the sequence of bytes representing the bytecode
* @return a FullBytecode object containing the bytecode
*/
public static Bytecode of(final byte... bytes) {
return new FullBytecode(Bytes.of(bytes));
}

/**
* Wraps an existing byte array into a FullBytecode object.
*
* @param bytes the byte array to wrap
* @return a FullBytecode object containing the bytecode
*/
public static Bytecode wrap(final byte[] bytes) {
return new FullBytecode(bytes);
}

/**
* Wraps an existing Bytes object into a FullBytecode object.
*
* @param bytes the Bytes object to wrap
* @return a FullBytecode object containing the bytecode
*/
public static Bytecode wrap(final Bytes bytes) {
return new FullBytecode(bytes);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,27 @@
*/
package org.hyperledger.besu.evm.code;

/**
* Represents a partial view (slice) of a larger bytecode. The slice is defined by a starting offset
* and length within the parent bytecode. This class allows accessing and manipulating a specific
* portion of the bytecode without modifying the parent bytecode.
*/
public class SlicedBytecode extends Bytecode {

private final Bytecode parent;
private final int sliceOffset;
private final int sliceLength;

/**
* Constructs a SlicedBytecode object, which represents a portion (slice) of a larger parent
* bytecode. The slice is defined by an offset and a length within the parent bytecode.
*
* @param parent the parent bytecode from which the slice is derived
* @param offset the starting offset of the slice within the parent bytecode
* @param length the length of the slice
* @throws IndexOutOfBoundsException if the slice's offset or length is out of bounds within the
* parent bytecode
*/
public SlicedBytecode(final Bytecode parent, final int offset, final int length) {
// Validate range within parent
if (offset < 0 || length < 0 || offset + length > parent.size()) {
Expand All @@ -30,34 +45,66 @@ public SlicedBytecode(final Bytecode parent, final int offset, final int length)
this.sliceLength = length;
}

/**
* Returns the raw bytecode of the slice as a RawByteArray, which is a portion of the parent
* bytecode.
*
* @return the raw bytecode of the slice
*/
@Override
public RawByteArray getRawByteArray() {
return new RawByteArray(parent.getRawByteArray().get(sliceOffset, sliceLength));
}

/**
* Returns the size of the sliced portion of bytecode.
*
* @return the size of the slice
*/
@Override
public int size() {
return sliceLength;
}

/**
* Returns the byte at the specified index within the slice. The index is relative to the slice,
* not to the parent bytecode.
*
* @param index the index within the slice
* @return the byte at the specified index
* @throws IndexOutOfBoundsException if the index is outside the slice's range
*/
@Override
public byte get(final int index) {
if (index < 0 || index >= sliceLength) {
throw new IndexOutOfBoundsException("Index out of slice range");
}
// Delegate to the parent, adding the slice offset
// Delegate to the parent bytecode, adding the slice offset
return parent.get(sliceOffset + index);
}

/**
* Creates a new copy of the sliced bytecode. The copy is a new instance representing the same
* slice from the parent bytecode.
*
* @return a new SlicedBytecode object that is a copy of the current slice
*/
@Override
public Bytecode copy() {
return new SlicedBytecode(parent.copy(), sliceOffset, sliceLength);
}

/**
* Creates a new slice from the current slice, defined by a new offset and length. The offset is
* relative to the current sliced view, not the parent bytecode.
*
* @param offset the new offset relative to the current slice
* @param length the length of the new slice
* @return a new SlicedBytecode object representing the new slice
*/
@Override
public Bytecode slice(final int offset, final int length) {
// Just compose the offset again relative to the parent
// offset is relative to this sliced view
// Create a new slice with the specified offset and length, relative to the parent bytecode
return new SlicedBytecode(parent, sliceOffset + offset, length);
}
}

0 comments on commit adf9301

Please sign in to comment.