use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writeExpression.
@SuppressWarnings("unchecked")
public Memory writeExpression(ExprStmtToken expression, boolean returnValue, boolean returnMemory, boolean writeOpcode) {
int initStackSize = method.getStackCount();
exprStackInit.push(initStackSize);
if (!expression.isStmtList()) {
if (expression.getAsmExpr() == null) {
throw new CriticalException("Invalid expression token without asm expr, on line " + expression.getMeta().getStartLine() + ", expr = " + expression.getWord());
}
// new ASMExpression(compiler.getEnvironment(), compiler.getContext(), expression).getResult();
expression = expression.getAsmExpr();
}
List<Token> tokens = expression.getTokens();
int operatorCount = 0;
for (Token token : tokens) {
if (token instanceof OperatorExprToken)
operatorCount++;
}
boolean invalid = false;
for (Token token : tokens) {
if (token == null)
continue;
writeTickTrigger(token);
if (writeOpcode) {
if (token instanceof StmtToken) {
if (!(token instanceof ReturnStmtToken))
method.entity.setImmutable(false);
}
BaseStatementCompiler cmp = getCompiler(token.getClass());
if (cmp != null && !(cmp instanceof BaseExprCompiler)) {
cmp.write(token);
continue;
}
}
if (token instanceof ValueExprToken) {
// mixed, calls, numbers, strings, vars, etc.
if (token instanceof CallExprToken && ((CallExprToken) token).getName() instanceof OperatorExprToken) {
if (writeOpcode) {
writePush((ValueExprToken) token, true, true);
method.entity.setImmutable(false);
} else
break;
} else
stackPush((ValueExprToken) token);
} else if (token instanceof OperatorExprToken) {
// + - * / % && || or ! and == > < etc.
operatorCount--;
if (operatorCount >= 0) {
Memory result;
if (operatorCount == 0) {
result = writeOperator((OperatorExprToken) token, returnValue, writeOpcode);
} else
result = writeOperator((OperatorExprToken) token, true, writeOpcode);
if (!writeOpcode && result == null) {
invalid = true;
break;
}
if (result == null)
method.entity.setImmutable(false);
}
} else
break;
}
Memory result = null;
if (!invalid && returnMemory && returnValue && !stackEmpty(false) && stackPeek().isConstant()) {
result = stackPop().memory;
invalid = true;
}
if (!invalid) {
if (returnValue && !stackEmpty(false) && stackPeek().isKnown()) {
if (returnMemory)
result = tryWritePush(stackPop(), writeOpcode, returnValue, true);
else
writePush(stackPop());
} else if (method.getStackCount() > 0) {
if (stackPeekToken() instanceof CallableExprToken) {
if (returnMemory)
result = tryWritePush(stackPopToken(), returnValue, writeOpcode, true);
else
writePush(stackPopToken(), returnValue, true);
} else if (stackPeek().isConstant()) {
stackPop();
}
}
}
if (!returnValue && writeOpcode) {
writePopAll(method.getStackCount() - initStackSize);
} else if (!writeOpcode) {
int count = method.getStackCount() - initStackSize;
for (int i = 0; i < count; i++) {
stackPop();
}
}
exprStackInit.pop();
return result;
}
use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushCall.
Memory writePushCall(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
Token name = function.getName();
if (name instanceof NameToken) {
String realName = ((NameToken) name).getName();
CompileFunction compileFunction = compiler.getScope().findCompileFunction(realName);
// try find system function, like max, sin, cos, etc.
if (compileFunction == null && name instanceof FulledNameToken && compiler.getEnvironment().fetchFunction(realName) == null && compiler.findFunction(realName) == null) {
String tryName = ((FulledNameToken) name).getLastName().getName();
compileFunction = compiler.getScope().findCompileFunction(tryName);
}
if (compileFunction != null) {
return writePushCompileFunction(function, compileFunction, returnValue, writeOpcode, statistic);
} else {
if (!writeOpcode)
return null;
method.entity.setImmutable(false);
int index = method.clazz.getAndIncCallFuncCount();
writePushEnv();
writePushTraceInfo(function);
writePushString(realName.toLowerCase());
writePushString(realName);
writePushParameters(function.getParameters());
writeGetStatic("$CALL_FUNC_CACHE", FunctionCallCache.class);
writePushConstInt(index);
writeSysStaticCall(InvokeHelper.class, "call", Memory.class, Environment.class, TraceInfo.class, String.class, String.class, Memory[].class, FunctionCallCache.class, Integer.TYPE);
if (!returnValue)
writePopAll(1);
}
} else if (name instanceof StaticAccessExprToken) {
method.entity.setImmutable(false);
if (((StaticAccessExprToken) name).isAsParent())
return writePushParentDynamicMethod(function, returnValue, writeOpcode, statistic);
else
return writePushStaticMethod(function, returnValue, writeOpcode, statistic);
} else if (name instanceof DynamicAccessExprToken) {
method.entity.setImmutable(false);
return writePushDynamicMethod(function, returnValue, writeOpcode, statistic);
} else {
if (!writeOpcode)
return null;
method.entity.setImmutable(false);
writeLineNumber(function);
writePush((ValueExprToken) function.getName(), true, false);
writePopBoxing();
writePushParameters(function.getParameters());
writePushEnv();
writePushTraceInfo(function);
writeSysStaticCall(InvokeHelper.class, "callAny", Memory.class, Memory.class, Memory[].class, Environment.class, TraceInfo.class);
if (!returnValue)
writePopAll(1);
}
return null;
}
use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushStaticMethod.
Memory writePushStaticMethod(CallExprToken function, boolean returnValue, boolean writeOpcode, PushCallStatistic statistic) {
StaticAccessExprToken access = (StaticAccessExprToken) function.getName();
if (!writeOpcode)
return null;
writeLineNumber(function);
if (writePushFastStaticMethod(function, returnValue))
return null;
writePushEnv();
writePushTraceInfo(function.getName());
String methodName = null;
ValueExprToken clazz = access.getClazz();
if ((clazz instanceof NameToken || (clazz instanceof SelfExprToken && !method.clazz.entity.isTrait())) && access.getField() instanceof NameToken) {
String className;
if (clazz instanceof SelfExprToken)
className = getMacros(clazz).toString();
else
className = ((NameToken) clazz).getName();
writePushString(className.toLowerCase());
methodName = ((NameToken) access.getField()).getName();
writePushString(methodName.toLowerCase());
writePushString(className);
writePushString(methodName);
writePushParameters(function.getParameters());
if (method.clazz.statement.isTrait()) {
writePushConstNull();
writePushConstInt(0);
} else {
int cacheIndex = method.clazz.getAndIncCallMethCount();
writeGetStatic("$CALL_METH_CACHE", MethodCallCache.class);
writePushConstInt(cacheIndex);
}
writeSysStaticCall(InvokeHelper.class, "callStatic", Memory.class, Environment.class, TraceInfo.class, // lower sign name
String.class, // lower sign name
String.class, // origin names
String.class, // origin names
String.class, Memory[].class, MethodCallCache.class, Integer.TYPE);
} else {
if (clazz instanceof NameToken) {
writePushString(((NameToken) clazz).getName());
writePushDupLowerCase();
} else if (clazz instanceof SelfExprToken) {
writePushSelf(true);
} else if (clazz instanceof StaticExprToken) {
writePushStatic();
writePushDupLowerCase();
} else {
writePush(clazz, true, false);
writePopString();
writePushDupLowerCase();
}
if (access.getField() != null) {
ValueExprToken field = access.getField();
if (field instanceof NameToken) {
writePushString(((NameToken) field).getName());
writePushString(((NameToken) field).getName().toLowerCase());
} else if (field instanceof ClassExprToken) {
unexpectedToken(field);
} else {
writePush(access.getField(), true, false);
writePopString();
writePushDupLowerCase();
}
} else {
writeExpression(access.getFieldExpr(), true, false);
writePopString();
writePushDupLowerCase();
}
writePushParameters(function.getParameters());
if (clazz instanceof StaticExprToken || method.clazz.statement.isTrait() || clazz instanceof VariableExprToken) {
writePushConstNull();
writePushConstInt(0);
} else {
int cacheIndex = method.clazz.getAndIncCallMethCount();
writeGetStatic("$CALL_METH_CACHE", MethodCallCache.class);
writePushConstInt(cacheIndex);
}
writeSysStaticCall(InvokeHelper.class, "callStaticDynamic", Memory.class, Environment.class, TraceInfo.class, String.class, String.class, String.class, String.class, Memory[].class, MethodCallCache.class, Integer.TYPE);
}
if (statistic != null)
statistic.returnType = StackItem.Type.REFERENCE;
return null;
}
use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.
the class ASMExpression method processToken.
protected void processToken(Token token, Stack<Token> stack, List<Token> result) {
if (token instanceof CallExprToken) {
CallExprToken call = (CallExprToken) token;
if (call.getName() instanceof OperatorExprToken) {
processOperator(stack, result, (OperatorExprToken) call.getName());
}
result.add(token);
} else if (token instanceof ValueExprToken) {
result.add(token);
} else if (token instanceof BraceExprToken) {
BraceExprToken brace = (BraceExprToken) token;
if (brace.isSimpleOpened()) {
stack.push(brace);
} else if (brace.isSimpleClosed()) {
if (stack.empty())
unexpectedToken(brace);
boolean done = false;
do {
Token el = stack.pop();
if (el instanceof BraceExprToken && ((BraceExprToken) el).isSimpleOpened()) {
done = true;
break;
}
result.add(el);
} while (!stack.isEmpty());
if (!done)
unexpectedToken(brace);
} else
unexpectedToken(brace);
} else if (token instanceof OperatorExprToken) {
OperatorExprToken operator = (OperatorExprToken) token;
/*boolean done = !stack.empty();
if (done){
if (operator.isRightSide())
done = getPriority(stack.peek()) > prior;
else
done = getPriority(stack.peek()) > prior;
}
if (done){
if (prior == 1){
processOperator(stack, result, prior);
result.add(token);
return;
}
stack.push(token);
return;
}*/
processOperator(stack, result, operator);
stack.push(token);
}
}
use of org.develnext.jphp.core.tokenizer.token.expr.ValueExprToken in project jphp by jphp-compiler.
the class StaticAccessValueCompiler method write.
@Override
public void write(StaticAccessExprToken token, boolean returnValue) {
boolean isConstant = token.getField() instanceof NameToken;
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);
}
Aggregations