use of php.runtime.Memory in project jphp by jphp-compiler.
the class ClassStmtCompiler method writeConstant.
protected void writeConstant(ConstStmtToken constant) {
MethodStmtCompiler methodStmtCompiler = new MethodStmtCompiler(this, (MethodStmtToken) null);
ExpressionStmtCompiler expressionStmtCompiler = new ExpressionStmtCompiler(methodStmtCompiler, null);
DocumentComment documentComment = null;
if (constant.getDocComment() != null)
documentComment = new DocumentComment(constant.getDocComment().getComment());
for (ConstStmtToken.Item el : constant.items) {
Memory value = expressionStmtCompiler.writeExpression(el.value, true, true, false);
ConstantEntity constantEntity = new ConstantEntity(el.getFulledName(), value, true);
constantEntity.setTrace(el.name.toTraceInfo(compiler.getContext()));
constantEntity.setDocComment(documentComment);
if (value != null && !value.isArray()) {
ConstantEntity c = entity.findConstant(el.getFulledName());
if (c != null && c.getClazz().getId() == entity.getId()) {
compiler.getEnvironment().error(constant.toTraceInfo(compiler.getContext()), ErrorType.E_ERROR, Messages.ERR_CANNOT_REDEFINE_CLASS_CONSTANT, entity.getName() + "::" + el.getFulledName());
return;
}
entity.addConstant(constantEntity);
} else {
if (ValueExprToken.isConstable(el.value.getSingle(), false)) {
dynamicConstants.add(el);
entity.addConstant(constantEntity);
} else
compiler.getEnvironment().error(constant.toTraceInfo(compiler.getContext()), Messages.ERR_EXPECTED_CONST_VALUE.fetch(entity.getName() + "::" + el.getFulledName()));
}
}
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writeOperator.
Memory writeOperator(OperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
if (writeOpcode) {
BaseExprCompiler compiler = (BaseExprCompiler) getCompiler(operator.getClass());
if (compiler != null) {
if (writeOpcode) {
writeLineNumber(operator);
}
compiler.write(operator, returnValue);
return null;
}
}
if (operator instanceof LogicOperatorExprToken) {
return writeLogicOperator((LogicOperatorExprToken) operator, returnValue, writeOpcode);
}
if (!operator.isBinary()) {
return writeUnaryOperator(operator, returnValue, writeOpcode);
}
if (stackEmpty(true))
unexpectedToken(operator);
StackItem o1 = stackPop();
if (o1.isInvalidForOperations())
unexpectedToken(operator);
if (stackEmpty(true))
unexpectedToken(operator);
StackItem o2 = stackPeek();
ValueExprToken L = stackPopToken();
if (o2.isInvalidForOperations())
unexpectedToken(operator);
if (!(operator instanceof AssignExprToken || operator instanceof AssignOperatorExprToken))
if (o1.getMemory() != null && o2.getMemory() != null) {
Memory result;
stackPush(result = CompilerUtils.calcBinary(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), o2.getMemory(), o1.getMemory(), operator, false));
return result;
}
LocalVariable variable = null;
if (L instanceof VariableExprToken) {
variable = method.getLocalVariable(((VariableExprToken) L).getName());
}
if (operator instanceof AssignExprToken) {
if (L instanceof VariableExprToken) {
if (!writeOpcode)
return null;
writeVariableAssign((VariableExprToken) L, o1, (AssignExprToken) operator, returnValue);
return null;
}
}
Memory value1 = operator instanceof AssignableOperatorToken ? null : // LEFT
tryWritePush(o2, false, false, true);
// RIGHT
Memory value2 = tryWritePush(o1, false, false, true);
if (value1 != null && value2 != null) {
stackPush(value1);
stackPush(value2);
return writeOperator(operator, returnValue, writeOpcode);
}
if (!returnValue && CompilerUtils.isOperatorAlwaysReturn(operator)) {
unexpectedToken(operator);
}
if (!writeOpcode) {
stackPush(o2);
stackPush(o1);
return null;
}
if (writeOpcode) {
writeLineNumber(operator);
}
StackItem.Type Lt = tryGetType(o2);
StackItem.Type Rt = tryGetType(o1);
String name = operator.getCode();
Class operatorResult = operator.getResultClass();
boolean isInvert = false;
boolean sideOperator = operator.isSide();
if (variable != null && !variable.isReference()) {
if (operator instanceof AssignOperatorExprToken) {
name = ((AssignOperatorExprToken) operator).getOperatorCode();
if (operator instanceof AssignConcatExprToken)
operatorResult = String.class;
if (operator instanceof AssignPlusExprToken || operator instanceof AssignMulExprToken)
sideOperator = false;
}
}
if (operator instanceof AssignableOperatorToken && tryIsImmutable(o2))
unexpectedToken(operator);
if (Lt.isConstant() && Rt.isConstant()) {
if (operator instanceof AssignableOperatorToken)
unexpectedToken(operator);
writeScalarOperator(o2, Lt, o1, Rt, operator, operatorResult, name);
} else {
isInvert = !o1.isKnown();
if (!o1.isKnown() && !o2.isKnown() && o1.getLevel() > o2.getLevel())
isInvert = false;
if (Lt.isConstant() && !isInvert) {
writePush(o2);
if (methodExists(OperatorUtils.class, name, Lt.toClass(), Rt.toClass())) {
writePush(o1);
writeSysStaticCall(OperatorUtils.class, name, operatorResult, Lt.toClass(), Rt.toClass());
} else {
writePopBoxing();
writePush(o1);
writeSysDynamicCall(Memory.class, name, operatorResult, Rt.toClass());
}
} else {
if (isInvert) {
stackPush(o1);
if (o2.isKnown())
writePopBoxing(false);
writePush(o2);
if (!o2.isKnown() && !o2.type.isReference()) {
writeSysStaticCall(OperatorUtils.class, name, operatorResult, Lt.toClass(), Rt.toClass());
name = null;
} else if (sideOperator) {
name += "Right";
}
/*if (cloneValue){
writeSysDynamicCall(Memory.class, name, operatorResult, isInvert ? Lt.toClass() : Rt.toClass());
writePush(o2);
name = null;
}*/
} else {
writePush(o2);
writePopBoxing(false);
/*if (cloneValue)
writePushDup();*/
writePush(o1);
if (Rt.isReference()) {
writePopBoxing(false);
}
if (!o1.immutable && !operator.isMutableArguments())
writePopImmutable();
}
if (name != null) {
writeSysDynamicCall(Memory.class, name, operatorResult, isInvert ? Lt.toClass() : Rt.toClass());
}
if (operator.getCheckerCode() != null) {
writePopBoxing();
writePushEnv();
writePushTraceInfo(operator);
writeSysDynamicCall(Memory.class, operator.getCheckerCode(), Memory.class, Environment.class, TraceInfo.class);
}
}
setStackPeekAsImmutable();
if (operator instanceof AssignOperatorExprToken) {
if (variable == null || variable.isReference()) {
/*if (isInvert)
writeSysStaticCall(Memory.class, "assignRight", Memory.class, Rt.toClass(), Memory.class);
else
writeSysDynamicCall(Memory.class, "assign", Memory.class, stackPeek().type.toClass());
*/
if (!returnValue)
writePopAll(1);
} else {
if (returnValue)
writePushDup(StackItem.Type.valueOf(operatorResult));
writePopBoxing(operatorResult);
makeVarStore(variable);
variable.setValue(!stackPeek().isConstant() ? null : stackPeek().getMemory());
stackPop();
}
}
}
return null;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writeUnaryOperator.
Memory writeUnaryOperator(OperatorExprToken operator, boolean returnValue, boolean writeOpcode) {
if (stackEmpty(true))
unexpectedToken(operator);
StackItem o = stackPop();
ValueExprToken L = o.getToken();
Memory mem = tryWritePush(o, false, false, true);
StackItem.Type type = tryGetType(o);
if (mem != null) {
Memory result = CompilerUtils.calcUnary(getCompiler().getEnvironment(), operator.toTraceInfo(getCompiler().getContext()), mem, operator);
if (operator instanceof ValueIfElseToken) {
ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
ExprStmtToken ret = valueIfElseToken.getValue();
if (mem.toBoolean()) {
if (ret == null)
result = mem;
else
result = writeExpression(ret, true, true, false);
} else {
result = writeExpression(valueIfElseToken.getAlternative(), true, true, false);
}
} else if (operator instanceof ArrayGetExprToken && !(operator instanceof ArrayGetRefExprToken)) {
// TODO: check!!!
/*Memory array = mem;
ArrayGetExprToken arrayGet = (ArrayGetExprToken)operator;
for(ExprStmtToken expr : arrayGet.getParameters()){
Memory key = writeExpression(expr, true, true, false);
if (key == null)
break;
result = array = array.valueOfIndex(key).toImmutable();
}*/
}
if (result != null) {
stackPush(result);
setStackPeekAsImmutable();
return result;
}
}
if (!writeOpcode)
return null;
writeLineNumber(operator);
String name = operator.getCode();
Class operatorResult = operator.getResultClass();
LocalVariable variable = null;
if (L instanceof VariableExprToken) {
variable = method.getLocalVariable(((VariableExprToken) L).getName());
if (operator instanceof ArrayPushExprToken || operator instanceof ArrayGetRefExprToken)
variable.setValue(null);
}
if (operator instanceof IncExprToken || operator instanceof DecExprToken) {
if (variable == null || variable.isReference()) {
if (operator.getAssociation() == Association.LEFT && returnValue) {
writePush(o);
if (stackPeek().type.isConstant())
unexpectedToken(operator);
writePushDup();
writePopImmutable();
code.add(new InsnNode(SWAP));
writePushDup();
} else {
writePush(o);
if (stackPeek().type.isConstant())
unexpectedToken(operator);
writePushDup();
}
writeSysDynamicCall(Memory.class, name, operatorResult);
writeSysDynamicCall(Memory.class, "assign", Memory.class, operatorResult);
if (!returnValue || operator.getAssociation() == Association.LEFT) {
writePopAll(1);
}
} else {
writePush(o);
if (stackPeek().type.isConstant())
unexpectedToken(operator);
if (operator.getAssociation() == Association.LEFT && returnValue) {
writeVarLoad(variable);
}
writeSysDynamicCall(Memory.class, name, operatorResult);
// TODO for constant values
variable.setValue(null);
if (operator.getAssociation() == Association.RIGHT)
writeVarStore(variable, returnValue);
else {
writeVarStore(variable, false);
}
}
} else if (operator instanceof AmpersandRefToken) {
writePush(o, false, false);
setStackPeekAsImmutable();
Token token = o.getToken();
if (token instanceof VariableExprToken) {
LocalVariable local = method.getLocalVariable(((VariableExprToken) token).getName());
local.setValue(null);
}
} else if (operator instanceof SilentToken) {
writePushEnv();
writeSysDynamicCall(Environment.class, "__pushSilent", void.class);
writePush(o);
writePushEnv();
writeSysDynamicCall(Environment.class, "__popSilent", void.class);
} else if (operator instanceof ValueIfElseToken) {
writePush(o);
ValueIfElseToken valueIfElseToken = (ValueIfElseToken) operator;
LabelNode end = new LabelNode();
LabelNode elseL = new LabelNode();
if (valueIfElseToken.getValue() == null) {
StackItem.Type dup = stackPeek().type;
writePushDup();
writePopBoolean();
code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
stackPop();
writePopBoxing();
stackPop();
code.add(new JumpInsnNode(Opcodes.GOTO, end));
code.add(elseL);
// remove duplicate of condition value , IMPORTANT!!!
makePop(dup);
writeExpression(valueIfElseToken.getAlternative(), true, false);
writePopBoxing();
code.add(end);
} else {
writePopBoolean();
code.add(new JumpInsnNode(Opcodes.IFEQ, elseL));
stackPop();
writeExpression(valueIfElseToken.getValue(), true, false);
writePopBoxing();
stackPop();
// goto end
code.add(new JumpInsnNode(Opcodes.GOTO, end));
// else
code.add(elseL);
writeExpression(valueIfElseToken.getAlternative(), true, false);
writePopBoxing();
code.add(end);
}
setStackPeekAsImmutable(false);
} else if (operator instanceof ArrayGetExprToken) {
stackPush(o);
writeArrayGet((ArrayGetExprToken) operator, returnValue);
} else if (operator instanceof CallOperatorToken) {
stackPush(o);
CallOperatorToken call = (CallOperatorToken) operator;
writePushParameters(call.getParameters());
writePushEnv();
writePushTraceInfo(operator);
writeSysStaticCall(InvokeHelper.class, "callAny", Memory.class, Memory.class, Memory[].class, Environment.class, TraceInfo.class);
if (!returnValue)
writePopAll(1);
} else {
writePush(o);
writePopBoxing();
if (operator.isEnvironmentNeeded() && operator.isTraceNeeded()) {
writePushEnv();
writePushTraceInfo(operator);
writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class, TraceInfo.class);
} else if (operator.isEnvironmentNeeded()) {
writePushEnv();
writeSysDynamicCall(Memory.class, name, operatorResult, Environment.class);
} else if (operator.isTraceNeeded()) {
writePushTraceInfo(operator);
writeSysDynamicCall(Memory.class, name, operatorResult, TraceInfo.class);
} else
writeSysDynamicCall(Memory.class, name, operatorResult);
if (!returnValue) {
writePopAll(1);
}
}
return null;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushFastStaticMethod.
boolean writePushFastStaticMethod(CallExprToken function, boolean returnValue) {
StaticAccessExprToken access = (StaticAccessExprToken) function.getName();
CompileClass compileClass = compiler.getEnvironment().scope.findCompileClass(access.getClazz().getWord());
if (compileClass == null)
return false;
ClassEntity classEntity = compiler.getEnvironment().fetchClass(compileClass.getNativeClass());
MethodEntity methodEntity = classEntity.findMethod(access.getField().getWord().toLowerCase());
if (methodEntity != null && methodEntity.getNativeMethod() != null && methodEntity.getNativeMethod().isAnnotationPresent(Runtime.FastMethod.class)) {
int cnt = methodEntity.getRequiredParamCount();
if (cnt > function.getParameters().size()) {
writeWarning(function, Messages.ERR_EXPECT_EXACTLY_PARAMS.fetch(methodEntity.getClazzName() + "::" + methodEntity.getName(), cnt, function.getParameters().size()));
if (returnValue)
writePushNull();
return true;
}
List<Memory> additional = new ArrayList<Memory>();
for (ParameterEntity param : methodEntity.getParameters()) {
if (param.getDefaultValue() != null)
additional.add(param.getDefaultValue());
else if (!additional.isEmpty())
throw new IllegalStateException("Arguments with default values must be located at the end");
}
writePushEnv();
writePushParameters(function.getParameters(), additional.toArray(new Memory[0]));
writeSysStaticCall(compileClass.getNativeClass(), methodEntity.getName(), Memory.class, Environment.class, Memory[].class);
if (!returnValue)
writePopAll(1);
return true;
}
return false;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method stackPush.
public void stackPush(ValueExprToken token) {
Memory o = CompilerUtils.toMemory(token);
if (o != null) {
stackPush(o);
} else if (token instanceof StaticAccessExprToken) {
StaticAccessExprToken access = (StaticAccessExprToken) token;
if (access.getField() instanceof NameToken) {
String constant = ((NameToken) access.getField()).getName();
String clazz = null;
ClassEntity entity = null;
if (access.getClazz() instanceof ParentExprToken) {
entity = method.clazz.entity.getParent();
if (entity != null)
clazz = entity.getName();
} else if (access.getClazz() instanceof FulledNameToken) {
clazz = ((FulledNameToken) access.getClazz()).getName();
entity = compiler.getModule().findClass(clazz);
}
if (entity == null && method.clazz.entity != null && method.clazz.entity.getName().equalsIgnoreCase(clazz))
entity = method.clazz.entity;
if (entity != null) {
ConstantEntity c = entity.findConstant(constant);
if (c != null && c.getValue() != null) {
stackPush(c.getValue());
stackPeek().setLevel(-1);
return;
}
}
}
stackPush(token, StackItem.Type.REFERENCE);
} else {
if (token instanceof VariableExprToken && !methodStatement.isUnstableVariable((VariableExprToken) token)) {
LocalVariable local = method.getLocalVariable(((VariableExprToken) token).getName());
if (local != null && local.getValue() != null) {
stackPush(token, local.getValue());
stackPeek().setLevel(-1);
return;
}
}
stackPush(token, StackItem.Type.REFERENCE);
}
stackPeek().setLevel(-1);
}
Aggregations