/*
Copyright 2018 0KIMS association.
This file is part of circom (Zero Knowledge Circuit Compiler).
circom is a free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
circom is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with circom. If not, see .
*/
const assert = require("assert");
const utils = require("./utils");
const gen = require("./gencode").gen;
const createRefs = require("./gencode").createRefs;
const BigArray = require("./bigarray");
module.exports = build;
function build(ctx) {
ctx.definedFunctions = {};
ctx.functionCodes = [];
ctx.buildFunction = buildFunction;
ctx.conditionalCodeHeader = "";
ctx.codes_sizes = [];
ctx.definedSizes = {};
ctx.addSizes = addSizes;
ctx.addConstant = addConstant;
ctx.addConstant(ctx.F.zero);
ctx.addConstant(ctx.F.one);
if (ctx.verbose) console.log("buildHeader...");
buildHeader(ctx);
if (ctx.verbose) console.log("buildEntryTables...");
buildEntryTables(ctx);
ctx.globalNames = ctx.uniqueNames;
if (ctx.verbose) console.log("buildCode...");
buildCode(ctx);
if (ctx.verbose) console.log("buildComponentsArray...");
buildComponentsArray(ctx);
if (ctx.verbose) console.log("buildMapIsInput...");
buildMapIsInput(ctx);
if (ctx.verbose) console.log("buildWit2Sig...");
buildWit2Sig(ctx);
}
function buildEntryTables(ctx) {
const definedHashMaps = {};
for (let i=0; i ((a>b) ? 1 : -1));
const h = utils.fnvHash(keys.join(","));
if (definedHashMaps[h]) return definedHashMaps[h];
definedHashMaps[h] = {};
definedHashMaps[h].htName = ctx.getUniqueName("_ht"+ctx.components[cIdx].template);
definedHashMaps[h].htMap = [];
const t = [];
for (let i=0; i=0) continue; // If has an alias, continue..
assert(typeof outIdx != "undefined", `Signal ${i} does not have index`);
if (outIdx>=NVars) continue; // Is a constant or a discarded variable
if (typeof arr[ctx.signals[i].id] == "undefined") {
arr[outIdx] = i;
}
}
ctx.builder.setWit2Sig(arr);
}
function addSizes(_sizes) {
const sizes = _sizes || [];
let name = "sizes";
for (let i=0; i0) code += ",";
code += accSizes[i];
}
code += "};\n";
this.codes_sizes.push(code);
return labelName;
}
function addConstant(c) {
return this.builder.addConstant(c);
}
function buildFunction(name, paramValues) {
const ctx = this;
const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues);
if (ctx.definedFunctions[h]) return ctx.definedFunctions[h];
const res = {
fnName: `${name}_${h}`
};
const oldRefs = ctx.refs;
const oldConditionalCode = ctx.conditionalCode;
const oldCodeBuilder = ctx.codeBuilder;
const oldFnBuilder = ctx.fnBuilder;
const oldUniqueNames = ctx.uniqueNames;
const oldFileName = ctx.fileName;
const oldFilePath = ctx.oldFilePath;
const oldReturnSizes = ctx.returnSizes;
const oldReturnValue = ctx.returnValue;
ctx.scopes = [{}];
ctx.refs = [];
ctx.conditionalCode = false;
ctx.fnBuilder = ctx.builder.newFunctionBuilder(`${name}_${h}`, instanceDef, ctx.functions[name].params);
ctx.codeBuilder = ctx.fnBuilder.newCodeBuilder();
ctx.uniqueNames = Object.assign({},ctx.globalNames);
ctx.returnValue = null;
ctx.returnSizes = null;
ctx.fileName = ctx.functions[name].fileName;
ctx.filePath = ctx.functions[name].filePath;
let paramLabels = [];
for (let i=0; i {
if (utils.isDefined(ctx.signals[offset].v)) {
constParams.push(prefix + "=" + ctx.F.e(ctx.signals[offset].v));
}
});
}
}
let instanceDef = ctx.components[cIdx].template;
if (constParams.length>0) {
instanceDef += "\n";
constParams.sort();
instanceDef += constParams.join("\n");
}
const h = utils.fnvHash(instanceDef);
return {h, instanceDef};
function travelSizes(prefix, offset, sizes, fn) {
if (sizes.length == 0) {
fn(prefix, offset);
return 1;
} else {
let o = offset;
for (let i=0; i0) {
instanceDef += "\n";
constParams.sort();
instanceDef += constParams.join("\n");
}
const h = utils.fnvHash(instanceDef);
return {h, instanceDef};
}
function value2str(F, v) {
if (Array.isArray(v)) {
let S="[";
for (let i=0; i0) S+=",";
S+=value2str(F, v[i]);
}
S+="]";
return S;
} else {
return F.toString(F.e(v));
}
}