use of php.runtime.exceptions.CriticalException in project jphp by jphp-compiler.
the class GlobalDefinitionCompiler method write.
@Override
public void write(GlobalStmtToken token) {
for (ValueExprToken variable : token.getVariables()) {
if (variable instanceof VariableExprToken) {
LocalVariable local = method.getLocalVariable(((VariableExprToken) variable).getName());
assert local != null;
expr.writePushEnv();
expr.writePushConstString(local.name);
expr.writeSysDynamicCall(Environment.class, "getOrCreateGlobal", Memory.class, String.class);
expr.writeVarStore(local, false, false);
} else if (variable instanceof GetVarExprToken) {
BaseExprCompiler<GetVarExprToken> compiler = (BaseExprCompiler<GetVarExprToken>) expr.getCompiler(GetVarExprToken.class);
if (compiler == null)
throw new CriticalException("Cannot find a valid compiler for " + GetVarExprToken.class.getName());
compiler.write((GetVarExprToken) variable, true);
expr.writePushEnv();
Memory name = expr.writeExpression(((GetVarExprToken) variable).getName(), true, true, true);
if (name != null) {
expr.writePushConstString(name.toString());
} else {
expr.writePopString();
}
expr.writeSysDynamicCall(Environment.class, "getOrCreateGlobal", Memory.class, String.class);
expr.writeSysDynamicCall(Memory.class, "assign", Memory.class, Memory.class);
expr.writePopAll(1);
}
}
}
use of php.runtime.exceptions.CriticalException in project jphp by jphp-compiler.
the class JavaReflection method exception.
public static void exception(Environment env, Throwable e) {
if (cachedThClasses == null)
cachedThClasses = new ConcurrentHashMap<Class<? extends Throwable>, Class<? extends JavaException>>();
if (constructors == null)
constructors = new ConcurrentHashMap<Class<? extends JavaException>, Constructor<? extends JavaException>>();
Class tmp = e.getClass();
Class<? extends JavaException> clazz = cachedThClasses.get(tmp);
if (clazz == null) {
while (tmp != null) {
clazz = env.scope.findJavaException(tmp);
if (clazz != null) {
cachedThClasses.put(e.getClass(), clazz);
break;
}
tmp = tmp.getSuperclass();
}
}
if (clazz == null) {
ClassEntity context = env.getLastClassOnStack();
while (context != null) {
clazz = env.scope.findJavaExceptionForContext(context.getLowerName());
if (clazz != null)
break;
context = context.getParent();
}
}
JavaException exception;
if (clazz == null) {
exception = new JavaException(env, e);
} else {
try {
Constructor<? extends JavaException> constructor = constructors.get(clazz);
if (constructor == null) {
constructors.put(clazz, constructor = clazz.getConstructor(Environment.class, Throwable.class));
}
exception = constructor.newInstance(env, e);
} catch (InvocationTargetException e1) {
throw new CriticalException(e1.getCause());
} catch (Exception e1) {
throw new CriticalException(e1);
}
}
env.__throwException(exception, false);
}
use of php.runtime.exceptions.CriticalException in project jphp by jphp-compiler.
the class ObjectInvokeHelper method invokeParentMethod.
public static Memory invokeParentMethod(Memory object, String methodName, String methodLowerName, Environment env, TraceInfo trace, Memory[] args) throws Throwable {
Memory[] passed = null;
boolean doublePop = false;
if (object.isNull()) {
ClassEntity parent = env.__getParentClass(trace);
return InvokeHelper.callStatic(env, trace, parent.getLowerName(), methodLowerName, parent.getName(), methodName, args, null, 0);
}
IObject iObject = ((ObjectMemory) object).value;
ClassEntity childClazz = iObject.getReflection();
ClassEntity clazz = env.getLastClassOnStack().getParent();
MethodEntity method;
if (clazz == null) {
env.error(trace, "Cannot access parent:: when current class scope has no parent");
return Memory.NULL;
}
if (methodName == null) {
method = childClazz.methodMagicInvoke != null ? childClazz.methodMagicInvoke : clazz.methodMagicInvoke;
} else {
method = clazz.findMethod(methodLowerName);
if (method == null && ((method = childClazz.methodMagicCall != null ? childClazz.methodMagicCall : clazz.methodMagicCall) != null)) {
passed = new Memory[] { new StringMemory(methodName), ArrayMemory.of(args) };
doublePop = true;
}
}
String className = clazz.getName();
if (method == null) {
if (methodName == null)
methodName = "__invoke";
env.error(trace, ErrorType.E_ERROR, Messages.ERR_CALL_TO_UNDEFINED_METHOD.fetch(className + "::" + methodName));
return Memory.NULL;
}
InvokeHelper.checkAccess(env, trace, method);
if (passed == null) {
passed = InvokeHelper.makeArguments(env, args, method.getParameters(), className, methodName, trace);
}
Memory result = method.getImmutableResult();
if (result != null)
return result;
try {
if (trace != null) {
env.pushCall(trace, iObject, args, methodName, method.getClazz().getName(), className);
if (doublePop)
env.pushCall(trace, iObject, passed, method.getName(), method.getClazz().getName(), className);
}
result = method.invokeDynamic(iObject, env, passed);
} catch (ArrayIndexOutOfBoundsException e) {
throw new CriticalException("Unable to call parent:: method " + className + "::" + methodName + "(), error = " + e.getMessage());
} finally {
if (trace != null) {
env.popCall();
if (doublePop)
env.popCall();
}
}
return result;
}
use of php.runtime.exceptions.CriticalException in project jphp by jphp-compiler.
the class ClassStmtCompiler method writeCopiedMethod.
protected void writeCopiedMethod(ClassStmtToken.Alias alias, String methodName, ClassEntity trait) {
final MethodEntity methodEntity = fetchClassAndCheck(alias.getTrait()).findMethod(methodName.toLowerCase());
String name = alias.getName();
if (name == null)
name = methodName;
MethodEntity origin = entity.findMethod(name.toLowerCase());
if (origin != null) {
if (origin.getClazz() == entity) {
if (origin.getTrait() != null) {
compiler.getEnvironment().error(entity.getTrace(), Messages.ERR_TRAIT_METHOD_COLLISION.fetch(methodName, trait.getName(), origin.getTrait().getName(), entity.getName()));
}
return;
}
}
if (methodEntity == null) {
compiler.getEnvironment().error(entity.getTrace(), Messages.ERR_METHOD_NOT_FOUND.fetch(alias.getTrait(), methodName));
return;
}
MethodEntity dup = methodEntity.duplicateForInject();
dup.setClazz(entity);
dup.setTrait(trait);
if (alias.getName() != null)
dup.setName(alias.getName());
if (alias.getModifier() != null)
dup.setModifier(alias.getModifier());
MethodNodeImpl methodNode = MethodNodeImpl.duplicate(methodEntity.getAdditionalData("methodNode", MethodNode.class, new Function<MethodNode>() {
@Override
public MethodNode call() {
ClassNode classNode = methodEntity.getClazz().getAdditionalData("classNode", ClassNode.class, new Function<ClassNode>() {
@Override
public ClassNode call() {
ClassReader classReader;
if (methodEntity.getClazz().getData() != null)
classReader = new ClassReader(methodEntity.getClazz().getData());
else {
try {
classReader = new ClassReader(methodEntity.getClazz().getName());
} catch (IOException e) {
throw new CriticalException(e);
}
}
ClassNode classNode = new ClassNode();
classReader.accept(classNode, 0);
return classNode;
}
});
for (Object m : classNode.methods) {
MethodNode method = (MethodNode) m;
if (method.name.equals(methodEntity.getInternalName())) {
return method;
}
}
throw new CriticalException("Cannot find MethodNode for method - " + methodEntity.getName() + "(" + methodEntity.getSignatureString(true) + ")");
}
}));
if (origin != null) {
dup.setPrototype(origin);
}
dup.setInternalName(dup.getName() + "$" + entity.nextMethodIndex());
methodNode.name = dup.getInternalName();
ClassEntity.SignatureResult result = entity.addMethod(dup, null);
result.check(compiler.getEnvironment());
node.methods.add(methodNode);
}
use of php.runtime.exceptions.CriticalException 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;
}
Aggregations