mirror of
https://github.com/arnaucube/circom.git
synced 2026-02-07 19:26:43 +01:00
constants
This commit is contained in:
100
src/c_build.js
100
src/c_build.js
@@ -140,7 +140,7 @@ function buildCode(ctx) {
|
||||
|
||||
const fnComponents = [];
|
||||
for (let i=0; i<ctx.components.length; i++) {
|
||||
const h = hashComponentCall(ctx, i);
|
||||
const {h, instanceDef} = hashComponentCall(ctx, i);
|
||||
const fName = ctx.components[i].template+"_"+h;
|
||||
if (!fDefined[fName]) {
|
||||
|
||||
@@ -159,15 +159,20 @@ function buildCode(ctx) {
|
||||
|
||||
gen(ctx, ctx.templates[ctx.components[i].template].block);
|
||||
|
||||
const S = `void ${fName}(Circom_CalcWit *ctx) {\n` +
|
||||
const S =
|
||||
"/*\n" +
|
||||
instanceDef +
|
||||
"\n*/\n" +
|
||||
`void ${fName}(Circom_CalcWit *ctx) {\n` +
|
||||
utils.ident(
|
||||
ctx.codeHeader + "\n" +
|
||||
ctx.code + "\n" +
|
||||
ctx.codeFooter
|
||||
) +
|
||||
"}\n";
|
||||
"}\n";
|
||||
|
||||
fnComponents.push(S);
|
||||
fDefined[fName] = true;
|
||||
}
|
||||
ctx.components[i].fnName = fName;
|
||||
}
|
||||
@@ -269,9 +274,9 @@ function buildWit2Sig(ctx) {
|
||||
const arr = Array(NVars);
|
||||
for (let i=0; i<ctx.signals.length; i++) {
|
||||
const outIdx = ctx.signals[i].id;
|
||||
if (typeof outIdx == "undefined") continue;
|
||||
if (ctx.signals[i].e>=0) continue; // If has an alias, continue..
|
||||
assert(outIdx<NVars);
|
||||
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;
|
||||
}
|
||||
@@ -312,11 +317,6 @@ function buildCircuitVar() {
|
||||
|
||||
|
||||
|
||||
function hashComponentCall(ctx, cIdx) {
|
||||
// TODO: At the moment generate a diferent function for each instance of the component
|
||||
return cIdx;
|
||||
}
|
||||
|
||||
|
||||
function getTmpName(_suggestedName) {
|
||||
let suggestedName;
|
||||
@@ -374,7 +374,7 @@ function addSizes(_sizes) {
|
||||
|
||||
function buildFunction(name, paramValues) {
|
||||
const ctx = this;
|
||||
const h = hashFunctionCall(ctx, name, paramValues);
|
||||
const {h, instanceDef} = hashFunctionCall(ctx, name, paramValues);
|
||||
|
||||
if (ctx.definedFunctions[h]) return ctx.definedFunctions[h];
|
||||
|
||||
@@ -430,7 +430,11 @@ function buildFunction(name, paramValues) {
|
||||
if (ctx.returnValue == null) {
|
||||
if (ctx.returnSizes == null) assert(false, `Funciont ${name} does not return any value`);
|
||||
res.type = "VARVAL_CONSTSIZE";
|
||||
let code = `void ${name}_${h}(Circom_CalcWit *ctx, PBigInt __retValue ${paramsStr}) {`;
|
||||
let code =
|
||||
"/*\n" +
|
||||
instanceDef +
|
||||
"\n*/\n" +
|
||||
`void ${name}_${h}(Circom_CalcWit *ctx, PBigInt __retValue ${paramsStr}) {`;
|
||||
code += utils.ident(ctx.codeHeader);
|
||||
code += utils.ident(ctx.code);
|
||||
code += utils.ident("returnFunc:\n");
|
||||
@@ -455,7 +459,77 @@ function buildFunction(name, paramValues) {
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
|
||||
function hashComponentCall(ctx, cIdx) {
|
||||
// TODO: At the moment generate a diferent function for each instance of the component
|
||||
const constParams = [];
|
||||
for (let p in ctx.components[cIdx].params) {
|
||||
constParams.push(p + "=" + value2str(ctx.components[cIdx].params[p]));
|
||||
}
|
||||
|
||||
for (let n in ctx.components[cIdx].names.o) {
|
||||
const entry = ctx.components[cIdx].names.o[n];
|
||||
if ((entry.type == "S")&&(ctx.signals[entry.offset].o & ctx.IN)) {
|
||||
travelSizes(n, entry.offset, entry.sizes, (prefix, offset) => {
|
||||
if (utils.isDefined(ctx.signals[offset].v)) {
|
||||
constParams.push(prefix + "=" + bigInt(ctx.signals[offset].value));
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
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; i<sizes[0]; i++) {
|
||||
o += travelSizes(prefix + "[" + i + "]", o, sizes.slice(1), fn);
|
||||
}
|
||||
return o-offset;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function hashFunctionCall(ctx, name, paramValues) {
|
||||
// TODO
|
||||
return "1234";
|
||||
const constParams = [];
|
||||
for (let i=0; i<ctx.functions[name].params.length; i++) {
|
||||
if (!paramValues[i].used) {
|
||||
constParams.push(ctx.functions[name].params[i] + "=" + value2str(paramValues[i]));
|
||||
}
|
||||
}
|
||||
let instanceDef = name;
|
||||
if (constParams.length>0) {
|
||||
instanceDef += "\n";
|
||||
constParams.sort();
|
||||
instanceDef += constParams.join("\n");
|
||||
}
|
||||
|
||||
const h = utils.fnvHash(instanceDef);
|
||||
return {h, instanceDef};
|
||||
}
|
||||
|
||||
function value2str(v) {
|
||||
if (Array.isArray(v)) {
|
||||
let S="[";
|
||||
for (let i=0; i<v.length; i++) {
|
||||
if (i>0) S+=",";
|
||||
S+=value2str(v[i]);
|
||||
}
|
||||
return S;
|
||||
} else {
|
||||
return bigInt(v).toString();
|
||||
}
|
||||
}
|
||||
|
||||
17
src/c_gen.js
17
src/c_gen.js
@@ -6,7 +6,6 @@ module.exports.gen = gen;
|
||||
module.exports.newRef = newRef;
|
||||
|
||||
function newRef(ctx, type, _name, value, sizes) {
|
||||
const isValue = ((typeof(value) != "undefined")&&(value != null));
|
||||
let name;
|
||||
if (!_name) {
|
||||
name = ctx.getTmpName();
|
||||
@@ -19,7 +18,7 @@ function newRef(ctx, type, _name, value, sizes) {
|
||||
}
|
||||
if (Array.isArray(sizes)) {
|
||||
sizes = utils.accSizes(sizes);
|
||||
} else if (isValue) {
|
||||
} else if (utils.isDefined(value)) {
|
||||
sizes = utils.accSizes(utils.extractSizes(value));
|
||||
} else {
|
||||
sizes = [1, 0];
|
||||
@@ -37,7 +36,7 @@ function newRef(ctx, type, _name, value, sizes) {
|
||||
label: label
|
||||
};
|
||||
|
||||
if (isValue) {
|
||||
if (utils.isDefined(value)) {
|
||||
scope[name].value = value;
|
||||
}
|
||||
|
||||
@@ -59,7 +58,7 @@ function instantiateRef(ctx, name, initValue) {
|
||||
ctx.codeHeader += `Circom_Sizes ${v.label};\n`;
|
||||
}
|
||||
v.used = true;
|
||||
if ((typeof initValue!= "undefined")&&(initValue != null)) {
|
||||
if (utils.isDefined(initValue)) {
|
||||
const flatedValue = utils.flatArray(initValue);
|
||||
for (let i=0; i<flatedValue.length; i++) {
|
||||
const c = `mpz_set_str(${v.label}[${i}], "${flatedValue[i].toString(10)}", 10);\n`;
|
||||
@@ -738,7 +737,7 @@ function genFor(ctx, ast) {
|
||||
`${condVar} = ctx->field->isTrue(${condName});\n` +
|
||||
`while (${condVar}) {\n`;
|
||||
} else {
|
||||
if ((typeof cond.value == "undefined")||(cond.value == null)) return error(ctx, ast, "condition value not assigned");
|
||||
if (!utils.isDefined(cond.value)) return error(ctx, ast, "condition value not assigned");
|
||||
if (cond.value.isZero()) end=true;
|
||||
}
|
||||
|
||||
@@ -834,8 +833,8 @@ function genReturn(ctx, ast) {
|
||||
if (v.used) {
|
||||
ctx.code += `ctx->field->copyn(__retValue, ${vName}, ${v.sizes[0]});\n`;
|
||||
} else {
|
||||
if ((typeof v.value == "undefined") || v == null) return error(ctx, ast, "Returning an unknown value");
|
||||
if ((typeof ctx.returnValue == "undefined") || (ctx.returnValue == null)) {
|
||||
if (!utils.isDefined(v.value)) return error(ctx, ast, "Returning an unknown value");
|
||||
if (!utils.isDefined(ctx.returnValue)) {
|
||||
ctx.returnValue = v.value;
|
||||
}
|
||||
}
|
||||
@@ -885,8 +884,8 @@ function genBinaryOp(ctx, ast, op) {
|
||||
if (ctx.error) return;
|
||||
const b = getScope(ctx, bName);
|
||||
|
||||
if ((!a.used)&&(typeof a.value == "undefined")) return error(ctx, ast, "Using a not assigned varialble: "+aName);
|
||||
if ((!b.used)&&(typeof b.value == "undefined")) return error(ctx, ast, "Using a not assigned varialble: "+bName);
|
||||
if ((!a.used)&&(!utils.isDefined(a.value))) return error(ctx, ast, "Using a not assigned varialble: "+aName);
|
||||
if ((!b.used)&&(!utils.isDefined(b.value))) return error(ctx, ast, "Using a not assigned varialble: "+bName);
|
||||
|
||||
let rName;
|
||||
if (a.used || b.used) {
|
||||
|
||||
@@ -29,6 +29,7 @@ const exec = require("./exec");
|
||||
const lc = require("./lcalgebra");
|
||||
const Ctx = require("./ctx");
|
||||
const ZqField = require("./zqfield");
|
||||
const utils = require("./utils");
|
||||
|
||||
module.exports = compile;
|
||||
|
||||
@@ -130,6 +131,7 @@ function classifySignals(ctx) {
|
||||
return t1;
|
||||
}
|
||||
if ((t1 == ctx.stONE) || (t2 == ctx.stONE)) return ctx.stONE;
|
||||
if ((t1 == ctx.stOUTPUT) || (t2 == ctx.stOUTPUT)) return ctx.stOUTPUT;
|
||||
if ((t1 == ctx.stCONSTANT) || (t2 == ctx.stCONSTANT)) return ctx.stCONSTANT;
|
||||
if ((t1 == ctx.stDISCARDED) || (t2 == ctx.stDISCARDED)) return ctx.stDISCARDED;
|
||||
if (t1!=t2) return ERROR;
|
||||
@@ -146,8 +148,6 @@ function classifySignals(ctx) {
|
||||
let t = lSignal.c || ctx.stINTERNAL;
|
||||
if (s == 0) {
|
||||
t = ctx.stONE;
|
||||
} else if (lSignal.v) {
|
||||
t = ctx.stCONSTANT;
|
||||
} else if (lSignal.o & ctx.MAIN) {
|
||||
if (lSignal.o & ctx.IN) {
|
||||
if (lSignal.o & ctx.PRV) {
|
||||
@@ -158,6 +158,8 @@ function classifySignals(ctx) {
|
||||
} else if (lSignal.o & ctx.OUT) {
|
||||
t = ctx.stOUTPUT;
|
||||
}
|
||||
} else if (utils.isDefined(lSignal.v)) {
|
||||
t = ctx.stCONSTANT;
|
||||
}
|
||||
tAll = priorize(t,tAll);
|
||||
if (lSignal.e>=0) {
|
||||
|
||||
14
src/exec.js
14
src/exec.js
@@ -20,6 +20,8 @@
|
||||
const path = require("path");
|
||||
const fs = require("fs");
|
||||
|
||||
const utils = require("./utils");
|
||||
|
||||
const bigInt = require("big-integer");
|
||||
const __P__ = new bigInt("21888242871839275222246405745257275088548364400416034343698204186575808495617");
|
||||
const __MASK__ = new bigInt(2).pow(253).minus(1);
|
||||
@@ -495,15 +497,15 @@ function execDeclareSignal(ctx, ast) {
|
||||
if (ast.name.type != "VARIABLE") return error(ctx, ast, "Invalid component name");
|
||||
if (getScope(ctx, ast.name.name)) return error(ctx, ast, "Name already exists: "+ast.name.name);
|
||||
|
||||
let totalSize = 1;
|
||||
const sizes=[];
|
||||
let totalSize=1;
|
||||
for (let i=0; i< ast.name.selectors.length; i++) {
|
||||
const size = exec(ctx, ast.name.selectors[i]);
|
||||
if (ctx.error) return;
|
||||
|
||||
if (size.type != "NUMBER") return error(ctx, ast.name.selectors[i], "expected a number");
|
||||
const s = size.value.toJSNumber();
|
||||
totalSize *= s;
|
||||
totalSize = totalSize * s;
|
||||
sizes.push( s );
|
||||
}
|
||||
|
||||
@@ -529,7 +531,7 @@ function execDeclareSignal(ctx, ast) {
|
||||
ctx.signals[i].o |= ctx.MAIN;
|
||||
}
|
||||
|
||||
// ctx.components[ctx.currentComponent].signals.push(i);
|
||||
// ctx.components[ctx.currentComponent].signals.push(i);
|
||||
}
|
||||
scope[ast.name.name] = {
|
||||
type: "SIGNAL",
|
||||
@@ -584,10 +586,10 @@ function execVariable(ctx, ast) {
|
||||
if (!v) return error(ctx, ast, "Variable not defined");
|
||||
|
||||
// If the signal has an assigned value (constant) just return the constant
|
||||
if ((v.type == "SIGNAL") && (ctx.signals[v.sIdx].value)) {
|
||||
if ((v.type == "SIGNAL") && (utils.isDefined(ctx.signals[v.sIdx].v))) {
|
||||
return {
|
||||
type: "NUMBER",
|
||||
value: ctx.signals[v.sIdx].value
|
||||
value: ctx.signals[v.sIdx].v
|
||||
};
|
||||
}
|
||||
let res;
|
||||
@@ -1121,7 +1123,7 @@ function execSignalAssign(ctx, ast) {
|
||||
const v = lc.evaluate(ctx, src);
|
||||
|
||||
if (v.value) {
|
||||
sDest.value = v.value;
|
||||
sDest.v = v.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,7 @@ module.exports.fnvHash = fnvHash;
|
||||
module.exports.stringifyBigInts = stringifyBigInts;
|
||||
module.exports.unstringifyBigInts = unstringifyBigInts;
|
||||
module.exports.sameSizes = sameSizes;
|
||||
module.exports.isDefined = isDefined;
|
||||
|
||||
function ident(text) {
|
||||
let lines = text.split("\n");
|
||||
@@ -116,5 +117,9 @@ function sameSizes(s1, s2) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function isDefined(v) {
|
||||
return ((typeof(v) != "undefined")&&(v != null));
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user