Right now, this class abstracts the following execution scopes:
Method, Closure, Module, Class, MetaClass
Top-level Script, and Eval Script
In the compiler-land, IR versions of these scopes encapsulate only as much
information as is required to convert Ruby code into equivalent Java code.
But, in the non-compiler land, there will be a corresponding java object for
some of these scopes which encapsulates the runtime semantics and data needed
for implementing them. In the case of Module, Class, MetaClass, and Method,
they also happen to be instances of the corresponding Ruby classes -- so,
in addition to providing code that help with this specific ruby implementation,
they also have code that let them behave as ruby instances of their corresponding
classes.
Examples:
- the runtime class object might have refs. to the runtime method objects.
- the runtime method object might have a slot for a heap frame (for when it
has closures that need access to the method's local variables), it might
have version information, it might have references to other methods that
were optimized with the current version number, etc.
- the runtime closure object will have a slot for a heap frame (for when it
has closures within) and might get reified as a method in the java land
(but inaccessible in ruby land). So, passing closures in Java land might
be equivalent to passing around the method handles.
and so on ...
File within which this scope has been defined
Starting line for this scope's definition
Parser static-scope that this IR scope corresponds to
Live version of module within whose context this method executes
List of IR instructions for this method
Control flow graph representation of this method's instructions
List of (nested) closures in this scope
Local variables defined in this scope
Local variables used in this scope
Is %block implicit block arg unused?
%current_module and %current_scope variables
Map of name -> dataflow problem
Keeps track of types of prefix indexes for variables and labels
Does this scope call any eval
Since backref ($~) and lastline ($_) vars are allocated space on the dynamic scope,
this is an useful flag to compute.
Does this scope call any zsuper
Does this scope have loops?
# of thread poll instrs added to this scope
Does this scope have explicit call protocol instructions?
If yes, there are IR instructions for managing bindings/frames, etc.
If not, this has to be managed implicitly as in the current runtime
For now, only dyn-scopes are managed explicitly.
Others will come in time
Should we re-run compiler passes -- yes after we've inlined, for example
Returns the lexical scope that contains this scope definition
while (current != null && !(current instanceof IRMethod)) {
Returns the nearest scope which we can extract a live module from. If
this returns null (like for evals), then it means it cannot be statically
determined.
if (current == null || current instanceof IREvalScript) return null;
Returns the top level scope
if (s == closure) return true;
LOG.error("Error linearizing cfg: ", e);
int bbInstrsLength = bbInstrs.size();
for (int i = 0; i < bbInstrsLength; i++) {
Run any necessary passes to get the IR ready for interpretation
Run any necessary passes to get the IR ready for compilation
LOG.error("Error linearizing cfg: ", e);
if ((eBB != null) && (rBB == eBB || rBB == null)) {
} else if (rBB != null) {
if (labels == null) return new Label[] {cat};
System.arraycopy(labels, 0, newLabels, 0, labels.length);
newLabels[labels.length] = cat;
receivesClosureArg = true;
if (receivesClosureArg && (call.getCallArgs().length > 1)) {
gvName.equals("$LAST_READ_LINE") ||
gvName.equals("$LAST_MATCH_INFO") ||
gvName.equals("$POSTMATCH") ||
gvName.equals("$LAST_PAREN_MATCH")) {
return receivesClosureArg;
boolean receivesClosureArg = false;
b.append("\n\n------ Closures encountered in this scope ------\n");
b.append("------------------------------------------------\n");
---------------------------------------
SSS FIXME: What is this method for?
- Interp:
- public void calculateParameterCounts() {
for (int i = instrList.size() - 1; i >= 0; i--) {
Instr instr = instrList.get(i);
}
}
------------------------------------------
Find or create a local variable. By default, scopes are assumed to
only check current depth. Blocks/Closures override this because they
have special nesting rules.
if (cfg != null) throw new RuntimeException("Please use the CFG to access this scope's instructions.");
LOG.error("Fell through looking for rescuer ipc for " + excInstr);
LOG.error("Fell through looking for ensurer ipc for " + excInstr);
assert obj != null: "Unsatisfied dependency and this depends() was set " +
"up wrong. Use depends(build()) not depends(build).";
assert cfg != null: "Trying to access build before build started";