Experimental support for compiling closures using GCC.
This commit is contained in:
Родитель
7f0c4a6ed8
Коммит
23182abe5d
|
@ -1370,7 +1370,7 @@ module TDev.AST
|
|||
}
|
||||
}
|
||||
|
||||
if (!this.inShim && this.invisibleLocals.indexOf(l) >= 0) {
|
||||
if (!this.inShim && this.invisibleLocals.indexOf(l) >= 0 && !document.location.href.match(/usegcc=1/)) {
|
||||
this.markError(t, lf("TD208: inline functions cannot access locals from outside; try 'promote to data' on '{0}'", l.getName()))
|
||||
}
|
||||
|
||||
|
|
|
@ -92,6 +92,23 @@ module TDev {
|
|||
return env.indent + this.visit(env, expr)+";";
|
||||
}
|
||||
|
||||
public visitInlineActions(env: EmitterEnv, expr: J.JExprHolder, actions: J.JInlineAction[]) {
|
||||
var map = {};
|
||||
expr.locals.forEach((l: J.JLocalDef) => { map[l.id] = l.name });
|
||||
var lambdas = actions.map((a: J.JInlineAction) => {
|
||||
var n = H.mangleUnique(env, map[a.reference.id], a.reference.id);
|
||||
return (
|
||||
env.indent + "auto "+n+"_ = "+
|
||||
this.visitAction(env, "", n, a.inParameters, a.outParameters, a.body, true)+";\n" +
|
||||
env.indent + "auto "+n+" = new std::function<"+
|
||||
H.mkSignature(env, this.libraryMap, "", a.inParameters, a.outParameters)+
|
||||
">("+n+"_);"
|
||||
);
|
||||
});
|
||||
return (lambdas.join("\n")+"\n"+
|
||||
env.indent + this.visit(env, expr.tree) + ";");
|
||||
}
|
||||
|
||||
public visitExprHolder(env: EmitterEnv, locals: J.JLocalDef[], expr: J.JExprHolder) {
|
||||
var decls = locals.map(d => {
|
||||
var x = H.defaultValueForType(this.libraryMap, d.type);
|
||||
|
@ -387,7 +404,8 @@ module TDev {
|
|||
id: string,
|
||||
inParams: J.JLocalDef[],
|
||||
outParams: J.JLocalDef[],
|
||||
body: J.JStmt[])
|
||||
body: J.JStmt[],
|
||||
isLambda=false)
|
||||
{
|
||||
// This function is always called with H.willCompile == true, meaning
|
||||
// it's not a shim.
|
||||
|
@ -402,8 +420,8 @@ module TDev {
|
|||
].filter(x => x != "").join("\n");
|
||||
// The name of a function is unique per library, so don't go through
|
||||
// [mangleUnique].
|
||||
var head = H.mkSignature(env, this.libraryMap, H.mangleName(name), inParams, outParams);
|
||||
return env.indent + head + " {\n" + bodyText + "\n"+env.indent+"}";
|
||||
var head = H.mkSignature(env, this.libraryMap, H.mangleName(name), inParams, outParams, isLambda);
|
||||
return (isLambda ? "" : env.indent) + head + " {\n" + bodyText + "\n"+env.indent+"}";
|
||||
}
|
||||
|
||||
private compileImageLiterals(e: EmitterEnv) {
|
||||
|
|
|
@ -263,17 +263,17 @@ module TDev {
|
|||
return mkType(env, libMap, p.type)+" "+mangleDef(env, p);
|
||||
}
|
||||
|
||||
export function mkSignature(env: Env, libMap: LibMap, name: string, inParams: J.JLocalDef[], outParams: J.JLocalDef[]) {
|
||||
export function mkSignature(env: Env, libMap: LibMap, name: string, inParams: J.JLocalDef[], outParams: J.JLocalDef[], isLambda=false) {
|
||||
if (outParams.length > 1)
|
||||
throw new Error("Not supported (multiple return parameters)");
|
||||
var retType = outParams.length ? mkType(env, libMap, outParams[0].type) : "void";
|
||||
if (name == "main")
|
||||
name = "app_main";
|
||||
return [
|
||||
retType, " ", name, "(",
|
||||
inParams.map(p => mkParam(env, libMap, p)).join(", "),
|
||||
")",
|
||||
].join("");
|
||||
var args = "(" + inParams.map(p => mkParam(env, libMap, p)).join(", ") + ")";
|
||||
if (isLambda)
|
||||
return "[=] "+args+" -> "+retType;
|
||||
else
|
||||
return retType + " " + name + args;
|
||||
}
|
||||
|
||||
// Generate the return instruction for the function.
|
||||
|
|
|
@ -129,7 +129,7 @@ module TDev {
|
|||
public visitContinue(env: T): U { throw new Error("Not implemented"); }
|
||||
public visitInlineActions(
|
||||
env: T,
|
||||
expr: J.JExpr,
|
||||
expr: J.JExprHolder,
|
||||
actions: J.JInlineAction[]): U { throw new Error("Not implemented"); }
|
||||
public visitWhile(env: T, cond: J.JExprHolder, body: J.JStmt[]): U { throw new Error("Not implemented"); }
|
||||
public visitFor(
|
||||
|
|
Загрузка…
Ссылка в новой задаче