use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushParameters.
public void writePushParameters(Collection<Memory> memories) {
writePushSmallInt(memories.size());
code.add(new TypeInsnNode(ANEWARRAY, Type.getInternalName(Memory.class)));
stackPop();
stackPush(Memory.Type.REFERENCE);
int i = 0;
for (Memory param : memories) {
writePushDup();
writePushSmallInt(i);
writePushMemory(param);
writePopBoxing(true, false);
code.add(new InsnNode(AASTORE));
stackPop();
stackPop();
stackPop();
i++;
}
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushMemory.
public void writePushMemory(Memory memory) {
Memory.Type type = Memory.Type.REFERENCE;
if (memory instanceof UndefinedMemory) {
code.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Memory.class), "UNDEFINED", Type.getDescriptor(Memory.class)));
} else if (memory instanceof NullMemory) {
code.add(new FieldInsnNode(GETSTATIC, Type.getInternalName(Memory.class), "NULL", Type.getDescriptor(Memory.class)));
} else if (memory instanceof FalseMemory) {
writePushConstBoolean(false);
return;
} else if (memory instanceof TrueMemory) {
writePushConstBoolean(true);
return;
} else if (memory instanceof KeyValueMemory) {
writePushMemory(((KeyValueMemory) memory).key);
writePopBoxing();
writePushMemory(((KeyValueMemory) memory).value);
writePopBoxing();
writeSysStaticCall(KeyValueMemory.class, "valueOf", Memory.class, Memory.class, Memory.class);
setStackPeekAsImmutable();
return;
} else if (memory instanceof ReferenceMemory) {
code.add(new TypeInsnNode(NEW, Type.getInternalName(ReferenceMemory.class)));
code.add(new InsnNode(DUP));
code.add(new MethodInsnNode(INVOKESPECIAL, Type.getInternalName(ReferenceMemory.class), Constants.INIT_METHOD, "()V", false));
} else if (memory instanceof ArrayMemory) {
writePushNewObject(ArrayMemory.class);
ArrayMemory array = (ArrayMemory) memory;
ForeachIterator foreachIterator = ((ArrayMemory) memory).foreachIterator(false, false);
while (foreachIterator.next()) {
writePushDup();
if (array.isList()) {
writePushMemory(foreachIterator.getValue());
writePopBoxing();
writeSysDynamicCall(ArrayMemory.class, "add", ReferenceMemory.class, Memory.class);
} else {
Memory key = foreachIterator.getMemoryKey();
writePushMemory(key);
if (!key.isString())
writePopBoxing();
writePushMemory(foreachIterator.getValue());
writePopBoxing();
writeSysDynamicCall(ArrayMemory.class, "put", ReferenceMemory.class, Object.class, Memory.class);
}
writePopAll(1);
}
stackPop();
stackPush(Memory.Type.ARRAY);
setStackPeekAsImmutable();
return;
} else {
switch(memory.type) {
case INT:
{
code.add(new LdcInsnNode(memory.toLong()));
type = Memory.Type.INT;
}
break;
case DOUBLE:
{
code.add(new LdcInsnNode(memory.toDouble()));
type = Memory.Type.DOUBLE;
}
break;
case STRING:
{
code.add(new LdcInsnNode(memory.toString()));
type = Memory.Type.STRING;
}
break;
}
}
stackPush(type);
setStackPeekAsImmutable();
}
use of php.runtime.Memory 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 php.runtime.Memory in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushArray.
public Memory writePushArray(ArrayExprToken array, boolean returnMemory, boolean writeOpcode) {
if (array.getParameters().isEmpty()) {
if (returnMemory)
return new ArrayMemory();
else if (writeOpcode)
writeSysStaticCall(ArrayMemory.class, "valueOf", Memory.class);
} else {
ArrayMemory ret = returnMemory ? new ArrayMemory() : null;
if (ret == null) {
writePushNewObject(ArrayMemory.class);
}
for (ExprStmtToken param : array.getParameters()) {
if (ret == null)
writePushDup();
Memory result = writeExpression(param, true, true, ret == null);
if (result != null) {
if (ret != null) {
ret.add(result);
continue;
} else {
writePushMemory(result);
}
} else {
if (!writeOpcode) {
return null;
}
ret = null;
}
if (result == null && returnMemory) {
return writePushArray(array, false, writeOpcode);
}
writePopBoxing();
writePopImmutable();
writeSysDynamicCall(ArrayMemory.class, "add", ReferenceMemory.class, Memory.class);
writePopAll(1);
}
if (ret != null)
return ret;
}
setStackPeekAsImmutable();
return null;
}
use of php.runtime.Memory in project jphp by jphp-compiler.
the class MethodStmtCompiler method writeHeader.
void writeHeader() {
int access = 0;
if (statement != null) {
if (compiler.getScope().isDebugMode()) {
statement.setDynamicLocal(true);
}
switch(statement.getModifier()) {
case PRIVATE:
access += Opcodes.ACC_PRIVATE;
break;
case PROTECTED:
access += Opcodes.ACC_PROTECTED;
break;
case PUBLIC:
access += Opcodes.ACC_PUBLIC;
break;
}
if (statement.isStatic())
access += Opcodes.ACC_STATIC;
//if (statement.isAbstract()) access += Opcodes.ACC_ABSTRACT;
if (statement.isFinal())
access += Opcodes.ACC_FINAL;
node.access = access;
node.name = clazz.isSystem() || entity == null ? statement.getName().getName() : entity.getInternalName();
node.desc = Type.getMethodDescriptor(Type.getType(Memory.class), Type.getType(Environment.class), Type.getType(Memory[].class));
if (external) {
node.desc = Type.getMethodDescriptor(Type.getType(Memory.class), Type.getType(Environment.class), Type.getType(Memory[].class), Type.getType(ArrayMemory.class));
}
}
if (statement != null) {
LabelNode label = labelStart = writeLabel(node, statement.getMeta().getStartLine());
if (!statement.isStatic())
addLocalVariable("~this", label, Object.class);
ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(this, null);
// Environment env
addLocalVariable("~env", label, Environment.class);
// Memory[] arguments
LocalVariable args = addLocalVariable("~args", label, Memory[].class);
if (statement.isDynamicLocal()) {
if (external)
addLocalVariable("~passedLocal", label, ArrayMemory.class);
LocalVariable local = addLocalVariable("~local", label, ArrayMemory.class);
if (external) {
expressionCompiler.writeVarLoad("~passedLocal");
expressionCompiler.writeSysStaticCall(ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
expressionCompiler.setStackPeekAsImmutable();
expressionCompiler.writeVarStore(local, false, true);
} else {
expressionCompiler.writePushConstNull();
expressionCompiler.writeSysStaticCall(ArrayMemory.class, "valueOfRef", ArrayMemory.class, ArrayMemory.class);
expressionCompiler.setStackPeekAsImmutable();
expressionCompiler.writeVarStore(local, false, true);
}
}
if (statement.getUses() != null && !statement.getUses().isEmpty()) {
int i = 0;
expressionCompiler.writeVarLoad("~this");
expressionCompiler.writeGetDynamic("uses", Memory[].class);
for (ArgumentStmtToken argument : statement.getUses()) {
LocalVariable local;
if (statement.isDynamicLocal()) {
expressionCompiler.writeDefineVariable(argument.getName());
local = getLocalVariable(argument.getName().getName());
} else {
local = addLocalVariable(argument.getName().getName(), label, Memory.class);
}
if (argument.isReference()) {
local.setReference(true);
statement.variable(argument.getName()).setUnstable(true);
}
expressionCompiler.writePushDup();
expressionCompiler.writePushGetFromArray(i, Memory.class);
if (statement.isDynamicLocal()) {
expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
} else {
expressionCompiler.writeVarStore(local, false, false);
}
local.pushLevel();
i++;
}
expressionCompiler.writePopAll(1);
}
int i = 0;
for (ArgumentStmtToken argument : statement.getArguments()) {
if (argument.isReference()) {
statement.variable(argument.getName()).setReference(true).setUnstable(true);
}
LabelNode next = new LabelNode();
expressionCompiler.writeDefineVariable(argument.getName());
LocalVariable local = getLocalVariable(argument.getName().getName());
if (local != null) {
expressionCompiler.writeVarLoad(args);
expressionCompiler.writePushGetFromArray(i, Memory.class);
expressionCompiler.writeVarAssign(local, argument.getName(), true, false);
// if length <= i then undefined
node.instructions.add(new JumpInsnNode(Opcodes.IFNONNULL, next));
expressionCompiler.stackPop();
if (argument.getValue() == null)
expressionCompiler.writePushNull();
else
expressionCompiler.writeExpression(argument.getValue(), true, false);
expressionCompiler.writeVarAssign(local, argument.getName(), false, false);
node.instructions.add(next);
local.pushLevel();
}
i++;
}
} else {
LabelNode label = labelStart = writeLabel(node, clazz.statement.getMeta().getStartLine());
}
}
Aggregations