use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable 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());
}
}
use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.
the class MethodStmtCompiler method writeFooter.
@SuppressWarnings("unchecked")
void writeFooter() {
LabelNode endL = new LabelNode();
node.instructions.add(endL);
for (LocalVariable variable : localVariables.values()) {
String description = Type.getDescriptor(variable.getClazz() == null ? Object.class : variable.getClazz());
if (variable.name.equals("~this")) {
//if (variable.getClazz() != Memory.class && !clazz.statement.isTrait()) {
description = "L" + clazz.entity.getCompiledInternalName() + ";";
//}
}
node.localVariables.add(new LocalVariableNode(variable.name, description, null, variable.label == null ? labelStart : variable.label, variable.getEndLabel() == null ? endL : variable.getEndLabel(), variable.index));
}
//node.maxStack = this.stackMaxSize; !!! we don't need this, see: ClassWriter.COMPUTE_FRAMES
//node.maxLocals = this.localVariables.size();
}
use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.
the class ClassStmtCompiler method writeInitEnvironment.
@SuppressWarnings("unchecked")
protected void writeInitEnvironment() {
if (!dynamicConstants.isEmpty() || !dynamicProperties.isEmpty()) {
initDynamicExists = true;
MethodNode node = new MethodNodeImpl();
node.access = ACC_STATIC + ACC_PUBLIC;
node.name = "__$initEnvironment";
node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class));
if (entity.isTrait()) {
node.desc = Type.getMethodDescriptor(Type.getType(void.class), Type.getType(Environment.class), Type.getType(String.class));
}
MethodStmtCompiler methodCompiler = new MethodStmtCompiler(this, node);
ExpressionStmtCompiler expressionCompiler = new ExpressionStmtCompiler(methodCompiler, null);
methodCompiler.writeHeader();
LabelNode l0 = expressionCompiler.makeLabel();
methodCompiler.addLocalVariable("~env", l0, Environment.class);
if (entity.isTrait())
methodCompiler.addLocalVariable("~class_name", l0, String.class);
LocalVariable l_class = methodCompiler.addLocalVariable("~class", l0, ClassEntity.class);
expressionCompiler.writePushEnv();
if (entity.isTrait()) {
expressionCompiler.writeVarLoad("~class_name");
expressionCompiler.writePushDupLowerCase();
} else {
expressionCompiler.writePushConstString(entity.getName());
expressionCompiler.writePushConstString(entity.getLowerName());
}
expressionCompiler.writePushConstBoolean(true);
expressionCompiler.writeSysDynamicCall(Environment.class, "fetchClass", ClassEntity.class, String.class, String.class, Boolean.TYPE);
expressionCompiler.writeVarStore(l_class, false, false);
// corrects defination of constants
final List<ConstStmtToken.Item> first = new ArrayList<ConstStmtToken.Item>();
final Set<String> usedNames = new HashSet<String>();
final List<ConstStmtToken.Item> other = new ArrayList<ConstStmtToken.Item>();
for (ConstStmtToken.Item el : dynamicConstants) {
Token tk = el.value.getSingle();
if (tk instanceof StaticAccessExprToken) {
StaticAccessExprToken access = (StaticAccessExprToken) tk;
boolean self = false;
if (access.getClazz() instanceof SelfExprToken)
self = true;
else if (access.getClazz() instanceof FulledNameToken && ((FulledNameToken) access.getClazz()).getName().equalsIgnoreCase(entity.getName())) {
self = true;
}
if (self) {
String name = ((NameToken) access.getField()).getName();
if (usedNames.contains(el.getFulledName()))
first.add(0, el);
else
first.add(el);
usedNames.add(name);
continue;
}
}
if (usedNames.contains(el.getFulledName()))
first.add(0, el);
else
other.add(el);
}
other.addAll(0, first);
for (ConstStmtToken.Item el : other) {
expressionCompiler.writeVarLoad(l_class);
expressionCompiler.writePushEnv();
expressionCompiler.writePushConstString(el.getFulledName());
expressionCompiler.writeExpression(el.value, true, false, true);
expressionCompiler.writePopBoxing(true);
expressionCompiler.writeSysDynamicCall(ClassEntity.class, "addDynamicConstant", void.class, Environment.class, String.class, Memory.class);
}
for (ClassVarStmtToken el : dynamicProperties) {
expressionCompiler.writeVarLoad(l_class);
expressionCompiler.writePushEnv();
expressionCompiler.writePushConstString(el.getVariable().getName());
expressionCompiler.writeExpression(el.getValue(), true, false, true);
expressionCompiler.writePopBoxing(true);
expressionCompiler.writeSysDynamicCall(ClassEntity.class, el.isStatic() ? "addDynamicStaticProperty" : "addDynamicProperty", void.class, Environment.class, String.class, Memory.class);
}
node.instructions.add(new InsnNode(RETURN));
methodCompiler.writeFooter();
this.node.methods.add(node);
}
}
use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writeDefineVariable.
protected void writeDefineVariable(VariableExprToken value) {
if (methodStatement.isUnusedVariable(value))
return;
LocalVariable variable = method.getLocalVariable(value.getName());
if (variable == null) {
LabelNode label = writeLabel(node, value.getMeta().getStartLine());
variable = method.addLocalVariable(value.getName(), label, Memory.class);
if (methodStatement.isReference(value) || compiler.getScope().superGlobals.contains(value.getName())) {
variable.setReference(true);
} else {
variable.setReference(false);
}
if (variable.name.equals("this") && method.getLocalVariable("~this") != null) {
// $this
writeDefineThis(variable);
} else if (compiler.getScope().superGlobals.contains(value.getName())) {
// super-globals
writeDefineGlobalVar(value.getName());
} else if (methodStatement.isDynamicLocal()) {
// ref-local variables
writePushLocal();
writePushConstString(value.getName());
writeSysDynamicCall(Memory.class, "refOfIndex", Memory.class, String.class);
makeVarStore(variable);
stackPop();
variable.pushLevel();
variable.setValue(null);
variable.setReference(true);
} else {
// simple local variables
if (variable.isReference()) {
writePushNewObject(ReferenceMemory.class);
} else {
writePushNull();
}
makeVarStore(variable);
stackPop();
variable.pushLevel();
}
} else
variable.pushLevel();
}
use of org.develnext.jphp.core.compiler.jvm.misc.LocalVariable in project jphp by jphp-compiler.
the class ExpressionStmtCompiler method writePushThis.
public void writePushThis() {
if (method.clazz.isClosure() || method.getGeneratorEntity() != null) {
writeVarLoad("~this");
writeGetDynamic("self", Memory.class);
} else {
if (method.getLocalVariable("this") == null) {
if (!methodStatement.isStatic()) {
LabelNode label = writeLabel(node);
LocalVariable local = method.addLocalVariable("this", label, Memory.class);
writeDefineThis(local);
} else {
writePushNull();
return;
}
}
writeVarLoad("this");
}
}
Aggregations