package org.develnext.jphp.core.compiler.jvm.statement.expr.value;
import org.develnext.jphp.core.compiler.jvm.statement.ExpressionStmtCompiler;
import org.develnext.jphp.core.compiler.jvm.statement.expr.BaseExprCompiler;
import org.develnext.jphp.core.tokenizer.token.expr.ClassExprToken;
import org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken;
import org.develnext.jphp.core.tokenizer.token.expr.value.*;
import php.runtime.Memory;
import php.runtime.env.Environment;
import php.runtime.env.TraceInfo;
import php.runtime.invoke.ObjectInvokeHelper;
import php.runtime.invoke.cache.ConstantCallCache;
import php.runtime.invoke.cache.MethodCallCache;
import php.runtime.invoke.cache.PropertyCallCache;
public class StaticAccessValueCompiler extends BaseExprCompiler<StaticAccessExprToken> {
public StaticAccessValueCompiler(ExpressionStmtCompiler exprCompiler) {
super(exprCompiler);
}
@Override
public void write(StaticAccessExprToken token, boolean returnValue) {
boolean isConstant = token.getField() instanceof NameToken;
/*if (token.getField() == null)
expr.unexpectedToken(token.getFieldExpr().getSingle());*/
if (token.getField() instanceof ClassExprToken) {
if (token.getClazz() instanceof ParentExprToken) {
expr.writePushParent(token.getClazz());
} else if (token.getClazz() instanceof StaticExprToken) {
expr.writePushStatic();
} else if (token.getClazz() instanceof SelfExprToken) {
expr.writePushSelf(false);
} else
expr.unexpectedToken(token);
} else {
ValueExprToken clazz = token.getClazz();
if (clazz instanceof ParentExprToken){
expr.writePushParent(clazz);
} else if (clazz instanceof NameToken){
expr.writePushConstString(((NameToken) clazz).getName());
expr.writePushConstString(((NameToken) clazz).getName().toLowerCase());
} else {
if (clazz instanceof StaticExprToken){
expr.writePushStatic();
} else {
if (clazz != null) {
expr.writePush(clazz, true, false);
} else {
// it static access operator. skip.
}
}
expr.writePopString();
expr.writePushDupLowerCase();
}
if (isConstant) {
expr.writePushConstString(((NameToken) token.getField()).getName());
expr.writePushEnv();
expr.writePushTraceInfo(token);
int cacheIndex = method.clazz.getAndIncCallConstCount();
expr.writeGetStatic("$CALL_CONST_CACHE", ConstantCallCache.class);
expr.writePushConstInt(cacheIndex);
expr.writeSysStaticCall(ObjectInvokeHelper.class, "getConstant",
Memory.class, String.class, String.class, String.class, Environment.class, TraceInfo.class,
ConstantCallCache.class, Integer.TYPE
);
expr.setStackPeekAsImmutable();
} else {
if (token.getFieldExpr() != null) {
expr.writeExpression(token.getFieldExpr(), true, false);
expr.writePopString();
} else {
if (!(token.getField() instanceof VariableExprToken))
expr.unexpectedToken(token.getField());
expr.writePushConstString(((VariableExprToken) token.getField()).getName());
}
expr.writePushEnv();
expr.writePushTraceInfo(token);
String name = "get";
if (token instanceof StaticAccessUnsetExprToken)
name = "unset";
else if (token instanceof StaticAccessIssetExprToken)
name = "isset";
if (token.getFieldExpr() == null && token.getField() instanceof NameToken) {
expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
} else {
expr.writePushConstNull();
expr.writePushConstInt(0);
}
expr.writeSysStaticCall(ObjectInvokeHelper.class,
name + "StaticProperty",
Memory.class, String.class, String.class, String.class, Environment.class, TraceInfo.class,
PropertyCallCache.class, int.class
);
}
}
if (!returnValue)
expr.writePopAll(1);
}
}