Skip to content

Commit

Permalink
Showing 3 changed files with 36 additions and 11 deletions.
6 changes: 3 additions & 3 deletions core/src/main/java/org/jruby/Ruby.java
Original file line number Diff line number Diff line change
@@ -1371,7 +1371,7 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
}

// Object is ready, create top self
topSelf = TopSelfFactory.createTopSelf(this);
topSelf = TopSelfFactory.createTopSelf(this, false);

// Pre-create all the core classes potentially referenced during startup
RubyNil.createNilClass(this);
@@ -2850,7 +2850,7 @@ public void printError(RubyException excp) {
}

public void loadFile(String scriptName, InputStream in, boolean wrap) {
IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this) : getTopSelf();
IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this, true) : getTopSelf();
ThreadContext context = getCurrentContext();
String file = context.getFile();

@@ -2962,7 +2962,7 @@ public void loadScript(Script script, boolean wrap) {
* @param wrap Whether to use a new "self" for toplevel
*/
public void loadExtension(String extName, BasicLibraryService extension, boolean wrap) {
IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this) : getTopSelf();
IRubyObject self = wrap ? TopSelfFactory.createTopSelf(this, true) : getTopSelf();
ThreadContext context = getCurrentContext();

try {
40 changes: 33 additions & 7 deletions core/src/main/java/org/jruby/TopSelfFactory.java
Original file line number Diff line number Diff line change
@@ -31,6 +31,7 @@
package org.jruby;

import org.jruby.internal.runtime.methods.JavaMethod;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
@@ -47,41 +48,66 @@ public final class TopSelfFactory {
private TopSelfFactory() {
super();
}

public static IRubyObject createTopSelf(final Ruby runtime) {
return createTopSelf(runtime, false);
}

public static IRubyObject createTopSelf(final Ruby runtime, final boolean wrapper) {
IRubyObject topSelf = new RubyObject(runtime, runtime.getObject());

topSelf.getSingletonClass().addMethod("to_s", new JavaMethod.JavaMethodZero(topSelf.getSingletonClass(), Visibility.PUBLIC) {

final RubyClass singletonClass = topSelf.getSingletonClass();

singletonClass.addMethod("to_s", new JavaMethod.JavaMethodZero(singletonClass, Visibility.PUBLIC) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name) {
return runtime.newString("main");
}
});
topSelf.getSingletonClass().defineAlias("inspect", "to_s");
singletonClass.defineAlias("inspect", "to_s");

// The following three methods must be defined fast, since they expect to modify the current frame
// (i.e. they expect no frame will be allocated for them). JRUBY-1185.
topSelf.getSingletonClass().addMethod("include", new JavaMethod.JavaMethodN(topSelf.getSingletonClass(), Visibility.PRIVATE) {
singletonClass.addMethod("include", new JavaMethod.JavaMethodN(singletonClass, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
return context.runtime.getObject().include(args);
}
});

topSelf.getSingletonClass().addMethod("public", new JavaMethod.JavaMethodN(topSelf.getSingletonClass(), Visibility.PRIVATE) {
singletonClass.addMethod("public", new JavaMethod.JavaMethodN(singletonClass, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
return context.runtime.getObject().rbPublic(context, args);
}
});

topSelf.getSingletonClass().addMethod("private", new JavaMethod.JavaMethodN(topSelf.getSingletonClass(), Visibility.PRIVATE) {
singletonClass.addMethod("private", new JavaMethod.JavaMethodN(singletonClass, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args) {
return context.runtime.getObject().rbPrivate(context, args);
}
});

final RubyClass klass = wrapper ? singletonClass : runtime.getObject();
singletonClass.addMethod("define_method", new JavaMethod.JavaMethodOneOrTwoBlock(singletonClass, Visibility.PRIVATE) {
@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, Block block) {
if (klass == singletonClass) warnWrapper(context);
return klass.define_method(context, arg0, block);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject arg0, IRubyObject arg1, Block block) {
if (klass == singletonClass) warnWrapper(context);
return klass.define_method(context, arg0, arg1, block);
}
});

return topSelf;
}

private static void warnWrapper(ThreadContext context) {
context.runtime.getWarnings().warning("main.define_method in the wrapped load is effective only in wrapper module");
}
}
1 change: 0 additions & 1 deletion test/mri/excludes/TestEval.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
exclude :test_define_method_toplevel, "needs investigation"
exclude :test_eval_ascii_incompatible, "needs investigation"
exclude :test_eval_location_fstring, "needs investigation"
exclude :test_file_encoding, "needs investigation"

0 comments on commit 400b5d6

Please sign in to comment.