Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
ab2ccf6
WIP: first demo of 0-arg ctor callable from java getClass().newInstan…
byteit101 Oct 2, 2020
fa00023
WIP: Moving Concrete extension code into Reification code to add ctor…
byteit101 Oct 22, 2020
5c04320
More WIP constructor code. Multi-constructors should function, and no…
byteit101 Oct 24, 2020
2998f72
Remove test class reference
byteit101 Oct 24, 2020
4c61162
Reasonable multi-signature support (codegen, helpers missing) and hor…
byteit101 Nov 1, 2020
d1f30e0
Refactorings & actually detect which ctor to call. Also supports supe…
byteit101 Nov 12, 2020
9cd6bb3
Merge branch 'master' of https://github.com/jruby/jruby into wip_newi…
byteit101 Nov 12, 2020
99239f0
Update hack to use most recent api
byteit101 Nov 12, 2020
5f9b618
Make more tests work and be less verbose
byteit101 Nov 12, 2020
996197f
Minor cleanups of type safety and move AST transform to new file
byteit101 Nov 15, 2020
c0995d5
missed a file
byteit101 Nov 15, 2020
89f90db
General cleanup, fixes, and flailing around trying to get the scope w…
byteit101 Nov 15, 2020
be1653a
Add support for split allocate+initialize and arbitrary ruby argument…
byteit101 Nov 17, 2020
ef43757
Working scoping for most code. Missing some elements still
byteit101 Nov 17, 2020
eb1ecdb
Start fixing some easy test failures
byteit101 Nov 18, 2020
cfcc2fd
Several test fixes
byteit101 Nov 18, 2020
3b181d8
Update for import/style consistency
enebo Nov 25, 2020
913736c
Super bridges, partial work on ruby<ruby<java heirarchy, other assort…
byteit101 Nov 25, 2020
cf4adfe
Move some gen code into split/finish Init pair
byteit101 Nov 25, 2020
e0d2ddb
Down to 1+4+ant failures
byteit101 Nov 27, 2020
52dd70f
Very questionable implementation of ruby < ruby < java hierarchy
byteit101 Nov 27, 2020
7859cd5
Method overrides on the java side
byteit101 Nov 27, 2020
7f2058c
Class#clone should copy local reify state
byteit101 Nov 27, 2020
08ae7dd
Add WIP unconnected interpreter which will allow stopping and continuing
enebo Nov 30, 2020
1322977
Filled out to the point I believe RubyClass can ask for the interpreter
enebo Nov 30, 2020
3311fa0
Add depth logic to IR super splitting.
enebo Dec 1, 2020
5fe86f0
Revert "Update for import/style consistency"
byteit101 Dec 3, 2020
945f66e
Merge branch 'enebo_newinstance' into wip_newinstance
byteit101 Dec 3, 2020
1519da7
Assign superCall when found
byteit101 Dec 3, 2020
5e8c211
Tie in new IR work
byteit101 Dec 3, 2020
90fb7cf
Add proper scopes to fix errors, and guesses at frames.
byteit101 Dec 4, 2020
8d6d424
proper zsuper support from @enebo
byteit101 Dec 6, 2020
d2fb097
Reorganize and clean up split invocations; add support for custom names
byteit101 Dec 6, 2020
8fa6ba1
All are compileable, for some reason
byteit101 Dec 6, 2020
73b6e89
Cleanup and bug fixes
byteit101 Dec 9, 2020
5bddf82
More tests and fixes for nested classes
byteit101 Dec 12, 2020
abb05c1
Merge branch 'master' of https://github.com/jruby/jruby into wip_newi…
byteit101 Dec 12, 2020
53d7eff
Fix merge issues & add new test
byteit101 Dec 12, 2020
d27fab3
module support, split new support, nicer ruby api
byteit101 Dec 12, 2020
39adc70
More tests & updated configure
byteit101 Dec 12, 2020
ce66437
Lots of cleanup and refactoring
byteit101 Feb 15, 2021
9ae5915
Merge remote-tracking branch 'origin/master' into wip_newinstance
byteit101 Feb 17, 2021
e51ce30
Formatting, cleanup, licence blocks
byteit101 Feb 21, 2021
091c868
More cleanup
byteit101 Feb 23, 2021
18dfe11
(non-working) test for interface default super
byteit101 Feb 23, 2021
5860ce9
Mark failing tests, fix 1 test, add 1 test for negative super looping…
byteit101 Mar 5, 2021
da2bc4e
Missed update for prior commit
byteit101 Mar 6, 2021
67f03ae
Merge master and update to Signature
byteit101 Mar 6, 2021
300005f
Refactor RCG to pass index and converted args from splitInit
byteit101 Mar 6, 2021
2eed247
Re-reify if we are an unreified child
byteit101 Mar 6, 2021
d68357e
Don't hide static int exceptions?
byteit101 Mar 6, 2021
03b5554
Only the last half of java integration is pending
byteit101 Mar 6, 2021
b12e5a6
Merge remote-tracking branch 'origin/master' into wip_newinstance
byteit101 May 13, 2021
a5b1b8d
This PR still needs a public ctor
byteit101 May 14, 2021
dc3f34f
Doc & remove puts in class configurator
byteit101 May 17, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Add support for split allocate+initialize and arbitrary ruby argument…
… fallback.

