Skip to content

Commit

Permalink
Fix args decoder.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomusdrw committed Jan 2, 2025
1 parent ec25c5d commit 9b51ecf
Show file tree
Hide file tree
Showing 3 changed files with 17 additions and 26 deletions.
10 changes: 2 additions & 8 deletions assembly/api-generic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,10 @@ export function getAssembly(p: Program): string {
v += changetype<string>(iData.namePtr);
v += `(${instruction})`;

const argsLen = p.mask.argsLen(i);
const argsLen = p.mask.argsLen(i, len);
const end = i + 1 + argsLen;
if (end > len) {
const name = changetype<string>(iData.namePtr);
const intro = "Invalid program - code is not long enough";
throw new Error(`${intro} Expected: ${argsLen} for ${name} at ${i} (${end} > ${len})`);
}

const args = decodeArguments(iData.kind, p.code.subarray(i + 1, end));
const argsArray = args === null ? [0, 0, 0, 0] : [args.a, args.b, args.c, args.d];
const argsArray = [args.a, args.b, args.c, args.d];
const relevantArgs = RELEVANT_ARGS[iData.kind];
for (let i = 0; i < relevantArgs; i++) {
v += ` ${argsArray[i]}, `;
Expand Down
11 changes: 1 addition & 10 deletions assembly/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,18 +80,9 @@ export class Interpreter {
}

// get args and invoke instruction
const argsLen = this.program.mask.argsLen(pc);
const argsLen = this.program.mask.argsLen(pc, this.program.code.length);
const end = pc + 1 + argsLen;
if (end > <u32>this.program.code.length) {
this.status = Status.PANIC;
return false;
}

const args = decodeArguments(iData.kind, this.program.code.subarray(pc + 1, end));
if (args === null) {
this.status = Status.PANIC;
return false;
}

// additional gas cost of sbrk
if (iData === SBRK) {
Expand Down
22 changes: 14 additions & 8 deletions assembly/program.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ export function decodeProgram(program: Uint8Array): Program {

export class Mask {
// NOTE: might be longer than code (bit-alignment)
readonly bytesToSkip: StaticArray<u8>;
readonly bytesToSkip: StaticArray<u32>;

constructor(packedMask: Uint8Array, codeLength: i32) {
this.bytesToSkip = new StaticArray<u8>(codeLength);
let lastInstructionOffset: u8 = 0;
this.bytesToSkip = new StaticArray<u32>(codeLength);
let lastInstructionOffset: u32 = 0;
for (let i: i32 = packedMask.length - 1; i >= 0; i -= 1) {
let bits = packedMask[i];
const index = i * 8;
Expand All @@ -91,11 +91,12 @@ export class Mask {
return this.bytesToSkip[index] === 0;
}

argsLen(i: u32): u8 {
if (i + 1 < <u32>this.bytesToSkip.length) {
argsLen(i: u32, maxLen: u32): u32 {
if (i + 1 < this.bytesToSkip.length) {
return this.bytesToSkip[i + 1];
}
return 0;

return maxLen - i - 1;
}

toString(): string {
Expand Down Expand Up @@ -198,9 +199,14 @@ export class Program {
}
}

export function decodeArguments(kind: Arguments, data: Uint8Array): Args | null {
export function decodeArguments(kind: Arguments, data: Uint8Array): Args {
if (data.length < REQUIRED_BYTES[kind]) {
return null;
// in case we have less data than needed we extend the data with zeros.
const extended = new Uint8Array(REQUIRED_BYTES[kind]);
for (let i = 0; i < data.length; i++) {
extended[i] = data[i];
}
return DECODERS[kind](extended);
}
return DECODERS[kind](data);
}
Expand Down

0 comments on commit 9b51ecf

Please sign in to comment.