package php.runtime.ext.core;
import php.runtime.Memory;
import php.runtime.annotation.Reflection;
import php.runtime.annotation.Runtime;
import php.runtime.common.AbstractCompiler;
import php.runtime.common.GrammarUtils;
import php.runtime.common.LangMode;
import php.runtime.env.*;
import php.runtime.env.handler.ErrorHandler;
import php.runtime.env.handler.ExceptionHandler;
import php.runtime.env.handler.ShutdownHandler;
import php.runtime.env.message.SystemMessage;
import php.runtime.exceptions.ParseException;
import php.runtime.exceptions.support.ErrorException;
import php.runtime.exceptions.support.ErrorType;
import php.runtime.ext.core.classes.util.WrapFlow;
import php.runtime.ext.support.compile.FunctionsContainer;
import php.runtime.invoke.Invoker;
import php.runtime.lang.Closure;
import php.runtime.lang.ForeachIterator;
import php.runtime.lang.IObject;
import php.runtime.lang.Resource;
import php.runtime.memory.ArrayMemory;
import php.runtime.memory.LongMemory;
import php.runtime.memory.ObjectMemory;
import php.runtime.memory.StringMemory;
import php.runtime.reflection.*;
import php.runtime.util.StackTracer;
public class LangFunctions extends FunctionsContainer {
private static String evalErrorMessage(ErrorException e){
return e.getMessage() + ", eval()'s code on line " + (e.getTraceInfo().getStartLine() + 1)
+ ", position " + (e.getTraceInfo().getStartPosition() + 1);
}
public static Memory eval(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals, String code)
throws Throwable {
try {
return env.eval(code, locals);
} catch (ErrorException e){
if (e.getType() == ErrorType.E_PARSE){
if (env.isHandleErrors(ErrorType.E_PARSE))
throw new ParseException(evalErrorMessage(e), trace);
} else
env.error(trace, e.getType(), evalErrorMessage(e));
}
return Memory.FALSE;
}
public static Memory time() {
return LongMemory.valueOf(System.currentTimeMillis() / 1000);
}
public static void sleep(int sec) throws InterruptedException {
Thread.sleep(sec * 1000);
}
public static void usleep(long microsec) throws InterruptedException {
Thread.sleep(microsec / 1000);
}
public static boolean time_nanosleep(long second, int nanosecond) throws InterruptedException {
Thread.sleep(second * 1000, nanosecond);
return true;
}
public static boolean time_sleep_until(double time) throws InterruptedException {
long now = System.currentTimeMillis();
long to = (long) (time * 1000);
long diff = to - now;
if (diff >= 0) {
Thread.sleep(diff);
return true;
} else {
return false;
}
}
public static Memory compact(@Runtime.GetLocals ArrayMemory locals, Memory varName, Memory... varNames) {
ArrayMemory result = new ArrayMemory();
Memory value = locals.valueOfIndex(varName).toValue();
if (value != Memory.UNDEFINED)
result.refOfIndex(varName).assign(value.toImmutable());
if (varNames != null) {
for (Memory el : varNames) {
value = locals.valueOfIndex(el).toValue();
if (value != Memory.UNDEFINED)
result.refOfIndex(el).assign(value.toImmutable());
}
}
return result.toImmutable();
}
public static void register_shutdown_function(Environment env, TraceInfo trace, @Runtime.Reference Memory handler,
Memory... args) {
Invoker invoker = expectingCallback(env, trace, 1, handler);
if (invoker != null)
env.registerShutdownFunction(new ShutdownHandler(invoker, args));
}
public static int error_reporting(Environment env, int level) {
int old = env.getErrorFlags();
env.setErrorFlags(level);
return old;
}
public static int error_reporting(Environment env) {
return env.getErrorFlags();
}
public static Memory error_get_last(Environment env) {
SystemMessage err = env.getLastMessage();
if (err == null)
return Memory.NULL;
ArrayMemory result = new ArrayMemory();
result.refOfIndex("type").assign(err.getType().value);
result.refOfIndex("message").assign(err.getMessage());
if (err.getTrace() != null && err.getTrace().trace != null) {
result.refOfIndex("file").assign(err.getTrace().trace.getFileName());
result.refOfIndex("line").assign(err.getTrace().trace.getStartLine() + 1);
result.refOfIndex("position").assign(err.getTrace().trace.getStartPosition() + 1);
}
return result.toConstant();
}
public static boolean trigger_error(Environment env, TraceInfo trace, String message, int type) {
ErrorType _type = ErrorType.valueOf(type);
if (_type == null)
return false;
env.error(trace, _type, message);
return true;
}
public static boolean user_error(Environment env, TraceInfo trace, String message, int type) {
return trigger_error(env, trace, message, type);
}
public static boolean trigger_error(Environment env, TraceInfo trace, String message) {
return trigger_error(env, trace, message, ErrorType.E_USER_NOTICE.value);
}
public static boolean user_error(Environment env, TraceInfo trace, String message) {
return trigger_error(env, trace, message);
}
public static Memory set_error_handler(Environment env, TraceInfo trace, @Runtime.Reference Memory handler,
int flags) {
Invoker invoker = expectingCallback(env, trace, 1, handler);
if (invoker != null) {
ErrorHandler last = env.getErrorHandler();
env.setErrorHandler(new ErrorHandler(invoker, handler.toImmutable(), flags));
return last == null ? Memory.NULL : last.invokerMemory;
} else
return Memory.FALSE;
}
public static Memory set_error_handler(Environment env, TraceInfo trace, @Runtime.Reference Memory handler) {
return set_error_handler(env, trace, handler, ErrorType.E_ALL.value | ErrorType.E_STRICT.value);
}
public static boolean restore_error_handler(Environment env) {
env.setErrorHandler(env.getPreviousErrorHandler());
return true;
}
public static Memory set_exception_handler(Environment env, TraceInfo trace, @Runtime.Reference Memory handler) {
Invoker invoker = expectingCallback(env, trace, 1, handler);
if (invoker != null) {
ExceptionHandler eh = env.getExceptionHandler();
env.setExceptionHandler(new ExceptionHandler(invoker, handler.toImmutable()));
return eh == null || eh.invoker == null ? Memory.NULL : eh.invokerMemory;
} else
return Memory.FALSE;
}
public static boolean restore_exception_handler(Environment env) {
env.setExceptionHandler(env.getPreviousExceptionHandler());
return true;
}
public static Memory get_defined_vars(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals) {
return locals.toImmutable();
}
public static int extract(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals,
@Runtime.Reference Memory array, int extractType) {
return extract(env, trace, locals, array, extractType, Memory.NULL);
}
public static int extract(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals,
@Runtime.Reference Memory array) {
return extract(env, trace, locals, array, LangConstants.EXTR_OVERWRITE, Memory.NULL);
}
public static int extract(Environment env, TraceInfo trace, @Runtime.GetLocals ArrayMemory locals,
@Runtime.Reference Memory array, int extractType, Memory _prefix) {
if (expecting(env, trace, 1, array, Memory.Type.ARRAY)) {
boolean isRefs = (extractType & LangConstants.EXTR_REFS) == LangConstants.EXTR_REFS;
ForeachIterator iterator = array.getNewIterator(env, isRefs, false);
int count = 0;
if (extractType == LangConstants.EXTR_PREFIX_ALL || extractType == LangConstants.EXTR_PREFIX_IF_EXISTS
|| extractType == LangConstants.EXTR_PREFIX_INVALID || extractType == LangConstants.EXTR_PREFIX_SAME)
if (_prefix.isNull()) {
env.warning(trace, "extract(): specified extract type requires the prefix parameter");
return 0;
}
String prefix = _prefix.isNull() ? "" : _prefix.concat("_");
if (!prefix.isEmpty())
if (!GrammarUtils.isValidName(prefix)) {
env.warning(trace, "extract(): prefix is not a valid identifier");
return 0;
}
while (iterator.next()) {
Object key = iterator.getKey();
String keyS = key.toString();
String var;
Memory value = iterator.getValue();
if (!isRefs)
value = value.toImmutable();
switch (extractType) {
case LangConstants.EXTR_OVERWRITE:
if (GrammarUtils.isValidName(keyS)) {
locals.refOfIndex(keyS).assign(value);
count++;
}
break;
case LangConstants.EXTR_SKIP:
if (GrammarUtils.isValidName(keyS) && locals.valueOfIndex(keyS).isUndefined()) {
locals.refOfIndex(keyS).assign(value);
count++;
}
break;
case LangConstants.EXTR_PREFIX_SAME:
if (!locals.valueOfIndex(keyS).isUndefined()) {
var = prefix.concat(keyS);
if (GrammarUtils.isValidName(var)) {
locals.refOfIndex(var).assign(value);
count++;
}
} else if (GrammarUtils.isValidName(keyS)) {
locals.refOfIndex(keyS).assign(value);
count++;
}
break;
case LangConstants.EXTR_PREFIX_ALL:
var = prefix.concat(keyS);
if (GrammarUtils.isValidName(var)) {
locals.refOfIndex(prefix.concat(keyS)).assign(value);
count++;
}
break;
case LangConstants.EXTR_PREFIX_INVALID:
if (GrammarUtils.isValidName(keyS)) {
locals.refOfIndex(keyS).assign(value);
count++;
} else {
var = prefix.concat(keyS);
if (GrammarUtils.isValidName(var)) {
locals.refOfIndex(var).assign(value);
count++;
}
}
break;
case LangConstants.EXTR_IF_EXISTS:
if (GrammarUtils.isValidName(keyS))
if (!locals.valueOfIndex(keyS).isUndefined()) {
locals.refOfIndex(keyS).assign(value);
count++;
}
break;
case LangConstants.EXTR_PREFIX_IF_EXISTS:
if (!locals.valueOfIndex(keyS).isUndefined()) {
var = prefix.concat(keyS);
if (GrammarUtils.isValidName(var)) {
locals.refOfIndex(var).assign(value);
count++;
}
}
break;
}
}
return count;
} else
return 0;
}
public static boolean defined(Environment env, String name) {
Memory value = env.findConstant(name);
return value != null;
}
public static boolean define(Environment env, TraceInfo trace, String name, Memory value, boolean caseInSentisise) {
return env.defineConstant(name, value, !caseInSentisise);
}
public static boolean define(Environment env, TraceInfo trace, String name, Memory value) {
return define(env, trace, name, value, false);
}
public static Memory constant(Environment env, TraceInfo trace, String name) {
int pos;
if ((pos = name.indexOf("::")) > -1) {
String className = name.substring(0, pos);
String constName = name.substring(pos + 2);
ClassEntity entity = env.fetchClass(className, true);
if (entity == null)
return Memory.NULL;
ConstantEntity constant = entity.findConstant(constName);
return constant == null ? Memory.NULL : constant.getValue();
} else {
Memory value = env.findConstant(name);
if (value == null)
return Memory.NULL;
else
return value;
}
}
@Runtime.Immutable
public static String gettype(Memory memory) {
switch (memory.getRealType()) {
case ARRAY:
return "array";
case BOOL:
return "boolean";
case INT:
return "integer";
case DOUBLE:
return "double";
case STRING:
return "string";
case OBJECT:
if (memory.isResource())
return "resource";
return "object";
case NULL:
return "NULL";
default:
return "unknown type";
}
}
public static boolean is_array(@Runtime.Reference Memory memory) {
return memory.isArray();
}
@Runtime.Immutable
public static boolean is_bool(Memory memory) {
return memory.toValue().type == Memory.Type.BOOL;
}
@Runtime.Immutable
public static boolean is_double(Memory memory) {
return memory.toValue().type == Memory.Type.DOUBLE;
}
@Runtime.Immutable
public static boolean is_float(Memory memory) {
return memory.toValue().type == Memory.Type.DOUBLE;
}
@Runtime.Immutable
public static boolean is_int(Memory memory) {
return memory.toValue().type == Memory.Type.INT;
}
@Runtime.Immutable
public static boolean is_integer(Memory memory) {
return memory.toValue().type == Memory.Type.INT;
}
@Runtime.Immutable
public static boolean is_long(Memory memory) {
return memory.toValue().type == Memory.Type.INT;
}
@Runtime.Immutable
public static boolean is_null(Memory memory) {
return memory.isNull();
}
public static boolean is_object(@Runtime.Reference Memory memory) {
return memory.isObject();
}
@Runtime.Immutable
public static boolean is_real(Memory memory) {
return is_float(memory);
}
@Runtime.Immutable
public static boolean is_string(Memory memory) {
return memory.isString();
}
@Runtime.Immutable
public static boolean is_numeric(Memory memory) {
return StringMemory.toNumeric(memory.toString(), false, null) != null;
}
@Runtime.Immutable
public static boolean is_scalar(Memory memory) {
switch (memory.getRealType()) {
case BOOL:
case NULL:
case INT:
case DOUBLE:
case STRING:
return true;
}
return false;
}
public static boolean is_resource(@Runtime.Reference Memory memory) {
return memory.isResource();
}
public static Memory get_resource_type(@Runtime.Reference Memory memory) {
if (memory.isObject()) {
if (((ObjectMemory) memory).value instanceof Resource)
return new StringMemory(
((Resource) ((ObjectMemory) memory).value).getResourceType()
);
}
return Memory.NULL;
}
public static boolean is_callable(Environment env, TraceInfo trace, @Runtime.Reference Memory memory)
throws Throwable {
// optimize
if (memory.isObject() && memory.toValue(ObjectMemory.class).value instanceof Closure)
return true;
Invoker invoker = Invoker.valueOf(env, null, memory);
return invoker != null && invoker.canAccess(env) == 0;
}
@Runtime.Immutable
public static boolean boolval(Memory memory) {
return memory.toBoolean();
}
@Runtime.Immutable
public static String strval(Memory memory) {
return memory.toString();
}
@Runtime.Immutable
public static long intval(Memory memory) {
return memory.toLong();
}
@Runtime.Immutable
public static double floatval(Memory memory) {
return memory.toDouble();
}
@Runtime.Immutable
public static double doubleval(Memory memory) {
return memory.toDouble();
}
public static boolean settype(@Runtime.Reference Memory memory, String type) {
if (memory.isReference()) {
if ("string".equals(type)) {
memory.assign(memory.toString());
} else if ("bool".equals(type) || "boolean".equals(type)) {
memory.assign(memory.toBoolean());
} else if ("int".equals(type) || "integer".equals(type)) {
memory.assign(memory.toLong());
} else if ("float".equals(type) || "double".equals(type)) {
memory.assign(memory.toDouble());
} else if ("null".equals(type)) {
memory.assign(Memory.NULL);
} else
return false;
return true;
}
return false;
}
public void debug_zval_dump(Environment env, TraceInfo trace) {
env.warning(trace, "debug_zval_dump(): unsupported");
}
public static Memory func_get_args(Environment env, TraceInfo trace) {
if (env.getCallStackTop() == 0) {
return Memory.FALSE;
}
return ArrayMemory.of(env.peekCall(0).args);
}
public static Memory func_num_args(Environment env, TraceInfo trace) {
if (env.getCallStackTop() == 0) {
return Memory.FALSE;
}
return LongMemory.valueOf(env.peekCall(0).args.length);
}
public static Memory func_get_arg(Environment env, TraceInfo trace, int argNum) {
if (env.getCallStackTop() == 0) {
return Memory.FALSE;
}
if (argNum < 0)
return Memory.FALSE;
Memory[] args = env.peekCall(0).args;
if (argNum < args.length)
return args[argNum];
else
return Memory.FALSE;
}
private static Memory _call_user_func(Environment env, TraceInfo trace, Memory function, Memory... args)
throws Throwable {
Invoker invoker = expectingCallback(env, trace, 1, function);
if (invoker == null) {
return Memory.FALSE;
}
invoker.setTrace(trace);
return invoker.call(args);
}
public static Memory call_user_func(Environment env, TraceInfo trace, Memory function, Memory... args)
throws Throwable {
Memory[] passed;
if (args == null) {
passed = new Memory[]{function};
} else {
passed = new Memory[args.length + 1];
System.arraycopy(args, 0, passed, 1, args.length);
passed[0] = function;
}
env.pushCall(trace, null, passed, "call_user_func", null, null);
try {
return _call_user_func(env, trace, function, args);
} finally {
env.popCall();
}
}
public static Memory call_user_func_array(Environment env, TraceInfo trace, Memory function, Memory args)
throws Throwable {
if (expecting(env, trace, 2, args, Memory.Type.ARRAY)) {
Memory[] passed = new Memory[]{function, args};
env.pushCall(trace, null, passed, "call_user_func_array", null, null);
try {
return _call_user_func(env, trace, function, ((ArrayMemory) args).values(false));
} finally {
env.popCall();
}
}
return Memory.FALSE;
}
public static Memory debug_backtrace(Environment env, TraceInfo trace, int options, int limit) {
boolean provideObject = (options & LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT)
== LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT;
boolean ignoreArgs = (options & LangConstants.DEBUG_BACKTRACE_IGNORE_ARGS)
== LangConstants.DEBUG_BACKTRACE_IGNORE_ARGS;
ArrayMemory result = new ArrayMemory();
for (int i = 0; i < env.getCallStackTop(); i++) {
if (limit != 0 && i >= limit)
break;
CallStackItem item = env.peekCall(i);
ArrayMemory el = item.toArray(provideObject, ignoreArgs);
result.add(el);
}
return result.toConstant();
}
public static Memory debug_backtrace(Environment env, TraceInfo trace, int options) {
return debug_backtrace(env, trace, options, 0);
}
public static Memory debug_backtrace(Environment env, TraceInfo trace) {
return debug_backtrace(env, trace, LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT, 0);
}
public static void debug_print_backtrace(Environment env, TraceInfo trace, int options, int limit) {
boolean provideObject = (options & LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT)
== LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT;
boolean ignoreArgs = (options & LangConstants.DEBUG_BACKTRACE_IGNORE_ARGS)
== LangConstants.DEBUG_BACKTRACE_IGNORE_ARGS;
StackTracer stackTracer = new StackTracer(env, limit);
env.echo(stackTracer.toString(!ignoreArgs));
}
public static void debug_print_backtrace(Environment env, TraceInfo trace, int options) {
debug_print_backtrace(env, trace, options, 0);
}
public static void debug_print_backtrace(Environment env, TraceInfo trace) {
debug_print_backtrace(env, trace, LangConstants.DEBUG_BACKTRACE_PROVIDE_OBJECT, 0);
}
public static boolean function_exists(Environment env, String name) {
FunctionEntity function = env.fetchFunction(name);
return function != null;
}
public static boolean class_exists(Environment env, String name, boolean autoload) {
ClassEntity entity = env.fetchClass(name, autoload);
return entity != null && entity.isClass();
}
public static boolean class_exists(Environment env, String name) {
return class_exists(env, name, true);
}
public static boolean interface_exists(Environment env, String name, boolean autoload) {
ClassEntity entity = env.fetchClass(name, autoload);
return entity != null && entity.isInterface();
}
public static boolean interface_exists(Environment env, String name) {
return interface_exists(env, name, true);
}
public static boolean trait_exists(Environment env, String name, boolean autoload) {
ClassEntity entity = env.fetchClass(name, autoload);
return entity != null && entity.isTrait();
}
public static boolean trait_exists(Environment env, String name) {
return trait_exists(env, name, true);
}
public static boolean method_exists(Environment env, Memory clazz, String method) {
ClassEntity classEntity;
if (clazz.isObject()) {
ObjectMemory tmp = clazz.toValue(ObjectMemory.class);
classEntity = tmp.getReflection();
} else {
String name = clazz.toString();
String nameL = name.toLowerCase();
classEntity = env.fetchClass(name, nameL, true);
if (classEntity == null)
classEntity = env.fetchMagicClass(name, nameL);
}
return classEntity != null && classEntity.findMethod(method.toLowerCase()) != null;
}
public static Memory property_exists(Environment env, Memory clazz, String property) throws Throwable {
ClassEntity classEntity;
IObject object = null;
boolean isMagic = false;
if (clazz.isObject()) {
ObjectMemory tmp = clazz.toValue(ObjectMemory.class);
classEntity = tmp.getReflection();
object = tmp.value;
} else {
String name = clazz.toString();
String nameL = name.toLowerCase();
classEntity = env.fetchClass(name, nameL, true);
if (classEntity == null) {
classEntity = env.fetchMagicClass(name, nameL);
isMagic = true;
}
}
if (classEntity == null) {
return Memory.FALSE;
}
if (object != null) {
ArrayMemory props = object.getProperties();
ClassEntity context = env.getLastClassOnStack();
PropertyEntity entity = classEntity.isInstanceOf(context)
? context.properties.get(property) : classEntity.properties.get(property);
int accessFlags = entity == null ? 0 : entity.canAccess(env);
if (accessFlags != 0)
return Memory.FALSE;
return (props != null && props.getByScalar(entity == null ? property : entity.getSpecificName()) != null)
? Memory.TRUE : Memory.FALSE;
} else {
PropertyEntity entity = classEntity.properties.get(property);
if (isMagic) {
int accessFlags = entity == null ? 0 : entity.canAccess(env);
if (accessFlags != 0)
return Memory.FALSE;
}
return entity != null ? Memory.TRUE : Memory.FALSE;
}
}
public static Memory is_a(Environment env, TraceInfo trace, Memory object, String className,
boolean allowedString) {
ClassEntity classEntity = null;
ClassEntity parentClass;
if (allowedString && !object.isObject()) {
String name = object.toString();
String nameL = name.toLowerCase();
classEntity = env.fetchClass(name, nameL, false);
if (classEntity == null)
classEntity = env.fetchMagicClass(name, nameL);
} else if (expecting(env, trace, 1, object, Memory.Type.OBJECT)) {
classEntity = object.toValue(ObjectMemory.class).getReflection();
}
if (classEntity == null)
return Memory.FALSE;
parentClass = env.fetchClass(className, false);
if (parentClass == null)
return Memory.FALSE;
return classEntity.isInstanceOf(parentClass) ? Memory.TRUE : Memory.FALSE;
}
public static Memory is_a(Environment env, TraceInfo trace, Memory object, String className) {
return is_a(env, trace, object, className, false);
}
public static Memory is_subclass_of(Environment env, TraceInfo trace, Memory object, String className,
boolean allowedString) {
ClassEntity classEntity = null;
ClassEntity parentClass;
if (allowedString && !object.isObject()) {
String name = object.toString();
String nameL = name.toLowerCase();
classEntity = env.fetchClass(name, nameL, true);
if (classEntity == null)
classEntity = env.fetchMagicClass(name, nameL);
} else if (expecting(env, trace, 1, object, Memory.Type.OBJECT)) {
classEntity = object.toValue(ObjectMemory.class).getReflection();
}
parentClass = env.fetchClass(className, true);
if (classEntity == null) {
return Memory.NULL;
} else if (parentClass == null) {
return Memory.NULL;
} else {
if (object.isObject() && object.toValue(ObjectMemory.class).value instanceof Closure)
return Memory.FALSE;
return classEntity.isInstanceOf(parentClass)
&& !classEntity.equals(parentClass) ? Memory.TRUE : Memory.FALSE;
}
}
public static Memory is_subclass_of(Environment env, TraceInfo trace, Memory object, String className) {
return is_subclass_of(env, trace, object, className, true);
}
public static Memory get_class(Environment env, TraceInfo trace, Memory object) {
if (object.isNull()) {
if (object == Memory.UNDEFINED) {
return Memory.FALSE;
}
CallStackItem item = env.peekCall(0);
if (item.clazz != null) {
if (item.classEntity == null)
item.classEntity = env.fetchClass(item.clazz, false);
if (item.classEntity == null)
return Memory.FALSE;
else {
MethodEntity method = item.classEntity.findMethod(item.function);
if (method == null)
return Memory.FALSE;
return new StringMemory(method.getClazz().getName());
}
}
} else if (expecting(env, trace, 1, object, Memory.Type.OBJECT)) {
return new StringMemory(object.toValue(ObjectMemory.class).getReflection().getName());
}
return Memory.FALSE;
}
public static Memory get_class(Environment env, TraceInfo trace) {
return get_class(env, trace, Memory.NULL);
}
public static Memory get_called_class(Environment env) {
String name = env.getLateStatic();
return name == null || name.isEmpty() ? Memory.FALSE : new StringMemory(name);
}
public static Memory get_class_methods(Environment env, TraceInfo trace, Memory value) {
ClassEntity entity;
if (value.isString()) {
entity = env.fetchClass(value.toString(), true);
} else if (value.isObject()) {
entity = value.toValue(ObjectMemory.class).getReflection();
} else {
env.warning(
trace, "get_class_methods(): Argument 1 must be string or object, %s given",
value.getRealType().toString()
);
return Memory.NULL;
}
if (entity == null)
return Memory.NULL;
ClassEntity context = env.getLastClassOnStack();
ArrayMemory result = new ArrayMemory();
for (MethodEntity el : entity.getMethods().values()) {
if (el.canAccess(env, context) == 0)
result.refOfPush().assign(el.getName());
}
return result.toConstant();
}
public static Memory get_class_vars(Environment env, TraceInfo trace, Memory value) {
ClassEntity entity;
if (value.isString()) {
entity = env.fetchClass(value.toString(), true);
} else if (value.isObject()) {
entity = value.toValue(ObjectMemory.class).getReflection();
} else {
env.warning(
trace, "get_class_vars(): Argument 1 must be string or object, %s given",
value.getRealType().toString()
);
return Memory.NULL;
}
if (entity == null)
return Memory.NULL;
ClassEntity context = env.getLastClassOnStack();
ArrayMemory result = new ArrayMemory();
for (PropertyEntity el : entity.getProperties()) {
if (el.canAccess(env, context) == 0)
result.refOfIndex(el.getName()).assign(el.getDefaultValue(env));
}
for (PropertyEntity el : entity.getStaticProperties()) {
if (el.canAccess(env, context) == 0)
result.refOfIndex(el.getName()).assign(el.getDefaultValue(env));
}
return result.toConstant();
}
public static Memory get_object_vars(Environment env, TraceInfo trace, Memory object) {
if (expecting(env, trace, 1, object, Memory.Type.OBJECT)) {
ObjectMemory o = object.toValue(ObjectMemory.class);
ArrayMemory props = o.value.getProperties();
ClassEntity entity = o.getReflection();
ClassEntity context = env.getLastClassOnStack();
ForeachIterator iterator = props.foreachIterator(false, false);
ArrayMemory result = new ArrayMemory();
while (iterator.next()) {
PropertyEntity prop = entity.findProperty(iterator.getKey().toString());
if (prop == null || prop.canAccess(env, context) == 0)
result.refOfIndex(prop == null ? iterator.getKey().toString() : prop.getName())
.assign(iterator.getValue());
}
return result.toConstant();
} else
return Memory.NULL;
}
public static Memory get_parent_class(Memory object) {
if (object.isObject()) {
ClassEntity classEntity = object.toValue(ObjectMemory.class).getReflection().getParent();
if (classEntity == null)
return Memory.FALSE;
else
return new StringMemory(classEntity.getName());
} else {
return Memory.FALSE;
}
}
public static Memory get_parent_class(Environment env) {
CallStackItem item = env.peekCall(0);
if (item.clazz != null) {
if (item.classEntity == null)
item.classEntity = env.fetchClass(item.clazz, false);
if (item.classEntity == null)
return Memory.FALSE;
else {
MethodEntity method = item.classEntity.findMethod(item.function);
if (method == null)
return Memory.FALSE;
ClassEntity parent = method.getClazz().getParent();
return parent == null ? Memory.FALSE : new StringMemory(parent.getName());
}
}
return Memory.FALSE;
}
public static Memory flow(Environment env, Memory result) {
return WrapFlow.of(env, result);
}
/*public static Memory define_package(Environment env, TraceInfo trace, String name, Memory info) {
if (env.scope.getLangMode() != LangMode.MODERN) {
env.error(trace, ErrorType.E_NOTICE, "define_package(): Packages are available only in modern language mode");
return Memory.FALSE;
}
if (!expecting(env, trace, 1, info, Memory.Type.ARRAY)) {
return Memory.FALSE;
}
PackageManager manager = env.getPackageManager();
if (manager.has(name)) {
env.error(trace, "define_package(): Package '" + name + "' already defined");
return Memory.FALSE;
}
php.runtime.env.Package aPackage = manager.fetch(name, trace);
for (Memory cls : classes.toValue(ArrayMemory.class)) {
aPackage.addClass(cls.toString());
}
for (Memory func : functions.toValue(ArrayMemory.class)) {
aPackage.addFunction(func.toString());
}
for (Memory c : constants.toValue(ArrayMemory.class)) {
aPackage.addConstant(c.toString());
}
return Memory.TRUE;
}*/
}