@fluffylabs/anan-as 1.1.3-dde58f0 → 1.1.3-e01d5ea
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/index.js +91 -109
- package/dist/bin/test-w3f.js +0 -2
- package/dist/build/compiler-inline.js +1 -1
- package/dist/build/compiler.d.ts +2 -2
- package/dist/build/compiler.js +1 -1
- package/dist/build/compiler.wasm +0 -0
- package/dist/build/debug-inline.js +1 -1
- package/dist/build/debug-raw-inline.js +1 -1
- package/dist/build/debug-raw.d.ts +30 -8
- package/dist/build/debug-raw.js +29 -4
- package/dist/build/debug-raw.wasm +0 -0
- package/dist/build/debug.d.ts +30 -8
- package/dist/build/debug.js +30 -4
- package/dist/build/debug.wasm +0 -0
- package/dist/build/release-inline.js +1 -1
- package/dist/build/release-mini-inline.js +1 -1
- package/dist/build/release-mini.d.ts +30 -8
- package/dist/build/release-mini.js +30 -4
- package/dist/build/release-mini.wasm +0 -0
- package/dist/build/release-stub-inline.js +1 -1
- package/dist/build/release-stub.d.ts +30 -8
- package/dist/build/release-stub.js +30 -4
- package/dist/build/release-stub.wasm +0 -0
- package/dist/build/release.d.ts +30 -8
- package/dist/build/release.js +30 -4
- package/dist/build/release.wasm +0 -0
- package/dist/build/test-inline.js +1 -1
- package/dist/build/test.wasm +0 -0
- package/package.json +1 -1
package/dist/bin/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import minimist from "minimist";
|
|
|
4
4
|
import { disassemble, HasMetadata, InputKind, prepareProgram, runProgram } from "../build/release.js";
|
|
5
5
|
const HELP_TEXT = `Usage:
|
|
6
6
|
anan-as disassemble [--spi] [--no-metadata] <file.(jam|pvm|spi|bin)>
|
|
7
|
-
anan-as run [--spi] [--no-logs] [--no-metadata] [--pc <number>] [--gas <number>] <file.jam> [spi-args.bin
|
|
7
|
+
anan-as run [--spi] [--no-logs] [--no-metadata] [--pc <number>] [--gas <number>] <file.jam> [spi-args.bin]
|
|
8
8
|
|
|
9
9
|
Commands:
|
|
10
10
|
disassemble Disassemble PVM bytecode to assembly
|
|
@@ -15,7 +15,7 @@ Flags:
|
|
|
15
15
|
--no-metadata Input does not contain metadata
|
|
16
16
|
--no-logs Disable execution logs (run command only)
|
|
17
17
|
--pc <number> Set initial program counter (default: 0)
|
|
18
|
-
--gas <number> Set initial gas amount (default:
|
|
18
|
+
--gas <number> Set initial gas amount (default: 0)
|
|
19
19
|
--help, -h Show this help message`;
|
|
20
20
|
main();
|
|
21
21
|
function main() {
|
|
@@ -42,9 +42,8 @@ function main() {
|
|
|
42
42
|
}
|
|
43
43
|
function handleDisassemble(args) {
|
|
44
44
|
const parsed = minimist(args, {
|
|
45
|
-
boolean: ["spi", "metadata", "help"],
|
|
45
|
+
boolean: ["spi", "no-metadata", "help"],
|
|
46
46
|
alias: { h: "help" },
|
|
47
|
-
default: { metadata: true },
|
|
48
47
|
});
|
|
49
48
|
if (parsed.help) {
|
|
50
49
|
console.log(HELP_TEXT);
|
|
@@ -77,7 +76,7 @@ function handleDisassemble(args) {
|
|
|
77
76
|
process.exit(1);
|
|
78
77
|
}
|
|
79
78
|
const kind = parsed.spi ? InputKind.SPI : InputKind.Generic;
|
|
80
|
-
const hasMetadata = parsed
|
|
79
|
+
const hasMetadata = parsed["no-metadata"] ? HasMetadata.No : HasMetadata.Yes;
|
|
81
80
|
const f = readFileSync(file);
|
|
82
81
|
const name = kind === InputKind.Generic ? "generic PVM" : "JAM SPI";
|
|
83
82
|
console.log(`🤖 Assembly of ${file} (as ${name})`);
|
|
@@ -85,11 +84,9 @@ function handleDisassemble(args) {
|
|
|
85
84
|
}
|
|
86
85
|
function handleRun(args) {
|
|
87
86
|
const parsed = minimist(args, {
|
|
88
|
-
boolean: ["spi", "logs", "metadata", "help"],
|
|
89
|
-
|
|
90
|
-
string: ["pc", "gas", "_"],
|
|
87
|
+
boolean: ["spi", "no-logs", "no-metadata", "help"],
|
|
88
|
+
string: ["pc", "gas"],
|
|
91
89
|
alias: { h: "help" },
|
|
92
|
-
default: { metadata: true, logs: true },
|
|
93
90
|
});
|
|
94
91
|
if (parsed.help) {
|
|
95
92
|
console.log(HELP_TEXT);
|
|
@@ -103,16 +100,16 @@ function handleRun(args) {
|
|
|
103
100
|
}
|
|
104
101
|
const kind = parsed.spi ? InputKind.SPI : InputKind.Generic;
|
|
105
102
|
let programFile;
|
|
106
|
-
let
|
|
103
|
+
let spiArgsFile;
|
|
107
104
|
if (kind === InputKind.SPI) {
|
|
108
|
-
// For SPI programs, expect: <program.spi> [spi-args.bin
|
|
105
|
+
// For SPI programs, expect: <program.spi> [spi-args.bin]
|
|
109
106
|
if (files.length > 2) {
|
|
110
107
|
console.error("Error: Too many arguments for SPI run command.");
|
|
111
|
-
console.error("Usage: anan-as run --spi [--no-logs] [--no-metadata] [--pc <number>] [--gas <number>] <program.spi> [spi-args.bin
|
|
108
|
+
console.error("Usage: anan-as run --spi [--no-logs] [--no-metadata] [--pc <number>] [--gas <number>] <program.spi> [spi-args.bin]");
|
|
112
109
|
process.exit(1);
|
|
113
110
|
}
|
|
114
111
|
programFile = files[0];
|
|
115
|
-
|
|
112
|
+
spiArgsFile = files[1]; // optional
|
|
116
113
|
}
|
|
117
114
|
else {
|
|
118
115
|
// For generic programs, expect exactly one file
|
|
@@ -123,116 +120,101 @@ function handleRun(args) {
|
|
|
123
120
|
}
|
|
124
121
|
programFile = files[0];
|
|
125
122
|
}
|
|
123
|
+
// Validate program file extension
|
|
124
|
+
const expectedExt = kind === InputKind.SPI ? ".spi" : ".jam";
|
|
125
|
+
const dotIndex = programFile.lastIndexOf(".");
|
|
126
|
+
if (dotIndex === -1) {
|
|
127
|
+
console.error(`Error: File '${programFile}' has no extension.`);
|
|
128
|
+
console.error(`Expected: ${expectedExt}`);
|
|
129
|
+
process.exit(1);
|
|
130
|
+
}
|
|
131
|
+
const ext = programFile.substring(dotIndex);
|
|
132
|
+
if (ext !== expectedExt) {
|
|
133
|
+
console.error(`Error: Invalid file extension '${ext}' for run command.`);
|
|
134
|
+
console.error(`Expected: ${expectedExt}`);
|
|
135
|
+
process.exit(1);
|
|
136
|
+
}
|
|
126
137
|
// Validate SPI args file if provided
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
138
|
+
let spiArgs;
|
|
139
|
+
if (spiArgsFile) {
|
|
140
|
+
const argsDotIndex = spiArgsFile.lastIndexOf(".");
|
|
141
|
+
if (argsDotIndex === -1) {
|
|
142
|
+
console.error(`Error: SPI args file '${spiArgsFile}' has no extension.`);
|
|
143
|
+
console.error(`Expected: .bin`);
|
|
144
|
+
process.exit(1);
|
|
145
|
+
}
|
|
146
|
+
const argsExt = spiArgsFile.substring(argsDotIndex);
|
|
147
|
+
if (argsExt !== ".bin") {
|
|
148
|
+
console.error(`Error: SPI args file must have .bin extension, got '${argsExt}'.`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
spiArgs = new Uint8Array(readFileSync(spiArgsFile));
|
|
152
|
+
}
|
|
153
|
+
const logs = !parsed["no-logs"];
|
|
154
|
+
const hasMetadata = parsed["no-metadata"] ? HasMetadata.No : HasMetadata.Yes;
|
|
130
155
|
// Parse and validate PC and gas options
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
156
|
+
let initialPc = 0;
|
|
157
|
+
if (parsed.pc !== undefined) {
|
|
158
|
+
// Ensure it's a string/number, not boolean
|
|
159
|
+
if (typeof parsed.pc === "boolean") {
|
|
160
|
+
console.error("Error: --pc requires a value.");
|
|
161
|
+
process.exit(1);
|
|
162
|
+
}
|
|
163
|
+
const pcStr = String(parsed.pc);
|
|
164
|
+
// Reject floats and non-integer strings
|
|
165
|
+
if (pcStr.includes(".") || !/^-?\d+$/.test(pcStr)) {
|
|
166
|
+
console.error("Error: --pc must be a valid integer.");
|
|
167
|
+
process.exit(1);
|
|
168
|
+
}
|
|
169
|
+
const pcValue = parseInt(pcStr, 10);
|
|
170
|
+
if (!Number.isInteger(pcValue) || pcValue < 0 || pcValue > 0xffffffff) {
|
|
171
|
+
console.error("Error: --pc must be a non-negative integer <= 2^32-1.");
|
|
172
|
+
process.exit(1);
|
|
173
|
+
}
|
|
174
|
+
initialPc = pcValue;
|
|
175
|
+
}
|
|
176
|
+
let initialGas = BigInt(0);
|
|
177
|
+
if (parsed.gas !== undefined) {
|
|
178
|
+
// Ensure it's a string/number, not boolean
|
|
179
|
+
if (typeof parsed.gas === "boolean") {
|
|
180
|
+
console.error("Error: --gas requires a value.");
|
|
181
|
+
process.exit(1);
|
|
182
|
+
}
|
|
183
|
+
const gasStr = String(parsed.gas);
|
|
184
|
+
// Reject floats and non-integer strings
|
|
185
|
+
if (gasStr.includes(".") || !/^-?\d+$/.test(gasStr)) {
|
|
186
|
+
console.error("Error: --gas must be a valid integer.");
|
|
187
|
+
process.exit(1);
|
|
188
|
+
}
|
|
189
|
+
let gasValue;
|
|
190
|
+
try {
|
|
191
|
+
gasValue = BigInt(gasStr);
|
|
192
|
+
}
|
|
193
|
+
catch (_e) {
|
|
194
|
+
console.error("Error: --gas must be a valid integer.");
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
const MAX_I64 = (1n << 63n) - 1n;
|
|
198
|
+
if (gasValue < 0n || gasValue > MAX_I64) {
|
|
199
|
+
console.error("Error: --gas must be a non-negative integer <= 2^63-1.");
|
|
200
|
+
process.exit(1);
|
|
201
|
+
}
|
|
202
|
+
initialGas = gasValue;
|
|
203
|
+
}
|
|
204
|
+
const f = readFileSync(programFile);
|
|
134
205
|
const name = kind === InputKind.Generic ? "generic PVM" : "JAM SPI";
|
|
135
206
|
console.log(`🚀 Running ${programFile} (as ${name})`);
|
|
136
207
|
try {
|
|
137
|
-
const program = prepareProgram(kind, hasMetadata,
|
|
208
|
+
const program = prepareProgram(kind, hasMetadata, Array.from(f), [], [], [], spiArgs ? Array.from(spiArgs) : []);
|
|
138
209
|
const result = runProgram(program, initialGas, initialPc, logs, false);
|
|
139
210
|
console.log(`Status: ${result.status}`);
|
|
140
211
|
console.log(`Exit code: ${result.exitCode}`);
|
|
141
212
|
console.log(`Program counter: ${result.pc}`);
|
|
142
213
|
console.log(`Gas remaining: ${result.gas}`);
|
|
143
214
|
console.log(`Registers: [${result.registers.join(", ")}]`);
|
|
144
|
-
console.log(`Result: [${hexEncode(result.result)}]`);
|
|
145
215
|
}
|
|
146
216
|
catch (error) {
|
|
147
217
|
console.error(`Error running ${programFile}:`, error);
|
|
148
218
|
process.exit(1);
|
|
149
219
|
}
|
|
150
220
|
}
|
|
151
|
-
function parseGas(parsed) {
|
|
152
|
-
if (parsed.gas === undefined) {
|
|
153
|
-
return BigInt(10_000);
|
|
154
|
-
}
|
|
155
|
-
// Ensure it's a string/number, not boolean
|
|
156
|
-
if (typeof parsed.gas === "boolean") {
|
|
157
|
-
console.error("Error: --gas requires a value.");
|
|
158
|
-
process.exit(1);
|
|
159
|
-
}
|
|
160
|
-
const gasStr = String(parsed.gas);
|
|
161
|
-
// Reject floats and non-integer strings
|
|
162
|
-
if (gasStr.includes(".") || !/^-?\d+$/.test(gasStr)) {
|
|
163
|
-
console.error("Error: --gas must be a valid integer.");
|
|
164
|
-
process.exit(1);
|
|
165
|
-
}
|
|
166
|
-
let gasValue;
|
|
167
|
-
try {
|
|
168
|
-
gasValue = BigInt(gasStr);
|
|
169
|
-
}
|
|
170
|
-
catch (_e) {
|
|
171
|
-
console.error("Error: --gas must be a valid integer.");
|
|
172
|
-
process.exit(1);
|
|
173
|
-
}
|
|
174
|
-
const MAX_I64 = (1n << 63n) - 1n;
|
|
175
|
-
if (gasValue < 0n || gasValue > MAX_I64) {
|
|
176
|
-
console.error("Error: --gas must be a non-negative integer <= 2^63-1.");
|
|
177
|
-
process.exit(1);
|
|
178
|
-
}
|
|
179
|
-
return gasValue;
|
|
180
|
-
}
|
|
181
|
-
function parseSpiArgs(spiArgsStr) {
|
|
182
|
-
if (!spiArgsStr) {
|
|
183
|
-
return [];
|
|
184
|
-
}
|
|
185
|
-
try {
|
|
186
|
-
return Array.from(hexDecode(spiArgsStr));
|
|
187
|
-
}
|
|
188
|
-
catch (e) {
|
|
189
|
-
console.log(`Attempting to read ${spiArgsStr} as a file, since it's not a hex value: ${e}`);
|
|
190
|
-
return Array.from(readFileSync(spiArgsStr));
|
|
191
|
-
}
|
|
192
|
-
}
|
|
193
|
-
function parsePc(parsed) {
|
|
194
|
-
if (parsed.pc === undefined) {
|
|
195
|
-
return 0;
|
|
196
|
-
}
|
|
197
|
-
// Ensure it's a string/number, not boolean
|
|
198
|
-
if (typeof parsed.pc === "boolean") {
|
|
199
|
-
console.error("Error: --pc requires a value.");
|
|
200
|
-
process.exit(1);
|
|
201
|
-
}
|
|
202
|
-
const pcStr = String(parsed.pc);
|
|
203
|
-
// Reject floats and non-integer strings
|
|
204
|
-
if (pcStr.includes(".") || !/^-?\d+$/.test(pcStr)) {
|
|
205
|
-
console.error("Error: --pc must be a valid integer.");
|
|
206
|
-
process.exit(1);
|
|
207
|
-
}
|
|
208
|
-
const pcValue = parseInt(pcStr, 10);
|
|
209
|
-
if (!Number.isInteger(pcValue) || pcValue < 0 || pcValue > 0xffffffff) {
|
|
210
|
-
console.error("Error: --pc must be a non-negative integer <= 2^32-1.");
|
|
211
|
-
process.exit(1);
|
|
212
|
-
}
|
|
213
|
-
return pcValue;
|
|
214
|
-
}
|
|
215
|
-
function hexEncode(result) {
|
|
216
|
-
return `0x${result.map((x) => x.toString(16).padStart(2, "0")).join("")}`;
|
|
217
|
-
}
|
|
218
|
-
function hexDecode(data) {
|
|
219
|
-
if (!data.startsWith("0x")) {
|
|
220
|
-
throw new Error("hex input must start with 0x");
|
|
221
|
-
}
|
|
222
|
-
const hex = data.substring(2);
|
|
223
|
-
const len = hex.length;
|
|
224
|
-
if (len % 2 === 1) {
|
|
225
|
-
throw new Error("Odd number of nibbles");
|
|
226
|
-
}
|
|
227
|
-
const bytes = new Uint8Array(len / 2);
|
|
228
|
-
for (let i = 0; i < len; i += 2) {
|
|
229
|
-
const c = hex.substring(i, i + 2);
|
|
230
|
-
const byteIndex = i / 2;
|
|
231
|
-
const value = parseInt(c, 16);
|
|
232
|
-
if (Number.isNaN(value)) {
|
|
233
|
-
throw new Error(`hexDecode: invalid hex pair "${c}" in data "${data}" for bytes[${byteIndex}]`);
|
|
234
|
-
}
|
|
235
|
-
bytes[byteIndex] = value;
|
|
236
|
-
}
|
|
237
|
-
return bytes;
|
|
238
|
-
}
|
package/dist/bin/test-w3f.js
CHANGED
|
@@ -68,8 +68,6 @@ function processW3f(data, options) {
|
|
|
68
68
|
}
|
|
69
69
|
// compare with expected values
|
|
70
70
|
const expected = {
|
|
71
|
-
// just copy JAM-output result field
|
|
72
|
-
result: result.result,
|
|
73
71
|
status: read(data, "expected-status"),
|
|
74
72
|
registers: read(data, "expected-regs").map((x) => BigInt(x)),
|
|
75
73
|
pc: read(data, "expected-pc"),
|