/** * Returns the n-th parent scope of this scope. * May return <code>null</code>. * @param n - number of levels above to look. * @return The n-th parent scope or <code>null</code>. */ public DynamicScope getNthParentScope(int n) { DynamicScope scope = this; for (int i = 0; i < n; i++) { if (scope != null) { scope = scope.getNextCapturedScope(); } else { break; } } return scope; }
/** * Returns the n-th parent scope of this scope. * May return <code>null</code>. * @param n - number of levels above to look. * @return The n-th parent scope or <code>null</code>. */ public DynamicScope getNthParentScope(int n) { DynamicScope scope = this; for (int i = 0; i < n; i++) { if (scope != null) { scope = scope.getNextCapturedScope(); } else { break; } } return scope; }
DynamicScope parent = dynamicScope.getNextCapturedScope();
public final DynamicScope getEvalScope(Ruby runtime) { // We create one extra dynamicScope on a binding so that when we 'eval "b=1", binding' the // 'b' will get put into this new dynamic scope. The original scope does not see the new // 'b' and successive evals with this binding will. I take it having the ability to have // succesive binding evals be able to share same scope makes sense from a programmers // perspective. One crappy outcome of this design is it requires Dynamic and Static // scopes to be mutable for this one case. // Note: In Ruby 1.9 all of this logic can go away since they will require explicit // bindings for evals. // We only define one special dynamic scope per 'logical' binding. So all bindings for // the same scope should share the same dynamic scope. This allows multiple evals with // different different bindings in the same scope to see the same stuff. // No binding scope so we should create one if (evalScope == null) { // If the next scope out has the same binding scope as this scope it means // we are evaling within an eval and in that case we should be sharing the same // binding scope. DynamicScope parent = getNextCapturedScope(); if (parent != null && parent.getEvalScope(runtime) == this) { evalScope = this; } else { // bindings scopes must always be ManyVars scopes since evals can grow them evalScope = new ManyVarsDynamicScope(runtime.getStaticScopeFactory().newEvalScope(getStaticScope()), this); } } return evalScope; }
DynamicScope parent = dynamicScope.getNextCapturedScope();
public final DynamicScope getEvalScope(Ruby runtime) { // We create one extra dynamicScope on a binding so that when we 'eval "b=1", binding' the // 'b' will get put into this new dynamic scope. The original scope does not see the new // 'b' and successive evals with this binding will. I take it having the ability to have // succesive binding evals be able to share same scope makes sense from a programmers // perspective. One crappy outcome of this design is it requires Dynamic and Static // scopes to be mutable for this one case. // Note: In Ruby 1.9 all of this logic can go away since they will require explicit // bindings for evals. // We only define one special dynamic scope per 'logical' binding. So all bindings for // the same scope should share the same dynamic scope. This allows multiple evals with // different different bindings in the same scope to see the same stuff. // No binding scope so we should create one if (evalScope == null) { // If the next scope out has the same binding scope as this scope it means // we are evaling within an eval and in that case we should be sharing the same // binding scope. DynamicScope parent = getNextCapturedScope(); if (parent != null && parent.getEvalScope(runtime) == this) { evalScope = this; } else { // bindings scopes must always be ManyVars scopes since evals can grow them evalScope = new ManyVarsDynamicScope(runtime.getStaticScopeFactory().newEvalScope(getStaticScope()), this); } } return evalScope; }
@Override public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block aBlock) { DynamicScope argsDynScope = currDynScope; // Find args that need to be passed into super while (!argsDynScope.getStaticScope().isArgumentScope()) argsDynScope = argsDynScope.getNextCapturedScope(); IRScope argsIRScope = ((IRStaticScope)argsDynScope.getStaticScope()).getIRScope(); Operand[] superArgs = (argsIRScope instanceof IRMethod) ? ((IRMethod)argsIRScope).getCallArgs() : ((IRClosure)argsIRScope).getBlockArgs(); // Prepare args -- but look up in 'argsDynScope', not 'currDynScope' IRubyObject[] args = prepareArguments(context, self, superArgs, argsDynScope, temp); // Prepare block -- fetching from the frame stack, if necessary Block block = prepareBlock(context, self, currDynScope, temp); if (block == null || !block.isGiven()) block = context.getFrameBlock(); return interpretSuper(context, self, args, block); }
@Override public Object interpret(ThreadContext context, DynamicScope currDynScope, IRubyObject self, Object[] temp, Block aBlock) { DynamicScope argsDynScope = currDynScope; // Find args that need to be passed into super while (!argsDynScope.getStaticScope().isArgumentScope()) argsDynScope = argsDynScope.getNextCapturedScope(); IRScope argsIRScope = ((IRStaticScope)argsDynScope.getStaticScope()).getIRScope(); Operand[] superArgs = (argsIRScope instanceof IRMethod) ? ((IRMethod)argsIRScope).getCallArgs() : ((IRClosure)argsIRScope).getBlockArgs(); // Prepare args -- but look up in 'argsDynScope', not 'currDynScope' IRubyObject[] args = prepareArguments(context, self, superArgs, argsDynScope, temp); // Prepare block -- fetching from the frame stack, if necessary Block block = prepareBlock(context, self, currDynScope, temp); if (block == null || !block.isGiven()) block = context.getFrameBlock(); return interpretSuper(context, self, args, block); }