use of php.runtime.lang.IObject in project jphp by jphp-compiler.
the class ClassesTest method testProperties.
@Test
public void testProperties() throws Throwable {
Memory memory;
memory = runDynamic("class A { var $x = 11, $y = 30; } return new A();", false);
Assert.assertTrue(memory.isObject());
IObject object = ((ObjectMemory) memory).value;
Assert.assertEquals(11, object.getReflection().getProperty(environment, null, object, "x", null, 0).toLong());
Assert.assertEquals(30, object.getReflection().getProperty(environment, null, object, "y", null, 0).toLong());
memory = runDynamic("class A { public $arr = array(1, 2, 3); } return new A()->arr;", false);
Assert.assertTrue(memory.isArray());
}
use of php.runtime.lang.IObject 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.lang.IObject in project jphp by jphp-compiler.
the class ObjectInvokeHelper method getProperty.
public static Memory getProperty(Memory object, String property, Environment env, TraceInfo trace, PropertyCallCache callCache, int cacheIndex) throws Throwable {
object = object.toValue();
if (!object.isObject()) {
env.error(trace, Messages.ERR_CANNOT_GET_PROPERTY_OF_NON_OBJECT.fetch(property));
return Memory.NULL;
}
IObject iObject = ((ObjectMemory) object).value;
return iObject.getReflection().getProperty(env, trace, iObject, property, callCache, cacheIndex);
}
use of php.runtime.lang.IObject in project jphp by jphp-compiler.
the class MemoryOperation method get.
@SuppressWarnings("unchecked")
public static MemoryOperation get(final Class<?> type, Type genericTypes, boolean includeParents) {
MemoryOperation operation = null;
if (genericTypes instanceof ParameterizedType) {
operation = genericOperations.get(new ParametrizedClass(type, ((ParameterizedType) genericTypes).getActualTypeArguments()));
}
if (operation == null) {
operation = operations.get(type);
if (operation == null) {
if (type.isArray()) {
MemoryOperation arrayMemoryOperation = new ArrayMemoryOperation(type);
register(arrayMemoryOperation);
return arrayMemoryOperation;
}
if (Enum.class.isAssignableFrom(type)) {
return new MemoryOperation() {
@Override
public Class<?>[] getOperationClasses() {
return new Class<?>[] { Enum.class };
}
@Override
@SuppressWarnings("unchecked")
public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
return arg.isNull() ? null : Enum.valueOf((Class<? extends Enum>) type, arg.toString());
}
@Override
public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
return arg == null ? Memory.NULL : StringMemory.valueOf(((Enum) arg).name());
}
@Override
public void applyTypeHinting(ParameterEntity parameter) {
parameter.setTypeEnum((Class<? extends Enum>) type);
}
};
}
final Class<? extends BaseWrapper> wrapperClass = wrappers.get(type);
if (wrapperClass != null) {
Constructor<BaseWrapper> constructor;
try {
constructor = (Constructor<BaseWrapper>) wrapperClass.getConstructor(Environment.class, type);
} catch (NoSuchMethodException e) {
try {
constructor = (Constructor<BaseWrapper>) wrapperClass.getConstructor(Environment.class, Object.class);
} catch (NoSuchMethodException e1) {
throw new CriticalException(e);
}
}
final Constructor<BaseWrapper> finalConstructor = constructor;
return new MemoryOperation() {
@Override
public Class<?>[] getOperationClasses() {
return new Class<?>[0];
}
@Override
public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
if (arg.isNull()) {
return null;
}
return arg.toObject(BaseWrapper.class).getWrappedObject();
}
@Override
public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
if (arg == null) {
return Memory.NULL;
}
Constructor<BaseWrapper> constructorContext = finalConstructor;
Class<? extends BaseWrapper> wrapperClassContext = wrapperClass;
if (arg.getClass() != type) {
wrapperClassContext = wrappers.get(arg.getClass());
}
if (wrapperClassContext != null && wrapperClassContext != wrapperClass) {
constructorContext = (Constructor<BaseWrapper>) wrapperClassContext.getConstructor(Environment.class, arg.getClass());
}
try {
BaseWrapper instance = constructorContext.newInstance(env, arg);
return ObjectMemory.valueOf(instance.__getOriginInstance());
} catch (InstantiationException | IllegalAccessException | InvocationTargetException e) {
throw new CriticalException(e);
}
}
@Override
public void applyTypeHinting(ParameterEntity parameter) {
parameter.setTypeNativeClass(type);
}
};
} else if (IObject.class.isAssignableFrom(type)) {
return new MemoryOperation() {
@Override
public Class<?>[] getOperationClasses() {
return new Class<?>[] { IObject.class };
}
@Override
@SuppressWarnings("unchecked")
public Object convert(Environment env, TraceInfo trace, Memory arg) throws Throwable {
if (arg.isNull()) {
return null;
}
return arg.toObject((Class<? extends IObject>) type);
}
@Override
public Memory unconvert(Environment env, TraceInfo trace, Object arg) throws Throwable {
if (arg == null) {
return Memory.NULL;
}
return ObjectMemory.valueOf((IObject) arg);
}
@Override
public void applyTypeHinting(ParameterEntity parameter) {
parameter.setType(ReflectionUtils.getClassName(type));
}
};
} else {
Class<?> superType = type.getSuperclass();
if (Object.class != superType && (includeParents || type.isAnonymousClass())) {
return get(superType, type.getGenericSuperclass(), includeParents);
}
}
}
}
if (operation == null) {
return null;
}
if (genericTypes instanceof ParameterizedType) {
return operation.instance(((ParameterizedType) genericTypes).getActualTypeArguments());
}
return operation;
}
use of php.runtime.lang.IObject in project jphp by jphp-compiler.
the class PropertyEntity method getValue.
public Memory getValue(Environment env, TraceInfo trace, Object object) throws Throwable {
if (getter != null && object instanceof IObject) {
return ObjectInvokeHelper.invokeMethod((IObject) object, getter, env, trace, null, false);
}
ArrayMemory props = ((IObject) object).getProperties();
Memory result = props.getByScalar(specificName);
if (result == null) {
result = props.getByScalar(name);
}
return result;
}
Aggregations