From 75f4b052392d1b101776269efebdeaa5e3c03a06 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Julien=20Pag=C3=A8s?= Date: Fri, 13 Mar 2015 16:54:18 +0100 Subject: [PATCH] nitvm: The interpreter and the vm have each their own specialized frames MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit The class Frame is now abstract Signed-off-by: Julien Pagès --- src/interpreter/debugger.nit | 4 +-- src/interpreter/naive_interpreter.nit | 17 +++++++---- src/variables_numbering.nit | 51 +++++++++++++++++++++++++++++++++ 3 files changed, 65 insertions(+), 7 deletions(-) diff --git a/src/interpreter/debugger.nit b/src/interpreter/debugger.nit index 4400939..1765d9e 100644 --- a/src/interpreter/debugger.nit +++ b/src/interpreter/debugger.nit @@ -225,7 +225,7 @@ class Debugger # Auto continues the execution until the end or until an error is encountered var autocontinue = false - redef type FRAME: Frame + redef type FRAME: InterpreterFrame ####################################################################### ## Execution of statement function ## @@ -1411,7 +1411,7 @@ redef class AMethPropdef # Not supposed to be used by anyone else than the Debugger. private fun rt_call(v: Debugger, mpropdef: MMethodDef, args: Array[Instance]): nullable Instance do - var f = new Frame(self, self.mpropdef.as(not null), args) + var f = new InterpreterFrame(self, self.mpropdef.as(not null), args) var curr_instances = v.frame.map for i in curr_instances.keys do f.map[i] = curr_instances[i] diff --git a/src/interpreter/naive_interpreter.nit b/src/interpreter/naive_interpreter.nit index c92ba90..311d917 100644 --- a/src/interpreter/naive_interpreter.nit +++ b/src/interpreter/naive_interpreter.nit @@ -323,7 +323,7 @@ class NaiveInterpreter # *`args` Arguments of the call fun new_frame(node: ANode, mpropdef: MPropDef, args: Array[Instance]): FRAME do - return new Frame(node, mpropdef, args) + return new InterpreterFrame(node, mpropdef, args) end # Exit the program with a message @@ -352,14 +352,14 @@ class NaiveInterpreter # Retrieve the value of the variable in the current frame fun read_variable(v: Variable): Instance do - var f = frames.first + var f = frames.first.as(InterpreterFrame) return f.map[v] end # Assign the value of the variable in the current frame fun write_variable(v: Variable, value: Instance) do - var f = frames.first + var f = frames.first.as(InterpreterFrame) f.map[v] = value end @@ -679,7 +679,7 @@ class PrimitiveInstance[E] end # Information about local variables in a running method -class Frame +abstract class Frame # The current visited node # The node is stored by frame to keep a stack trace var current_node: ANode @@ -688,9 +688,16 @@ class Frame var mpropdef: MPropDef # Arguments of the method (the first is the receiver) var arguments: Array[Instance] + # Indicate if the expression has an array comprehension form + var comprehension: nullable Array[Instance] = null +end + +# Implementation of a Frame with a Hashmap to store local variables +class InterpreterFrame + super Frame + # Mapping between a variable and the current value private var map: Map[Variable, Instance] = new HashMap[Variable, Instance] - var comprehension: nullable Array[Instance] = null end redef class ANode diff --git a/src/variables_numbering.nit b/src/variables_numbering.nit index 7698ad2..1190fab 100644 --- a/src/variables_numbering.nit +++ b/src/variables_numbering.nit @@ -21,6 +21,9 @@ import vm redef class VirtualMachine + # The frames of the VirtualMachine are specialized + redef type FRAME: VmFrame + # Number the variables in `n`. # Do nothing if `n` is null fun numbering(n: nullable AExpr, position: Int): Int @@ -30,6 +33,46 @@ redef class VirtualMachine var pos = n.numbering(self, position) return pos end + + # Redef to add the numbering of variables and arguments + redef fun new_frame(node, mpropdef, args) + do + var f = new VmFrame(node, mpropdef, args) + + # If this Frame is for a method then number variables into the body of the method + if node isa AMethPropdef then + # Number the variables + if not node.is_numbering then node.numbering_variables(self, mpropdef.as(MMethodDef)) + + # Create an empty environment + f.variables = new Array[Instance].filled_with(initialization_value, node.environment_size) + end + + # If this Frame is for an attribute with a block then number the block + if node isa AAttrPropdef then + # Number the variables + if not node.is_numbering then node.numbering_variables(self) + + # Create an empty environment + f.variables = new Array[Instance].filled_with(initialization_value, node.environment_size) + end + + # Putting self at the beginning of the environment + f.variables[0] = args[0] + return f + end + + # Read a `Variable` from a frame by using its position + redef fun read_variable(v: Variable): Instance + do + return frame.variables[v.position] + end + + # Assign the value of the `Variable` in an environment + redef fun write_variable(v: Variable, value: Instance) + do + frame.variables[v.position] = value + end end redef class Variable @@ -37,6 +80,14 @@ redef class Variable var position: Int end +# Implementation of a Frame with numbered variables +class VmFrame + super Frame + + # Contains the value of Variables (which are numbered) + var variables: Array[Instance] = new Array[Instance] +end + redef class AExpr # Give a position to each variable declared in the node. # NOTE: Do not call this method directly, but use `v.numbering` -- 1.7.9.5