git.delta.rocks / jrsonnet / refs/commits / 7d9fe5cc7023

difftreelog

source

bindings/js/index.js3.6 KiBsourcehistory
1const fs = require('fs');2const { WASI } = require('wasi');3const wasi = new WASI({4	args: process.argv,5	env: process.env,6	preopens: {},7});8const importObject = { wasi_snapshot_preview1: wasi.wasiImport };910class JsonnetVM {11	constructor(wasm, vm) {12		this.wasm = wasm;13		this.vm = vm;14	}1516	alloc(length) {17		return this.wasm.exports.jsonnet_realloc(this.vm, 0, length);18	}19	allocateString(string) {20		const byteLength = new TextEncoder().encode(string).length;21		const addr = this.alloc(byteLength);22		this.wasm.writeString(addr, string);23		return addr;24	}25	dealloc(addr) {26		return this.wasm.exports.jsonnet_realloc(this.vm, addr, 0);27	}2829	evaluateFile(path) {30		const pathAddr = this.allocateString(path);31		const resultCodeAddr = this.alloc(4);32		const resultAddr = this.wasm.exports.jsonnet_evaluate_file(this.vm, pathAddr, resultCodeAddr);33		this.dealloc(pathAddr);34		const resultCode = this.wasm.memorySliceLen(resultCodeAddr, 4);35		this.dealloc(resultCodeAddr);36		const result = this.wasm.readString(resultAddr).trim();37		this.dealloc(resultAddr);38		if (resultCode[0] === 1) {39			const error = new Error(this.normalizeErrorString(result));40			throw error;41		} else {42			return result;43		}44	}45	evaluateSnippet(path, snippet) {46		const pathAddr = this.allocateString(path);47		const snippetAddr = this.allocateString(snippet);48		const resultCodeAddr = this.alloc(4);49		const resultAddr = this.wasm.exports.jsonnet_evaluate_snippet(this.vm, pathAddr, snippetAddr, resultCodeAddr);50		this.dealloc(pathAddr);51		this.dealloc(snippetAddr);52		const resultCode = this.wasm.memorySliceLen(resultCodeAddr, 4);53		this.dealloc(resultCodeAddr);54		const result = this.wasm.readString(resultAddr);55		this.dealloc(resultAddr);56		if (resultCode[0] === 1) {57			const error = new Error(this.normalizeErrorString(result));58			throw error;59		} else {60			return result;61		}62	}63	normalizeErrorString(str) {64		str = str.trim();65		const newLine = str.indexOf('\n');66		if (newLine === -1) return str;67		let message = str.slice(0, newLine);68		let trace = str.slice(newLine + 1).split('\n').map(s => s.split(' ---- ')).map(([p, v]) => `    at ${v} (${p})`).join('\n');69		return `${message}\n${trace}`;70	}71}7273class JsonnetWASM {74	constructor() { }7576	async init(buf) {77		const wasm = await WebAssembly.compile(buf);78		const instance = await WebAssembly.instantiate(wasm, importObject);79		wasi.start(instance);80		this.instance = instance;81	}82	get exports() {83		return this.instance.exports;84	}85	get memory() {86		return this.exports.memory;87	}88	get memoryBuffer() {89		return this.memory.buffer;90	}91	memorySliceLen(start, length) {92		return new Uint8Array(this.memoryBuffer, start, length);93	}94	memorySlice(start, end) {95		return new Uint8Array(this.memoryBuffer, start, start && end && (end - start));96	}9798	readString(addr) {99		let end;100		let slice = this.memorySlice();101		for (end = addr; slice[end]; end++);102		return (new TextDecoder()).decode(this.memorySlice(addr, end));103	}104	writeString(addr, string) {105		let slice = this.memorySlice(addr);106		let result = new TextEncoder().encodeInto(string, slice);107		slice[result.written] = 0;108	}109110	version() {111		return this.readString(this.exports.jsonnet_version());112	}113114	newVM() {115		return new JsonnetVM(this, this.exports.jsonnet_make());116	}117}118119(async () => {120	try {121		const jsonnet = new JsonnetWASM();122		await jsonnet.init(fs.readFileSync(`${__dirname}/../../target/wasm32-wasi/release/jsonnet.wasi.wasm`));123		console.log(`Version = ${jsonnet.version()}`);124125		const vm = jsonnet.newVM();126		console.log(vm.evaluateSnippet('./snip.jsonnet', `127			local a(b) = error "sad" + b;128			local c() = a(2 + 2);129			c()130		`))131		console.log(vm.evaluateFile('./test.jsonnet'));132	} catch (e) {133		console.log(e.stack);134	}135})();