package org.develnext.jphp.core.compiler.jvm.statement.expr.value; import org.develnext.jphp.core.compiler.jvm.misc.LocalVariable; 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.DynamicAccessExprToken; import org.develnext.jphp.core.tokenizer.token.expr.value.ListExprToken; import org.develnext.jphp.core.tokenizer.token.expr.value.VariableExprToken; import org.develnext.jphp.core.tokenizer.token.stmt.ExprStmtToken; import php.runtime.Memory; import php.runtime.env.Environment; import php.runtime.env.TraceInfo; import php.runtime.invoke.ObjectInvokeHelper; import php.runtime.invoke.cache.PropertyCallCache; import php.runtime.memory.support.MemoryUtils; public class ListCompiler extends BaseExprCompiler<ListExprToken> { public ListCompiler(ExpressionStmtCompiler exprCompiler) { super(exprCompiler); } @Override public void write(ListExprToken list, boolean returnValue) { write(list, returnValue, true); } public void write(ListExprToken list, boolean returnValue, boolean writeValue) { if (writeValue) { expr.writeExpression(list.getValue(), true, false); expr.writePopBoxing(); } int i, length = list.getVariables().size(); for(i = length - 1; i >= 0; i--){ // desc order as in PHP ListExprToken.Variable v = list.getVariables().get(i); expr.writePushDup(); if (v.indexes != null){ for(int index : v.indexes){ expr.writePushConstLong(index); expr.writeSysStaticCall(MemoryUtils.class, "valueForList", Memory.class, Memory.class, expr.stackPeek().type.toClass()); //expr.writeSysDynamicCall(Memory.class, "valueOfIndex", Memory.class, expr.stackPeek().type.toClass()); } } expr.writePushConstLong(v.index); expr.writeSysStaticCall(MemoryUtils.class, "valueForList", Memory.class, Memory.class, expr.stackPeek().type.toClass()); if (v.isVariable()){ LocalVariable variable = method.getLocalVariable(v.getVariableName()); expr.writeVarAssign(variable, (VariableExprToken) v.var.getSingle(), false, true); } else if (v.isArray() || v.isStaticProperty() || v.isArrayPush()) { expr.writeExpression(v.var, true, false); if (expr.stackPeek().immutable || expr.stackPeek().isConstant()) expr.unexpectedToken(v.var.getSingle()); expr.writeSysStaticCall(Memory.class, "assignRight", Memory.class, Memory.class, Memory.class); expr.writePopAll(1); } else if (v.isDynamicProperty()){ DynamicAccessExprToken dynamic = (DynamicAccessExprToken)v.var.getLast(); ExprStmtToken var = new ExprStmtToken(this.env, this.compiler.getContext(), v.var.getTokens()); var.getTokens().remove(var.getTokens().size() - 1); var.updateAsmExpr(this.env, this.compiler.getContext()); expr.writeDynamicAccessInfo(dynamic, false); expr.writeExpression(var, true, false); expr.writePopBoxing(false); expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class); expr.writePushConstInt(method.clazz.getAndIncCallPropCount()); expr.writeSysStaticCall(ObjectInvokeHelper.class, "assignPropertyRight", Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, Memory.class, PropertyCallCache.class, int.class ); expr.writePopAll(1); } } if (!returnValue) expr.writePopAll(1); } }