-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2015 Jay Freeman (saurik)
+/* Cycript - The Truly Universal Scripting Language
+ * Copyright (C) 2009-2016 Jay Freeman (saurik)
*/
/* GNU Affero General Public License, Version 3 {{{ */
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
public class Cycript {
-public class OnInvoke implements InvocationHandler {
- native public Object invoke(Object proxy, Method method, Object[] args) throws Throwable;
+public static Method GetMethod(Class<?> type, String name, Class... types) {
+ try {
+ return type.getMethod(name, types);
+ } catch (NoSuchMethodException e) {
+ throw new RuntimeException();
+ }
+}
+
+public static final Method Object$equals = GetMethod(Object.class, "equals", Object.class);
+public static final Method Object$hashCode = GetMethod(Object.class, "hashCode");
+
+public static native void delete(long protect);
+
+public static native Object handle(long protect, String property, Object[] arguments)
+ throws Throwable;
+
+public static class Wrapper
+ extends RuntimeException
+ implements InvocationHandler
+{
+ private long protect_;
+
+ public Wrapper(long protect) {
+ protect_ = protect;
+ }
+
+ protected void finalize()
+ throws Throwable
+ {
+ delete(protect_);
+ }
+
+ public long getProtect() {
+ return protect_;
+ }
+
+ public Object call(String property, Object[] arguments) {
+ try {
+ return handle(protect_, property, arguments);
+ } catch (Throwable throwable) {
+ return new RuntimeException(throwable);
+ }
+ }
+
+ public String toString() {
+ return call("toString", null).toString();
+ }
+
+ public Object invoke(Object proxy, Method method, Object[] args)
+ throws Throwable
+ {
+ if (false)
+ return null;
+ else if (method.equals(Object$equals))
+ // XXX: this assumes there is only one proxy
+ return proxy == args[0];
+ else if (method == Object$hashCode)
+ // XXX: this assumes there is only one wrapper
+ return hashCode();
+ else
+ return handle(protect_, method.getName(), args);
+ }
+}
+
+public static Object proxy(Class proxy, Wrapper wrapper) {
+ return Proxy.newProxyInstance(proxy.getClassLoader(), new Class[] {proxy}, wrapper);
}
}