Skip to content

Instantly share code, notes, and snippets.

@headius
Created September 23, 2016 19:30
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save headius/2be4be6b1b8bc71f714901519ee6b5b0 to your computer and use it in GitHub Desktop.
Save headius/2be4be6b1b8bc71f714901519ee6b5b0 to your computer and use it in GitHub Desktop.
commit fd79f530c513260c26c8153e34cd1c60705705a1
Author: Charles Oliver Nutter <headius@headius.com>
Date: Fri Sep 23 14:28:13 2016 -0500
Compile scope variable accesses to direct fields.
diff --git a/core/src/main/java/org/jruby/Ruby.java b/core/src/main/java/org/jruby/Ruby.java
index ae7fc8b..4e278ae 100644
--- a/core/src/main/java/org/jruby/Ruby.java
+++ b/core/src/main/java/org/jruby/Ruby.java
@@ -138,7 +138,6 @@ import org.jruby.runtime.profile.ProfileCollection;
import org.jruby.runtime.profile.ProfilingService;
import org.jruby.runtime.profile.ProfilingServiceLookup;
import org.jruby.runtime.profile.builtin.ProfiledMethods;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.threading.DaemonThreadFactory;
import org.jruby.util.ByteList;
import org.jruby.util.ClassDefiningClassLoader;
@@ -453,7 +452,7 @@ public final class Ruby implements Constantizable {
public IRubyObject evalScriptlet(String script) {
ThreadContext context = getCurrentContext();
DynamicScope currentScope = context.getCurrentScope();
- ManyVarsDynamicScope newScope = new ManyVarsDynamicScope(getStaticScopeFactory().newEvalScope(currentScope.getStaticScope()), currentScope);
+ DynamicScope newScope = DynamicScope.newDynamicScope(getStaticScopeFactory().newEvalScope(currentScope.getStaticScope()), currentScope);
return evalScriptlet(script, newScope);
}
@@ -3275,7 +3274,7 @@ public final class Ruby implements Constantizable {
// bogus scope back for at_exit block run. This is buggy if at_exit is capturing vars.
if (!context.hasAnyScopes()) {
StaticScope topStaticScope = getStaticScopeFactory().newLocalScope(null);
- context.pushScope(new ManyVarsDynamicScope(topStaticScope, null));
+ context.pushScope(DynamicScope.newDynamicScope(topStaticScope));
}
while (!atExitBlocks.empty()) {
diff --git a/core/src/main/java/org/jruby/RubyBinding.java b/core/src/main/java/org/jruby/RubyBinding.java
index ded429d..44e05c7 100644
--- a/core/src/main/java/org/jruby/RubyBinding.java
+++ b/core/src/main/java/org/jruby/RubyBinding.java
@@ -163,7 +163,7 @@ public class RubyBinding extends RubyObject {
if (slot == -1) { // Yay! New variable associated with this binding
slot = evalScope.getStaticScope().addVariable(name.intern());
- evalScope.growIfNeeded();
+// evalScope.growIfNeeded();
}
return evalScope.setValue(slot & 0xffff, value, slot >> 16);
diff --git a/core/src/main/java/org/jruby/embed/EmbedEvalUnit.java b/core/src/main/java/org/jruby/embed/EmbedEvalUnit.java
index 58cc98d..82c386c 100644
--- a/core/src/main/java/org/jruby/embed/EmbedEvalUnit.java
+++ b/core/src/main/java/org/jruby/embed/EmbedEvalUnit.java
@@ -31,7 +31,7 @@ package org.jruby.embed;
import org.jruby.ast.Node;
import org.jruby.javasupport.JavaEmbedUtils;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
+import org.jruby.runtime.DynamicScope;
/**
* Wrapper interface of {@link JavaEmbedUtils.EvalUnit} for embedding.
@@ -54,5 +54,5 @@ public interface EmbedEvalUnit extends JavaEmbedUtils.EvalUnit {
*
* @return scope to refer local variables.
*/
- public ManyVarsDynamicScope getScope();
+ public DynamicScope getScope();
}
diff --git a/core/src/main/java/org/jruby/embed/internal/BiVariableMap.java b/core/src/main/java/org/jruby/embed/internal/BiVariableMap.java
index 60e9f72..f80ca7f 100644
--- a/core/src/main/java/org/jruby/embed/internal/BiVariableMap.java
+++ b/core/src/main/java/org/jruby/embed/internal/BiVariableMap.java
@@ -44,8 +44,8 @@ import org.jruby.RubyObject;
import org.jruby.embed.LocalVariableBehavior;
import org.jruby.embed.variable.BiVariable;
import org.jruby.embed.variable.VariableInterceptor;
+import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import static org.jruby.util.StringSupport.EMPTY_STRING_ARRAY;
/**
@@ -380,7 +380,7 @@ public class BiVariableMap implements Map<String, Object> {
return localVarValues.toArray( new IRubyObject[ localVarValues.size() ] );
}
- void inject(final ManyVarsDynamicScope scope, final int depth, final IRubyObject receiver) {
+ void inject(final DynamicScope scope, final int depth, final IRubyObject receiver) {
VariableInterceptor.inject(this, provider.getRuntime(), scope, depth, receiver);
}
diff --git a/core/src/main/java/org/jruby/embed/internal/EmbedEvalUnitImpl.java b/core/src/main/java/org/jruby/embed/internal/EmbedEvalUnitImpl.java
index 7d94212..76901ec 100644
--- a/core/src/main/java/org/jruby/embed/internal/EmbedEvalUnitImpl.java
+++ b/core/src/main/java/org/jruby/embed/internal/EmbedEvalUnitImpl.java
@@ -39,9 +39,9 @@ import org.jruby.embed.EmbedEvalUnit;
import org.jruby.embed.EvalFailedException;
import org.jruby.embed.ScriptingContainer;
import org.jruby.exceptions.RaiseException;
+import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
* Implementation of org.jruby.javasupport.JavaEmbedUtils.EvalUnit for embeddiing.
@@ -57,14 +57,14 @@ public class EmbedEvalUnitImpl implements EmbedEvalUnit {
private final ScriptingContainer container;
private final Node node;
- private final ManyVarsDynamicScope scope;
+ private final DynamicScope scope;
private final Script script;
- public EmbedEvalUnitImpl(ScriptingContainer container, Node node, ManyVarsDynamicScope scope) {
+ public EmbedEvalUnitImpl(ScriptingContainer container, Node node, DynamicScope scope) {
this(container, node, scope, null);
}
- public EmbedEvalUnitImpl(ScriptingContainer container, Node node, ManyVarsDynamicScope scope, Script script) {
+ public EmbedEvalUnitImpl(ScriptingContainer container, Node node, DynamicScope scope, Script script) {
this.container = container;
this.node = node;
this.scope = scope;
@@ -86,7 +86,7 @@ public class EmbedEvalUnitImpl implements EmbedEvalUnit {
*
* @return a scope to refer local variables
*/
- public ManyVarsDynamicScope getScope() {
+ public DynamicScope getScope() {
return scope;
}
diff --git a/core/src/main/java/org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java b/core/src/main/java/org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java
index 292ca61..6304313 100644
--- a/core/src/main/java/org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java
+++ b/core/src/main/java/org/jruby/embed/internal/EmbedRubyObjectAdapterImpl.java
@@ -48,11 +48,11 @@ import org.jruby.javasupport.Java;
import org.jruby.javasupport.JavaEmbedUtils;
import org.jruby.javasupport.JavaObject;
import org.jruby.javasupport.JavaUtil;
+import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Helpers;
import org.jruby.runtime.Block;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
* Implementation of {@link EmbedRubyObjectAdapter}. Users get an instance of this
@@ -298,9 +298,9 @@ public class EmbedRubyObjectAdapterImpl implements EmbedRubyObjectAdapter {
}
if (sharing_variables) {
- ManyVarsDynamicScope scope;
+ DynamicScope scope;
if (unit != null && unit.getScope() != null) scope = unit.getScope();
- else scope = EmbedRubyRuntimeAdapterImpl.getManyVarsDynamicScope(container, 0);
+ else scope = EmbedRubyRuntimeAdapterImpl.getDynamicScope(container, 0);
container.getVarMap().inject(scope, 0, rubyReceiver);
runtime.getCurrentContext().pushScope(scope);
}
diff --git a/core/src/main/java/org/jruby/embed/internal/EmbedRubyRuntimeAdapterImpl.java b/core/src/main/java/org/jruby/embed/internal/EmbedRubyRuntimeAdapterImpl.java
index b7806c8..4caab7d 100644
--- a/core/src/main/java/org/jruby/embed/internal/EmbedRubyRuntimeAdapterImpl.java
+++ b/core/src/main/java/org/jruby/embed/internal/EmbedRubyRuntimeAdapterImpl.java
@@ -63,7 +63,6 @@ import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.IAccessor;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.load.LoadService;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
*
@@ -174,14 +173,14 @@ public class EmbedRubyRuntimeAdapterImpl implements EmbedRubyRuntimeAdapter {
line = lines[0];
}
try {
- ManyVarsDynamicScope scope = null;
+ DynamicScope scope = null;
boolean sharing_variables = true;
Object obj = container.getAttribute(AttributeName.SHARING_VARIABLES);
if (obj != null && obj instanceof Boolean && ((Boolean) obj) == false) {
sharing_variables = false;
}
if (sharing_variables) {
- scope = getManyVarsDynamicScope(container, 0);
+ scope = getDynamicScope(container, 0);
}
final Node node;
if (input instanceof String) {
@@ -216,20 +215,20 @@ public class EmbedRubyRuntimeAdapterImpl implements EmbedRubyRuntimeAdapter {
}
}
- static ManyVarsDynamicScope getManyVarsDynamicScope(ScriptingContainer container, int depth) {
- ManyVarsDynamicScope scope;
+ static DynamicScope getDynamicScope(ScriptingContainer container, int depth) {
+ DynamicScope scope;
StaticScopeFactory scopeFactory = container.getProvider().getRuntime().getStaticScopeFactory();
// root our parsing scope with a dummy scope
StaticScope topStaticScope = scopeFactory.newLocalScope(null);
topStaticScope.setModule(container.getProvider().getRuntime().getObject());
- DynamicScope currentScope = new ManyVarsDynamicScope(topStaticScope, null);
+ DynamicScope currentScope = DynamicScope.newDynamicScope(topStaticScope, null);
String[] names4Injection = container.getVarMap().getLocalVarNames();
StaticScope evalScope = names4Injection == null || names4Injection.length == 0 ?
scopeFactory.newEvalScope(currentScope.getStaticScope()) :
scopeFactory.newEvalScope(currentScope.getStaticScope(), names4Injection);
- scope = new ManyVarsDynamicScope(evalScope, currentScope);
+ scope = DynamicScope.newDynamicScope(evalScope, currentScope);
// JRUBY-5501: ensure we've set up a cref for the scope too
scope.getStaticScope().determineModule();
diff --git a/core/src/main/java/org/jruby/embed/variable/PersistentLocalVariable.java b/core/src/main/java/org/jruby/embed/variable/PersistentLocalVariable.java
index 0699cee..9f7e75c 100644
--- a/core/src/main/java/org/jruby/embed/variable/PersistentLocalVariable.java
+++ b/core/src/main/java/org/jruby/embed/variable/PersistentLocalVariable.java
@@ -32,9 +32,7 @@ package org.jruby.embed.variable;
import org.jruby.RubyObject;
import org.jruby.embed.internal.BiVariableMap;
import org.jruby.runtime.DynamicScope;
-import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
* An implementation of BiVariable for a persistent local variable. This type of
@@ -107,8 +105,7 @@ public class PersistentLocalVariable extends AbstractVariable {
* @param vars map to save retrieved local variables.
*/
public static void retrieve(RubyObject receiver, BiVariableMap vars) {
- ManyVarsDynamicScope scope =
- (ManyVarsDynamicScope) receiver.getRuntime().getCurrentContext().getCurrentScope();
+ DynamicScope scope = receiver.getRuntime().getCurrentContext().getCurrentScope();
if (scope == null) {
return;
}
@@ -146,15 +143,5 @@ public class PersistentLocalVariable extends AbstractVariable {
*/
@Override
public void remove() {
- final ThreadContext context = getCurrentContext();
- try {
- DynamicScope currentScope = context.getCurrentScope();
- ManyVarsDynamicScope scope = (ManyVarsDynamicScope) context.getCurrentScope();
- scope = new ManyVarsDynamicScope(context.runtime.getStaticScopeFactory().newEvalScope(currentScope.getStaticScope()), currentScope);
- }
- catch (ArrayIndexOutOfBoundsException e) {
- //no context is left.
- //no operation is needed.
- }
}
}
diff --git a/core/src/main/java/org/jruby/embed/variable/VariableInterceptor.java b/core/src/main/java/org/jruby/embed/variable/VariableInterceptor.java
index 0853bdc..bbd15b6 100644
--- a/core/src/main/java/org/jruby/embed/variable/VariableInterceptor.java
+++ b/core/src/main/java/org/jruby/embed/variable/VariableInterceptor.java
@@ -38,8 +38,8 @@ import org.jruby.Ruby;
import org.jruby.RubyObject;
import org.jruby.embed.internal.BiVariableMap;
import org.jruby.embed.LocalVariableBehavior;
+import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
/**
* This class is responsible to local variable behavior dependent processing.
@@ -127,7 +127,7 @@ public class VariableInterceptor {
* @param depth depth of a frame to inject local variable values
* @param receiver a receiver when the script has been evaluated once
*/
- public static void inject(BiVariableMap map, Ruby runtime, ManyVarsDynamicScope scope, int depth, IRubyObject receiver) {
+ public static void inject(BiVariableMap map, Ruby runtime, DynamicScope scope, int depth, IRubyObject receiver) {
// lvar might not be given while parsing but be given when evaluating.
// to avoid ArrayIndexOutOfBoundsException, checks the length of scope.getValues()
if (scope != null && scope.getValues().length > 0) {
diff --git a/core/src/main/java/org/jruby/ir/Compiler.java b/core/src/main/java/org/jruby/ir/Compiler.java
index d0f4925..56c344a 100644
--- a/core/src/main/java/org/jruby/ir/Compiler.java
+++ b/core/src/main/java/org/jruby/ir/Compiler.java
@@ -102,7 +102,7 @@ public class Compiler extends IRTranslator<ScriptAndCode, ClassDefiningClassLoad
} else {
sscope = tlbScope.getStaticScope();
context.preScopedBody(tlbScope);
- tlbScope.growIfNeeded();
+// tlbScope.growIfNeeded();
}
context.setCurrentVisibility(Visibility.PRIVATE);
diff --git a/core/src/main/java/org/jruby/ir/interpreter/Interpreter.java b/core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
index 60050b1..597cee9 100644
--- a/core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
+++ b/core/src/main/java/org/jruby/ir/interpreter/Interpreter.java
@@ -27,7 +27,6 @@ import org.jruby.runtime.Frame;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.Visibility;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.util.cli.Options;
import org.jruby.util.log.Logger;
import org.jruby.util.log.LoggerFactory;
@@ -90,7 +89,7 @@ public class Interpreter extends IRTranslator<IRubyObject, IRubyObject> {
context.preMethodScopeOnly(scope);
} else {
context.preScopedBody(tlbScope);
- tlbScope.growIfNeeded();
+// tlbScope.growIfNeeded();
}
context.setCurrentVisibility(Visibility.PRIVATE);
@@ -150,7 +149,7 @@ public class Interpreter extends IRTranslator<IRubyObject, IRubyObject> {
// no binding, just eval in "current" frame (caller's frame)
DynamicScope parentScope = context.getCurrentScope();
- DynamicScope evalScope = new ManyVarsDynamicScope(runtime.getStaticScopeFactory().newEvalScope(parentScope.getStaticScope()), parentScope);
+ DynamicScope evalScope = DynamicScope.newDynamicScope(runtime.getStaticScopeFactory().newEvalScope(parentScope.getStaticScope()), parentScope);
evalScope.getStaticScope().setModule(under);
context.pushEvalSimpleFrame(self);
@@ -170,7 +169,7 @@ public class Interpreter extends IRTranslator<IRubyObject, IRubyObject> {
evalScope.setEvalType(evalType);
context.pushScope(evalScope);
try {
- evalScope.growIfNeeded();
+// evalScope.growIfNeeded();
runBeginBlocks(ic.getBeginBlocks(), context, self, ss, null);
diff --git a/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java b/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
index c0845a2..f57f108 100644
--- a/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
+++ b/core/src/main/java/org/jruby/ir/targets/JVMVisitor.java
@@ -392,41 +392,7 @@ public class JVMVisitor extends IRVisitor {
private void jvmStoreLocal(Variable variable) {
if (variable instanceof LocalVariable) {
-
- LocalVariable localvariable = (LocalVariable) variable;
-
- jvmLoadLocal(DYNAMIC_SCOPE);
-
- jvmAdapter().swap();
-
- if (localvariable.getScopeDepth() == 0) {
-
- switch (localvariable.getOffset()) {
- case 0:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueZeroDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 1:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueOneDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 2:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueTwoDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 3:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueThreeDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- default:
- jvmAdapter().ldc(localvariable.getOffset());
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueDepthZeroVoid", sig(void.class, IRubyObject.class, int.class));
- break;
- }
-
- } else {
-
- jvmAdapter().ldc(localvariable.getOffset());
- jvmAdapter().ldc(localvariable.getScopeDepth());
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueVoid", sig(void.class, IRubyObject.class, int.class, int.class));
-
- }
+ storeLocalVariable((LocalVariable) variable);
} else if (variable instanceof TemporaryLocalVariable) {
switch (((TemporaryLocalVariable)variable).getType()) {
case FLOAT: jvmAdapter().dstore(getJVMLocalVarIndex(variable)); break;
@@ -441,44 +407,7 @@ public class JVMVisitor extends IRVisitor {
private void jvmStoreLocal(Runnable source, Variable variable) {
if (variable instanceof LocalVariable) {
-
- LocalVariable localvariable = (LocalVariable) variable;
-
- jvmLoadLocal(DYNAMIC_SCOPE);
-
- if (localvariable.getScopeDepth() == 0) {
-
- source.run();
-
- switch (localvariable.getOffset()) {
- case 0:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueZeroDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 1:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueOneDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 2:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueTwoDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- case 3:
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueThreeDepthZeroVoid", sig(void.class, IRubyObject.class));
- break;
- default:
- jvmAdapter().ldc(localvariable.getOffset());
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueDepthZeroVoid", sig(void.class, IRubyObject.class, int.class));
- break;
- }
-
- } else {
-
- source.run();
-
- jvmAdapter().ldc(localvariable.getOffset());
- jvmAdapter().ldc(localvariable.getScopeDepth());
-
- jvmAdapter().invokevirtual(p(DynamicScope.class), "setValueVoid", sig(void.class, IRubyObject.class, int.class, int.class));
-
- }
+ storeLocalVariable((LocalVariable) variable, source);
} else if (variable instanceof TemporaryLocalVariable) {
source.run();
@@ -2055,48 +1984,53 @@ public class JVMVisitor extends IRVisitor {
@Override
public void StoreLocalVarInstr(StoreLocalVarInstr storelocalvarinstr) {
+ LocalVariable localvariable = storelocalvarinstr.getLocalVar();
+ Operand storeValue = storelocalvarinstr.getValue();
+
+ storeLocalVariable(localvariable, storeValue);
+ }
+
+ private void storeLocalVariable(LocalVariable localvariable) {
+ storeLocalVariable(localvariable, new Runnable() {
+ @Override
+ public void run() {
+ jvmAdapter().swap();
+ }
+ });
+ }
+
+ private void storeLocalVariable(LocalVariable localvariable, final Operand storeValue) {
+ storeLocalVariable(localvariable, new Runnable() {
+ @Override
+ public void run() {
+ storeValue.visit(JVMVisitor.this);
+ }
+ });
+ }
+
+ private void storeLocalVariable(LocalVariable localvariable, Runnable storeValue) {
IRBytecodeAdapter m = jvmMethod();
+ int depth = localvariable.getScopeDepth();
+ int location = localvariable.getLocation();
+ StaticScope scope = jvm.methodData().scope.getStaticScope().getNthEnclosingScope(depth);
+
jvmLoadLocal(DYNAMIC_SCOPE);
- int depth = storelocalvarinstr.getLocalVar().getScopeDepth();
- int location = storelocalvarinstr.getLocalVar().getLocation();
- Operand storeValue = storelocalvarinstr.getValue();
- switch (depth) {
- case 0:
- switch (location) {
- case 0:
- storeValue.visit(this);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValueZeroDepthZero", sig(IRubyObject.class, IRubyObject.class));
- m.adapter.pop();
- return;
- case 1:
- storeValue.visit(this);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValueOneDepthZero", sig(IRubyObject.class, IRubyObject.class));
- m.adapter.pop();
- return;
- case 2:
- storeValue.visit(this);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValueTwoDepthZero", sig(IRubyObject.class, IRubyObject.class));
- m.adapter.pop();
- return;
- case 3:
- storeValue.visit(this);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValueThreeDepthZero", sig(IRubyObject.class, IRubyObject.class));
- m.adapter.pop();
- return;
- default:
- storeValue.visit(this);
- m.adapter.pushInt(location);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValueDepthZero", sig(IRubyObject.class, IRubyObject.class, int.class));
- m.adapter.pop();
- return;
- }
- default:
- m.adapter.pushInt(location);
- storeValue.visit(this);
- m.adapter.pushInt(depth);
- m.adapter.invokevirtual(p(DynamicScope.class), "setValue", sig(IRubyObject.class, int.class, IRubyObject.class, int.class));
- m.adapter.pop();
+
+ if (depth != 0) {
+ m.adapter.pushInt(depth);
+ m.adapter.invokevirtual(p(DynamicScope.class), "getNthParentScope", sig(DynamicScope.class, int.class));
}
+
+ int numberOfVariables = scope.getNumberOfVariables();
+ if (numberOfVariables == 0) {
+ throw new RuntimeException("attempting to access a variable from a zero-width scope: " + jvm.methodData().scope);
+ }
+ String scopeName = "org/jruby/runtime/scopes/DynamicScope" + numberOfVariables;
+ jvmAdapter().checkcast(scopeName);
+
+ storeValue.run();
+
+ jvmAdapter().putfield(scopeName, "var" + location, ci(IRubyObject.class));
}
@Override
@@ -2363,34 +2297,25 @@ public class JVMVisitor extends IRVisitor {
@Override
public void LocalVariable(LocalVariable localvariable) {
IRBytecodeAdapter m = jvmMethod();
- jvmLoadLocal(DYNAMIC_SCOPE);
int depth = localvariable.getScopeDepth();
int location = localvariable.getLocation();
- OUTER: switch (depth) {
- case 0:
- switch (location) {
- case 0:
- m.adapter.invokevirtual(p(DynamicScope.class), "getValueZeroDepthZero", sig(IRubyObject.class));
- break OUTER;
- case 1:
- m.adapter.invokevirtual(p(DynamicScope.class), "getValueOneDepthZero", sig(IRubyObject.class));
- break OUTER;
- case 2:
- m.adapter.invokevirtual(p(DynamicScope.class), "getValueTwoDepthZero", sig(IRubyObject.class));
- break OUTER;
- case 3:
- m.adapter.invokevirtual(p(DynamicScope.class), "getValueThreeDepthZero", sig(IRubyObject.class));
- break OUTER;
- default:
- m.adapter.pushInt(location);
- m.adapter.invokevirtual(p(DynamicScope.class), "getValueDepthZero", sig(IRubyObject.class, int.class));
- break OUTER;
- }
- default:
- m.adapter.pushInt(location);
- m.adapter.pushInt(depth);
- m.adapter.invokevirtual(p(DynamicScope.class), "getValue", sig(IRubyObject.class, int.class, int.class));
+ StaticScope scope = jvm.methodData().scope.getStaticScope().getNthEnclosingScope(depth);
+
+ jvmLoadLocal(DYNAMIC_SCOPE);
+
+ if (depth != 0) {
+ m.adapter.pushInt(depth);
+ m.adapter.invokevirtual(p(DynamicScope.class), "getNthParentScope", sig(DynamicScope.class, int.class));
}
+
+ int numberOfVariables = scope.getNumberOfVariables();
+ if (numberOfVariables == 0) {
+ throw new RuntimeException("attempting to access a variable from a zero-width scope: " + jvm.methodData().scope);
+ }
+ String scopeName = "org/jruby/runtime/scopes/DynamicScope" + numberOfVariables;
+ jvmAdapter().checkcast(scopeName);
+
+ jvmAdapter().getfield(scopeName, "var" + location, ci(IRubyObject.class));
}
@Override
diff --git a/core/src/main/java/org/jruby/parser/Parser.java b/core/src/main/java/org/jruby/parser/Parser.java
index 88bf152..3f17552 100644
--- a/core/src/main/java/org/jruby/parser/Parser.java
+++ b/core/src/main/java/org/jruby/parser/Parser.java
@@ -150,7 +150,7 @@ public class Parser {
// currently since we create the DynamicScope for a LocalStaticScope before parse begins.
// Refactoring should make this fixable.
if (result.getScope() != null) {
- result.getScope().growIfNeeded();
+// result.getScope().growIfNeeded();
}
Node ast = result.getAST();
diff --git a/core/src/main/java/org/jruby/parser/ParserConfiguration.java b/core/src/main/java/org/jruby/parser/ParserConfiguration.java
index ad685b0..af01628 100644
--- a/core/src/main/java/org/jruby/parser/ParserConfiguration.java
+++ b/core/src/main/java/org/jruby/parser/ParserConfiguration.java
@@ -37,7 +37,6 @@ import org.jruby.RubyInstanceConfig;
import org.jruby.ext.coverage.CoverageData;
import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.encoding.EncodingService;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.util.KCode;
import java.util.Arrays;
@@ -160,7 +159,7 @@ public class ParserConfiguration {
// will always happen because of $~ and $_).
// FIXME: Because we end up adjusting this after-the-fact, we can't use
// any of the specific-size scopes.
- return new ManyVarsDynamicScope(runtime.getStaticScopeFactory().newLocalScope(null, file), existingScope);
+ return DynamicScope.newDynamicScope(50, runtime.getStaticScopeFactory().newLocalScope(null, file), runtime.getJRubyClassLoader(), existingScope);
}
public boolean isCoverageEnabled() {
diff --git a/core/src/main/java/org/jruby/parser/StaticScope.java b/core/src/main/java/org/jruby/parser/StaticScope.java
index 402bd46..91ad186 100644
--- a/core/src/main/java/org/jruby/parser/StaticScope.java
+++ b/core/src/main/java/org/jruby/parser/StaticScope.java
@@ -47,7 +47,6 @@ import org.jruby.runtime.DynamicScope;
import org.jruby.runtime.Signature;
import org.jruby.runtime.ThreadContext;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.DummyDynamicScope;
/**
* StaticScope represents lexical scoping of variables and module/class constants.
@@ -314,6 +313,20 @@ public class StaticScope implements Serializable {
}
/**
+ * Get the nth enclosing scope.
+ *
+ * @param nth how deep to dig
+ * @return the nth enclosing scope
+ */
+ public StaticScope getNthEnclosingScope(int nth) {
+ StaticScope scope = this;
+ for (int i = 0; i < nth; i++) {
+ scope = scope.getEnclosingScope();
+ }
+ return scope;
+ }
+
+ /**
* Does the variable exist?
*
* @param name of the variable to find
@@ -526,7 +539,7 @@ public class StaticScope implements Serializable {
}
public DynamicScope getDummyScope() {
- return dummyScope == null ? dummyScope = new DummyDynamicScope(this) : dummyScope;
+ return dummyScope == null ? dummyScope = DynamicScope.newDynamicScope(this) : dummyScope;
}
public void setCommandArgumentStack(long commandArgumentStack) {
diff --git a/core/src/main/java/org/jruby/runtime/Binding.java b/core/src/main/java/org/jruby/runtime/Binding.java
index fe483e1..55dec8b 100644
--- a/core/src/main/java/org/jruby/runtime/Binding.java
+++ b/core/src/main/java/org/jruby/runtime/Binding.java
@@ -38,8 +38,6 @@ import org.jruby.parser.StaticScopeFactory;
import org.jruby.runtime.backtrace.BacktraceElement;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
-import org.jruby.runtime.scope.NoVarsDynamicScope;
/**
* Internal live representation of a block ({...} or do ... end).
@@ -52,7 +50,7 @@ public class Binding {
// Can't use Frame.DUMMY because of circular static init seeing it before it's assigned
new Frame(),
Visibility.PUBLIC,
- new NoVarsDynamicScope(StaticScopeFactory.newStaticScope(null, StaticScope.Type.BLOCK, null)),
+ DynamicScope.newDynamicScope(StaticScopeFactory.newStaticScope(null, StaticScope.Type.BLOCK, null)),
"<dummy>",
"dummy",
-1);
@@ -282,7 +280,7 @@ public class Binding {
// No eval scope set, so we create one
if (evalScopeBinding.evalScope == null) {
// bindings scopes must always be ManyVars scopes since evals can grow them
- evalScopeBinding.evalScope = new ManyVarsDynamicScope(runtime.getStaticScopeFactory().newEvalScope(dynamicScope.getStaticScope()), dynamicScope);
+ evalScopeBinding.evalScope = DynamicScope.newDynamicScope(runtime.getStaticScopeFactory().newEvalScope(dynamicScope.getStaticScope()), dynamicScope);
}
return evalScopeBinding.evalScope;
diff --git a/core/src/main/java/org/jruby/runtime/DynamicScope.java b/core/src/main/java/org/jruby/runtime/DynamicScope.java
index 6b6313f..1a72964 100644
--- a/core/src/main/java/org/jruby/runtime/DynamicScope.java
+++ b/core/src/main/java/org/jruby/runtime/DynamicScope.java
@@ -34,14 +34,12 @@ import me.qmx.jitescript.internal.org.objectweb.asm.Label;
import me.qmx.jitescript.internal.org.objectweb.asm.tree.LabelNode;
import org.jruby.EvalType;
import org.jruby.Ruby;
-import org.jruby.runtime.scope.NoVarsDynamicScope;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.runtime.scope.DummyDynamicScope;
import static org.jruby.util.CodegenUtils.*;
-import org.jruby.util.OneShotClassLoader;
+import org.jruby.util.JRubyClassLoader;
import org.jruby.util.collections.NonBlockingHashMapLong;
public abstract class DynamicScope {
@@ -66,12 +64,14 @@ public abstract class DynamicScope {
}
public static DynamicScope newDynamicScope(StaticScope staticScope, DynamicScope parent) {
- switch (staticScope.getNumberOfVariables()) {
- case 0:
- return new NoVarsDynamicScope(staticScope, parent);
- default:
- return construct(staticScope, parent);
- }
+ JRubyClassLoader loader = staticScope.getModule() == null ?
+ new JRubyClassLoader(Ruby.getClassLoader()) :
+ staticScope.getModule().getRuntime().getJRubyClassLoader();
+ return construct(staticScope.getNumberOfVariables(), staticScope, parent, loader);
+ }
+
+ public static DynamicScope newDynamicScope(int size, StaticScope staticScope, JRubyClassLoader loader, DynamicScope parent) {
+ return construct(size, staticScope, parent, loader);
}
private static final NonBlockingHashMapLong<Class<? extends DynamicScope>> prototypes = new NonBlockingHashMapLong<>();
@@ -80,8 +80,8 @@ public abstract class DynamicScope {
return prototypes.get(size);
}
- public static DynamicScope construct(StaticScope staticScope, DynamicScope parent) {
- Class<DynamicScope> tupleType = generate(staticScope.getNumberOfVariables());
+ private static DynamicScope construct(int size, StaticScope staticScope, DynamicScope parent, JRubyClassLoader cl) {
+ Class<DynamicScope> tupleType = generate(size, cl);
try {
return tupleType.getConstructor(StaticScope.class, DynamicScope.class).newInstance(staticScope, parent);
} catch (Exception e) {
@@ -89,7 +89,7 @@ public abstract class DynamicScope {
}
}
- public static Class<DynamicScope> generate(final int size) {
+ private static Class<DynamicScope> generate(final int size, JRubyClassLoader cl) {
Class p = protoClassFromProps(size);
final String name = "org/jruby/runtime/scopes/DynamicScope" + size;
@@ -120,15 +120,17 @@ public abstract class DynamicScope {
cases[i] = new LabelNode(new Label());
}
ifne(superCall);
- iload(1);
- tableswitch(0, size - 1, defaultError, cases);
- for (int i = 0; i < size; i++) {
- label(cases[i]);
- aload(0);
- getfield(name, newFields[i], ci(IRubyObject.class));
- areturn();
+ if (size > 0) {
+ iload(1);
+ tableswitch(0, size - 1, defaultError, cases);
+ for (int i = 0; i < size; i++) {
+ label(cases[i]);
+ aload(0);
+ getfield(name, newFields[i], ci(IRubyObject.class));
+ areturn();
+ }
+ label(defaultError);
}
- label(defaultError);
line(1);
newobj(p(RuntimeException.class));
dup();
@@ -158,17 +160,19 @@ public abstract class DynamicScope {
cases[i] = new LabelNode(new Label());
}
ifne(superCall);
- iload(1);
- tableswitch(0, size - 1, defaultError, cases);
- for (int i = 0; i < size; i++) {
- label(cases[i]);
- aload(0);
- aload(2);
- putfield(name, newFields[i], ci(IRubyObject.class));
- aload(2);
- areturn();
+ if (size > 0) {
+ iload(1);
+ tableswitch(0, size - 1, defaultError, cases);
+ for (int i = 0; i < size; i++) {
+ label(cases[i]);
+ aload(0);
+ aload(2);
+ putfield(name, newFields[i], ci(IRubyObject.class));
+ aload(2);
+ areturn();
+ }
+ label(defaultError);
}
- label(defaultError);
line(4);
newobj(p(RuntimeException.class));
dup();
@@ -194,7 +198,7 @@ public abstract class DynamicScope {
}
}};
- p = defineClass(jiteClass);
+ p = defineClass(jiteClass, cl);
prototypes.put(size, p);
}
@@ -204,9 +208,8 @@ public abstract class DynamicScope {
}
}
- private static Class defineClass(JiteClass jiteClass) {
- return new OneShotClassLoader(Ruby.getClassLoader())
- .defineClass(jiteClass.getClassName().replaceAll("/", "."), jiteClass.toBytes(JDKVersion.V1_7));
+ private static Class defineClass(JiteClass jiteClass, JRubyClassLoader cl) {
+ return cl.defineClass(jiteClass.getClassName().replaceAll("/", "."), jiteClass.toBytes(JDKVersion.V1_7));
}
public static String[] varList(int size) {
@@ -219,6 +222,12 @@ public abstract class DynamicScope {
return vars;
}
+ public static DynamicScope newDynamicScope(int size, JRubyClassLoader loader, StaticScope staticScope, DynamicScope parent, EvalType evalType) {
+ DynamicScope newScope = DynamicScope.newDynamicScope(size, staticScope, loader, parent);
+ newScope.setEvalType(evalType);
+ return newScope;
+ }
+
public static DynamicScope newDynamicScope(StaticScope staticScope, DynamicScope parent, EvalType evalType) {
DynamicScope newScope = newDynamicScope(staticScope, parent);
newScope.setEvalType(evalType);
@@ -226,7 +235,7 @@ public abstract class DynamicScope {
}
public static DynamicScope newDummyScope(StaticScope staticScope, DynamicScope parent) {
- return new DummyDynamicScope(staticScope, parent);
+ return DynamicScope.newDynamicScope(staticScope, parent);
}
/**
diff --git a/core/src/main/java/org/jruby/runtime/ThreadContext.java b/core/src/main/java/org/jruby/runtime/ThreadContext.java
index 02adf80..842cbe0 100644
--- a/core/src/main/java/org/jruby/runtime/ThreadContext.java
+++ b/core/src/main/java/org/jruby/runtime/ThreadContext.java
@@ -56,7 +56,6 @@ import org.jruby.runtime.backtrace.TraceType;
import org.jruby.runtime.backtrace.TraceType.Gather;
import org.jruby.runtime.builtin.IRubyObject;
import org.jruby.runtime.profile.ProfileCollection;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.util.RecursiveComparator;
import org.jruby.util.RubyDateFormatter;
import org.jruby.util.cli.Options;
@@ -198,7 +197,8 @@ public final class ThreadContext {
// TOPLEVEL self and a few others want a top-level scope. We create this one right
// away and then pass it into top-level parse so it ends up being the top level.
StaticScope topStaticScope = runtime.getStaticScopeFactory().newLocalScope(null);
- pushScope(new ManyVarsDynamicScope(topStaticScope, null));
+ topStaticScope.setModule(runtime.getObject());
+ pushScope(DynamicScope.newDynamicScope(topStaticScope, null));
Frame[] stack = frameStack;
int length = stack.length;
diff --git a/core/src/main/java/org/jruby/runtime/scope/DummyDynamicScope.java b/core/src/main/java/org/jruby/runtime/scope/DummyDynamicScope.java
deleted file mode 100644
index 64878db..0000000
--- a/core/src/main/java/org/jruby/runtime/scope/DummyDynamicScope.java
+++ /dev/null
@@ -1,40 +0,0 @@
-package org.jruby.runtime.scope;
-
-import org.jruby.parser.StaticScope;
-import org.jruby.runtime.DynamicScope;
-
-/**
- * This is a DynamicScope that does not support any variables. It differs from
- * NoVarsDynamicScope in that it has hard failures for "backref" and "lastline"
- * accesses, since in the JRuby 1.3 cycle it was discovered that threads were
- * sharing a single dummyscope while still setting per-call backrefs. The hard
- * errors here are an attempt to catch such situations in the future, before
- * the optimizing compiler work makes such determinations in advance.
- */
-public class DummyDynamicScope extends NoVarsDynamicScope {
- private static final int SIZE = 0;
- private static final String GROW_ERROR = "DummyDynamicScope cannot be grown; use ManyVarsDynamicScope";
-
- public DummyDynamicScope(StaticScope staticScope, DynamicScope parent) {
- super(staticScope, parent);
- }
-
- public DummyDynamicScope(StaticScope staticScope) {
- super(staticScope);
- }
-
- public void growIfNeeded() {
- growIfNeeded(SIZE, GROW_ERROR);
- }
-
- protected void growIfNeeded(int size, String message) {
- if (staticScope.getNumberOfVariables() != size) {
- throw new RuntimeException(message);
- }
- }
-
- public DynamicScope cloneScope() {
- // there should be no mutable state in this scope, so return same
- return this;
- }
-}
diff --git a/core/src/main/java/org/jruby/runtime/scope/ManyVarsDynamicScope.java b/core/src/main/java/org/jruby/runtime/scope/ManyVarsDynamicScope.java
deleted file mode 100644
index 3372869..0000000
--- a/core/src/main/java/org/jruby/runtime/scope/ManyVarsDynamicScope.java
+++ /dev/null
@@ -1,268 +0,0 @@
-package org.jruby.runtime.scope;
-
-import org.jruby.parser.StaticScope;
-import org.jruby.runtime.DynamicScope;
-import org.jruby.runtime.builtin.IRubyObject;
-import org.jruby.util.ArraySupport;
-
-/**
- * Represents the the dynamic portion of scoping information. The variableValues are the
- * values of assigned local or block variables. The staticScope identifies which sort of
- * scope this is (block or local).
- *
- * Properties of Dynamic Scopes:
- * 1. static and dynamic scopes have the same number of names to values
- * 2. size of variables (and thus names) is determined during parsing. So those structured do
- * not need to change
- *
- * FIXME: When creating dynamic scopes we sometimes accidentally pass in extra parents. This
- * is harmless (other than wasting memory), but we should not do that. We can fix this in two
- * ways:
- * 1. Fix all callers
- * 2. Check parent that is passed in and make if new instance is local, then its parent is not local
- */
-public class ManyVarsDynamicScope extends DynamicScope {
- // Our values holder (name of variables are kept in staticScope)
- private IRubyObject[] variableValues;
-
- public ManyVarsDynamicScope(StaticScope staticScope, DynamicScope parent) {
- super(staticScope, parent);
- allocate();
- }
-
- public ManyVarsDynamicScope(StaticScope staticScope) {
- super(staticScope);
- allocate();
- }
-
- private void allocate() {
- if(variableValues == null) {
- int size = staticScope.getNumberOfVariables();
- variableValues = new IRubyObject[size];
- }
- }
-
- public DynamicScope cloneScope() {
- return new ManyVarsDynamicScope(staticScope, parent);
- }
-
- public IRubyObject[] getValues() {
- return variableValues;
- }
-
- /**
- * Get value from current scope or one of its captured scopes.
- *
- * FIXME: block variables are not getting primed to nil so we need to null check those
- * until we prime them properly. Also add assert back in.
- *
- * @param offset zero-indexed value that represents where variable lives
- * @param depth how many captured scopes down this variable should be set
- * @return the value here
- */
- public IRubyObject getValue(int offset, int depth) {
- if (depth > 0) {
- return parent.getValue(offset, depth - 1);
- }
- assertGetValue(offset, depth);
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- return variableValues[offset];
- }
-
- public IRubyObject getValueDepthZero(int offset) {
- return variableValues[offset];
- }
-
- public IRubyObject getValueZeroDepthZero() {
- return variableValues[0];
- }
-
- public IRubyObject getValueOneDepthZero() {
- return variableValues[1];
- }
-
- public IRubyObject getValueTwoDepthZero() {
- return variableValues[2];
- }
-
- public IRubyObject getValueThreeDepthZero() {
- return variableValues[3];
- }
-
- /**
- * Variation of getValue that checks for nulls, returning and setting the given value (presumably nil)
- */
- public IRubyObject getValueOrNil(int offset, int depth, IRubyObject nil) {
- if (depth > 0) {
- return parent.getValueOrNil(offset, depth - 1, nil);
- } else {
- return getValueDepthZeroOrNil(offset, nil);
- }
- }
-
- public IRubyObject getValueDepthZeroOrNil(int offset, IRubyObject nil) {
- assertGetValueDepthZeroOrNil(offset);
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- IRubyObject value = variableValues[offset];
- return value == null ? setValueDepthZero(nil, offset) : value;
- }
-
- public IRubyObject getValueZeroDepthZeroOrNil(IRubyObject nil) {
- assertGetValueZeroDepthZeroOrNil();
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- IRubyObject value = variableValues[0];
- return value == null ? setValueZeroDepthZero(nil) : value;
- }
-
- public IRubyObject getValueOneDepthZeroOrNil(IRubyObject nil) {
- assertGetValueOneDepthZeroOrNil();
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- IRubyObject value = variableValues[1];
- return value == null ? setValueOneDepthZero(nil) : value;
- }
-
- public IRubyObject getValueTwoDepthZeroOrNil(IRubyObject nil) {
- assertGetValueTwoDepthZeroOrNil();
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- IRubyObject value = variableValues[2];
- return value == null ? setValueTwoDepthZero(nil) : value;
- }
-
- public IRubyObject getValueThreeDepthZeroOrNil(IRubyObject nil) {
- assertGetValueThreeDepthZeroOrNil();
- // &foo are not getting set from somewhere...I want the following assert to be true though
- //assert variableValues[offset] != null : "Getting unassigned: " + staticScope.getVariables()[offset];
- IRubyObject value = variableValues[3];
- return value == null ? setValueThreeDepthZero(nil) : value;
- }
-
- /**
- * Set value in current dynamic scope or one of its captured scopes.
- *
- * @param offset zero-indexed value that represents where variable lives
- * @param value to set
- * @param depth how many captured scopes down this variable should be set
- */
- public IRubyObject setValue(int offset, IRubyObject value, int depth) {
- if (depth > 0) {
- assertParent();
-
- return parent.setValue(offset, value, depth - 1);
- } else {
- assertSetValue(offset, value);
-
- return setValueDepthZero(value, offset);
- }
- }
-
- public IRubyObject setValueDepthZero(IRubyObject value, int offset) {
- assertSetValueDepthZero(offset, value);
-
- return variableValues[offset] = value;
- }
- public IRubyObject setValueZeroDepthZero(IRubyObject value) {
- assertSetValueZeroDepthZero(value);
-
- return variableValues[0] = value;
- }
- public IRubyObject setValueOneDepthZero(IRubyObject value) {
- assertSetValueOneDepthZero(value);
-
- return variableValues[1] = value;
- }
- public IRubyObject setValueTwoDepthZero(IRubyObject value) {
- assertSetValueTwoDepthZero(value);
-
- return variableValues[2] = value;
- }
- public IRubyObject setValueThreeDepthZero(IRubyObject value) {
- assertSetValueThreeDepthZero(value);
-
- return variableValues[3] = value;
- }
-
- /**
- *
- * Make a larger dynamic scope if the static scope grew.
- *
- * Eval's with bindings require us to possibly change the size of the dynamic scope if
- * things like 'eval "b = 2", binding' happens.
- *
- */
- public void growIfNeeded() {
- int dynamicSize = variableValues == null ? 0: variableValues.length;
-
- if (staticScope.getNumberOfVariables() > dynamicSize) {
- IRubyObject values[] = new IRubyObject[staticScope.getNumberOfVariables()];
-
- if (dynamicSize > 0) {
- ArraySupport.copy(variableValues, 0, values, 0, dynamicSize);
- }
-
- variableValues = values;
- }
- }
-
- private void assertGetValue(int offset, int depth) {
- IRubyObject[] values = variableValues;
- assert values != null && offset < values.length : "No variables or index to big for getValue off: " + offset + ", Dep: " + depth + ", O: " + this;
- }
-
- private void assertGetValueDepthZeroOrNil(int offset) {
- IRubyObject[] values = variableValues;
- assert values != null && offset < values.length : "No variables or index too big for getValue off: " + offset + ", Dep: " + 0 + ", O: " + this;
- }
-
- private void assertGetValueZeroDepthZeroOrNil() {
- IRubyObject[] values = variableValues;
- assert values != null && 0 < values.length : "No variables or index to big for getValue off: " + 0 + ", Dep: " + 0 + ", O: " + this;
- }
-
- private void assertGetValueOneDepthZeroOrNil() {
- IRubyObject[] values = variableValues;
- assert values != null && 1 < values.length : "No variables or index to big for getValue off: " + 1 + ", Dep: " + 0 + ", O: " + this;
- }
-
- private void assertGetValueTwoDepthZeroOrNil() {
- IRubyObject[] values = variableValues;
- assert values != null && 3 < values.length : "No variables or index to big for getValue off: " + 3 + ", Dep: " + 0 + ", O: " + this;
- }
-
- private void assertGetValueThreeDepthZeroOrNil() {
- IRubyObject[] values = variableValues;
- assert values != null && 2 < values.length : "No variables or index to big for getValue off: " + 2 + ", Dep: " + 0 + ", O: " + this;
- }
-
- private void assertParent() {
- assert parent != null : "If depth > 0, then parent should not ever be null";
- }
-
- private void assertSetValue(int offset, IRubyObject value) {
- assert offset < variableValues.length : "Setting " + offset + " to " + value + ", O: " + this;
- }
-
- private void assertSetValueDepthZero(int offset, IRubyObject value) {
- assert offset < variableValues.length : "Setting " + offset + " to " + value + ", O: " + this;
- }
-
- private void assertSetValueZeroDepthZero(IRubyObject value) {
- assert 0 < variableValues.length : "Setting " + 0 + " to " + value + ", O: " + this;
- }
-
- private void assertSetValueOneDepthZero(IRubyObject value) {
- assert 1 < variableValues.length : "Setting " + 1 + " to " + value + ", O: " + this;
- }
-
- private void assertSetValueThreeDepthZero(IRubyObject value) {
- assert 3 < variableValues.length : "Setting " + 3 + " to " + value + ", O: " + this;
- }
-
- private void assertSetValueTwoDepthZero(IRubyObject value) {
- assert 2 < variableValues.length : "Setting " + 2 + " to " + value + ", O: " + this;
- }
-}
diff --git a/core/src/main/java/org/jruby/runtime/scope/NoVarsDynamicScope.java b/core/src/main/java/org/jruby/runtime/scope/NoVarsDynamicScope.java
deleted file mode 100644
index 7bcf559..0000000
--- a/core/src/main/java/org/jruby/runtime/scope/NoVarsDynamicScope.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package org.jruby.runtime.scope;
-
-import org.jruby.parser.StaticScope;
-import org.jruby.runtime.DynamicScope;
-import org.jruby.runtime.builtin.IRubyObject;
-
-/**
- * This is a DynamicScope that does not support any variables.
- */
-public class NoVarsDynamicScope extends DynamicScope {
- private static final int SIZE = 0;
- private static final String SIZE_ERROR = "NoVarsDynamicScope only supports scopes with no variables";
- private static final String GROW_ERROR = "NoVarsDynamicScope cannot be grown; use ManyVarsDynamicScope";
-
- public NoVarsDynamicScope(StaticScope staticScope, DynamicScope parent) {
- super(staticScope, parent);
- }
-
- public NoVarsDynamicScope(StaticScope staticScope) {
- super(staticScope);
- }
-
- public void growIfNeeded() {
- growIfNeeded(SIZE, GROW_ERROR);
- }
-
- protected void growIfNeeded(int size, String message) {
- if (staticScope.getNumberOfVariables() != size) {
- throw new RuntimeException(message);
- }
- }
-
- public DynamicScope cloneScope() {
- return new NoVarsDynamicScope(staticScope, parent);
- }
-
- public IRubyObject[] getValues() {
- return IRubyObject.NULL_ARRAY;
- }
-
- /**
- * Get value from current scope or one of its captured scopes.
- *
- * FIXME: block variables are not getting primed to nil so we need to null check those
- * until we prime them properly. Also add assert back in.
- *
- * @param offset zero-indexed value that represents where variable lives
- * @param depth how many captured scopes down this variable should be set
- * @return the value here
- */
- public IRubyObject getValue(int offset, int depth) {
- assert depth != 0: SIZE_ERROR;
- return parent.getValue(offset, depth - 1);
- }
-
- public IRubyObject getValueDepthZero(int offset) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with any variables");
- }
- public IRubyObject getValueZeroDepthZero() {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with one or more variables");
- }
- public IRubyObject getValueOneDepthZero() {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with two or more variables");
- }
- public IRubyObject getValueTwoDepthZero() {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with three or more variables");
- }
- public IRubyObject getValueThreeDepthZero() {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with four or more variables");
- }
-
- /**
- * Variation of getValue that checks for nulls, returning and setting the given value (presumably nil)
- */
- public IRubyObject getValueOrNil(int offset, int depth, IRubyObject nil) {
- return parent.getValueOrNil(offset, depth - 1, nil);
- }
-
- public IRubyObject getValueDepthZeroOrNil(int offset, IRubyObject nil) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with any variables");
- }
- public IRubyObject getValueZeroDepthZeroOrNil(IRubyObject nil) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with one or more variables");
- }
- public IRubyObject getValueOneDepthZeroOrNil(IRubyObject nil) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with two or more variables");
- }
- public IRubyObject getValueTwoDepthZeroOrNil(IRubyObject nil) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with three or more variables");
- }
- public IRubyObject getValueThreeDepthZeroOrNil(IRubyObject nil) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with four or more variables");
- }
-
- /**
- * Set value in current dynamic scope or one of its captured scopes.
- *
- * @param offset zero-indexed value that represents where variable lives
- * @param value to set
- * @param depth how many captured scopes down this variable should be set
- */
- public IRubyObject setValue(int offset, IRubyObject value, int depth) {
- return parent.setValue(offset, value, depth - 1);
- }
-
- public IRubyObject setValueDepthZero(IRubyObject value, int offset) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with any variables");
- }
- public IRubyObject setValueZeroDepthZero(IRubyObject value) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with one or more variables");
- }
- public IRubyObject setValueOneDepthZero(IRubyObject value) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with two or more variables");
- }
- public IRubyObject setValueTwoDepthZero(IRubyObject value) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with three or more variables");
- }
- public IRubyObject setValueThreeDepthZero(IRubyObject value) {
- throw new RuntimeException(this.getClass().getSimpleName() + " does not support scopes with four or more variables");
- }
-}
diff --git a/truffle/src/main/java/org/jruby/truffle/language/parser/jruby/TranslatorDriver.java b/truffle/src/main/java/org/jruby/truffle/language/parser/jruby/TranslatorDriver.java
index a965045..49f2ca0 100644
--- a/truffle/src/main/java/org/jruby/truffle/language/parser/jruby/TranslatorDriver.java
+++ b/truffle/src/main/java/org/jruby/truffle/language/parser/jruby/TranslatorDriver.java
@@ -21,7 +21,6 @@ import com.oracle.truffle.api.source.SourceSection;
import org.jcodings.Encoding;
import org.jruby.parser.StaticScope;
import org.jruby.runtime.DynamicScope;
-import org.jruby.runtime.scope.ManyVarsDynamicScope;
import org.jruby.truffle.RubyContext;
import org.jruby.truffle.core.LoadRequiredLibrariesNode;
import org.jruby.truffle.core.SetTopLevelBindingNode;
@@ -111,7 +110,7 @@ public class TranslatorDriver implements Parser {
}
}
- final DynamicScope dynamicScope = new ManyVarsDynamicScope(staticScope);
+ final DynamicScope dynamicScope = DynamicScope.newDynamicScope(staticScope);
boolean isInlineSource = parserContext == ParserContext.SHELL;
boolean isEvalParse = parserContext == ParserContext.EVAL || parserContext == ParserContext.INLINE || parserContext == ParserContext.MODULE;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment