Warning: session_start(): open(/var/lib/php/sessions/sess_kpo4a074rgkeufgdult2up1giv, O_RDWR) failed: No space left on device (28) in /var/www/tb-usercake/models/config.php on line 51
Warning: session_start(): Failed to read session data: files (path: /var/lib/php/sessions) in /var/www/tb-usercake/models/config.php on line 51
set flag AllPublic. // so we can access main call()
srecord noeq LASToByteCode(MethodMaker m) {
bool callPing = true;
replace Tb with GazelleV_LeftArrowScript. // Short for "Toolbox"
delegate Evaluable to Tb.
// parameter index of VarContext
settable int iVarContext = -1;
delegate none, objValue, intValue, doubleValue to JVMStackCellType.
delegate convertToObject, discardStackTop, here, loadNull to m.
void compileToObject(Tb.Evaluable code) {
convertToObject(compile(code));
}
JVMStackCellType compile(Tb.Evaluable code) {
if (code cast Tb.Const) {
O o = code.value;
if (o == null) {
m.add(new ACONST_NULL);
ret objValue;
} else if (o cast S) {
m.stringConstant(o);
ret objValue;
} else if (o cast Int) { m.intConstant(o); ret intValue; }
else if (o cast Double) { m.doubleConstant(o); ret doubleValue; }
else if (o cast Class) {
m.classConstant(o);
ret objValue;
} else if (o cast Bool) {
m.boolConstant(o);
ret intValue;
} else
fail("Can't compile const value: " + className(o));
} else if (code cast Tb.Script) {
var stackTop = none;
for (step : code.steps) {
// pop result of last instruction if any
if (stackTop != none)
m.add(new POP);
stackTop = compile(step);
}
ret stackTop;
} else if (code cast Tb.CallMethod) {
// push target
compileToObject(code.target);
// push method name
m.stringConstant(code.methodName);
// push argument array
argumentsAsArray(code.args);
// call call()
m.invokeStatic(mainFunctionHolder call, O, "call", O, S, O[].class);
ret objValue;
} else if (code cast Tb.NewObject) {
// push class
m.classConstant(code.c);
argumentsAsArray(code.args);
// call nuObject()
m.invokeStatic(mainFunctionHolder nuObject, O, "nuObject", Class.class, O[].class);
ret objValue;
} else if (code cast Tb.Assignment) {
// evaluate expression, store in temporary variable
compileToObject(code.expression);
m.astore(iTemp());
// Call VarContext.set()
loadVarContext();
m.stringConstant(code.var);
m.aload(iTemp());
m.invokeVirtual(VarContext, void.class, "set", S, O);
m.aload(iTemp());
ret objValue;
} else if (code cast Tb.While) {
/* Simulating this:
while (ping() && (Bool) condition.get(ctx)) {
body.get(ctx);
}
null;
*/
// Mark loop start as jump target
var loopStart = m.il.append(new NOP);
// Call ping() unless disabled
BranchInstruction branch1 = null;
if (callPing) {
m.invokeStatic(mainFunctionHolder ping, bool.class, "ping");
branch1 = new IFEQ(null);
m.add(branch1);
}
// Evaluate condition
compileToBool(code.condition);
var branch2 = new IFEQ(null);
m.add(branch2);
// Evaluate body
discardStackTop(compile(code.body));
// Jump to loop start
m.add(new GOTO(loopStart));
// Update forward branches
var loopEnd = m.il.append(new NOP);
branch1?.setTarget(loopEnd);
branch2.setTarget(loopEnd);
ret none;
} else if (code cast Tb.IfThen) {
compileToBool(code.condition);
var branch1 = new IFEQ(null);
m.add(branch1);
// Evaluate body
var stackTop = compile(code.body);
// body returns nothing? then we don't need an else branch
if (stackTop == none) {
branch1.setTarget(here());
ret stackTop;
} else {
// otherwise, convert to object and return null in else branch
convertToObject(stackTop);
var jumpToEnd = m.forwardGoto();
var elseBranch = m.il.append(loadNull());
branch1.setTarget(elseBranch);
jumpToEnd.setTarget(m.here());
ret objValue;
}
} else if (code cast Tb.GetVar) {
// Prepare VarContext.get()
loadVarContext();
m.stringConstant(code.var);
// call VarContext.get()
m.invokeVirtual(VarContext, O, "get", S);
ret objValue;
}
fail("Can't compile yet: " + className(code));
}
void argumentsAsArray(L args) {
int n = l(args);
m.intConst(n);
m.add(new ANEWARRAY(m.classRef(O)));
for iArg to n: {
m.dup(); // get array again
m.intConst(iArg);
compileToObject(args.get(iArg));
m.add(new AASTORE);
}
}
void loadVarContext {
assertTrue("Need VarContext", iVarContext >= 0);
m.aload(iVarContext);
}
// index of a temporary variable, created on demand
simplyCached int iTemp() {
ret m.newLocalVar();
}
void compileToBool(Evaluable condition) {
var stackTop = compile(condition);
if (stackTop == objValue) {
// cast to Boolean
m.checkCast(Bool.class);
// call Boolean.booleanValue()
m.invokeVirtual(Bool.class, bool.class, "booleanValue");
} else if (stackTop == intValue) {} // ok
else fail("Can't convert to bool: " + stackTop);
}
}