write code in stream mode
Jordi Baylina jordi@baylina.cat
Mon, 27 Jan 2020 13:08:11 +0700
9 files changed,
108 insertions(+),
45 deletions(-)
M
c/buildasm/buildzqfieldtester.js
→
c/buildasm/buildzqfieldtester.js
@@ -35,7 +35,7 @@ ` ${path.join(dir.path, "tester.cpp")}` +
` ${path.join(dir.path, "fr.o")}` + ` ${path.join(dir.path, "fr.c")}` + ` -o ${path.join(dir.path, "tester")}` + - " -lgmp" + " -lgmp -g" ); const inLines = [];
M
c/buildasm/fr.c.ejs
→
c/buildasm/fr.c.ejs
@@ -63,7 +63,6 @@ return r;
} else { mpz_init_set_si(r, pE->shortVal); mpz_add(r, r, q); - mpz_clear(q); } } else { <%=name%>_toNormal(pE);
M
c/buildasm/fr.h
→
c/buildasm/fr.h
@@ -8,8 +8,8 @@ #define Fr_LONG 0x80000000
#define Fr_LONGMONTGOMERY 0xC0000000 typedef struct __attribute__((__packed__)) { int32_t shortVal; - u_int32_t type; - u_int64_t longVal[Fr_N64]; + uint32_t type; + uint64_t longVal[Fr_N64]; } FrElement; typedef FrElement *PFrElement; extern FrElement Fr_q;
M
c/buildasm/fr.h.ejs
→
c/buildasm/fr.h.ejs
@@ -8,8 +8,8 @@ #define <%=name%>_LONG 0x80000000
#define <%=name%>_LONGMONTGOMERY 0xC0000000 typedef struct __attribute__((__packed__)) { int32_t shortVal; - u_int32_t type; - u_int64_t longVal[<%=name%>_N64]; + uint32_t type; + uint64_t longVal[<%=name%>_N64]; } <%=name%>Element; typedef <%=name%>Element *P<%=name%>Element; extern <%=name%>Element <%=name%>_q;
M
c/calcwit.cpp
→
c/calcwit.cpp
@@ -5,6 +5,7 @@ #include <iostream>
#include <iomanip> #include <stdlib.h> #include <assert.h> +#include <stdarg.h> #include <thread> #include "calcwit.h" #include "utils.h"
M
src/c_build.js
→
src/c_build.js
@@ -22,6 +22,7 @@ const bigInt = require("big-integer");
const utils = require("./utils"); const gen = require("./c_gen").gen; const createRefs = require("./c_gen").createRefs; +const streamFromMultiArray = require("./stream_from_multiarray"); module.exports = buildC;@@ -55,17 +56,18 @@ const mapIsInput = buildMapIsInput(ctx);
const wit2Sig = buildWit2Sig(ctx); const circuitVar = buildCircuitVar(ctx); - return "" + - headder + "\n" + - sizes + "\n" + - constants + "\n" + - entryTables + "\n" + - functions + "\n" + - code + "\n" + - compnentsArray + "\n" + - mapIsInput + "\n" + - wit2Sig +"\n" + - circuitVar; + return streamFromMultiArray([ + headder , "\n" , + sizes , "\n" , + constants , "\n" , + entryTables , "\n" , + functions , "\n" , + code , "\n" , + compnentsArray , "\n" , + mapIsInput , "\n" , + wit2Sig , "\n" , + circuitVar + ]); } function buildEntryTables(ctx) {@@ -96,13 +98,14 @@ ctx.components[i].etName = componentEntriesTableName;
} - return "" + - "// HashMaps\n" + - codes_hashMaps.join("\n") + "\n" + - "\n" + - "// Component Entries\n" + - codes_componentEntries.join("\n") + "\n" + - "\n"; + return [ + "// HashMaps\n" , + codes_hashMaps , "\n" , + "\n" , + "// Component Entries\n" , + codes_componentEntries , "\n" , + "\n" + ]; function addHashTable(cIdx) { const keys = Object.keys(ctx.components[cIdx].names.o);@@ -198,12 +201,18 @@ }
ctx.components[i].fnName = fName; } - return fnComponents.join("\n"); + return fnComponents; } function buildFuncFunctions(ctx) { - return "// Functions\n" + - ctx.functionCodes.join("\n"); + if (ctx.functionCodes) { + return ["// Functions\n" , + ctx.functionCodes + ]; + } else { + return ""; + } + } function buildComponentsArray(ctx) {@@ -225,12 +234,11 @@ ccodes.push(i>0 ? " ," : " ");
ccodes.push(`{${ctx.components[i].htName},${ctx.components[i].etName},${ctx.components[i].fnName}, ${ctx.components[i].nInSignals}, ${newThread}}\n`); } ccodes.push("};\n"); - const codeComponents = ccodes.join(""); - return "" + - "// Components\n" + - codeComponents + - "\n"; + return [ + "// Components\n" , + ccodes , "\n" + ]; }@@ -247,8 +255,10 @@ "\n";
} function buildSizes(ctx) { - return "// Sizes\n" + - ctx.codes_sizes.join("\n"); + return [ + "// Sizes\n" , + ctx.codes_sizes + ]; } function buildConstants(ctx) {@@ -256,14 +266,14 @@ const n64 = Math.floor((ctx.field.p.bitLength() - 1) / 64)+1;
const R = bigInt.one.shiftLeft(n64*64); const lines = []; - lines.push("// Constants"); - lines.push(`FrElement _constants[${ctx.constants.length}] = {`); + lines.push("// Constants\n"); + lines.push(`FrElement _constants[${ctx.constants.length}] = {\n`); for (let i=0; i<ctx.constants.length; i++) { - lines.push((i>0 ? "," : " ") + "{" + number2Code(ctx.constants[i]) + "}"); + lines.push((i>0 ? "," : " ") + "{" + number2Code(ctx.constants[i]) + "}\n"); } - lines.push("};"); + lines.push("};\n"); - return lines.join("\n"); + return lines; function number2Code(n) { if (n.lt(bigInt("80000000", 16)) ) {@@ -343,10 +353,11 @@ if (line != "") {
arr.push(line); } - return "// mapIsArray\n" + - `u32 _mapIsInput[${Math.floor((ctx.signals.length-1) / 32)+1}] = {\n`+ - arr.join("\n") + "\n" + - "};\n"; + return ["// mapIsArray\n" , + `u32 _mapIsInput[${Math.floor((ctx.signals.length-1) / 32)+1}] = {\n`, + arr, "\n" , + "};\n" + ]; function toHex(number) { if (number < 0) number = 0xFFFFFFFF + number + 1;@@ -393,7 +404,7 @@ }
if (code != "") codes.push(code + "\n"); codes.push("};\n"); - return codes.join(""); + return codes; }
M
src/compiler.js
→
src/compiler.js
@@ -83,7 +83,8 @@
if (options.cSourceWriteStream) { const cSrc = buildC(ctx); - options.cSourceWriteStream.write(cSrc); + cSrc.pipe(options.cSourceWriteStream); + await new Promise(fulfill => options.cSourceWriteStream.on("finish", fulfill)); } // const mainCode = gen(ctx,ast);
A
src/stream_from_multiarray.js
@@ -0,0 +1,50 @@
+ +const Readable = require("stream").Readable; + +module.exports = function streamFromMultiarray(ma) { + const rs = Readable(); + + let curIndex = getFirstIdx(ma); + + rs._read = function() { + let res; + do { + res = objFromIdx(ma, curIndex); + curIndex = nextIdx(curIndex); + } while (res===""); + rs.push(res); + }; + + + return rs; + + + function getFirstIdx(ma) { + if (!Array.isArray(ma)) return []; + return [0, ...getFirstIdx(ma[0])]; + } + + function nextIdx(idx) { + if (idx == null) return null; + if (idx.length == 0) return null; + + const parentIdx = idx.slice(0,-1); + + const itObj = objFromIdx(ma, parentIdx); + const newLastIdx = idx[idx.length-1]+1; + if (newLastIdx < itObj.length) { + const resIdx = idx.slice(); + resIdx[resIdx.length-1] = newLastIdx; + return [...resIdx, ...getFirstIdx(itObj[newLastIdx])]; + } else { + return nextIdx(parentIdx); + } + } + + function objFromIdx(ma, idx) { + if (idx == null) return null; + if (idx.length == 0) return ma; + if (ma.length == 0) return ""; + return objFromIdx(ma[idx[0]], idx.slice(1)); + } +};
M
test/fieldasm.js
→
test/fieldasm.js
@@ -17,6 +17,7 @@ it("bn128r add", async () => {
const tv = buildTestVector2(bn128r, "add"); await tester(bn128r, tv); }); + it("secp256k1q add", async () => { const tv = buildTestVector2(secp256k1q, "add"); await tester(secp256k1q, tv);