Skip to content

Commit

Permalink
clean up public fields and methods for better ergonomics
Browse files Browse the repository at this point in the history
  • Loading branch information
lytles@takashi committed Sep 25, 2018
1 parent 41e5ec3 commit 03bbd9d
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 37 deletions.
8 changes: 4 additions & 4 deletions src/com/nqzero/unflect/Demo8.java
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package com.nqzero.unflect;

import com.nqzero.unflect.SaferUnsafe.Meth;
import static com.nqzero.unflect.Unflect.getField;
import static com.nqzero.unflect.Unflect.makeAccessible;
import static com.nqzero.unflect.Unflect.unLog;
import static com.nqzero.unflect.Unflect.build;
import java.io.FileDescriptor;
import java.io.RandomAccessFile;
import java.lang.reflect.Field;
import java.net.URL;
import static com.nqzero.unflect.UnsafeWrapper.uu;
import static com.nqzero.unflect.Unflect.setAccessible;

// duplicate the full demo since it uses java 11 classes for some of the tests (which are removed here)
public class Demo8 {
Expand All @@ -26,14 +27,14 @@ public static void main(String[] args) throws Exception {
catch (Throwable ex) {
vals[ii++] = -1;
}
makeAccessible(field);
setAccessible(field);
vals[ii++] = field.getInt(fd);


// for java 8 and later, use uu::getInt instead of meth
// but want this to compile with java 6

Unflect.Meth<Integer> meth = new Unflect.Meth() {
Meth<Integer> meth = new Meth() {
public Object meth(Object arg0,long arg1) {
return uu.getInt(arg0,arg1);
}
Expand All @@ -47,7 +48,6 @@ public Object meth(Object arg0,long arg1) {
Safer<RandomAccessFile,?> ref2 = build(RandomAccessFile.class,"fd").chain("fd");
Safer<RandomAccessFile,?> ref3 = build(RandomAccessFile.class,"fd.fd");


vals[ii++] = ref.getInt(fd);
vals[ii++] = ref2.getInt(raf);
vals[ii++] = ref3.getInt(raf);
Expand Down
9 changes: 5 additions & 4 deletions src/com/nqzero/unflect/DemoUnflect.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package com.nqzero.unflect;

import com.nqzero.unflect.SaferUnsafe.Meth;
import static com.nqzero.unflect.Unflect.getField;
import static com.nqzero.unflect.Unflect.makeAccessible;
import static com.nqzero.unflect.Unflect.unLog;
import static com.nqzero.unflect.Unflect.build;
import static com.nqzero.unflect.SaferUnsafe.logger;
Expand All @@ -12,6 +12,7 @@
import java.lang.reflect.Method;
import java.net.URL;
import static com.nqzero.unflect.UnsafeWrapper.uu;
import static com.nqzero.unflect.Unflect.setAccessible;

public class DemoUnflect {
public static void main(String[] args) throws Exception {
Expand All @@ -22,7 +23,7 @@ public static void main(String[] args) throws Exception {
Field field = FileDescriptor.class.getDeclaredField("fd");
Class ka = AccessibleObject.class;
Method export = Module.class.getDeclaredMethod("implAddOpens",String.class);
makeAccessible(export);
setAccessible(export);
Class log = Class.forName("jdk.internal.module.IllegalAccessLogger");
export.invoke(log.getModule(),"jdk.internal.module");
System.out.println("logger: " + logger(true));
Expand All @@ -34,14 +35,14 @@ public static void main(String[] args) throws Exception {
catch (Throwable ex) {
vals[ii++] = -1;
}
makeAccessible(field);
setAccessible(field);
vals[ii++] = field.getInt(fd);


// for java 8 and later, use uu::getInt instead of meth
// but want this to compile with java 6

Unflect.Meth<Integer> meth = new Unflect.Meth() {
Meth<Integer> meth = new Meth() {
public Object meth(Object arg0,long arg1) {
return uu.getInt(arg0,arg1);
}
Expand Down
16 changes: 8 additions & 8 deletions src/com/nqzero/unflect/Safer.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.nqzero.unflect;

import static com.nqzero.unflect.Unflect.getSuperField;
import static com.nqzero.unflect.Unflect.*;
import static com.nqzero.unflect.UnsafeWrapper.uu;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
Expand Down Expand Up @@ -33,7 +33,7 @@ public class Safer<TT,VV> extends SaferUnsafe<TT,VV> {
Exception ex = null;
field = getSuperField(klass,name);
if (field==null)
throw new SaferUnsafe.FieldNotFound(ex);
throw new FieldNotFound(name,ex);
isStatic = Modifier.isStatic(field.getModifiers());
if (isStatic) {
base = uu.staticFieldBase(field);
Expand All @@ -46,7 +46,7 @@ public class Safer<TT,VV> extends SaferUnsafe<TT,VV> {
public Safer<TT,VV> chain(Class klass,String name) {
Class nominal = last.klass();
if (!nominal.isAssignableFrom(klass) & !klass.isAssignableFrom(nominal))
throw new SaferUnsafe.IncompatibleClasses(klass,nominal);
throw new IncompatibleClasses(klass,nominal);
return chain(klass,name,false);
}
public Safer chain(String name) {
Expand All @@ -65,25 +65,25 @@ private Safer<TT,VV> chain(Class klass,String name,boolean known) {
public <XX> Safer<TT,XX> target(Class<XX> klass) {
return (Safer<TT,XX>) this;
}
public Class klass() {
private Class klass() {
if (isArray) return klass.getComponentType();
else return field.getType();
}

public class Link extends SaferUnsafe<TT,VV> {
public class Linked extends SaferUnsafe<TT,VV> {
int [] rows;
long offset() {
return Safer.this.last.addy(rows);
}
Object resolve(Object o) {
return Safer.this.resolve(o,rows);
}
public Link(int ... rows) {
public Linked(int ... rows) {
this.rows = rows;
}
}
public Link link(int ... rows) {
return new Link(rows);
public Linked link(int ... rows) {
return new Linked(rows);
}

Object resolve(Object o) {
Expand Down
12 changes: 2 additions & 10 deletions src/com/nqzero/unflect/SaferUnsafe.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,8 @@
public abstract class SaferUnsafe<TT,VV> {


public static class FieldNotFound extends RuntimeException {
public FieldNotFound(Exception ex) { super(ex); }
}
public static class IncompatibleClasses extends RuntimeException {
Class klass, nominal;
public IncompatibleClasses(Class klass,Class nominal) {
super(klass + " and " + nominal + " aren't assignable");
this.klass = klass;
this.nominal = nominal;
}
public interface Meth<VV> {
public VV meth(Object obj,long offset);
}


Expand Down
4 changes: 2 additions & 2 deletions src/com/nqzero/unflect/Support11.java
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
package com.nqzero.unflect;

import static com.nqzero.unflect.Unflect.dbg;
import static com.nqzero.unflect.Unflect.makeAccessible;
import java.lang.reflect.Method;
import java.util.HashSet;
import static com.nqzero.unflect.Unflect.setAccessible;

public class Support11 {
public static void godMode() {
try {
Method export = Module.class.getDeclaredMethod("implAddOpens",String.class);
makeAccessible(export);
setAccessible(export);
HashSet<Module> modules = new HashSet();
Module base = SaferUnsafe.class.getModule();
if (base.getLayer() != null)
Expand Down
39 changes: 30 additions & 9 deletions src/com/nqzero/unflect/Unflect.java
Original file line number Diff line number Diff line change
@@ -1,17 +1,22 @@
package com.nqzero.unflect;

import com.nqzero.unflect.SaferUnsafe.Meth;
import java.lang.reflect.AccessibleObject;
import java.lang.reflect.Field;
import static com.nqzero.unflect.UnsafeWrapper.uu;
import java.lang.reflect.Method;

public class Unflect {
public static final String splitChar = "\\.";

static Safer<AccessibleObject,Boolean> override = build(AccessibleObject.class,"override");
static void makeAccessible(AccessibleObject accessor) {


public static void setAccessible(AccessibleObject accessor) {
override.putBoolean(accessor,true);
}
static void unLog() {

public static void unLog() {
try {
Class cls = Class.forName("jdk.internal.module.IllegalAccessLogger");
build(cls,"logger").putObjectVolatile(null,null);
Expand All @@ -36,34 +41,50 @@ public static void godMode() {

public static Object getObject(Object cl,String name) {
try {
Field field = cl.getClass().getDeclaredField(name);
Field field = getSuperField(cl.getClass(),name);
long offset = uu.objectFieldOffset(field);
return uu.getObject(cl,offset);
}
catch (Exception ex) {}
return null;
}
public interface Meth<VV> {
public VV meth(Object obj,long offset);
}
public static <VV> VV getField(Object cl,Meth<VV> meth,String ... names) {
if (names.length==1)
names = names[0].split(splitChar);
try {
int num = names.length-1;
for (int ii = 0; ii <= num; ii++) {
Field field = cl.getClass().getDeclaredField(names[ii]);
Field field = getSuperField(cl.getClass(),names[ii]);
long offset = uu.objectFieldOffset(field);
if (ii < num)
cl = uu.getObject(cl,offset);
else
return meth.meth(cl,offset);
}
}
catch (Exception ex) {}
catch (Throwable ex) {
throw new FieldNotFound(String.join(splitChar,names),ex);
}
return null;
}

public static class FieldNotFound extends RuntimeException {
String name;
public FieldNotFound(String name,Throwable ex) {
super("field \"" + name + "\" not found",ex);
this.name = name;
}
}

public static class IncompatibleClasses extends RuntimeException {
Class klass, nominal;
public IncompatibleClasses(Class klass,Class nominal) {
super(klass + " and " + nominal + " aren't assignable");
this.klass = klass;
this.nominal = nominal;
}
}

public static <TT,VV> Safer<TT,VV> build(Class<TT> klass,String name) {
String [] names = name.split(splitChar);
String firstName = names.length==0 ? name : names[0];
Expand All @@ -77,7 +98,7 @@ public static <TT,VV> Safer<TT,VV> build(TT sample,String name) {
return build((Class<TT>) sample.getClass(),name);
}

static Field getSuperField(Class klass,String name) {
public static Field getSuperField(Class klass,String name) {
for (; klass != Object.class; klass = klass.getSuperclass()) {
try {
return klass.getDeclaredField(name);
Expand Down

0 comments on commit 03bbd9d

Please sign in to comment.