use of php.runtime.env.CallStack in project jphp by jphp-compiler.
the class StackGetCommand method run.
@Override
public void run(Debugger context, CommandArguments args, Document result) {
DebugTick tick = context.getRegisteredTick();
Element response = createResponse(args, result);
CallStack callStack = tick.getCallStack();
List<CallStackItem> list = new ArrayList<>();
Collections.addAll(list, callStack.getSnapshot());
CallStackItem last = list.get(list.size() - 1);
if (list.size() > 1) {
CallStackItem prevLast = list.get(list.size() - 2);
TraceInfo trace = prevLast.getTrace();
prevLast.setTrace(new TraceInfo(trace.getContext(), last.getTrace().getStartLine(), trace.getEndLine(), last.getTrace().getStartPosition(), trace.getEndLine()));
}
last.setTrace(tick.getTrace());
Collections.reverse(list);
int depth = args.containsKey("d") ? Integer.parseInt(args.get("d")) : -1;
if (depth > -1) {
list = list.subList(0, depth + 1);
}
int i = 0;
for (CallStackItem stackItem : list) {
Element stack = result.createElement("stack");
stack.setAttribute("level", String.valueOf(i));
stack.setAttribute("type", "file");
stack.setAttribute("filename", context.getFileName(stackItem.trace.getFileName()));
stack.setAttribute("lineno", String.valueOf(stackItem.trace.getStartLine() + 1));
stack.setAttribute("where", stackItem.getWhere());
response.appendChild(stack);
i++;
}
}
use of php.runtime.env.CallStack in project jphp by jphp-compiler.
the class InvokeHelper method call.
public static Memory call(Environment env, TraceInfo trace, FunctionEntity function, Memory[] args) throws Throwable {
Memory result = function.getImmutableResultTyped(env, trace);
Memory[] passed = null;
if (result != null && !function.hasParameters() && args == null) {
return result;
}
passed = InvokeArgumentHelper.makeArguments(env, args, function.getParameters(), function.getName(), null, null, trace);
if (result != null) {
return result;
}
CallStack callStack = trace != null && function.isUsesStackTrace() ? env.getCallStack() : null;
if (callStack != null) {
callStack.push(trace, null, args, function.getName(), (String) null, (String) null);
}
try {
result = function.invoke(env, trace, passed);
} finally {
if (callStack != null) {
callStack.pop();
}
}
return result;
}
use of php.runtime.env.CallStack in project jphp by jphp-compiler.
the class InvokeHelper method callStatic.
public static Memory callStatic(Environment env, TraceInfo trace, MethodEntity method, @Nullable String staticClass, Memory[] args, boolean checkAccess) throws Throwable {
if (checkAccess)
checkAccess(env, trace, method);
Memory result = method.getImmutableResultTyped(env, trace);
if (result != null) {
return result;
}
String originClassName = method.getClazz().getName();
String originMethodName = method.getName();
String staticClazz = staticClass == null ? originClassName : staticClass;
Memory[] passed = InvokeArgumentHelper.makeArguments(env, args, method.getParameters(), originClassName, originMethodName, staticClass, trace);
CallStack callStack = trace != null && method.isUsesStackTrace() ? env.getCallStack() : null;
try {
if (callStack != null) {
callStack.push(trace, null, passed, originMethodName, method.getClazz(), staticClazz);
}
return method.invokeStatic(env, passed);
} finally {
if (callStack != null) {
callStack.pop();
}
}
}
use of php.runtime.env.CallStack in project jphp by jphp-compiler.
the class InvokeHelper method callStatic.
public static Memory callStatic(Environment env, TraceInfo trace, String className, String methodName, String originClassName, String originMethodName, Memory[] args, MethodCallCache callCache, int cacheIndex) throws Throwable {
if (callCache != null) {
MethodEntity entity = callCache.get(env, cacheIndex);
if (entity != null) {
return callStatic(env, trace, entity, originClassName, args, false);
}
}
ClassEntity classEntity = env.fetchClass(originClassName, className, true);
MethodEntity method = classEntity == null ? null : classEntity.findMethod(methodName);
Memory[] passed = null;
boolean isMagic = false;
if (method == null) {
IObject maybeObject = env.getLateObject();
if (maybeObject != null && maybeObject.getReflection().isInstanceOf(classEntity))
return ObjectInvokeHelper.invokeMethod(new ObjectMemory(maybeObject), originMethodName, methodName, env, trace, args);
if (classEntity != null && classEntity.methodMagicCallStatic != null) {
method = classEntity.methodMagicCallStatic;
isMagic = true;
passed = new Memory[] { new StringMemory(originMethodName), ArrayMemory.of(args) };
} else {
if (classEntity == null) {
env.error(trace, Messages.ERR_CLASS_NOT_FOUND.fetch(originClassName));
return Memory.NULL;
}
}
}
if (method == null) {
env.error(trace, Messages.ERR_CALL_TO_UNDEFINED_METHOD.fetch(originClassName + "::" + originMethodName));
return Memory.NULL;
}
if (!method.isStatic()) {
IObject maybeObject = env.getLateObject();
if (maybeObject != null && maybeObject.getReflection().isInstanceOf(classEntity))
return ObjectInvokeHelper.invokeMethod(maybeObject, method, env, trace, args, true);
env.error(trace, ErrorType.E_STRICT, Messages.ERR_NON_STATIC_METHOD_CALLED_DYNAMICALLY, originClassName, originMethodName);
}
if (callCache != null && !isMagic) {
callCache.put(env, cacheIndex, method);
}
checkAccess(env, trace, method);
if (passed == null) {
passed = InvokeArgumentHelper.makeArguments(env, args, method.getParameters(), originClassName, originMethodName, originClassName, trace);
}
Memory result = method.getImmutableResultTyped(env, trace);
if (result != null) {
return result;
}
CallStack callStack = trace != null && method.isUsesStackTrace() ? env.getCallStack() : null;
try {
if (callStack != null) {
callStack.push(trace, (IObject) null, args, originMethodName, method.getClazz(), classEntity);
}
return method.invokeStatic(env, trace, passed);
} finally {
if (callStack != null) {
callStack.pop();
}
}
}
use of php.runtime.env.CallStack in project jphp by jphp-compiler.
the class ObjectInvokeHelper method invokeMethod.
public static Memory invokeMethod(Memory object, String methodName, String methodLowerName, Environment env, TraceInfo trace, Memory[] args) throws Throwable {
object = object.toValue();
Memory[] passed = null;
boolean doublePop = false;
if (object.type != Memory.Type.OBJECT) {
env.error(trace, ErrorType.E_RECOVERABLE_ERROR, Messages.ERR_CANNOT_CALL_OF_NON_OBJECT.fetch(methodName));
return Memory.NULL;
}
IObject iObject = ((ObjectMemory) object).value;
ClassEntity clazz = iObject.getReflection();
MethodEntity method;
if (methodName == null) {
method = clazz.methodMagicInvoke;
} else {
method = clazz.findMethod(methodLowerName);
if (method != null && method.isContextDepends()) {
ClassEntity context = env.getLastClassOnStack();
if (context != null) {
MethodEntity contextMethod = context.findMethod(methodLowerName);
if (contextMethod != null) {
method = contextMethod;
}
}
}
if (method == null && ((method = clazz.methodMagicCall) != null)) {
clazz.methodMagicCall.setModifier(Modifier.PUBLIC);
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);
Memory result = method.getImmutableResultTyped(env, trace);
if (passed == null) {
ParameterEntity[] parameters = method.getParameters(args == null ? 0 : args.length);
if (result != null && args == null && (parameters == null || parameters.length == 0)) {
return result;
}
passed = InvokeArgumentHelper.makeArguments(env, args, parameters, className, methodName, className, trace);
}
if (result != null) {
return result;
}
CallStack callStack = (trace == null || !method.isUsesStackTrace()) ? null : env.getCallStack();
try {
if (callStack != null) {
String staticClass = className;
if (iObject instanceof Closure) {
staticClass = ((Closure) iObject).getScope();
}
if (clazz.isHiddenInCallStack()) {
callStack.push(trace, iObject, args, methodName, staticClass, staticClass);
if (doublePop) {
callStack.push(trace, iObject, passed, method.getName(), staticClass, staticClass);
// env.pushCall(trace, iObject, passed, method.getName(), staticClass, staticClass);
}
} else {
callStack.push(trace, iObject, args, methodName, method.getClazz(), staticClass);
if (doublePop) {
callStack.push(trace, iObject, passed, method.getName(), method.getClazz(), staticClass);
// env.pushCallEx(trace, iObject, passed, method.getName(), method.getClazz(), staticClass);
}
}
}
return method.invokeDynamic(iObject, env, trace, passed);
} catch (NoClassDefFoundError e) {
throw new CriticalException("Unable to call method " + className + "::" + methodName + "(), " + e.getMessage());
} finally {
if (callStack != null) {
callStack.pop();
if (doublePop) {
callStack.pop();
// env.popCall();
}
}
}
}
Aggregations