]> git.saurik.com Git - cycript.git/blobdiff - Java/Cycript.java
Temporarily remove Number.toCYON: way too verbose.
[cycript.git] / Java / Cycript.java
index 76ac7fca75c86a37d9b6a670b160eefee8908122..8fb7817f14e4c2e309ceaf2f07c46fadb61fe12a 100644 (file)
@@ -1,5 +1,5 @@
-/* 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);
 }
 
 }