"""Vervangt embind's createJsInvoker (bouwt functies met new Function) door een variant zonder codegeneratie.
Gedrag gelijk aan het origineel: zelfde closure-argumenten, zelfde volgorde van omzetten, aanroepen en opruimen.
Nodig omdat de site geen 'unsafe-eval' in de Content-Security-Policy toestaat."""
import sys

NEW = (
    "function createJsInvoker(argTypes,isClassMethodFunc,returns,isAsync){"
    "var needsDestructorStack=usesDestructorStack(argTypes);var argCount=argTypes.length-2;"
    "return function(humanName,throwBindingError,invoker,fn,runDestructors,fromRetWire,toClassParamWire){"
    "var extra=Array.prototype.slice.call(arguments,7);var toWire=extra.slice(0,argCount);var dtors=extra.slice(argCount);"
    "return function(){"
    "var destructors=needsDestructorStack?[]:null;var wired=[fn];var thisWired;"
    "if(isClassMethodFunc){thisWired=toClassParamWire(destructors,this);wired.push(thisWired)}"
    "var argsWired=new Array(argCount);"
    "for(var i=0;i<argCount;++i){argsWired[i]=toWire[i](destructors,arguments[i]);wired.push(argsWired[i])}"
    "var rv=invoker.apply(null,wired);"
    "if(needsDestructorStack){runDestructors(destructors)}"
    "else{var d=0;for(var k=isClassMethodFunc?1:2;k<argTypes.length;++k){if(argTypes[k].destructorFunction!==null){dtors[d++](k===1?thisWired:argsWired[k-2])}}}"
    "if(returns){return fromRetWire(rv)}"
    "}}}"
)

path = sys.argv[1]
s = open(path).read()
a = s.index('function createJsInvoker(')
b = s.index('function craftInvokerFunction(')
assert 'new Function(args1,invokerFnBody)' in s[a:b], 'onverwachte versie van de lijmcode'
s = s[:a] + NEW + s[b:]
open(path, 'w').write(s)
print('gepatcht | resterende new Function:', s.count('new Function('))
