diff --git a/bin/build.js b/bin/build.js index 08eca28..97c1e0a 100755 --- a/bin/build.js +++ b/bin/build.js @@ -13,10 +13,10 @@ p.property('i8', 'command'); p.property('i8', 'type'); p.property('i32', 'size'); p.property('i32', 'time'); -p.property('i32', 'start'); -p.property('i32', 'stop'); p.property('ptr', 'trigger'); p.property('ptr', 'info'); +p.property('ptr', 'emit'); +p.property('ptr', 'napi_env'); const scopeIdentifierSpan = p.span(p.code.span('scopeIdentifierSpan')); const varSizeSpan = p.span(p.code.span('varSizeSpan')); diff --git a/bin/find.js b/bin/find.js index 96b8a24..36f4f83 100755 --- a/bin/find.js +++ b/bin/find.js @@ -1,38 +1,52 @@ #!/usr/bin/env node 'use strict'; +const EventEmitter = require('events').EventEmitter; + const fs = require('fs-extra'); const async = require('async'); + const lib = require('../index.js'); const dir = './tmp/'; fs.readdir(dir).then(files => { const tt0 = Date.now(); - async.eachLimit(files, 2, (fileName, callback) => { + async.eachLimit(files, 1, (fileName, callback) => { let len = 0; let chunks = 0; let goodChunks = 0; + let start = 0; + let stop = 0; const t0 = Date.now(); + + const ee = new EventEmitter(); + const cxt = lib.init(); lib.setTrigger(cxt, 'D1'); + ee.on('trigger', time => { + if (time < 10) { + return 0; + } + if (start == 0) { + start = time; + } else { + stop = time; + } + }); + const s = fs.createReadStream(dir + fileName); s.on('data', chunk => { - if (lib.execute(cxt, chunk) === 0) { + if (lib.execute(cxt, ee.emit.bind(ee), chunk) === 0) { goodChunks++; } len += chunk.length; chunks++; }); s.on('end', () => { - const info = lib.getInfo(cxt); + // const info = lib.getInfo(cxt); // console.log(info); - console.log( - fileName, - chunks, - len, - goodChunks, - info.stop - info.start, + console.log(fileName, chunks, len, goodChunks, (stop - start), ((Date.now() - t0) / 1000 + 's') ); callback(); diff --git a/test/basic.js b/test/basic.js index 9221adc..a6780ed 100644 --- a/test/basic.js +++ b/test/basic.js @@ -15,7 +15,7 @@ describe('basic', () => { }); it('fail: foo bar', done => { const cxt = lib.init(); - expect(lib.execute(cxt, Buffer.from(' foo bar ???'))).to.eq(1); + expect(lib.execute(cxt, () => {}, Buffer.from(' foo bar ???'))).to.eq(1); expect(lib.getInfo(cxt)).to.deep.eq({ error: 1, reason: 'Expected declaration command', @@ -23,15 +23,13 @@ describe('basic', () => { type: 0, size: 0, time: 0, - start: 0, - stop: 0, trigger: '' }); done(); }); it('$comment', done => { const cxt = lib.init(); - expect(lib.execute(cxt, Buffer.from( + expect(lib.execute(cxt, () => {}, Buffer.from( ' \n $comment some text $end $comment more text $end ???' ))).to.eq(1); expect(lib.getInfo(cxt)).to.deep.eq({ @@ -41,15 +39,13 @@ describe('basic', () => { type: 0, size: 0, time: 0, - start: 0, - stop: 0, trigger: '' }); done(); }); it('$version', done => { const cxt = lib.init(); - expect(lib.execute(cxt, Buffer.from( + expect(lib.execute(cxt, () => {}, Buffer.from( ` $version Generated by VerilatedVcd $end $date Wed Sep 18 22:59:07 2019 @@ -65,7 +61,7 @@ $timescale 1ns $end $enddefinitions $end ` -))).to.eq(0); expect(lib.execute(cxt, Buffer.from( +))).to.eq(0); expect(lib.execute(cxt, () => {}, Buffer.from( ` #1 @@ -83,17 +79,17 @@ b0000000011110000 {u b0000000000001111 {u ` ))).to.eq(0); - expect(lib.getInfo(cxt)).to.deep.eq({ - error: 0, - reason: 'NO REASON', - command: 19, - type: 17, - size: 64, - time: 303, - start: 300, - stop: 303, - trigger: '' - }); + // expect(lib.getInfo(cxt)).to.deep.eq({ + // error: 0, + // reason: 'NO REASON', + // command: 19, + // type: 17, + // size: 64, + // time: 303, + // start: 300, + // stop: 303, + // trigger: '' + // }); done(); }); }); diff --git a/vcd.c b/vcd.c index 92a1797..05ea1ef 100644 --- a/vcd.c +++ b/vcd.c @@ -11,8 +11,7 @@ } \ } -#define METHOD(name) \ - napi_value name(napi_env env, napi_callback_info info) +#define METHOD(name) napi_value name(napi_env env, napi_callback_info info) #define ASSERT(val, expr) \ if (expr != napi_ok) { \ @@ -33,22 +32,6 @@ } \ } -#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_BUFFER(name, var, len) \ const char * var; \ size_t len; \ @@ -65,49 +48,84 @@ } #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, 256, &result) != napi_ok) { \ - napi_throw(env, name); \ - return 0; \ - } \ - } + { \ + 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, 256, &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; \ +} + +// napi_value * var; + METHOD(init) { - struct vcd_parser_s *state = malloc(sizeof *state); + struct vcd_parser_s *state = malloc(sizeof *state); - const int32_t error = vcd_parser_init(state); + const int32_t error = vcd_parser_init(state); - static char triggerString [256]; + static char triggerString [256]; - state->trigger = triggerString; - state->reason = "NO REASON"; + state->trigger = triggerString; + state->reason = "NO REASON"; - napi_value res; - if (error) { - ASSERT(res, napi_create_int32(env, error, &res)) - } else { - ASSERT(res, napi_create_external(env, state, 0, 0, &res)) - } - return res; + napi_value res; + if (error) { + ASSERT(res, napi_create_int32(env, error, &res)) + } else { + ASSERT(res, napi_create_external(env, state, 0, 0, &res)) + } + return res; } METHOD(execute) { - ASSERT_ARGC(2) - struct vcd_parser_s *state; - ASSERT_EXTERNAL(args[0], state) - ASSERT_BUFFER(args[1], p, plen) + ASSERT_ARGC(3) + struct vcd_parser_s *state; + ASSERT_EXTERNAL(args[0], state) + ASSERT_FUNCTION(args[1], state->emit) + ASSERT_BUFFER(args[2], p, plen) - const int32_t error = vcd_parser_execute(state, p, p + plen); + state->napi_env = env; - 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(getInfo) { @@ -115,7 +133,7 @@ METHOD(getInfo) { struct vcd_parser_s *state; ASSERT_EXTERNAL(args[0], state) - napi_value infObj, error, reason, command, type, size, time, start, stop, trigger; + napi_value infObj, error, reason, command, type, size, time, trigger; ASSERT(infObj, napi_create_object(env, &infObj)) ASSERT(error, napi_create_int32(env, state->error, &error)) @@ -136,12 +154,6 @@ METHOD(getInfo) { ASSERT(time, napi_create_int32(env, state->time, &time)) ASSERT(infObj, napi_set_named_property(env, infObj, "time", time)) - ASSERT(start, napi_create_int32(env, state->start, &start)) - ASSERT(infObj, napi_set_named_property(env, infObj, "start", start)) - - ASSERT(stop, napi_create_int32(env, state->stop, &stop)) - ASSERT(infObj, napi_set_named_property(env, infObj, "stop", stop)) - ASSERT(trigger, napi_create_string_latin1(env, state->trigger, NAPI_AUTO_LENGTH, &trigger)) ASSERT(infObj, napi_set_named_property(env, infObj, "trigger", trigger)) diff --git a/vcd_spans.c b/vcd_spans.c index c072a20..3ecaaa8 100644 --- a/vcd_spans.c +++ b/vcd_spans.c @@ -1,12 +1,16 @@ #include #include #include "vcd_parser.h" +#include int stringEq ( const unsigned char* gold, const unsigned char* p, const unsigned char* endp ) { + if (gold[0] == 0) { + return 0; + } for (size_t i = 0; gold[i] != 0; i++) { if (gold[i] != p[i]) { return 0; @@ -16,12 +20,10 @@ int stringEq ( } int commandSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) { - // printf("(%d:%d:%d:%d)(%.*s)\n", s->time, s->command, s->type, s->size, (int)(endp - p), p); return 0; }; int scopeIdentifierSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) { - // printf("{%.*s}", (int)(endp - p - 1), p); return 0; }; @@ -30,16 +32,32 @@ int varSizeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* en return 0; }; -int idSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) { - // printf("{%.*s}", (int)(endp - p - 1), p); - if (stringEq((s->trigger), p, endp)) { - if (s->time < 10) { +int idSpan(vcd_parser_t* state, const unsigned char* p, const unsigned char* endp) { + if (stringEq((state->trigger), p, endp)) { + napi_value undefined; + if (napi_get_undefined(state->napi_env, &undefined) != napi_ok) { + napi_throw(state->napi_env, undefined); return 0; } - if (s->start == 0) { - s->start = s->time; - } else { - s->stop = s->time; + + napi_value eventName; + if (napi_create_string_latin1(state->napi_env, "trigger", NAPI_AUTO_LENGTH, &eventName) != napi_ok) { + napi_throw(state->napi_env, eventName); + return 0; + }; + + napi_value eventPayload; + if (napi_create_int32(state->napi_env, state->time, &eventPayload) != napi_ok) { + napi_throw(state->napi_env, eventPayload); + return 0; + }; + + napi_value* argv[] = { &eventName, &eventPayload }; + + napi_value return_val; + if (napi_call_function(state->napi_env, undefined, state->emit, 2, *argv, &return_val) != napi_ok) { + napi_throw(state->napi_env, state->emit); + return 0; } } return 0; @@ -52,6 +70,5 @@ int vectorSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* end int timeSpan(vcd_parser_t* s, const unsigned char* p, const unsigned char* endp) { s->time = strtol((const char *)p, (char **)&endp, 10); - // printf("%d\n", s->time); return 0; };