Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin/master' into truffle-head
Browse files Browse the repository at this point in the history
  • Loading branch information
eregon committed Nov 30, 2016
2 parents 3b57e25 + ddbc53b commit 0a8110b
Show file tree
Hide file tree
Showing 8 changed files with 67 additions and 47 deletions.
3 changes: 3 additions & 0 deletions core/src/main/java/org/jruby/IncludedModule.java
Expand Up @@ -9,6 +9,9 @@ public IncludedModule(Ruby runtime, RubyClass superClass, RubyModule origin) {
super(runtime, superClass, false);
this.origin = origin;
this.metaClass = origin.metaClass;
if (superClass != null) {
setClassIndex(superClass.getClassIndex()); // use same ClassIndex as metaclass, since we're technically still of that type
}
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/MetaClass.java
Expand Up @@ -38,7 +38,7 @@ public final class MetaClass extends RubyClass {
public MetaClass(Ruby runtime, RubyClass superClass, IRubyObject attached) {
super(runtime, superClass, false);
this.attached = attached;
setClassIndex(superClass.classIndex); // use same ClassIndex as metaclass, since we're technically still of that type
setClassIndex(superClass.getClassIndex()); // use same ClassIndex as metaclass, since we're technically still of that type
}

@Override
Expand Down
2 changes: 1 addition & 1 deletion core/src/main/java/org/jruby/RubyInterrupt.java
Expand Up @@ -72,7 +72,7 @@ public IRubyObject initialize(ThreadContext context, IRubyObject[] args, Block b
args = new IRubyObject[]{signo, runtime.newString("Interrupt")};
}

super.initialize(args, block);
super.initialize(context, args, block);
return this;
}
}
38 changes: 26 additions & 12 deletions core/src/main/java/org/jruby/ir/IRBuilder.java
Expand Up @@ -280,6 +280,8 @@ public void cloneIntoHostScope(IRBuilder builder) {

private int _lastProcessedLineNum = -1;

public boolean underscoreVariableSeen = false;

public IRLoop getCurrentLoop() {
return loopStack.isEmpty() ? null : loopStack.peek();
}
Expand Down Expand Up @@ -1985,17 +1987,29 @@ private void addArgReceiveInstr(Variable v, int argIndex, boolean post, int numP
}
}

/* '_' can be seen as a variable only by its first assignment as a local variable. For any additional
* '_' we create temporary variables in the case the scope has a zsuper in it. If so, then the zsuper
* call will slurp those temps up as it's parameters so it can properly set up the call.
*/
private Variable argumentResult(String name) {
boolean isUnderscore = name.equals("_");

if (isUnderscore && underscoreVariableSeen) {
return createTemporaryVariable();
} else {
if (isUnderscore) underscoreVariableSeen = true;
return getNewLocalVariable(name, 0);
}
}

