-
Notifications
You must be signed in to change notification settings - Fork 46
Expand file tree
/
Copy pathCycript.java
More file actions
97 lines (79 loc) · 2.82 KB
/
Copy pathCycript.java
File metadata and controls
97 lines (79 loc) · 2.82 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
/* Cycript - The Truly Universal Scripting Language
* Copyright (C) 2009-2016 Jay Freeman (saurik)
*/
/* GNU Affero General Public License, Version 3 {{{ */
/*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
**/
/* }}} */
import java.lang.reflect.Field;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class Cycript {
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);
}
}