Wasm generation finished

This commit is contained in:
Jordi Baylina
2020-03-16 20:37:08 +01:00
parent 8f63d18ff4
commit ef899e618b
27 changed files with 2617 additions and 374 deletions

View File

@@ -545,15 +545,15 @@ module.exports = function buildRuntime(module, builder) {
f.addCode(
c.call(
"Fr_eq",
c.getLocal(c.i32_const(pTmp)),
c.i32_const(pTmp),
c.getLocal("pA"),
c.getLocal("pB")
),
c.if (
c.eqz(
c.i32_eqz(
c.call(
"Fr_isTrue",
c.getLocal(c.i32_const(pTmp)),
c.i32_const(pTmp),
)
),
c.call(
@@ -658,21 +658,6 @@ module.exports = function buildRuntime(module, builder) {
);
}
function buildFrToInt() {
const f = module.addFunction("Fr_toInt");
f.addParam("p", "i32");
f.setReturnType("i32");
const c = f.getCodeBuilder();
f.addCode(
c.i32_load(c.getLocal("p"))
);
// TODO Handle long and montgomery.
}
const fErr = module.addIimportFunction("err", "runtime");
fErr.addParam("code", "i32");
fErr.addParam("pStr", "i32");
@@ -703,6 +688,9 @@ module.exports = function buildRuntime(module, builder) {
fErr4.addParam("param3", "i32");
fErr4.addParam("param4", "i32");
const fLog = module.addIimportFunction("log", "runtime");
fLog.addParam("code", "i32");
buildWasmFf(module, "Fr", builder.header.P);
builder.pSignals=module.alloc(builder.header.NSignals*builder.sizeFr);
@@ -734,7 +722,7 @@ module.exports = function buildRuntime(module, builder) {
buildGetPWitness();
buildGetPRawPrime();
buildFrToInt();
// buildFrToInt();
module.exportFunction("init");
module.exportFunction("getNVars");

View File

@@ -104,6 +104,10 @@ class CodeBuilderWasm {
this.ops.push(...cb.ops);
}
log(val) {
this.ops.push({op: "LOG", val});
}
hasCode() {
for (let i=0; i<this.ops.length; i++) {
if (this.ops[i].op != "COMMENT") return true;
@@ -111,6 +115,7 @@ class CodeBuilderWasm {
return false;
}
_buildOffset(c, offsets) {
let rN=0;
let S = null;
@@ -671,7 +676,7 @@ class FunctionBuilderWasm {
}
class BuilderWasm {
constructor() {
constructor(sanityCheck) {
this.hashMaps={};
this.componentEntriesTables={};
this.sizes ={};
@@ -679,6 +684,7 @@ class BuilderWasm {
this.usedConstants = {};
this.functions = [];
this.components = [];
this.sanityCheck = sanityCheck;
this.TYPE_SIGNAL = 1;
this.TYPE_COMPONENT = 2;
@@ -989,6 +995,8 @@ class BuilderWasm {
this._buildMapIsInput(module);
this._buildWit2Sig(module);
this._buildCircuitVar(module);
module.setMemory(2000);
if (outType == "wasm") {
return streamFromArrayBin(module.build());
} else if (outType == "wat") {

View File

@@ -33,6 +33,7 @@ async function wasm_tester(circomFile, _options) {
options.wasmWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".wasm"));
options.symWriteStream = fs.createWriteStream(path.join(dir.path, baseName + ".sym"));
options.r1csFileName = path.join(dir.path, baseName + ".r1cs");
options.sanityCheck = true;
const promisesArr = [];
promisesArr.push(new Promise(fulfill => options.wasmWriteStream.on("finish", fulfill)));

View File

@@ -17,33 +17,55 @@ module.exports.fromBuffer = async function(code) {
const memory = new WebAssembly.Memory({initial:20000});
const wasmModule = await WebAssembly.compile(code);
let wc;
const instance = await WebAssembly.instantiate(wasmModule, {
env: {
"memory": memory
},
runtime: {
err: function(code, pstr) {
console.log("ERROR", code, p2str(pstr));
const errStr=p2str(pstr);
console.log("ERROR: ", code, errStr);
throw new Error(errStr);
},
err1: function(code, pstr, a) {
console.log("ERROR: ", code, p2str(pstr), a);
const errStr=p2str(pstr)+ " " + a;
console.log("ERROR: ", code, errStr);
throw new Error(errStr);
},
err2: function(code, pstr, a, b) {
console.log("ERROR: ", code, p2str(pstr), a, b);
const errStr=p2str(pstr)+ " " + a + " " + b;
console.log("ERROR: ", code, errStr);
throw new Error(errStr);
},
err3: function(code, pstr, a, b, c) {
console.log("ERROR: ", code, p2str(pstr), a, b, c);
const errStr=p2str(pstr)+ " " + a + " " + b + " " + c;
console.log("ERROR: ", code, errStr);
throw new Error(errStr);
},
err4: function(code, pstr, a,b,c,d) {
console.log("ERROR: ", code, p2str(pstr), a, b, c, d);
const errStr=p2str(pstr) + " " + wc.getFr(b).toString() + " != " + wc.getFr(c).toString() + " " +p2str(d);
console.log("ERROR: ", code, errStr);
throw new Error(errStr);
},
log: function(a) {
console.log(wc.getFr(a).toString());
},
}
});
return new WitnessCalculator(memory, instance);
wc = new WitnessCalculator(memory, instance);
return wc;
function p2str(p) {
return "TODO"+p;
const i8 = new Uint8Array(memory.buffer);
const bytes = [];
for (let i=0; i8[p+i]>0; i++) bytes.push(i8[p+i]);
return String.fromCharCode.apply(null, bytes);
}
};
@@ -120,30 +142,31 @@ class WitnessCalculator {
}
getFr(p) {
const self = this;
const idx = (p>>2);
if (this.i32[idx + 1] & 0x80000000) {
if (self.i32[idx + 1] & 0x80000000) {
let res= bigInt(0);
for (let i=this.n32-1; i>=0; i--) {
for (let i=self.n32-1; i>=0; i--) {
res = res.shiftLeft(32);
res = res.add(bigInt(this.i32[idx+2+i]));
res = res.add(bigInt(self.i32[idx+2+i]));
}
if (this.i32[idx + 1] & 0x40000000) {
if (self.i32[idx + 1] & 0x40000000) {
return fromMontgomery(res);
} else {
return res;
}
} else {
if (this.i32[idx] & 0x80000000) {
return this.prime.add( bigInt(this.i32[idx]).minus(bigInt(0x100000000)) );
if (self.i32[idx] & 0x80000000) {
return self.prime.add( bigInt(self.i32[idx]).minus(bigInt(0x100000000)) );
} else {
return bigInt(this.i32[idx]);
return bigInt(self.i32[idx]);
}
}
function fromMontgomery(n) {
return n.times(this.RInv).mod(this.prime);
return n.times(self.RInv).mod(self.prime);
}
}