Also some misc cleanup
  • Loading branch information
byteit101 committed Nov 17, 2020
commit be1653ab224b184b5094ee1bc4e2eeaea9f7e676
45 changes: 32 additions & 13 deletions core/src/main/java/org/jruby/RubyClass.java
Original file line number Diff line number Diff line change
Expand Up @@ -1361,10 +1361,17 @@ public synchronized void reify(String classDumpDir, boolean useChildLoader) {
{
setRubyStaticAllocator(result);
}
else if (((ConcreteJavaReifier)reifier).jcc.IroCtors)
{
//TODO: ensure CJP allocator is set
//setAllocator(ConcreteJavaProxy.ALLOCATOR);
//setRubyStaticAllocator(result);
}
else
{
/**Allocator "set" via clinit @see JavaProxyClass.setProxyClassReified
/**Allocator "set" via clinit {@see JavaProxyClass#setProxyClassReified()}
*/
//TODO: disable alloc method
}

// update java_class
Expand Down Expand Up @@ -1409,7 +1416,10 @@ interface Reificator {
public PositionAware getPositionOrDefault(DynamicMethod method)
{
if (method instanceof PositionAware)
return (PositionAware) method;
{
PositionAware pos = (PositionAware) method;
return new SimpleSourcePosition(pos.getFile(), pos.getLine()+1); // convert from 0-based to 1-based that the JVM requires
}
else
return defaultSimplePosition;
}
Expand Down Expand Up @@ -1519,7 +1529,7 @@ protected void reifyConstructors()
allocAndInitialize(m, true);
}
}

// TODO: allow java to pass args?
protected void allocAndInitialize(SkinnyMethodAdapter m, boolean initIfAllowed)
{
m.invokespecial(p(reifiedParent), "<init>", sig(void.class, Ruby.class, RubyClass.class));
Expand Down Expand Up @@ -1607,7 +1617,7 @@ private void defineClassMethods(Set<String> instanceMethods) {

String javaMethodName = JavaNameMangler.mangleMethodName(id);
PositionAware position = getPositionOrDefault(methodEntry.getValue());
cw.visitSource(position.getFile(), null);//TODO: ctors, etc
if (position.getLine() > 1) cw.visitSource(position.getFile(), null);

Map<Class,Map<String,Object>> methodAnnos = getMetaClass().getMethodAnnotations().get(id);
List<Map<Class,Map<String,Object>>> parameterAnnos = getMetaClass().getParameterAnnotations().get(id);
Expand Down Expand Up @@ -1685,7 +1695,7 @@ private void defineInstanceMethods(Set<String> instanceMethods) {

String javaMethodName = JavaNameMangler.mangleMethodName(id);
PositionAware position = getPositionOrDefault(methodEntry.getValue());
cw.visitSource(position.getFile(), null);//TODO: ctors, etc
if (position.getLine() > 1) cw.visitSource(position.getFile(), null);

Map<Class,Map<String,Object>> methodAnnos = getMethodAnnotations().get(id);
List<Map<Class,Map<String,Object>>> parameterAnnos = getParameterAnnotations().get(id);
Expand Down Expand Up @@ -1985,6 +1995,12 @@ protected void reifyConstructors()
}
}
// TODO: guess from arity?

// update the source location
DynamicMethod methodEntry = searchMethod("initialize");
PositionAware position = getPositionOrDefault(methodEntry);
cw.visitSource(position.getFile(), null);
int superpos = ConcreteJavaProxy.findSuperLine(runtime, methodEntry, position.getLine());


if (candidates.size() > 0 ) //TODO: doc: implies javaConstructable?
Expand All @@ -2011,12 +2027,12 @@ protected void reifyConstructors()
if (!jcc.allCtors) //TODO: fix logic
{
//if (jcc.rubyConstructable)
RealClassGenerator.makeConcreteConstructorSwitch(cw, true, true, this, new Class[0], savedSuperCtors, CtorFlags.Normal);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, true, true, this, new Class[0], savedSuperCtors, CtorFlags.Normal);


if (jcc.javaConstructable)
{
RealClassGenerator.makeConcreteConstructorSwitch(cw, false, true, this, new Class[0], savedSuperCtors, CtorFlags.Normal);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, false, true, this, new Class[0], savedSuperCtors, CtorFlags.Normal);
}
}
}
Expand All @@ -2033,10 +2049,10 @@ protected void reifyConstructors()
// if (zeroArg.isPresent() && constructor == zeroArg.get()) continue;

