package org.develnext.jphp.core.compiler.jvm.statement.expr.operator; 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.OperatorExprToken; import org.develnext.jphp.core.tokenizer.token.expr.operator.*; import org.develnext.jphp.core.tokenizer.token.expr.value.NameToken; import php.runtime.Memory; import php.runtime.common.Association; import php.runtime.env.Environment; import php.runtime.env.TraceInfo; import php.runtime.invoke.ObjectInvokeHelper; import php.runtime.invoke.cache.PropertyCallCache; public class DynamicAccessCompiler extends BaseExprCompiler<DynamicAccessExprToken> { public DynamicAccessCompiler(ExpressionStmtCompiler exprCompiler) { super(exprCompiler); } @Override public void write(DynamicAccessExprToken dynamic, boolean returnValue) { expr.writeDynamicAccessPrepare(dynamic, false); if (dynamic.getFieldExpr() == null && dynamic.getField() instanceof NameToken && !method.clazz.statement.isTrait()) { expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class); expr.writePushConstInt(method.clazz.getAndIncCallPropCount()); } else { expr.writePushConstNull(); expr.writePushConstInt(0); } if (dynamic instanceof DynamicAccessAssignExprToken){ OperatorExprToken operator = (OperatorExprToken) ((DynamicAccessAssignExprToken) dynamic).getAssignOperator(); String code = operator.getCode(); if (operator instanceof IncExprToken || operator instanceof DecExprToken) { if (operator.getAssociation() == Association.RIGHT) code = code + "AndGet"; else code = "GetAnd" + code.substring(0, 1).toUpperCase() + code.substring(1); expr.writeSysStaticCall(ObjectInvokeHelper.class, code + "Property", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); } else { expr.writeSysStaticCall(ObjectInvokeHelper.class, code + "Property", Memory.class, Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); } } else if (dynamic instanceof DynamicAccessUnsetExprToken){ expr.writeSysStaticCall(ObjectInvokeHelper.class, "unsetProperty", void.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); if (returnValue) expr.writePushNull(); } else if (dynamic instanceof DynamicAccessEmptyExprToken){ expr.writeSysStaticCall(ObjectInvokeHelper.class, "emptyProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); } else if (dynamic instanceof DynamicAccessIssetExprToken){ expr.writeSysStaticCall(ObjectInvokeHelper.class, "issetProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); } else { expr.writeSysStaticCall(ObjectInvokeHelper.class, dynamic instanceof DynamicAccessGetRefExprToken ? "getRefProperty" : "getProperty", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class ); } } }