package org.develnext.jphp.core.compiler.jvm.statement.expr.operator;
import org.develnext.jphp.core.compiler.common.misc.StackItem;
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.operator.InstanceofExprToken;
import org.develnext.jphp.core.tokenizer.token.expr.value.NameToken;
import php.runtime.Memory;
import php.runtime.OperatorUtils;
public class InstanceOfCompiler extends BaseExprCompiler<InstanceofExprToken> {
public InstanceOfCompiler(ExpressionStmtCompiler exprCompiler) {
super(exprCompiler);
}
protected void pushName(StackItem R) {
NameToken name = null;
if (R.getToken() instanceof NameToken)
name = this.compiler.getAnalyzer().getRealName((NameToken)R.getToken());
if (name == null) {
expr.writePush(R);
expr.writePopString();
expr.writePushDupLowerCase();
} else {
expr.writePushConstString(name.getName());
expr.writePushConstString(name.getName().toLowerCase());
}
}
@Override
public void write(InstanceofExprToken instanceOf, boolean returnValue) {
if (expr.stackEmpty(true))
expr.unexpectedToken(instanceOf);
StackItem R = expr.stackPop();
StackItem L = expr.stackPop();
boolean isInvert = !R.isKnown();
if (!R.isKnown() && !L.isKnown() && R.getLevel() > L.getLevel())
isInvert = false;
/*if (isInvert) {
StackItem tmp = R;
R = L;
L = tmp;
}*/
if (isInvert) {
pushName(R);
expr.writePopString();
expr.writePushDupLowerCase();
expr.writePush(L);
if (expr.stackPeek().isConstant())
expr.unexpectedToken(instanceOf);
expr.writePopBoxing();
expr.writeSysStaticCall(
OperatorUtils.class, "instanceOfRight", Boolean.TYPE, String.class, String.class, Memory.class
);
expr.writePopAll(1);
} else {
expr.writePush(L);
if (expr.stackPeek().isConstant())
expr.unexpectedToken(instanceOf);
expr.writePopBoxing();
pushName(R);
expr.writeSysDynamicCall(Memory.class, "instanceOf", Boolean.TYPE, String.class, String.class);
}
if (!returnValue)
expr.writePopAll(1);
}
}