From 3a9766a008de824bbbfc97fd7974e9488c2dfa5b Mon Sep 17 00:00:00 2001 From: Jordi Baylina Date: Mon, 27 Jan 2020 13:08:11 +0700 Subject: [PATCH] write code in stream mode --- c/buildasm/buildzqfieldtester.js | 2 +- c/buildasm/fr.c.ejs | 1 - c/buildasm/fr.h | 4 +- c/buildasm/fr.h.ejs | 4 +- c/calcwit.cpp | 1 + src/c_build.js | 87 ++++++++++++++++++-------------- src/compiler.js | 3 +- src/stream_from_multiarray.js | 50 ++++++++++++++++++ test/fieldasm.js | 1 + 9 files changed, 108 insertions(+), 45 deletions(-) create mode 100644 src/stream_from_multiarray.js diff --git a/c/buildasm/buildzqfieldtester.js b/c/buildasm/buildzqfieldtester.js index 8fdb1d6..eff7d2a 100644 --- a/c/buildasm/buildzqfieldtester.js +++ b/c/buildasm/buildzqfieldtester.js @@ -35,7 +35,7 @@ async function testField(prime, test) { ` ${path.join(dir.path, "fr.o")}` + ` ${path.join(dir.path, "fr.c")}` + ` -o ${path.join(dir.path, "tester")}` + - " -lgmp" + " -lgmp -g" ); const inLines = []; diff --git a/c/buildasm/fr.c.ejs b/c/buildasm/fr.c.ejs index 99033ed..8ed8ea1 100644 --- a/c/buildasm/fr.c.ejs +++ b/c/buildasm/fr.c.ejs @@ -63,7 +63,6 @@ char *<%=name%>_element2str(P<%=name%>Element pE) { } else { mpz_init_set_si(r, pE->shortVal); mpz_add(r, r, q); - mpz_clear(q); } } else { <%=name%>_toNormal(pE); diff --git a/c/buildasm/fr.h b/c/buildasm/fr.h index 31a181a..9cc2378 100644 --- a/c/buildasm/fr.h +++ b/c/buildasm/fr.h @@ -8,8 +8,8 @@ #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; diff --git a/c/buildasm/fr.h.ejs b/c/buildasm/fr.h.ejs index 19e155e..3359223 100644 --- a/c/buildasm/fr.h.ejs +++ b/c/buildasm/fr.h.ejs @@ -8,8 +8,8 @@ #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; diff --git a/c/calcwit.cpp b/c/calcwit.cpp index 04c77a1..9a9d17a 100644 --- a/c/calcwit.cpp +++ b/c/calcwit.cpp @@ -5,6 +5,7 @@ #include #include #include +#include #include #include "calcwit.h" #include "utils.h" diff --git a/src/c_build.js b/src/c_build.js index 12d6ea2..a6768ff 100644 --- a/src/c_build.js +++ b/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 @@ function buildC(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 @@ function buildEntryTables(ctx) { } - 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 @@ function buildCode(ctx) { 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 @@ function buildComponentsArray(ctx) { 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 @@ function buildHeader(ctx) { } function buildSizes(ctx) { - return "// Sizes\n" + - ctx.codes_sizes.join("\n"); + return [ + "// Sizes\n" , + ctx.codes_sizes + ]; } function buildConstants(ctx) { @@ -256,14 +266,14 @@ function buildConstants(ctx) { 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; i0 ? "," : " ") + "{" + 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 @@ function buildMapIsInput(ctx) { 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 @@ function buildWit2Sig(ctx) { if (code != "") codes.push(code + "\n"); codes.push("};\n"); - return codes.join(""); + return codes; } diff --git a/src/compiler.js b/src/compiler.js index 6714d8e..9e8e955 100644 --- a/src/compiler.js +++ b/src/compiler.js @@ -83,7 +83,8 @@ async function compile(srcFile, options) { 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); diff --git a/src/stream_from_multiarray.js b/src/stream_from_multiarray.js new file mode 100644 index 0000000..c9bc3a1 --- /dev/null +++ b/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)); + } +}; diff --git a/test/fieldasm.js b/test/fieldasm.js index 60146ec..ff69977 100644 --- a/test/fieldasm.js +++ b/test/fieldasm.js @@ -17,6 +17,7 @@ describe("field asm test", function () { const tv = buildTestVector2(bn128r, "add"); await tester(bn128r, tv); }); + it("secp256k1q add", async () => { const tv = buildTestVector2(secp256k1q, "add"); await tester(secp256k1q, tv);