From 60c77630cd92ec2c40615f52332bd121cff49f0e Mon Sep 17 00:00:00 2001 From: LSTM-Kirigaya <1193466151@qq.com> Date: Mon, 13 May 2024 14:05:13 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=20parameter=20=E7=9A=84?= =?UTF-8?q?=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bin/vcd.js | 24 +-- lib/web-vcd-parser.js | 402 +++++++++++++++++------------------------- out/vcd.wasm | Bin 127010 -> 127001 bytes test/debug/basic.js | 1 + test/wasm_iverilog.js | 19 +- vcd.c | 365 +++++++++++++++++++------------------- wasm_main.cpp | 257 +++++++++++---------------- wasm_main.hpp | 12 +- 8 files changed, 483 insertions(+), 597 deletions(-) diff --git a/bin/vcd.js b/bin/vcd.js index e63574a..1a67be1 100644 --- a/bin/vcd.js +++ b/bin/vcd.js @@ -26,7 +26,7 @@ const webVcdParser = require('../lib/web-vcd-parser.js'); * * @typedef {Object} VcdInfo * @property {number} t0 - * @property {string} timescale + * @property {number} timescale * @property {string} version * @property {string} date * @property {string} status @@ -103,6 +103,7 @@ function parseTimescale(timescale) { * write: (piece: Uint8Array) => void * consume: (arraybuffer: ArrayBuffer, config?: consumeConfig) => void * getBasicInfo: () => VcdBasicInfo + * clean: () => void * }} */ async function makeVcdStream() { @@ -120,12 +121,6 @@ async function makeVcdStream() { // console.log(time > MAX_SAFE_INTEGER); // } - // TODO: 解决这个问题,有关 parameter 参数读取 - if (time > MAX_SAFE_INTEGER) { - vcdBasicInfo.signalValues[id].wave = [[0, Number(value)]]; - return; - } - if (cmd >= 14 && cmd <= 28) { vcdBasicInfo.signalValues[id].kind = 'bit'; vcdBasicInfo.signalValues[id].wave.push([time53, cmd - 14]); @@ -147,6 +142,13 @@ async function makeVcdStream() { return vcdBasicInfo; }; + vcdstream.clean = () => { + vcdBasicInfo.signalValues = {}; + vcdBasicInfo.vcdInfo = undefined; + vcdBasicInfo.tgcd = undefined; + vcdBasicInfo.time = undefined; + } + return vcdstream; } @@ -206,11 +208,9 @@ async function getVcdStream() { // 测试时关闭该函数 // 部署时激活该函数 try { - if (self) { - self.getVcdStream = getVcdStream; - self.makeVcdStream = makeVcdStream; - self.vcdBasicInfo = vcdBasicInfo; - } + self.getVcdStream = getVcdStream; + self.makeVcdStream = makeVcdStream; + self.vcdBasicInfo = vcdBasicInfo; } catch (error) {} module.exports = { diff --git a/lib/web-vcd-parser.js b/lib/web-vcd-parser.js index ff87580..c23fa4a 100644 --- a/lib/web-vcd-parser.js +++ b/lib/web-vcd-parser.js @@ -1,110 +1,66 @@ 'use strict'; -/* eslint-disable no-console */ -/* eslint-disable indent */ -/* eslint-disable no-unused-vars */ const stream = require('stream'); const EventEmitter = require('events').EventEmitter; - const commandHandler = require('./command-handler.js'); -// function _waitForStart(mod) { -// return new Promise((resolve)=>{ -// mod.addOnPostRun(resolve); -// }); -// } - -// function u8ToBn(u8) { -// let str = ''; -// for (let i = 0; i < u8.length; i++) { -// const val = u8[i]; -// str = val.toString(16) + str; -// if (val < 16) { -// str = '0' + str; -// } -// } -// return BigInt('0x' + str); -// } - function h8ToBn(HEAPU8, start, len) { - if (len === 0) { - return 0n; - } - let str = ''; - const fin = start + len * 8; - for (let i = start; i < fin; i++) { - const val = HEAPU8[i]; - str = val.toString(16) + str; - if (val < 16) { - str = '0' + str; + if (len === 0) { + return 0n; } - } - return BigInt('0x' + str); + let str = ''; + const fin = start + len * 8; + for (let i = start; i < fin; i++) { + const val = HEAPU8[i]; + str = val.toString(16) + str; + if (val < 16) { + str = '0' + str; + } + } + return BigInt('0x' + str); } -// let startCalled = 0; - const bindCWrap = (c, wasm) => { - const w = wasm.cwrap; - c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'array', 'number']); - c.init = w('init', 'number', ['number', 'number', 'number', 'number']); - c.getTime = w('getTime', 'number', ['number']); - c.setTrigger = w('setTrigger', 'number', ['number', 'string']); + const w = wasm.cwrap; + c.execute = w('execute', 'number', ['number', 'number', 'number', 'number', 'number', 'array', 'number']); + c.init = w('init', 'number', ['number', 'number', 'number', 'number']); + c.getTime = w('getTime', 'number', ['number']); + c.setTrigger = w('setTrigger', 'number', ['number', 'string']); }; const getWrapper = wasm => { - // console.log(wasm); + const c = {}; + let bindCallback; + const start = async () => { + bindCWrap(c, wasm); + bindCallback(); + }; - const c = {}; + // gets a string from a c heap pointer and length + const getString = (name, len) => { + let string = ''; + const end = name + len; + for (let i = name; i < end; i++) { + string += String.fromCharCode(wasm.HEAPU8[i]); + } + return string; - let bindCallback; + }; + + let boundInfo; + + let boundSet; + let boundGet; + + let ee = []; + + let boundEE0; + let boundEE1; + + let context = -1; - const start = async() => { - // if( !startCalled ) { - // await _waitForStart(wasm); - // startCalled++; - // } - // console.log('s1'); - bindCWrap(c, wasm); - // console.log('s2'); - bindCallback(); - // console.log('s3'); - }; - - // gets a string from a c heap pointer and length - const getString = (name, len) => { - - // const view = wasm.HEAPU8.subarray(name, name+len); - // let string = ''; - // for (let i = 0; i < len; i++) { - // string += String.fromCharCode(view[i]); - // } - // return string; - - let string = ''; - const end = name + len; - for (let i = name; i < end; i++) { - string += String.fromCharCode(wasm.HEAPU8[i]); - } - return string; - - }; - - let boundInfo; - - let boundSet; - let boundGet; - - let ee = []; - - let boundEE0; - let boundEE1; - - let context = -1; - - - const onEE1 = ( + const onEE1 = ( /* const char* */ eventName, /* const size_t */ eventNameLength, // strlen(name) /* const int64_t */ time, @@ -113,168 +69,138 @@ const getWrapper = wasm => { /* uint64_t* */ value, /* const int */ maskWords, /* uint64_t* */ mask - ) => { - const name = getString(eventName, eventNameLength); - // console.log(`event name`); - // console.log({name, time, command, valueWords}); + ) => { + const name = getString(eventName, eventNameLength); + if (cmd >= 14 && cmd <= 28) { + ee[1](name, time, cmd); + } else { + const bigValue = h8ToBn(wasm.HEAPU8, value, valueWords); + const bigMask = h8ToBn(wasm.HEAPU8, mask, maskWords); + ee[1](name, time, cmd, bigValue, bigMask); + } + }; + + // wasm.addFunction can't be called until after + // start finishes + bindCallback = () => { + boundSet = wasm.addFunction(function (name, len, type, v0, v1) { + let prop = getString(name, len); + let tmp; + + switch (type) { + // set number + case 0: + boundInfo[prop] = v0; + break; + // set string + case 1: + boundInfo[prop] = getString(v0, v1); + break; + // set string to path + case 2: + break; + // path to path (any type) + case 3: + break; + // create empty object at path + case 4: + break; + case 5: + commandHandler(boundInfo, v0, prop); + break; + default: throw new Error(); + } + // viiiii means returns void, accepts int int int int int + }, 'viiiii'); + + boundGet = wasm.addFunction(function (name, len) { + let prop = getString(name, len); + return prop; + }, 'iii'); + boundEE0 = wasm.addFunction(function (name, len) { + ee[0](getString(name, len)); + }, 'vii'); - // const view0 = wasm.HEAPU8.subarray(value, value+(valueWords*8)); - // const view1 = wasm.HEAPU8.subarray(mask, mask+(valueWords*8)); + boundEE1 = wasm.addFunction(onEE1, 'viijiiiii'); + }; - // let bigValue = u8ToBn(view0); - // let bigMask = u8ToBn(view1); - // let bigValue = 0n; - - // console.log(bigValue.toString(16)); - - if (cmd >= 14 && cmd <= 28) { - ee[1](name, time, cmd); - } else { - const bigValue = h8ToBn(wasm.HEAPU8, value, valueWords); - const bigMask = h8ToBn(wasm.HEAPU8, mask, maskWords); - ee[1](name, time, cmd, bigValue, bigMask); - } - }; - - // wasm.addFunction can't be called until after - // start finishes - bindCallback = () => { - boundSet = wasm.addFunction(function(name, len, type, v0, v1) { - - let prop = getString(name, len); - let tmp; - - switch(type) { - // set number - case 0: - boundInfo[prop] = v0; - // console.log(`setting ${prop} to ${boundInfo[prop]}`); - break; - // set string - case 1: - boundInfo[prop] = getString(v0, v1); - // console.log(`setting ${prop} to ${boundInfo[prop]}`); - break; - // set string to path - case 2: - break; - // path to path (any type) - case 3: - break; - // create empty object at path - case 4: - break; - case 5: - commandHandler(boundInfo, v0, prop); - break; - default: throw new Error(); - } - - - // viiiii means returns void, accepts int int int int int - }, 'viiiii'); - - boundGet = wasm.addFunction(function(name, len) { - let prop = getString(name, len); - return prop; - }, 'iii'); - - - boundEE0 = wasm.addFunction(function(name, len) { - ee[0](getString(name, len)); - }, 'vii'); - - boundEE1 = wasm.addFunction(onEE1, 'viijiiiii'); - - }; - - return { - start, - c, - init: (cb0, cb1, info) => { - boundInfo = info; - ee[0] = cb0; - ee[1] = cb1; - context = c.init(boundEE0, boundEE1, boundSet, boundGet); - return context; - }, - execute: (ctx, cb0, cb1, info, chunk) => { - boundInfo = info; - ee[0] = cb0; - ee[1] = cb1; - return c.execute(ctx, boundEE0, boundEE1, boundSet, boundGet, chunk, chunk.length); - }, - setTrigger: (ctx, triggerString) => { - return c.setTrigger(ctx, triggerString); - }, - getTime: (ctx) => { - return BigInt(c.getTime(ctx)); - } - }; + return { + start, + c, + init: (cb0, cb1, info) => { + boundInfo = info; + ee[0] = cb0; + ee[1] = cb1; + context = c.init(boundEE0, boundEE1, boundSet, boundGet); + return context; + }, + /** + * + * @param {*} ctx + * @param {*} cb0 + * @param {*} cb1 + * @param {*} info + * @param {*} chunk + * @returns + */ + execute: (ctx, cb0, cb1, info, chunk) => { + boundInfo = info; + ee[0] = cb0; + ee[1] = cb1; + return c.execute(ctx, boundEE0, boundEE1, boundSet, boundGet, chunk, chunk.length); + }, + setTrigger: (ctx, triggerString) => { + return c.setTrigger(ctx, triggerString); + }, + getTime: (ctx) => { + return BigInt(c.getTime(ctx)); + } + }; }; module.exports = async wasm => { - const lib = getWrapper(wasm); - // console.log('getWrapper', lib); - await lib.start(); - // console.log('vcd wasm srarted'); - const wires = {kind: 'scope', type: '.', name: '.', body: []}; - const info = {stack: [wires], wires}; + const lib = getWrapper(wasm); + await lib.start(); + const wires = { kind: 'scope', type: '.', name: '.', body: [] }; + const info = { stack: [wires], wires }; + const s = new stream.Writable(); - const s = new stream.Writable(); + // gets called by c with 1 argument, a string + const lifemit = s.emit.bind(s); + const triee = new EventEmitter(); - // gets called by c with 1 argument, a string - const lifemit = s.emit.bind(s); + const triemit = triee.emit.bind(triee); + let triemit2 = triemit; - const triee = new EventEmitter(); + const cxt = lib.init(lifemit, triemit, info); - // gets called by c with 5 arguments - // string eventName - // number state->time - // int command - // int state->value - // int state->mask + s._write = function (chunk, encoding, callback) { + const err = lib.execute(cxt, lifemit, triemit2, info, chunk); + if (err) { + console.log(err); + } + callback(); + }; - const triemit = triee.emit.bind(triee); - let triemit2 = triemit; + s.change = { + on: (id, fn) => { + triemit2 = triemit; + triee.on(id, fn); + const triggerString = triee.eventNames().join(' ') + ' '; + lib.setTrigger(cxt, triggerString); + }, + any: fn => { + triemit2 = fn; + lib.setTrigger(cxt, '\0'); + } + }; - const cxt = lib.init(lifemit, triemit, info); + s.info = info; + s.getTime = () => lib.getTime(cxt); + s.start = lib.start; - s._write = function (chunk, encoding, callback) { - // console.log('chunk:', chunk.length); - const err = lib.execute(cxt, lifemit, triemit2, info, chunk); - if (err) { - console.log(err); - } - // console.log(util.inspect(info, {showHidden: true, depth : null, colorize: true})); - // console.log(info.stack[0].top); - // console.log(info.stack[1]); - // console.log(info.stack[0].top == info.stack[1]); - callback(); - }; - - s.change = { - on: (id, fn) => { - triemit2 = triemit; - triee.on(id, fn); - const triggerString = triee.eventNames().join(' ') + ' '; - // console.log(id, Buffer.from(triggerString)); - lib.setTrigger(cxt, triggerString); - }, - any: fn => { - triemit2 = fn; - lib.setTrigger(cxt, '\0'); - } - }; - - s.info = info; - - s.getTime = () => lib.getTime(cxt); - - s.start = lib.start; - - return s; + return s; }; diff --git a/out/vcd.wasm b/out/vcd.wasm index fccb593400261432d74aee0a5eaebe610d2e2b9f..d38682aa964ea92a864257e25e84b8b909facab7 100755 GIT binary patch delta 33 rcmV++0N($i;0KxD2e2gv0iJ^<2e&2%0m{4q)R*zY0jjs8!~uRQ>M#y8 delta 43 tcmbRFfPK*e_6@4+jLVzV*te^(GoISRcz628!;Gsq|HHuc*+&@bv;o0E7d-#~ diff --git a/test/debug/basic.js b/test/debug/basic.js index 4ffbaeb..52f6b8a 100644 --- a/test/debug/basic.js +++ b/test/debug/basic.js @@ -13,6 +13,7 @@ async function main() { vcdstream.consume(arraybuffer); const info = vcdstream.getBasicInfo(); console.log(info.signalValues['*']); + console.log(info.signalValues['+']); } main(); \ No newline at end of file diff --git a/test/wasm_iverilog.js b/test/wasm_iverilog.js index e322633..c6b36a2 100644 --- a/test/wasm_iverilog.js +++ b/test/wasm_iverilog.js @@ -20,6 +20,7 @@ describe('wasm iverilog', () => { // task 2 expect(info.vcdInfo.date.trim()).to.eq('Thu Jul 22 22:29:56 2021'); expect(info.vcdInfo.version.trim()).to.eq('Icarus Verilog'); + expect(info.vcdInfo.timescale).to.eq(-9); // task 3 for (const key of Object.keys(answers)) { @@ -33,7 +34,7 @@ describe('wasm iverilog', () => { const vcdstream = await makeVcdStream(); const arraybuffer = fs.readFileSync('./test/samples/iverilog.large.vcd'); // const answers = JSON.parse(fs.readFileSync('./test/samples/iverilog.large.json')); - + vcdstream.clean(); vcdstream.consume(arraybuffer); const info = vcdstream.getBasicInfo(); const values = info.signalValues; @@ -43,12 +44,6 @@ describe('wasm iverilog', () => { expect(values['*']).to.not.be.undefined; expect(values['+']).to.not.be.undefined; - console.log(info.signalValues['*']); - - // task 2 - // expect(info.vcdInfo.date.trim()).to.eq('Sat Apr 20 20:06:14 2024'); - // expect(info.vcdInfo.version.trim()).to.eq('Icarus Verilog'); - // expect(info.vcdInfo.timescale.trim()).to.eq('1ns'); // // task 2 // for (const key of Object.keys(answers)) { @@ -56,5 +51,15 @@ describe('wasm iverilog', () => { // expect(values[key]).to.not.be.undefined; // expect(values[key]).to.deep.eq(ans); // } + + // console.log(info.signalValues['*']); + + // task 3 + expect(info.vcdInfo.date.trim()).to.eq('Sat Apr 20 20:06:14 2024'); + expect(info.vcdInfo.version.trim()).to.eq('Icarus Verilog'); + expect(info.vcdInfo.timescale).to.eq(-9); + + // task 4 + }); }); diff --git a/vcd.c b/vcd.c index e0aaabe..e8aac4b 100644 --- a/vcd.c +++ b/vcd.c @@ -1,227 +1,234 @@ #define NAPI_VERSION 6 -#include #include -#include -#include "vcd_parser.h" #include +#include +#include -#define DECLARE_NAPI_METHOD(name, func) { \ - napi_property_descriptor desc = { name, 0, func, 0, 0, 0, napi_default, 0 }; \ - if (napi_define_properties(env, exports, 1, &desc) != napi_ok) { \ - napi_throw_error(env, 0, "Error"); \ - } \ -} +#include "vcd_parser.h" + +#define DECLARE_NAPI_METHOD(name, func) \ + { \ + napi_property_descriptor desc = {name, 0, func, 0, \ + 0, 0, napi_default, 0}; \ + if (napi_define_properties(env, exports, 1, &desc) != napi_ok) { \ + napi_throw_error(env, 0, "Error"); \ + } \ + } #define METHOD(name) napi_value name(napi_env env, napi_callback_info cbInfo) -#define ASSERT(val, expr) \ - if (expr != napi_ok) { \ +#define ASSERT(val, expr) \ + if (expr != napi_ok) { \ napi_throw(env, val); \ } -#define ASSERT_ARGC(count) \ - napi_value args[count]; \ - { \ - size_t argc = count; \ +#define ASSERT_ARGC(count) \ + napi_value args[count]; \ + { \ + size_t argc = count; \ if (napi_get_cb_info(env, cbInfo, &argc, args, 0, 0) != napi_ok) { \ - napi_throw_error(env, 0, "Error"); \ - return 0; \ - } \ - if (argc < count) { \ - napi_throw_type_error(env, 0, "Wrong number of arguments"); \ - return 0; \ - } \ + napi_throw_error(env, 0, "Error"); \ + return 0; \ + } \ + if (argc < count) { \ + napi_throw_type_error(env, 0, "Wrong number of arguments"); \ + return 0; \ + } \ } -#define ASSERT_BUFFER(name, var, len) \ - const char * var; \ - size_t len; \ - { \ - bool result; \ - if(napi_is_buffer(env, name, &result) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ +#define ASSERT_BUFFER(name, var, len) \ + const char *var; \ + size_t len; \ + { \ + bool result; \ + if (napi_is_buffer(env, name, &result) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ if (napi_get_buffer_info(env, name, (void **)&var, &len) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ + napi_throw(env, name); \ + return 0; \ + } \ } -#define ASSERT_STRING(name, var) \ - { \ - napi_value tmp; \ - if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - size_t result; \ - if (napi_get_value_string_latin1(env, tmp, var, 4096, &result) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - } - -#define ASSERT_EXTERNAL(name, var) { \ - napi_valuetype valuetype; \ - if (napi_typeof(env, name, &valuetype) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - if (valuetype != napi_external) { \ - napi_throw_type_error(env, 0, "Wrong arguments"); \ - return 0; \ - } \ - if (napi_get_value_external(env, name, (void **)(&var)) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ -} - -#define ASSERT_FUNCTION(name, var) { \ - napi_valuetype valuetype; \ - if (napi_typeof(env, name, &valuetype) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - if (valuetype != napi_function) { \ - napi_throw_type_error(env, 0, "Wrong arguments"); \ - return 0; \ - } \ - var = name; \ -} - -#define ASSERT_OBJECT(name, var) { \ - napi_valuetype valuetype; \ - if (napi_typeof(env, name, &valuetype) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - if (valuetype != napi_object) { \ - napi_throw_type_error(env, 0, "Wrong arguments"); \ - return 0; \ - } \ - var = name; \ -} +#define ASSERT_STRING(name, var) \ + { \ + napi_value tmp; \ + if (napi_coerce_to_string(env, name, &tmp) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + size_t result; \ + if (napi_get_value_string_latin1(env, tmp, var, 4096, &result) != \ + napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + } +#define ASSERT_EXTERNAL(name, var) \ + { \ + napi_valuetype valuetype; \ + if (napi_typeof(env, name, &valuetype) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + if (valuetype != napi_external) { \ + napi_throw_type_error(env, 0, "Wrong arguments"); \ + return 0; \ + } \ + if (napi_get_value_external(env, name, (void **)(&var)) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + } +#define ASSERT_FUNCTION(name, var) \ + { \ + napi_valuetype valuetype; \ + if (napi_typeof(env, name, &valuetype) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + if (valuetype != napi_function) { \ + napi_throw_type_error(env, 0, "Wrong arguments"); \ + return 0; \ + } \ + var = name; \ + } +#define ASSERT_OBJECT(name, var) \ + { \ + napi_valuetype valuetype; \ + if (napi_typeof(env, name, &valuetype) != napi_ok) { \ + napi_throw(env, name); \ + return 0; \ + } \ + if (valuetype != napi_object) { \ + napi_throw_type_error(env, 0, "Wrong arguments"); \ + return 0; \ + } \ + var = name; \ + } METHOD(init) { - napi_value res; + napi_value res; - struct vcd_parser_s *state = malloc(sizeof *state); + struct vcd_parser_s *state = malloc(sizeof *state); - const int32_t error = vcd_parser_init(state); - if (error) { - ASSERT(res, napi_create_int32(env, error, &res)) + const int32_t error = vcd_parser_init(state); + if (error) { + ASSERT(res, napi_create_int32(env, error, &res)) + return res; + } + + ASSERT_ARGC(3) + ASSERT_FUNCTION(args[0], state->lifee) + ASSERT_FUNCTION(args[1], state->triee) + ASSERT_OBJECT(args[2], state->info) + + static char triggerString[4096] = {0}; + static char tmpStr[4096] = {0}; + static char tmpStr2[4096] = {0}; + static char timeStampStr[4096] = {0}; + static char idStr[4096] = {0}; + static uint64_t valueBuf[4096] = {}; + static uint64_t maskBuf[4096] = {}; + + state->trigger = triggerString; + state->reason = "NO REASON"; + state->napi_env = env; + state->tmpStr = tmpStr; + state->tmpStr2 = tmpStr2; + state->timeStampStr = timeStampStr; + state->idStr = idStr; + state->value = valueBuf; + state->mask = maskBuf; + state->time = 0; + state->digitCount = 0; + state->maskCount = 0; + + napi_value status; + ASSERT(status, napi_create_string_latin1(env, "declaration", + NAPI_AUTO_LENGTH, &status)) + ASSERT(state->info, + napi_set_named_property(env, state->info, "status", status)) + // ASSERT(status, napi_get_named_property(env, state->info, "wires", + // &state->wires)) + + // napi_value hierObj; + // ASSERT(hierObj, napi_create_object(env, &hierObj)) + // state->info = hierObj; + + // ASSERT(state->info, napi_create_object(env, &state->info)) + + ASSERT(res, napi_create_external(env, state, 0, 0, &res)) return res; - } - - ASSERT_ARGC(3) - ASSERT_FUNCTION(args[0], state->lifee) - ASSERT_FUNCTION(args[1], state->triee) - ASSERT_OBJECT(args[2], state->info) - - static char triggerString [4096] = {0}; - static char tmpStr [4096] = {0}; - static char tmpStr2 [4096] = {0}; - static char timeStampStr [4096] = {0}; - static char idStr [4096] = {0}; - static uint64_t valueBuf [4096] = {}; - static uint64_t maskBuf [4096] = {}; - - state->trigger = triggerString; - state->reason = "NO REASON"; - state->napi_env = env; - state->tmpStr = tmpStr; - state->tmpStr2 = tmpStr2; - state->timeStampStr = timeStampStr; - state->idStr = idStr; - state->value = valueBuf; - state->mask = maskBuf; - state->time = INT64_MAX; - state->digitCount = 0; - state->maskCount = 0; - - napi_value status; - ASSERT(status, napi_create_string_latin1(env, "declaration", NAPI_AUTO_LENGTH, &status)) - ASSERT(state->info, napi_set_named_property(env, state->info, "status", status)) - // ASSERT(status, napi_get_named_property(env, state->info, "wires", &state->wires)) - - // napi_value hierObj; - // ASSERT(hierObj, napi_create_object(env, &hierObj)) - // state->info = hierObj; - - // ASSERT(state->info, napi_create_object(env, &state->info)) - - ASSERT(res, napi_create_external(env, state, 0, 0, &res)) - return res; } METHOD(done) { - ASSERT_ARGC(4) - struct vcd_parser_s *state; - // last use of all external objects - napi_value lifee, triee, info; - ASSERT_EXTERNAL(args[0], state) - ASSERT_FUNCTION(args[1], lifee) - ASSERT_FUNCTION(args[2], triee) - ASSERT_OBJECT(args[3], info) + ASSERT_ARGC(4) + struct vcd_parser_s *state; + // last use of all external objects + napi_value lifee, triee, info; + ASSERT_EXTERNAL(args[0], state) + ASSERT_FUNCTION(args[1], lifee) + ASSERT_FUNCTION(args[2], triee) + ASSERT_OBJECT(args[3], info) - // FIXME destroy parser state + // FIXME destroy parser state - const int32_t error = 0; - napi_value res; - ASSERT(res, napi_create_int32(env, error, &res)) - return res; + const int32_t error = 0; + napi_value res; + ASSERT(res, napi_create_int32(env, error, &res)) + return res; } METHOD(execute) { - ASSERT_ARGC(5) - struct vcd_parser_s *state; - ASSERT_EXTERNAL(args[0], state) - ASSERT_FUNCTION(args[1], state->lifee) - ASSERT_FUNCTION(args[2], state->triee) - ASSERT_OBJECT(args[3], state->info) - ASSERT_BUFFER(args[4], p, plen) + ASSERT_ARGC(5) + struct vcd_parser_s *state; + ASSERT_EXTERNAL(args[0], state) + ASSERT_FUNCTION(args[1], state->lifee) + ASSERT_FUNCTION(args[2], state->triee) + ASSERT_OBJECT(args[3], state->info) + ASSERT_BUFFER(args[4], p, plen) - state->napi_env = env; + state->napi_env = env; - const int32_t error = vcd_parser_execute(state, p, p + plen); - napi_value res; - ASSERT(res, napi_create_int32(env, error, &res)) - return res; + const int32_t error = vcd_parser_execute(state, p, p + plen); + napi_value res; + ASSERT(res, napi_create_int32(env, error, &res)) + return res; } METHOD(setTrigger) { - ASSERT_ARGC(2) - struct vcd_parser_s *state; - ASSERT_EXTERNAL(args[0], state) - ASSERT_STRING(args[1], state->trigger) + ASSERT_ARGC(2) + struct vcd_parser_s *state; + ASSERT_EXTERNAL(args[0], state) + ASSERT_STRING(args[1], state->trigger) - napi_value res; - ASSERT(res, napi_create_int32(env, state->error, &res)) - return res; + napi_value res; + ASSERT(res, napi_create_int32(env, state->error, &res)) + return res; } METHOD(getTime) { - ASSERT_ARGC(1) - struct vcd_parser_s *state; - ASSERT_EXTERNAL(args[0], state) + ASSERT_ARGC(1) + struct vcd_parser_s *state; + ASSERT_EXTERNAL(args[0], state) - napi_value res; - ASSERT(res, napi_create_bigint_int64(env, state->time, &res)) - return res; + napi_value res; + ASSERT(res, napi_create_bigint_int64(env, state->time, &res)) + return res; } napi_value Init(napi_env env, napi_value exports) { - DECLARE_NAPI_METHOD("init", init) - DECLARE_NAPI_METHOD("done", done) - DECLARE_NAPI_METHOD("execute", execute) - DECLARE_NAPI_METHOD("setTrigger", setTrigger) - DECLARE_NAPI_METHOD("getTime", getTime) - return exports; + DECLARE_NAPI_METHOD("init", init) + DECLARE_NAPI_METHOD("done", done) + DECLARE_NAPI_METHOD("execute", execute) + DECLARE_NAPI_METHOD("setTrigger", setTrigger) + DECLARE_NAPI_METHOD("getTime", getTime) + return exports; } NAPI_MODULE(NODE_GYP_MODULE_NAME, Init) diff --git a/wasm_main.cpp b/wasm_main.cpp index 72538fd..b859144 100644 --- a/wasm_main.cpp +++ b/wasm_main.cpp @@ -1,37 +1,33 @@ +#include #include #include #include -#include + #include + #include "vcd_parser.h" using namespace std; - /// Typedef used as part of c->js call typedef void externalJsMethodZero(const char* name, const size_t len); -// typedef void externalJsMethodOne (const char* name, const size_t len, const uint64_t time, const uint8_t command, const int valueWords, const int aValue, const int aMask); - -typedef void externalJsMethodOne ( - const char* name, - const size_t len, - const int64_t time, - const int command, - const int valueWords, - const int aValue, - const int maskWords, - const int aMask -); - -typedef int externalJsGetProperty(const char* name, const size_t len); -typedef void externalJsSetProperty(const char* name, const size_t len, const int type, const int v0, const int v1); +// typedef void externalJsMethodOne (const char* name, const size_t len, const +// uint64_t time, const uint8_t command, const int valueWords, const int aValue, +// const int aMask); +typedef void externalJsMethodOne(const char* name, const size_t len, + const int64_t time, const int command, + const int valueWords, const int aValue, + const int maskWords, const int aMask); +typedef int externalJsGetProperty(const char* name, const size_t len); +typedef void externalJsSetProperty(const char* name, const size_t len, + const int type, const int v0, const int v1); /// function pointer for c->js static externalJsMethodZero* externalZero = 0; -static externalJsMethodOne* externalOne = 0; +static externalJsMethodOne* externalOne = 0; static externalJsSetProperty* bound_set_property = 0; static externalJsGetProperty* bound_get_property = 0; static struct vcd_parser_s* state; @@ -39,177 +35,136 @@ static struct vcd_parser_s* state; extern "C" { void set_property_int(const char* name, const int value) { - bound_set_property(name, strlen(name), 0, value, 0); + bound_set_property(name, strlen(name), 0, value, 0); } void set_property_string(const char* name, const char* value) { - bound_set_property(name, strlen(name), 1, (int)value, strlen(value)); + bound_set_property(name, strlen(name), 1, (int)value, strlen(value)); } void set_path_string(const char* name, const char* value) { - bound_set_property(name, strlen(name), 2, (int)value, strlen(value)); + bound_set_property(name, strlen(name), 2, (int)value, strlen(value)); } void set_path_to_path(const char* name, const char* value) { - bound_set_property(name, strlen(name), 3, (int)value, strlen(value)); + bound_set_property(name, strlen(name), 3, (int)value, strlen(value)); } void new_object_path(const char* name) { - bound_set_property(name, strlen(name), 4, 0, 0); + bound_set_property(name, strlen(name), 4, 0, 0); } void on_command(const char* body, const int command) { - bound_set_property(body, strlen(body), 5, command, 0); + bound_set_property(body, strlen(body), 5, command, 0); } int get_property_int(const char* name) { - return bound_get_property(name, strlen(name)); + return bound_get_property(name, strlen(name)); } -void emit_lifee(const char* name) { - externalZero(name, strlen(name)); +void emit_lifee(const char* name) { externalZero(name, strlen(name)); } + +void emit_triee(const char* name, const int64_t time, const int command, + const int valueWords, uint64_t* aValue, const int maskWords, + uint64_t* aMask) { + // return; + // externalOne( + // "hi" + // ,2 + // ,time + // ,command + // ,0 + // ,0 + // ,0 + // ); + externalOne(name, strlen(name), time, command, valueWords, (int)aValue, + maskWords, (int)aMask); } -void emit_triee( - const char* name, - const int64_t time, - const int command, - const int valueWords, - uint64_t* aValue, - const int maskWords, - uint64_t* aMask -) { - - // return; - // externalOne( - // "hi" - // ,2 - // ,time - // ,command - // ,0 - // ,0 - // ,0 - // ); - externalOne( - name, - strlen(name), - time, - command, - valueWords, - (int)aValue, - maskWords, - (int)aMask - ); -} - - - - // returns context -int init( - externalJsMethodZero* f0, - externalJsMethodOne* f1, - externalJsSetProperty* sfn, - externalJsGetProperty* gfn - ) { +int init(externalJsMethodZero* f0, externalJsMethodOne* f1, + externalJsSetProperty* sfn, externalJsGetProperty* gfn) { + state = (struct vcd_parser_s*)malloc(sizeof *state); + const int32_t error = vcd_parser_init(state); + if (error) { + cout << "ERROR: " << error << "\n"; + return -1; + } - state = (struct vcd_parser_s*) malloc(sizeof *state); + bound_set_property = sfn; + bound_get_property = gfn; + externalZero = f0; + externalOne = f1; - const int32_t error = vcd_parser_init(state); - if (error) { - cout << "ERROR: " << error << "\n"; - return -1; - } + state->lifee = 0; + state->triee = 0; - bound_set_property = sfn; - bound_get_property = gfn; - externalZero = f0; - externalOne = f1; + static char triggerString[4096] = {0}; + static char tmpStr[4096] = {0}; + static char tmpStr2[4096] = {0}; + static char timeStampStr[4096] = {0}; + static char idStr[4096] = {0}; + static uint64_t valueBuf[4096] = {}; + static uint64_t maskBuf[4096] = {}; - state->lifee = 0; - state->triee = 0; + state->trigger = triggerString; + state->reason = "NO REASON"; + state->napi_env = 0; + state->tmpStr = tmpStr; + state->tmpStr2 = tmpStr2; + state->timeStampStr = timeStampStr; + state->idStr = idStr; + state->value = valueBuf; + state->mask = maskBuf; + // TODO: ensure here + state->time = 0; + state->digitCount = 0; + state->maskCount = 0; - static char triggerString [4096] = {0}; - static char tmpStr [4096] = {0}; - static char tmpStr2 [4096] = {0}; - static char timeStampStr [4096] = {0}; - static char idStr [4096] = {0}; - static uint64_t valueBuf [4096] = {}; - static uint64_t maskBuf [4096] = {}; + set_property_string("status", "declaration"); - state->trigger = triggerString; - state->reason = "NO REASON"; - state->napi_env = 0; - state->tmpStr = tmpStr; - state->tmpStr2 = tmpStr2; - state->timeStampStr = timeStampStr; - state->idStr = idStr; - state->value = valueBuf; - state->mask = maskBuf; - state->time = INT64_MAX; - state->digitCount = 0; - state->maskCount = 0; + static int context = 0; + context++; - set_property_string("status", "declaration"); - - - static int context = 0; - context++; - - return context; + return context; } +int32_t execute(const int context, externalJsMethodZero* f0, + externalJsMethodOne* f1, externalJsSetProperty* sfn, + externalJsGetProperty* gfn, char* p, const int plen) { + // cout << "execute got " << p << "\n"; + // cout << "execute " << (int)sfn << " and got " << p << "\n"; + bound_set_property = sfn; + bound_get_property = gfn; + externalZero = f0; + externalOne = f1; + // const size_t plen = strlen(p); + // printf("\n", plen); + const int32_t error = vcd_parser_execute(state, p, p + plen); -int32_t execute( - const int context, - externalJsMethodZero* f0, - externalJsMethodOne* f1, - externalJsSetProperty* sfn, - externalJsGetProperty* gfn, - char* p, - const int plen - ) { - - // cout << "execute got " << p << "\n"; - // cout << "execute " << (int)sfn << " and got " << p << "\n"; - bound_set_property = sfn; - bound_get_property = gfn; - externalZero = f0; - externalOne = f1; - - // const size_t plen = strlen(p); - // printf("\n", plen); - - - const int32_t error = vcd_parser_execute(state, p, p + plen); - - return error; + return error; } int setTrigger(const int context, char* triggerString) { - int triggerStringLen = strlen((char *)triggerString) - 1; - // state->trigger = malloc(strlen(triggerString)); - char* p = (char *)state->tmpStr; - for (int i = 0; i < triggerStringLen; i++) { - char c = *(triggerString + i); - if (c == 32) { - c = 0; + int triggerStringLen = strlen((char*)triggerString) - 1; + // state->trigger = malloc(strlen(triggerString)); + char* p = (char*)state->tmpStr; + for (int i = 0; i < triggerStringLen; i++) { + char c = *(triggerString + i); + if (c == 32) { + c = 0; + } + *(p + i) = c; } - *(p + i) = c; - } - // strcpy((char*)state->trigger, triggerString); - // cout << "[" << triggerString << "|" << p << "\n"; - return 0; + // strcpy((char*)state->trigger, triggerString); + // cout << "[" << triggerString << "|" << p << "\n"; + return 0; } -int64_t getTime(const int context) { - return state->time; -} - - +int64_t getTime(const int context) { return state->time; } // void execute( // const int context, @@ -229,7 +184,6 @@ int64_t getTime(const int context) { // set_property_int("foo", 10); - // int got = get_property_int("bar"); // cout << "got " << got << " for bar\n"; @@ -237,9 +191,8 @@ int64_t getTime(const int context) { // } int main(void) { - // cout << "main()\n"; - return 0; + // cout << "main()\n"; + return 0; } - -} // extern C +} // extern C diff --git a/wasm_main.hpp b/wasm_main.hpp index 0a1daa1..071734f 100644 --- a/wasm_main.hpp +++ b/wasm_main.hpp @@ -9,12 +9,6 @@ void new_object_path(const char* name); void on_command(const char* body, const int command); int get_property_int(const char* name); void emit_lifee(const char* name); -void emit_triee( - const char* name, - const int64_t time, - const int command, - const int valueWords, - uint64_t* aValue, - const int maskWords, - uint64_t* aMask -); +void emit_triee(const char* name, const int64_t time, const int command, + const int valueWords, uint64_t* aValue, const int maskWords, + uint64_t* aMask);