Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add call protocol to script body and separate non-protocol metas. #4388

Merged
merged 2 commits into from Dec 15, 2016
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
Expand Up @@ -40,6 +40,8 @@ public CompiledIRMethod(MethodHandle variable, MethodHandle specific, int specif
this.method.getStaticScope().determineModule();
this.hasKwargs = hasKwargs;

assert method.hasExplicitCallProtocol();

setHandle(variable);
}

Expand Down Expand Up @@ -67,16 +69,6 @@ public InterpreterContext ensureInstrsReady() {
return ic;
}

protected void post(ThreadContext context) {
// update call stacks (pop: ..)
context.postMethodFrameAndScope();
}

protected void pre(ThreadContext context, StaticScope staticScope, RubyModule implementationClass, IRubyObject self, String name, Block block) {
// update call stacks (push: frame, class, scope, etc.)
context.preMethodFrameAndScope(implementationClass, name, self, block, staticScope);
}

@Override
public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule clazz, String name, IRubyObject[] args, Block block) {
if (hasKwargs) args = IRRuntimeHelpers.frobnicateKwargsArgument(context, args, getSignature().required());
Expand Down
@@ -1,8 +1,11 @@
package org.jruby.internal.runtime.methods;

import org.jruby.RubyModule;
import org.jruby.internal.runtime.AbstractIRMethod;
import org.jruby.ir.IRFlags;
import org.jruby.ir.IRMethod;
import org.jruby.ir.IRScope;
import org.jruby.ir.interpreter.InterpreterContext;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.ArgumentDescriptor;
import org.jruby.runtime.Block;
Expand All @@ -14,13 +17,15 @@

import java.lang.invoke.MethodHandle;

public class CompiledIRMetaClassBody extends CompiledIRMethod {
public class CompiledIRNoProtocolMethod extends AbstractIRMethod {
private final boolean scope;
private final MethodHandle variable;

public CompiledIRMetaClassBody(MethodHandle handle, IRScope scope, RubyModule implementationClass) {
super(handle, scope, Visibility.PUBLIC, implementationClass, scope.receivesKeywordArgs());
public CompiledIRNoProtocolMethod(MethodHandle handle, IRScope scope, RubyModule implementationClass) {
super(scope, Visibility.PUBLIC, implementationClass);

this.scope = !scope.getFlags().contains(IRFlags.DYNSCOPE_ELIMINATED);
this.variable = handle;
}

public ArgumentDescriptor[] getArgumentDescriptors() {
Expand Down Expand Up @@ -63,7 +68,6 @@ public IRubyObject call(ThreadContext context, IRubyObject self, RubyModule claz
throw new RuntimeException("BUG: this path should never be called");
}

@Override
protected void post(ThreadContext context) {
// update call stacks (pop: ..)
context.popFrame();
Expand All @@ -72,7 +76,6 @@ protected void post(ThreadContext context) {
}
}

@Override
protected void pre(ThreadContext context, StaticScope staticScope, RubyModule implementationClass, IRubyObject self, String name, Block block) {
// update call stacks (push: frame, class, scope, etc.)
context.preMethodFrameOnly(implementationClass, name, self, block);
Expand All @@ -85,4 +88,16 @@ protected void pre(ThreadContext context, StaticScope staticScope, RubyModule im
context.setCurrentVisibility(getVisibility());
}

@Override
public InterpreterContext ensureInstrsReady() {
// FIXME: duplicated from MixedModeIRMethod
if (method instanceof IRMethod) {
return ((IRMethod) method).lazilyAcquireInterpreterContext();
}

InterpreterContext ic = method.getInterpreterContext();

return ic;
}

}
33 changes: 5 additions & 28 deletions core/src/main/java/org/jruby/ir/Compiler.java
Expand Up @@ -63,12 +63,13 @@ protected ScriptAndCode execute(final Ruby runtime, final IRScriptBody scope, Cl
}

final MethodHandle compiledHandle = _compiledHandle;
final StaticScope staticScope = scope.getStaticScope();

Script script = new AbstractScript() {
@Override
public IRubyObject __file__(ThreadContext context, IRubyObject self, IRubyObject[] args, Block block) {
try {
return (IRubyObject) compiledHandle.invokeWithArguments(context, scope.getStaticScope(), self, IRubyObject.NULL_ARRAY, block, self.getMetaClass(), Interpreter.ROOT);
return (IRubyObject) compiledHandle.invokeWithArguments(context, staticScope, self, IRubyObject.NULL_ARRAY, block, self.getMetaClass(), Interpreter.ROOT);
} catch (Throwable t) {
Helpers.throwException(t);
return null; // not reached
Expand All @@ -78,45 +79,21 @@ public IRubyObject __file__(ThreadContext context, IRubyObject self, IRubyObject
@Override
public IRubyObject load(ThreadContext context, IRubyObject self, boolean wrap) {
// Compiler does not support BEGIN/END yet and should fail to compile above
{
// BeginEndInterpreterContext ic = (BeginEndInterpreterContext) irScope.prepareForInterpretation();

// We get the live object ball rolling here.
// This give a valid value for the top of this lexical tree.
// All new scopes can then retrieve and set based on lexical parent.
// StaticScope scope = ic.getStaticScope();
}
// Copied from Interpreter
StaticScope sscope = scope.getStaticScope();
RubyModule currModule = sscope.getModule();
if (currModule == null) {
// SSS FIXME: Looks like this has to do with Kernel#load
// and the wrap parameter. Figure it out and document it here.
currModule = context.getRuntime().getObject();
}
RubyModule currModule = staticScope.getModule();

sscope.setModule(currModule);
DynamicScope tlbScope = scope.getToplevelScope();
if (tlbScope == null) {
context.preMethodScopeOnly(sscope);
} else {
sscope = tlbScope.getStaticScope();
context.preScopedBody(tlbScope);
tlbScope.growIfNeeded();
}
staticScope.setModule(currModule);
context.setCurrentVisibility(Visibility.PRIVATE);

try {
// runBeginEndBlocks(ic.getBeginBlocks(), context, self, scope, null);
return (IRubyObject) compiledHandle.invokeWithArguments(context, sscope, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, currModule, Interpreter.ROOT);
return (IRubyObject) compiledHandle.invokeWithArguments(context, staticScope, self, IRubyObject.NULL_ARRAY, Block.NULL_BLOCK, currModule, Interpreter.ROOT);
} catch (IRBreakJump bj) {
throw IRException.BREAK_LocalJumpError.getException(context.runtime);
} catch (Throwable t) {
Helpers.throwException(t);
return null; // not reached
} finally {
// runEndBlocks(ic.getEndBlocks(), context, self, scope, null);
context.popScope();
}
}
};
Expand Down
Expand Up @@ -22,8 +22,10 @@ public String getLabel() {

private boolean explicitCallProtocolSupported(IRScope scope) {
return scope instanceof IRMethod
|| (scope instanceof IRClosure && !(scope instanceof IREvalScript))
|| (scope instanceof IRModuleBody && !(scope instanceof IRMetaClassBody));
|| (scope instanceof IRClosure && !(scope instanceof IREvalScript))
|| (scope instanceof IRModuleBody && !(scope instanceof IRMetaClassBody)
|| (scope instanceof IRScriptBody)
);
}

/*
Expand Down
4 changes: 2 additions & 2 deletions core/src/main/java/org/jruby/ir/runtime/IRRuntimeHelpers.java
Expand Up @@ -6,7 +6,7 @@
import org.jruby.common.IRubyWarnings;
import org.jruby.exceptions.RaiseException;
import org.jruby.exceptions.Unrescuable;
import org.jruby.internal.runtime.methods.CompiledIRMetaClassBody;
import org.jruby.internal.runtime.methods.CompiledIRNoProtocolMethod;
import org.jruby.internal.runtime.methods.CompiledIRMethod;
import org.jruby.internal.runtime.methods.DynamicMethod;
import org.jruby.internal.runtime.methods.InterpretedIRBodyMethod;
Expand Down Expand Up @@ -1240,7 +1240,7 @@ public static DynamicMethod newInterpretedMetaClass(Ruby runtime, IRScope metaCl
public static DynamicMethod newCompiledMetaClass(ThreadContext context, MethodHandle handle, IRScope metaClassBody, IRubyObject obj) {
RubyClass singletonClass = newMetaClassFromIR(context.runtime, metaClassBody, obj);

return new CompiledIRMetaClassBody(handle, metaClassBody, singletonClass);
return new CompiledIRNoProtocolMethod(handle, metaClassBody, singletonClass);
}

private static RubyClass newMetaClassFromIR(Ruby runtime, IRScope metaClassBody, IRubyObject obj) {
Expand Down
9 changes: 9 additions & 0 deletions core/src/main/java/org/jruby/parser/StaticScope.java
Expand Up @@ -244,6 +244,9 @@ public int addVariableThisScope(String name) {

if (slot >= 0) return slot;

// Clear constructor since we are adding a name
constructor = null;

// This is perhaps innefficient timewise? Optimal spacewise
growVariableNames(name);

Expand Down Expand Up @@ -277,6 +280,9 @@ public int addVariable(String name) {

if (slot >= 0) return slot;

// Clear constructor since we are adding a name
constructor = null;

// This is perhaps innefficient timewise? Optimal spacewise
growVariableNames(name);

Expand All @@ -296,6 +302,9 @@ public void setVariables(String[] names) {
assert names != null : "names is not null";
assert namesAreInterned(names);

// Clear constructor since we are changing names
constructor = null;

variableNames = new String[names.length];
variableNamesLength = names.length;
System.arraycopy(names, 0, variableNames, 0, names.length);
Expand Down
4 changes: 1 addition & 3 deletions core/src/test/java/org/jruby/test/TestRubyBase.java
Expand Up @@ -81,9 +81,7 @@ protected final String eval(String script, String fileName) throws Exception {
runtime.getGlobalVariables().set("$>", lStream);
runtime.getGlobalVariables().set("$stderr", lStream);

runtime.runNormally(
runtime.parseFile(new ByteArrayInputStream(script.getBytes()), fileName, runtime.getCurrentContext().getCurrentScope())
);
runtime.runFromMain(new ByteArrayInputStream(script.getBytes()), fileName);
StringBuffer sb = new StringBuffer(new String(result.toByteArray()));
for (int idx = sb.indexOf("\n"); idx != -1; idx = sb.indexOf("\n")) {
sb.deleteCharAt(idx);
Expand Down