Warning: session_start(): open(/var/lib/php/sessions/sess_40j62p4pf9eo1ukokin1jlhltl, 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
sclass LASClassDef {
settable S userGivenName;
settable S classDefPrefix = "userCode.";
settable bool fullCompilation;
settable bool verbose = true;
replace Tb with GazelleV_LeftArrowScript.
delegate FunctionDef, Evaluable to Tb.
new L fields;
new L methods;
new L methodBodies;
sclass FieldDef {
settable S name;
settable Type type;
}
S structForHash() {
ret Tb.scriptStruct(litorderedmap(
+userGivenName, +fields, +methods, +fullCompilation
));
}
simplyCached S classHash() {
S struct = structForHash();
if (verbose) print(structForHash := struct);
ret md5(struct);
}
S finalClassName() {
ret classDefPrefix() + finalClassNameWithoutPrefix();
}
S finalClassNameWithoutPrefix() {
ret or2(userGivenName, "C") + "_" + classHash();
}
simplyCached byte[] toBytes() {
ClassMaker classMaker = new(finalClassName());
var cp = classMaker.getConstantPool();
for (field : fields) {
var type = field.type;
var fg = new FieldGen(
Const.ACC_PUBLIC, typeToBCELType(type),
field.name, cp);
if (type cast ParameterizedType)
fg.addAttribute(new org.apache.bcel.classfile.Signature(
cp.addUtf8("Signature"), 2,
cp.addUtf8(typeToVMSignature(type)),
cp.getConstantPool()));
classMaker.addField(fg);
}
for (method : methods)
if (fullCompilation)
fullyCompileMethod(classMaker, method);
else
semiCompileMethod(classMaker, method);
classMaker.addDefaultConstructor();
ret classMaker.toBytes();
}
// generate interpreted method (slower but always works)
// like this:
//
// new FlexibleVarContext ctx;
// ctx.put("this", this);
// ctx.put("arg1", arg1);
// ctx.put("arg2", arg2);
// ret methodBody.get(ctx);
void semiCompileMethod(ClassMaker classMaker, FunctionDef method) {
// make static field for method body later
int iMethod = l(methodBodies);
methodBodies.add(method);
S bodyFieldName = "_body" + iMethod;
classMaker.addField(new FieldGen(
Const.ACC_PUBLIC | Const.ACC_STATIC, classToBCELType(Evaluable.class),
bodyFieldName, classMaker.getConstantPool()));
int nArgs = l(method.args);
MethodMaker mm = new(classMaker, O.class, method.name,
repArray(Class.class, O.class, nArgs));
int iThis = 0, iFirstArg = 1, iCtx = iFirstArg+nArgs;
// new FlexibleVarContext ctx;
mm.newObject(FlexibleVarContext);
mm.astore(iCtx);
// ctx.put("this", this);
mm.aload(iCtx);
mm.stringConstant("this");
mm.aload(iThis);
mm.invokeVirtual(VarContext, void.class, "put", S, O);
// ctx.put("arg1", arg1);
for iArg to nArgs: {
mm.aload(iCtx);
mm.stringConstant(method.args[iArg]);
mm.aload(iFirstArg+iArg);
mm.invokeVirtual(VarContext, void.class, "put", S, O);
}
// ret methodBody.get(ctx);
mm.getStaticField(classMaker.className(), bodyFieldName, Evaluable.class);
mm.aload(iCtx);
mm.invokeInterface(Evaluable.class, O, "get", VarContext);
mm.areturn();
mm.done();
}
// fully compile method to byte code (this works only for very simple methods)
void fullyCompileMethod(ClassMaker classMaker, FunctionDef method) {
MethodMaker mm = new(classMaker, typeToClass(method.returnType()), method.name,
repArray(Class.class, O.class, l(method.args)));
var tbc = LASToByteCode(mm) {
JVMStackCellType compileGetVar(Tb.GetVar code) {
// load "this"
if (eq(code.var, "this")) {
mm.aload(0);
ret JVMStackCellType.objValue;
}
// load method argument
int iArg = indexOf(method.args, code.var);
if (iArg >= 0) {
mm.aload(iArg+1);
ret JVMStackCellType.objValue;
}
ret super.compileGetVar(code);
}
};
tbc.postConversion = stackTop -> mm.convertToObject(stackTop);
tbc.compileScript(method.body);
mm.areturn();
mm.done();
}
void init(Class c) {
for iMethod over methodBodies: {
S bodyFieldName = "_body" + iMethod;
set(c, bodyFieldName, methodBodies.get(iMethod).body);
}
}
}