public void receiveRequiredArg(Node node, int argIndex, boolean post, int numPreReqd, int numPostRead) {
switch (node.getNodeType()) {
case ARGUMENTNODE: {
ArgumentNode a = (ArgumentNode)node;
String argName = a.getName();
String argName = ((ArgumentNode)node).getName();

if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.req, argName);
// Ignore duplicate "_" args in blocks
// (duplicate _ args are named "_$0")
if (!argName.equals("_$0")) {
addArgReceiveInstr(getNewLocalVariable(argName, 0), argIndex, post, numPreReqd, numPostRead);
}

addArgReceiveInstr(argumentResult(argName), argIndex, post, numPreReqd, numPostRead);
break;
}
case MULTIPLEASGNNODE: {
Expand Down Expand Up @@ -2054,7 +2068,7 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
Label variableAssigned = getNewLabel();
OptArgNode optArg = (OptArgNode)args[optIndex + j];
String argName = optArg.getName();
Variable argVar = getNewLocalVariable(argName, 0);
Variable argVar = argumentResult(argName);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.opt, argName);
// You need at least required+j+1 incoming args for this opt arg to get an arg at all
addInstr(new ReceiveOptArgInstr(argVar, signature.required(), signature.pre(), j));
Expand Down Expand Up @@ -2085,7 +2099,7 @@ protected void receiveNonBlockArgs(final ArgsNode argsNode) {
// You need at least required+opt+1 incoming args for the rest arg to get any args at all
// If it is going to get something, then it should ignore required+opt args from the beginning
// because they have been accounted for already.
addInstr(new ReceiveRestArgInstr(getNewLocalVariable(argName, 0), signature.required() + opt, argIndex));
addInstr(new ReceiveRestArgInstr(argumentResult(argName), signature.required() + opt, argIndex));
}

// Post(-opt and rest) required args
Expand All @@ -2106,9 +2120,9 @@ protected void receiveBlockArg(final ArgsNode argsNode) {
// reify to Proc if we have a block arg
BlockArgNode blockArg = argsNode.getBlock();
if (blockArg != null) {
String blockArgName = blockArg.getName();
Variable blockVar = getLocalVariable(blockArgName, 0);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.block, blockArgName);
String argName = blockArg.getName();
Variable blockVar = argumentResult(argName);
if (scope instanceof IRMethod) addArgumentDescription(ArgumentType.block, argName);
Variable tmp = createTemporaryVariable();
addInstr(new LoadImplicitClosureInstr(tmp));
addInstr(new ReifyClosureInstr(blockVar, tmp));
Expand Down
31 changes: 5 additions & 26 deletions core/src/main/java/org/jruby/parser/ParserSupport.java
Expand Up @@ -1201,22 +1201,8 @@ public Node new_bv(String identifier) {
return arg_var(identifier);
}

// 1.9
public ArgumentNode arg_var(String name) {
StaticScope current = getCurrentScope();

// Multiple _ arguments are allowed. To not screw with tons of arity
// issues in our runtime we will allocate unnamed bogus vars so things
// still work. MRI does not use name as intern'd value so they don't
// have this issue.
if (name == "_") {
int count = 0;
while (current.exists(name) >= 0) {
name = ("_$" + count++).intern();
}
}

return new ArgumentNode(lexer.getPosition(), name, current.addVariableThisScope(name));
return new ArgumentNode(lexer.getPosition(), name, getCurrentScope().addVariableThisScope(name));
}

public String formal_argument(String identifier) {
Expand All @@ -1230,18 +1216,11 @@ public String shadowing_lvar(String name) {
if (name == "_") return name;

StaticScope current = getCurrentScope();
if (current.isBlockScope()) {
if (current.exists(name) >= 0) yyerror("duplicated argument name");
if (current.exists(name) >= 0) yyerror("duplicated argument name");

if (warnings.isVerbose() && current.isDefined(name) >= 0 &&
Options.PARSER_WARN_LOCAL_SHADOWING.load() &&
!ParserSupport.skipTruffleRubiniusWarnings(lexer)) {

warnings.warning(ID.STATEMENT_NOT_REACHED, lexer.getPosition(),
"shadowing outer local variable - " + name);
}
} else if (current.exists(name) >= 0) {
yyerror("duplicated argument name");
if (current.isBlockScope() && warnings.isVerbose() && current.isDefined(name) >= 0 &&
Options.PARSER_WARN_LOCAL_SHADOWING.load() && !ParserSupport.skipTruffleRubiniusWarnings(lexer)) {
warnings.warning(ID.STATEMENT_NOT_REACHED, lexer.getPosition(), "shadowing outer local variable - " + name);
}

return name;
Expand Down
7 changes: 0 additions & 7 deletions core/src/main/java/org/jruby/parser/StaticScope.java
Expand Up @@ -240,13 +240,6 @@ private static boolean namesAreInterned(String[] names) {
* @return index of variable
*/
public int addVariableThisScope(String name) {
// Ignore duplicate "_" args in blocks
// (duplicate _ args are named "_$0")
// Dont allocate slots for them.
if (name.equals("_$0")) {
return -1;
}

int slot = exists(name);

if (slot >= 0) return slot;
Expand Down
23 changes: 23 additions & 0 deletions spec/ruby/language/fixtures/super.rb
Expand Up @@ -455,6 +455,29 @@ def m_modified(a, b, *args)
end
end

module ZSuperWithUnderscores
class A
def m(*args)
args
end

def m_modified(*args)
args
end
end

class B < A
def m(_, _)
super
end

def m_modified(_, _)
_ = 14
super
end
end
end

module KeywordArguments
class A
def foo(**args)
Expand Down
8 changes: 8 additions & 0 deletions spec/ruby/language/super_spec.rb
Expand Up @@ -239,6 +239,14 @@ def obj.foobar(array)
Super::ZSuperWithRestAndOthers::B.new.m_modified(1, 2, 3, 4, 5).should == [3, 14, 5]
end

it "without explicit arguments that are '_'" do
Super::ZSuperWithUnderscores::B.new.m(1, 2).should == [1, 2]
end

it "without explicit arguments that are '_' including any modifications" do
Super::ZSuperWithUnderscores::B.new.m_modified(1, 2).should == [14, 2]
end

describe 'when using keyword arguments' do
it 'passes any given keyword arguments to the parent' do
b = Super::KeywordArguments::B.new
Expand Down

0 comments on commit 0a8110b

Please sign in to comment.