package org.develnext.jphp.core.compiler.jvm.statement.expr;
import org.develnext.jphp.core.compiler.jvm.misc.LocalVariable;
import org.develnext.jphp.core.compiler.jvm.statement.ExpressionStmtCompiler;
import org.develnext.jphp.core.tokenizer.token.stmt.StaticStmtToken;
import org.objectweb.asm.tree.JumpInsnNode;
import org.objectweb.asm.tree.LabelNode;
import php.runtime.Memory;
import php.runtime.env.Environment;
import static org.objectweb.asm.Opcodes.IFNONNULL;
public class StaticDefinitionCompiler extends BaseStatementCompiler<StaticStmtToken> {
public StaticDefinitionCompiler(ExpressionStmtCompiler exprCompiler) {
super(exprCompiler);
}
void writePushNameForStaticVariable(LocalVariable local) {
String name = method.clazz.isClosure()
? local.name
: method.getEntity().getClazz().getInternalName() + "\0" + local.name + "\0" + method.getMethodId();
if (method.getEntity().getClazz().isTrait()) {
expr.writePushSelf(false);
expr.writePushConstString(name);
expr.writeSysDynamicCall(String.class, "concat", String.class, String.class);
} else {
expr.writePushConstString(name);
}
}
@Override
public void write(StaticStmtToken token) {
LocalVariable local = method.getLocalVariable(token.getVariable().getName());
assert local != null;
LabelNode end = new LabelNode();
boolean isClosure = method.clazz.isClosure();
if (isClosure)
expr.writeVarLoad("~this");
else
expr.writePushEnv();
//writePushConstString(name);
writePushNameForStaticVariable(local);
expr.writeSysDynamicCall(isClosure ? null : Environment.class, "getStatic", Memory.class, String.class);
expr.writePushDup();
add(new JumpInsnNode(IFNONNULL, end));
expr.stackPop();
expr.writePopAll(1);
if (isClosure)
expr.writeVarLoad("~this");
else
expr.writePushEnv();
writePushNameForStaticVariable(local);
//writePushConstString(name);
if (token.getInitValue() != null){
expr.writeExpression(token.getInitValue(), true, false, true);
} else {
expr.writePushNull();
}
expr.writePopBoxing(true);
expr.writeSysDynamicCall(isClosure ? null : Environment.class, "getOrCreateStatic",
Memory.class,
String.class, Memory.class);
add(end);
expr.writeVarStore(local, false, false);
}
}