if (jcc.rubyConstructable)
RealClassGenerator.makeConcreteConstructorSwitch(cw, true, true, this, constructor.getParameterTypes(), savedSuperCtors, CtorFlags.Normal);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, true, true, this, constructor.getParameterTypes(), savedSuperCtors, CtorFlags.Normal);

if (jcc.javaConstructable)
RealClassGenerator.makeConcreteConstructorSwitch(cw, false, true, this, constructor.getParameterTypes(), savedSuperCtors, CtorFlags.Normal);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, false, true, this, constructor.getParameterTypes(), savedSuperCtors, CtorFlags.Normal);

}
}
Expand All @@ -2051,14 +2067,17 @@ protected void reifyConstructors()
// TODO: support annotations

if (jcc.rubyConstructable)
RealClassGenerator.makeConcreteConstructorSwitch(cw, true, true, this, constructor, savedSuperCtors, CtorFlags.NoSuper);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, true, true, this, constructor, savedSuperCtors, CtorFlags.NoSuper);

if (jcc.javaConstructable)
RealClassGenerator.makeConcreteConstructorSwitch(cw, false, true, this, constructor, savedSuperCtors, CtorFlags.NoSuper);
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, false, true, this, constructor, savedSuperCtors, CtorFlags.NoSuper);

}
}
// TODO: rubyargs
}
if (jcc.IroCtors)
{
RealClassGenerator.makeConcreteConstructorSwitch(cw, position, superpos, true, true, this, new Class[] {ConcreteJavaProxy.class, IRubyObject[].class, Block.class}, savedSuperCtors, CtorFlags.RubyArgs);
}
}

/**
Expand Down
102 changes: 61 additions & 41 deletions core/src/main/java/org/jruby/java/codegen/RealClassGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -832,49 +832,50 @@ public static enum CtorFlags
{
Normal,
NoSuper, // implicit `super` not allowed, no parent ctor with this signature
RubyArgs, // NoSuper + args don't need converting
RubyArgsBlock, // RubyArgs, plus has a block arg
RubyArgs, // NoSuper + args don't need converting (also includes the CJP and block args)

}
// TODO: add CJP ctor for alloc sep?
//:TODO: Add IRubyobject ctor?
// shouls this be in in this spot?
public static void makeConcreteConstructorSwitch(ClassWriter cw, boolean hasRuby, boolean callsInit, ConcreteJavaReifier cjr, Class[] ctorTypes, JavaConstructor[] constructors, CtorFlags flag)
public static void makeConcreteConstructorSwitch(ClassWriter cw, PositionAware initPosition, int superpos, boolean hasRuby, boolean callsInit, ConcreteJavaReifier cjr, Class[] ctorTypes, JavaConstructor[] constructors, CtorFlags flag)
{

// TODO: add source position of super call

/* This generates this code template. Note that lines of //// show what code is being generated
* public Demo(int var1, String var2) {
Ruby var3 = ruby;
this.$rubyInitArgs = new IRubyObject[]{JavaUtil.convertJavaToRuby(var3, var1), JavaUtil.convertJavaToUsableRubyObject(var3, var2)};
this.$rubyObject = new ConcreteJavaProxy(ruby, rubyClass);
IRubyObject c = this$rubyObject.splitInitialized(this.$rubyInitArgs);
RubyArray ra = c.convertToArray();
c = ra.entry(0);
IRubyObject continuation = ra.entry(1);
switch(Java.JCreateMethod.forTypes(constructors, c))
{
case -1:
ra = c.convertToArray();
thing(ra.entry(0).toJava(Integer.TYPE).longValue());
//return;
break;
case 0:
//ra = c.convertToArray();
thing(id);
break;
default:
throw new RuntimeException("NANANANANANA");
}

(this.$rubyObject.setObject(this))
Ruby var3 = ruby;
this.$rubyInitArgs = new IRubyObject[]{JavaUtil.convertJavaToRuby(var3, var1), JavaUtil.convertJavaToUsableRubyObject(var3, var2)};
this.$rubyObject = new ConcreteJavaProxy(ruby, rubyClass);
IRubyObject c = this$rubyObject.splitInitialized(this.$rubyInitArgs);
RubyArray ra = c.convertToArray();
c = ra.entry(0);
IRubyObject continuation = ra.entry(1);
switch(Java.JCreateMethod.forTypes(constructors, c))
{
case -1:
ra = c.convertToArray();
thing(ra.entry(0).toJava(Integer.TYPE).longValue());
//return;
break;
case 0:
//ra = c.convertToArray();
thing(id);
break;
default:
throw new RuntimeException("NANANANANANA");
}
(this.$rubyObject.setObject(this))

continuation.callMethod(null, "call")

}*/

