use of org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken in project jphp by jphp-compiler.
the class ListCompiler method write.
public void write(ListExprToken list, boolean returnValue, boolean writeValue) {
if (writeValue) {
expr.writeExpression(list.getValue(), true, false);
expr.writePopBoxing();
}
if (list.isHasRef() && (list.getValue() != null && list.getValue().isSingle() && ValueExprToken.isConstable(list.getValue().getSingle(), true))) {
compiler.getEnvironment().error(list.getValue().toTraceInfo(compiler.getContext()), Messages.ERR_CANNOT_ASSIGN_REF_TO_NON_REF_VALUE.fetch());
}
int i, length = list.getVariables().size();
for (i = 0; i < length; i++) {
// desc order as in PHP
ListExprToken.Variable v = list.getVariables().get(i);
expr.writePushDup();
if (v.indexes != null) {
for (Object index : v.indexes) {
expr.writePushTraceInfo(v.var);
if (v.isRef) {
expr.writePushConstBoolean(true);
}
if (index instanceof Integer) {
expr.writePushConstLong((Integer) index);
} else {
expr.writeExpression((ExprStmtToken) index, true, false);
switch(expr.stackPeek().type) {
case INT:
case STRING:
break;
default:
expr.writePopBoxing();
break;
}
}
// expr.writePushTraceInfo(list);
if (v.isRef) {
expr.writeSysStaticCall(MemoryUtils.class, REF_VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, Boolean.TYPE, expr.stackPeek().type.toClass());
} else {
expr.writeSysStaticCall(MemoryUtils.class, VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, expr.stackPeek().type.toClass());
}
// expr.writeSysDynamicCall(Memory.class, "valueOfIndex", Memory.class, expr.stackPeek().type.toClass());
}
expr.writePushTraceInfo(v.var);
} else {
expr.writePushTraceInfo(v.var);
}
if (v.isWithKey()) {
expr.writeExpression(v.exprIndex, true, false);
switch(expr.stackPeek().type) {
case INT:
case STRING:
break;
default:
expr.writePopBoxing();
break;
}
} else {
expr.writePushConstLong(v.index);
}
expr.writeSysStaticCall(MemoryUtils.class, v.isRef ? REF_VALUE_FOR_LIST_METHOD : VALUE_FOR_LIST_METHOD, Memory.class, Memory.class, TraceInfo.class, expr.stackPeek().type.toClass());
if (v.isVariable()) {
LocalVariable variable = method.getLocalVariable(v.getVariableName());
if (v.isRef) {
variable.setReference(false);
expr.writePushMemory(new ReferenceMemory());
expr.writeVarAssign(variable, (VariableExprToken) v.var.getSingle(), false, true);
variable.setReference(true);
}
expr.writeVarAssign(variable, (VariableExprToken) v.var.getSingle(), false, !v.isRef);
} 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);
}
use of org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken in project jphp by jphp-compiler.
the class TokenizerTest method testBraces.
@Test
public void testBraces() throws IOException {
Tokenizer tokenizer = new Tokenizer(new Context(" :: ->foobar('a', 1, 3.0);"));
assertTrue(tokenizer.nextToken() instanceof StaticAccessExprToken);
assertTrue(tokenizer.nextToken() instanceof DynamicAccessExprToken);
assertTrue(tokenizer.nextToken() instanceof NameToken);
assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
assertTrue(tokenizer.nextToken() instanceof StringExprToken);
assertTrue(tokenizer.nextToken() instanceof CommaToken);
assertTrue(tokenizer.nextToken() instanceof IntegerExprToken);
assertTrue(tokenizer.nextToken() instanceof CommaToken);
assertTrue(tokenizer.nextToken() instanceof DoubleExprToken);
assertTrue(tokenizer.nextToken() instanceof BraceExprToken);
assertTrue(tokenizer.nextToken() instanceof SemicolonToken);
}
use of org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken in project jphp by jphp-compiler.
the class CallCompiler method writePushDynamicMethod.
/**
* $var->method()
*/
public Memory writePushDynamicMethod(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
expr.getMethod().getEntity().setImmutable(false);
if (!writeOpcode)
return null;
DynamicAccessExprToken access = (DynamicAccessExprToken) function.getName();
if (access instanceof DynamicAccessAssignExprToken) {
expr.unexpectedToken(access);
}
expr.writeLineNumber(function);
expr.writeDynamicAccessPrepare(access, true);
expr.writePushParameters(function.getParameters());
expr.writeSysStaticCall(ObjectInvokeHelper.class, "invokeMethod", Memory.class, Memory.class, String.class, String.class, Environment.class, TraceInfo.class, Memory[].class);
if (!returnValue) {
expr.writePopAll(1);
}
if (statistic != null) {
statistic.returnType = StackItem.Type.REFERENCE;
}
return null;
}
use of org.develnext.jphp.core.tokenizer.token.expr.operator.DynamicAccessExprToken in project jphp by jphp-compiler.
the class ForeachCompiler method write.
@Override
public void write(ForeachStmtToken token) {
expr.writeDefineVariables(token.getLocal());
LabelNode start = new LabelNode();
LabelNode end = new LabelNode();
LabelNode l = new LabelNode();
add(l);
expr.writePushEnv();
expr.writePushTraceInfo(token);
expr.writeExpression(token.getIterator(), true, false, true);
expr.writePopBoxing();
expr.writePushConstBoolean(token.isValueReference());
expr.writePushConstBoolean(token.isKeyReference());
expr.writeSysDynamicCall(Environment.class, "__getIterator", ForeachIterator.class, TraceInfo.class, Memory.class, Boolean.TYPE, Boolean.TYPE);
String name = "~foreach~" + method.nextStatementIndex(ForeachIterator.class);
LocalVariable foreachVariable = method.getLocalVariable(name);
if (foreachVariable == null)
foreachVariable = method.addLocalVariable(name, l, ForeachIterator.class);
/*LocalVariable foreachVariable = method.addLocalVariable(
"~foreach~" + method.nextStatementIndex(ForeachIterator.class), l, ForeachIterator.class
);*/
foreachVariable.setEndLabel(end);
expr.writeVarStore(foreachVariable, false, false);
method.pushJump(end, start);
add(start);
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "next", Boolean.TYPE);
add(new JumpInsnNode(IFEQ, end));
expr.stackPop();
// $key
if (token.getKey() != null) {
LocalVariable key = method.getLocalVariable(token.getKey().getName());
expr.checkAssignableVar(token.getKey());
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getMemoryKey", Memory.class);
if (token.isKeyReference()) {
throw new FatalException("Key element cannot be a reference", token.getKey().toTraceInfo(compiler.getContext()));
// writeVarStore(key, false, false);
} else
expr.writeVarAssign(key, null, false, false);
}
// $var
// LocalVariable variable = method.getLocalVariable(token.getValue().getName());
Token last = token.getValue().getLast();
VariableExprToken var = null;
if (last instanceof DynamicAccessExprToken) {
DynamicAccessExprToken setter = (DynamicAccessExprToken) last;
ExprStmtToken value = new ExprStmtToken(this.env, this.compiler.getContext(), token.getValue().getTokens());
value.getTokens().remove(value.getTokens().size() - 1);
value.updateAsmExpr(this.env, this.compiler.getContext());
expr.writeExpression(value, true, false);
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
if (!token.isValueReference())
expr.writePopImmutable();
expr.writeDynamicAccessInfo(setter, false);
expr.writeGetStatic("$CALL_PROP_CACHE", PropertyCallCache.class);
expr.writePushConstInt(method.clazz.getAndIncCallPropCount());
expr.writeSysStaticCall(ObjectInvokeHelper.class, "assignProperty", Memory.class, Memory.class, Memory.class, String.class, Environment.class, TraceInfo.class, PropertyCallCache.class, int.class);
} else {
if (token.getValue().getSingle() instanceof VariableExprToken)
expr.checkAssignableVar(var = (VariableExprToken) token.getValue().getSingle());
ExprStmtToken value = token.getValue();
expr.writeVarLoad(foreachVariable);
expr.writeSysDynamicCall(ForeachIterator.class, "getValue", Memory.class);
if (value.isSingle() && value.getSingle() instanceof ListExprToken) {
ListExprToken listExprToken = (ListExprToken) value.getSingle();
if (!token.isValueReference() && !listExprToken.isHasRef()) {
expr.writePopImmutable();
}
ListCompiler listCompiler = (ListCompiler) expr.getCompiler(ListExprToken.class);
listCompiler.write(listExprToken, false, false);
} else {
if (!token.isValueReference())
expr.writePopImmutable();
expr.writeExpression(value, true, false);
if (expr.stackPeek().immutable)
expr.unexpectedToken(value.getLast());
expr.writeSysStaticCall(Memory.class, token.isValueReference() ? "assignRefRight" : "assignRight", Memory.class, Memory.class, Memory.class);
}
}
expr.writePopAll(1);
/*
if (token.isValueReference())
writeVarStore(variable, false, false);
else
writeVarAssign(variable, false, true); */
// body
expr.write(BodyStmtToken.class, token.getBody());
add(new JumpInsnNode(GOTO, start));
add(end);
/*if (compiler.getLangMode() == LangMode.JPHP){
if (token.isValueReference() && var != null){
expr.writeVarLoad(var.getName());
expr.writeSysDynamicCall(Memory.class, "unset", void.class);
}
}*/
method.popJump();
expr.writeUndefineVariables(token.getLocal());
method.prevStatementIndex(ForeachIterator.class);
}
Aggregations