use of php.runtime.reflection.ClassEntity in project jphp by jphp-compiler.
the class ObjectMemory method toString.
@Override
public String toString() {
ClassEntity entity = value.getReflection();
if (entity.methodMagicToString != null) {
Environment env = value.getEnvironment();
if (env == null)
return "Object";
// We can't get real trace info from toString method :(
env.pushCall(entity.methodMagicToString.getTrace(), value, null, entity.methodMagicToString.getName(), entity.getName(), null);
try {
Memory result = entity.methodMagicToString.invokeDynamic(value, env, (Memory[]) null);
if (!result.isString()) {
env.error(ErrorType.E_RECOVERABLE_ERROR, "Method %s must return a string value", entity.methodMagicToString.getSignatureString(false));
return "";
}
return result.toString();
} catch (RuntimeException e) {
throw e;
} catch (Throwable e) {
throw new RuntimeException(e);
} finally {
env.popCall();
}
} else
return "Object";
}
use of php.runtime.reflection.ClassEntity in project jphp by jphp-compiler.
the class ObjectMemory method manualUnset.
@Override
public void manualUnset(Environment env) {
ClassEntity entity = value.getReflection();
if (entity.methodDestruct != null) {
if (!value.isFinalized()) {
value.doFinalize();
env.pushCall(value, entity.methodDestruct.getName());
try {
if (value instanceof IManualDestructable) {
((IManualDestructable) value).onManualDestruct(env);
}
entity.methodDestruct.invokeDynamic(value, env);
} catch (InvocationTargetException e) {
env.__throwException(e);
} catch (RuntimeException e) {
throw e;
} catch (Throwable throwable) {
throw new CriticalException(throwable);
} finally {
env.popCall();
}
}
}
}
use of php.runtime.reflection.ClassEntity in project jphp by jphp-compiler.
the class ObjectMemory method getNewIterator.
@Override
public ForeachIterator getNewIterator(final Environment env, boolean getReferences, boolean getKeyReferences) {
if (value instanceof IteratorAggregate) {
return env.invokeMethodNoThrow(value, "getIterator").getNewIterator(env, getReferences, getKeyReferences);
} else if (value instanceof Iterator) {
final Iterator iterator = (Iterator) value;
final String className = value.getReflection().getName();
final boolean isNative = value.getReflection().isInternal();
return new ForeachIterator(getReferences, getKeyReferences, false) {
private boolean keyInit = false;
private boolean needNext = false;
private boolean rewind = false;
@Override
public void reset() {
rewind();
}
@Override
protected boolean init() {
return rewind();
}
protected boolean rewind() {
if (getReferences && value instanceof Generator) {
if (!((Generator) value).isReturnReferences()) {
env.exception(trace, "You can only iterate a generator by-reference if it declared that it yields by-reference");
}
}
if (!rewind) {
if (!isNative)
env.pushCall(trace, ObjectMemory.this.value, null, "rewind", className, null);
try {
return iterator.rewind(env).toValue() != FALSE;
} finally {
rewind = true;
if (!isNative)
env.popCall();
}
}
return true;
}
@Override
protected boolean prevValue() {
return false;
}
@Override
protected boolean nextValue() {
return true;
}
@Override
public boolean next() {
if (!rewind())
return false;
boolean valid = false;
keyInit = false;
if (needNext) {
if (!isNative)
env.pushCall(trace, ObjectMemory.this.value, null, "next", className, null);
try {
iterator.next(env);
} finally {
if (!isNative)
env.popCall();
}
}
needNext = true;
if (!isNative)
env.pushCall(trace, ObjectMemory.this.value, null, "valid", className, null);
try {
valid = iterator.valid(env).toBoolean();
if (valid) {
if (!isNative)
env.pushCall(trace, ObjectMemory.this.value, null, "current", className, null);
try {
currentValue = iterator.current(env);
if (!getReferences)
currentValue = currentValue.toImmutable();
} finally {
if (!isNative)
env.popCall();
}
} else {
rewind = false;
}
} finally {
if (!isNative)
env.popCall();
}
return valid;
}
@Override
public Object getKey() {
return getMemoryKey();
}
@Override
public Memory getMemoryKey() {
if (keyInit)
return (Memory) currentKey;
if (!isNative)
env.pushCall(trace, ObjectMemory.this.value, null, "key", className, null);
try {
currentKey = iterator.key(env).toImmutable();
keyInit = true;
return (Memory) currentKey;
} finally {
if (!isNative)
env.popCall();
}
}
};
} else if (value instanceof Traversable) {
return ((Traversable) value).getNewIterator(env, getReferences, getKeyReferences);
} else {
return new ForeachIterator(getReferences, getKeyReferences, false) {
private ForeachIterator child;
private ClassEntity reflection;
private ClassEntity context;
@Override
protected boolean init() {
context = env.getLastClassOnStack();
reflection = value.getReflection();
child = value.getProperties().foreachIterator(getReferences, getKeyReferences);
return true;
}
@Override
public void reset() {
child.reset();
}
@Override
protected boolean nextValue() {
while (true) {
if (!child.next())
return false;
Object key = child.getKey();
if (key instanceof String) {
String keyS = (String) key;
int pos = keyS.lastIndexOf('\0');
if (pos > -1)
keyS = keyS.substring(pos + 1);
PropertyEntity entity = reflection.isInstanceOf(context) ? context.properties.get(keyS) : reflection.properties.get(keyS);
int accessFlag = entity == null ? 0 : entity.canAccess(env);
if (accessFlag == 0) {
currentKey = entity == null ? keyS : entity.getName();
break;
} else
continue;
}
break;
}
//currentKey = child.getKey();
currentValue = child.getValue();
return true;
}
@Override
protected boolean prevValue() {
return false;
}
};
}
}
use of php.runtime.reflection.ClassEntity in project jphp by jphp-compiler.
the class ObjectMemory method toArray.
@Override
public Memory toArray() {
ArrayMemory result = new ArrayMemory();
ArrayMemory props = value.getProperties();
ForeachIterator iterator = props == null ? null : props.foreachIterator(false, false);
if (iterator == null) {
return new ArrayMemory().toConstant();
}
ClassEntity reflection = value.getReflection();
while (iterator.next()) {
Object key = iterator.getKey();
Memory value = iterator.getValue().toImmutable();
if (key instanceof String) {
String keyS = (String) key;
PropertyEntity prop = reflection.properties.get(keyS);
if (prop == null || prop.getModifier() == Modifier.PUBLIC) {
result.refOfIndex(keyS).assign(iterator.getValue().toImmutable());
} else {
if (prop.getModifier() == Modifier.PROTECTED) {
result.refOfIndex("\0*\0" + keyS).assign(value);
} else {
result.refOfIndex("\0" + prop.getClazz().getName() + "\0" + keyS).assign(value);
}
}
} else {
result.refOfIndex(null, iterator.getMemoryKey()).assign(value);
}
}
return result.toConstant();
}
use of php.runtime.reflection.ClassEntity in project jphp by jphp-compiler.
the class ModuleDumper method save.
@Override
public void save(ModuleEntity entity, OutputStream output) throws IOException {
if (entity.getData() == null)
throw new DumpException("Module '" + entity.getName() + "' not compiled");
DumpOutputStream data = new DumpOutputStream(output);
// version
data.writeInt(DUMP_STAMP);
data.writeInt(DUMP_VERSION);
// legacy code.
data.writeEnum(LangMode.DEFAULT);
// module name
data.writeName(entity.getContext().getModuleName());
data.writeName(entity.getInternalName());
// trace
data.writeTrace(entity.getTrace());
// constants
data.writeInt(entity.getConstants().size());
for (ConstantEntity e : entity.getConstants()) {
constantDumper.save(e, output);
}
// closures
data.writeInt(entity.getClosures().size());
for (ClosureEntity e : entity.getClosures()) {
closureDumper.save(e, output);
}
// generators
data.writeInt(entity.getGenerators().size());
for (GeneratorEntity e : entity.getGenerators()) {
generatorDumper.save(e, output);
}
// functions
data.writeInt(entity.getFunctions().size());
for (FunctionEntity e : entity.getFunctions()) {
functionDumper.save(e, output);
}
// classes
data.writeInt(entity.getClasses().size());
for (ClassEntity e : entity.getClasses()) {
classDumper.save(e, output);
}
if (includeData) {
// byte code
data.writeInt(entity.getData().length);
data.write(entity.getData());
} else {
data.writeInt(0);
}
// 5 mb
data.writeRawData(null, 1024 * 1024 * 5);
}
Aggregations