String sig = hasRuby ? sig(void.class, cjr.join(ctorTypes, Ruby.class, RubyClass.class)) : sig(void.class, ctorTypes);
SkinnyMethodAdapter m = new SkinnyMethodAdapter(cw, ACC_PUBLIC, "<init>", sig, null, null);
m.line(initPosition.getLine());
m.aload(0); // uninitialized this

// set args for init
Expand All @@ -884,28 +885,37 @@ public static void makeConcreteConstructorSwitch(ClassWriter cw, boolean hasRuby
final int rubyArrayIndex = baseIndex+2;
final int rubyContinuation = baseIndex+3;
final int rubyInitArgs = baseIndex+4;
m.dup(); // uninitialized this
//m.dup(); // uninitialized this
if (!hasRuby) // if java, extract and pretend we got a call with ruby on a local
{
m.getstatic(cjr.javaPath, "ruby", ci(Ruby.class));
m.astore(rubyIndex); // save ruby in local
}
//// this.$rubyInitArgs = new IRubyObject[]{JavaUtil.convertJavaToRuby(var3, var1), JavaUtil.convertJavaToUsableRubyObject(var3, var2)};
RealClassGenerator.coerceArgumentsToRuby(m, ctorTypes, rubyIndex);
if (flag == CtorFlags.Normal || flag == CtorFlags.NoSuper)
RealClassGenerator.coerceArgumentsToRuby(m, ctorTypes, rubyIndex);
else
m.aload(2); // RubyArgs is arg 2
m.astore(rubyInitArgs);
m.pop(); // pop the `this`. TODO: dont push the this
//m.pop(); // pop the `this`. TODO: dont push the this

////this.$rubyObject = new ConcreteJavaProxy(ruby, rubyClass);
{
//TODO: isInit?
m.newobj(p(ConcreteJavaProxy.class));
m.dup(); // rubyobject
m.aload(rubyIndex); // ruby
if (hasRuby)
m.aload(rubyIndex+1); // rubyclass
else
m.getstatic(cjr.javaPath, "rubyClass", ci(RubyClass.class)); // rubyclass
m.invokespecial(p(ConcreteJavaProxy.class), "<init>", sig(void.class, Ruby.class, RubyClass.class));
if (flag == CtorFlags.Normal || flag == CtorFlags.NoSuper)
{
m.newobj(p(ConcreteJavaProxy.class));
m.dup(); // rubyobject
m.aload(rubyIndex); // ruby
if (hasRuby)
m.aload(rubyIndex+1); // rubyclass
else
m.getstatic(cjr.javaPath, "rubyClass", ci(RubyClass.class)); // rubyclass
m.invokespecial(p(ConcreteJavaProxy.class), "<init>", sig(void.class, Ruby.class, RubyClass.class));
}
else
{
m.aload(1); // cjp is at arg 1 (to support alloc+initialize seperation)
}
m.dup(); // rubyobject
m.aload(0); // uninitialized this
m.swap();
Expand All @@ -915,9 +925,18 @@ public static void makeConcreteConstructorSwitch(ClassWriter cw, boolean hasRuby
if (callsInit) //TODO: should init be called when super calls an abstract method we implement?
{
m.aload(rubyInitArgs);
m.invokevirtual(cjr.rubyPath, "splitInitialized", sig(RubyArray.class, IRubyObject[].class) ); //pushes rubyarray
if (flag == CtorFlags.Normal || flag == CtorFlags.NoSuper)
{
m.getstatic(p(Block.class), "NULL_BLOCK", ci(Block.class));
}
else
{
m.aload(3); // load block from arg 3
}
m.invokevirtual(cjr.rubyPath, "splitInitialized", sig(RubyArray.class, IRubyObject[].class, Block.class) ); //pushes rubyarray
m.dup(); // rubyarray (results of splitInitialized)

m.line(superpos); // mark this line as the super call, so the stack trace is slightly accurate.

//// c = ra.entry(0);
////IRubyObject continuation = ra.entry(1);
Expand Down Expand Up @@ -1007,9 +1026,10 @@ public static void makeConcreteConstructorSwitch(ClassWriter cw, boolean hasRuby

}
else
m.pop(); // TODO: ???
m.pop(); // RubyObject

m.line(initPosition.getLine()); // This is the start of the method, but lets move it away from the super call to be slightly nicer to stack traces


//implied: if (this.$rubyObject.getObject() == null) // only checked on non-ctor paths
////(this.$rubyObject.setObject(this))

Expand Down
Loading