Commit eb282e9a authored by Stefan Marr's avatar Stefan Marr

Removing setters where possible from VM objects

Most fields can be initialized on construction of the object and do not need to be changeable later
Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent af26d07f
......@@ -31,14 +31,13 @@ class MethodGenerationContext(object):
def assemble(self, universe):
# create a method instance with the given number of bytecodes and literals
num_literals = len(self._literals)
meth = universe.new_method(self._signature, len(self._bytecode), num_literals)
# populate the fields that are immediately available
num_locals = len(self._locals)
meth.set_number_of_locals(universe.new_integer(num_locals))
meth.set_maximum_number_of_stack_elements(universe.new_integer(self._compute_stack_depth()))
num_locals = len(self._locals)
meth = universe.new_method(self._signature,
len(self._bytecode),
num_literals,
universe.new_integer(num_locals),
universe.new_integer(self._compute_stack_depth()))
# copy literals into the method
i = 0
......
......@@ -206,9 +206,9 @@ class Interpreter(object):
elif bytecode == Bytecodes.return_non_local:
self._do_return_non_local()
def push_new_frame(self, method):
def push_new_frame(self, method, context):
# Allocate a new frame and make it the current one
self._frame = self._universe.new_frame(self._frame, method)
self._frame = self._universe.new_frame(self._frame, method, context)
# Return the freshly allocated and pushed frame
return self._frame
......
......@@ -20,7 +20,7 @@ class Shell(object):
std_println("SOM Shell. Type \"quit\" to exit.\n");
# Create a fake bootstrap frame
current_frame = self._interpreter.push_new_frame(self._bootstrap_method)
current_frame = self._interpreter.push_new_frame(self._bootstrap_method, self._universe.nilObject)
# Remember the first bytecode index, e.g. index of the halt instruction
bytecode_index = current_frame.get_bytecode_index()
......
......@@ -89,16 +89,16 @@ class Universe(object):
def _create_bootstrap_method(self):
# Create a fake bootstrap method to simplify later frame traversal
bootstrap_method = self.new_method(self.symbol_for("bootstrap"), 1, 0)
bootstrap_method = self.new_method(self.symbol_for("bootstrap"), 1, 0,
self.new_integer(0),
self.new_integer(2))
bootstrap_method.set_bytecode(0, Bytecodes.halt)
bootstrap_method.set_number_of_locals(self.new_integer(0))
bootstrap_method.set_maximum_number_of_stack_elements(self.new_integer(2))
bootstrap_method.set_holder(self.systemClass)
return bootstrap_method
def _create_bootstrap_frame(self, bootstrap_method, receiver, arguments = None):
# Create a fake bootstrap frame with the system object on the stack
bootstrap_frame = self._interpreter.push_new_frame(bootstrap_method)
bootstrap_frame = self._interpreter.push_new_frame(bootstrap_method, self.nilObject)
bootstrap_frame.push(receiver)
if arguments:
......@@ -294,12 +294,9 @@ class Universe(object):
def new_array_with_length(self, length):
# Allocate a new array and set its class to be the array class
result = Array(self.nilObject)
result = Array(self.nilObject, length)
result.set_class(self.arrayClass)
# Set the number of indexable fields to the given value (length)
result.set_number_of_indexable_fields_and_clear(length, self.nilObject)
# Return the freshly allocated array
return result
......@@ -327,13 +324,9 @@ class Universe(object):
def new_block(self, method, context_frame, arguments):
# Allocate a new block and set its class to be the block class
result = Block(self.nilObject)
result = Block(self.nilObject, method, context_frame)
result.set_class(self._get_block_class(arguments))
# Set the method and context of block
result.set_method(method)
result.set_context(context_frame)
# Return the freshly allocated block
return result
......@@ -345,23 +338,17 @@ class Universe(object):
# Return the freshly allocated class
return result
def new_frame(self, previous_frame, method):
# Allocate a new frame and set its class to be the frame class
result = Frame(self.nilObject)
result.set_class(self.frameClass)
def new_frame(self, previous_frame, method, context):
# Compute the maximum number of stack locations (including arguments,
# locals and extra buffer to support doesNotUnderstand) and set the
# number of indexable fields accordingly
length = (method.get_number_of_arguments() +
method.get_number_of_locals().get_embedded_integer() +
method.get_maximum_number_of_stack_elements().get_embedded_integer() + 2)
result.set_number_of_indexable_fields_and_clear(length, self.nilObject)
# Set the method of the frame and the previous frame
result.set_method(method)
if previous_frame:
result.set_previous_frame(previous_frame)
# Allocate a new frame and set its class to be the frame class
result = Frame(self.nilObject, length, method, context, previous_frame)
result.set_class(self.frameClass)
# Reset the stack pointer and the bytecode index
result.reset_stack_pointer()
......@@ -370,16 +357,17 @@ class Universe(object):
# Return the freshly allocated frame
return result
def new_method(self, signature, num_bytecodes, num_literals):
def new_method(self, signature, num_bytecodes, num_literals,
num_locals, maximum_number_of_stack_elements):
# Allocate a new method and set its class to be the method class
result = Method(self.nilObject)
result = Method(self.nilObject,
num_literals,
num_locals,
maximum_number_of_stack_elements,
num_bytecodes,
signature)
result.set_class(self.methodClass)
# Set the signature and the number of bytecodes
result.set_signature(signature)
result.set_number_of_bytecodes(num_bytecodes)
result.set_number_of_indexable_fields_and_clear(num_literals, self.nilObject)
# Return the freshly allocated method
return result
......@@ -395,35 +383,26 @@ class Universe(object):
def new_integer(self, value):
assert isinstance(value, int)
# Allocate a new integer and set its class to be the integer class
result = Integer(self.nilObject)
result = Integer(self.nilObject, value)
result.set_class(self.integerClass)
# Set the embedded integer of the newly allocated integer
result.set_embedded_integer(value)
# Return the freshly allocated integer
return result
def new_biginteger(self, value):
# Allocate a new integer and set its class to be the integer class
result = BigInteger(self.nilObject)
result = BigInteger(self.nilObject, value)
result.set_class(self.bigintegerClass)
# Set the embedded integer of the newly allocated integer
result.set_embedded_biginteger(value)
# Return the freshly allocated integer
return result
def new_double(self, value):
# Allocate a new integer and set its class to be the double class
result = Double(self.nilObject)
result = Double(self.nilObject, value)
result.set_class(self.doubleClass)
# Set the embedded double of the newly allocated double
result.set_embedded_double(value)
# Return the freshly allocated double
return result
......@@ -440,23 +419,17 @@ class Universe(object):
def new_string(self, embedded_string):
# Allocate a new string and set its class to be the string class
result = String(self.nilObject)
result = String(self.nilObject, embedded_string)
result.set_class(self.stringClass)
# Put the embedded string into the new string
result.set_embedded_string(embedded_string)
# Return the freshly allocated string
return result
def new_symbol(self, string):
# Allocate a new symbol and set its class to be the symbol class
result = Symbol(self.nilObject)
result = Symbol(self.nilObject, string)
result.set_class(self.symbolClass)
# Put the string into the symbol
result.set_string(string)
# Insert the new symbol into the symbol table
self._symbol_table.insert(result)
......
......@@ -2,11 +2,11 @@ from som.vmobjects.object import Object
class Array(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, number_of_indexable_fields):
Object.__init__(self, nilObject)
# Private array of indexable fields
self._indexable_fields = None
self._indexable_fields = [nilObject] * number_of_indexable_fields
def get_indexable_field(self, index):
# Get the indexable field with the given index
......@@ -19,10 +19,6 @@ class Array(Object):
def get_number_of_indexable_fields(self):
# Get the number of indexable fields in this array
return len(self._indexable_fields)
def set_number_of_indexable_fields_and_clear(self, value, nilObject):
# Allocate a new array of indexable fields, initialized with nil
self._indexable_fields = [nilObject] * value
def copy_and_extend_with(self, value, universe):
# Allocate a new array which has one indexable field more than this
......
from som.vmobjects.object import Object
class BigInteger(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, value):
Object.__init__(self, nilObject)
self._embedded_biginteger = 0L
self._embedded_biginteger = value
def get_embedded_biginteger(self):
return self._embedded_biginteger
......@@ -11,6 +11,3 @@ class BigInteger(Object):
def get_embedded_value(self):
"""This Method is polymorphic with Integer"""
return self._embedded_biginteger
def set_embedded_biginteger(self, value):
self._embedded_biginteger = value
......@@ -7,16 +7,17 @@ class Block(Object):
CONTEXT_INDEX = 1 + METHOD_INDEX
NUMBER_OF_BLOCK_FIELDS = 1 + CONTEXT_INDEX
def __init__(self, nilObject):
def __init__(self, nilObject, method, context):
Object.__init__(self, nilObject)
self._number_of_arguments = 0
self._set_method(method)
self._set_context(context)
def get_method(self):
# Get the method of this block by reading the field with method index
return self.get_field(self.METHOD_INDEX)
def set_method(self, value):
def _set_method(self, value):
# Set the method of this block by writing to the field with method index
self.set_field(self.METHOD_INDEX, value)
......@@ -24,7 +25,7 @@ class Block(Object):
# Get the context of this block by reading the field with context index
return self.get_field(self.CONTEXT_INDEX)
def set_context(self, value):
def _set_context(self, value):
# Set the context of this block by writing to the field with context index
return self.set_field(self.CONTEXT_INDEX, value)
......@@ -43,9 +44,8 @@ class Block(Object):
# Push a new frame and set its context to be the one specified in
# the block
new_frame = interpreter.push_new_frame(rcvr.get_method())
new_frame = interpreter.push_new_frame(rcvr.get_method(), context)
new_frame.copy_arguments_from(frame)
new_frame.set_context(context)
Primitive.__init__(self, self._compute_signature_string(num_args), universe, _invoke)
self._number_of_arguments = num_args
......
......@@ -2,12 +2,9 @@ from som.vmobjects.object import Object
class Double(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, value):
Object.__init__(self, nilObject)
self._embedded_double = 0.0
self._embedded_double = value
def get_embedded_double(self):
return self._embedded_double
def set_embedded_double(self, value):
self._embedded_double = value
......@@ -19,17 +19,20 @@ class Frame(Array):
METHOD_INDEX = 1 + CONTEXT_INDEX
NUMBER_OF_FRAME_FIELDS = 1 + METHOD_INDEX
def __init__(self, nilObject):
Array.__init__(self, nilObject)
def __init__(self, nilObject, num_elements, method, context, previous_frame):
Array.__init__(self, nilObject, num_elements)
self._stack_pointer = 0
self._bytecode_index = 0
self._local_offset = 0
self._set_method(method)
self._set_context(context)
self._set_previous_frame(previous_frame if previous_frame else nilObject)
def get_previous_frame(self):
# Get the previous frame by reading the field with previous frame index
return self.get_field(self.PREVIOUS_FRAME_INDEX)
def set_previous_frame(self, value):
def _set_previous_frame(self, value):
# Set the previous frame by writing to the field with previous frame index
self.set_field(self.PREVIOUS_FRAME_INDEX, value)
......@@ -47,7 +50,7 @@ class Frame(Array):
# Get the context by reading the field with context index
return self.get_field(self.CONTEXT_INDEX)
def set_context(self, value):
def _set_context(self, value):
# Set the context by writing to the field with context index
self.set_field(self.CONTEXT_INDEX, value)
......@@ -84,7 +87,7 @@ class Frame(Array):
# Get the method by reading the field with method index
return self.get_field(self.METHOD_INDEX)
def set_method(self, value):
def _set_method(self, value):
# Set the method by writing to the field with method index
self.set_field(self.METHOD_INDEX, value)
......
......@@ -2,17 +2,13 @@ from som.vmobjects.object import Object
class Integer(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, value):
Object.__init__(self, nilObject)
self._embedded_integer = 0
self._embedded_integer = value
def get_embedded_integer(self):
return self._embedded_integer
def set_embedded_integer(self, value):
assert isinstance(value, int)
self._embedded_integer = value
def get_embedded_value(self):
"""This Method is polymorphic with BigInteger"""
return self._embedded_integer
......
......@@ -12,8 +12,9 @@ class Method(Array):
NUMBER_OF_METHOD_FIELDS = 1 + HOLDER_INDEX
def __init__(self, nilObject):
Array.__init__(self, nilObject)
def __init__(self, nilObject, num_literals, num_locals, max_stack_elements,
num_bytecodes, signature):
Array.__init__(self, nilObject, num_literals)
self._receiver_class_table = []
self._invoked_methods = []
......@@ -21,12 +22,16 @@ class Method(Array):
self._invocation_count = 0
self._bytecodes = None
self._inline_cache_class = None
self._inline_cache_invokable = None
# Set the number of bytecodes in this method
self._bytecodes = ["\x00"] * num_bytecodes
self._inline_cache_class = [None] * num_bytecodes
self._inline_cache_invokable = [None] * num_bytecodes
self._number_of_locals = num_locals
self._maximum_number_of_stack_elements = max_stack_elements
self._set_signature(signature)
self._number_of_locals = nilObject
self._maximum_number_of_stack_elements = nilObject
def is_primitive(self):
return False
......@@ -41,24 +46,16 @@ class Method(Array):
# Get the number of locals (converted to a Java integer)
return self._number_of_locals
def set_number_of_locals(self, value):
# Set the number of locals
self._number_of_locals = value
def get_maximum_number_of_stack_elements(self):
# Get the maximum number of stack elements
return self._maximum_number_of_stack_elements
def set_maximum_number_of_stack_elements(self, value):
# Set the maximum number of stack elements
self._maximum_number_of_stack_elements = value
def get_signature(self):
# Get the signature of this method by reading the field with signature
# index
return self.get_field(self.SIGNATURE_INDEX)
def set_signature(self, value):
def _set_signature(self, value):
# Set the signature of this method by writing to the field with
# signature index
self.set_field(self.SIGNATURE_INDEX, value)
......@@ -92,12 +89,6 @@ class Method(Array):
# Get the number of bytecodes in this method
return len(self._bytecodes)
def set_number_of_bytecodes(self, value):
# Set the number of bytecodes in this method
self._bytecodes = ["\x00"] * value
self._inline_cache_class = [None] * value
self._inline_cache_invokable = [None] * value
def get_bytecode(self, index):
# Get the bytecode at the given index
return ord(self._bytecodes[index])
......@@ -120,7 +111,8 @@ class Method(Array):
self._invocation_count += 1
# Allocate and push a new frame on the interpreter stack
new_frame = interpreter.push_new_frame(self)
new_frame = interpreter.push_new_frame(self,
interpreter.get_universe().nilObject)
new_frame.copy_arguments_from(frame)
def replace_bytecodes(self):
......
......@@ -6,8 +6,7 @@ class Object(object):
def __init__(self, nilObject, number_of_fields = -1):
num_fields = number_of_fields if number_of_fields != -1 else self._get_default_number_of_fields()
self._fields = None
self.set_number_of_fields_and_clear(num_fields, nilObject)
self._fields = [nilObject] * num_fields
def get_class(self):
# Get the class of this object by reading the field with class index
......@@ -27,11 +26,7 @@ class Object(object):
def get_number_of_fields(self):
# Get the number of fields in this object
return len(self._fields)
def set_number_of_fields_and_clear(self, value, nilObject):
# Allocate a new array of fields
self._fields = [nilObject] * value
return len(self._fields)
def _get_default_number_of_fields(self):
# Return the default number of fields in an object
......
......@@ -2,15 +2,12 @@ from som.vmobjects.object import Object
class String(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, value):
Object.__init__(self, nilObject)
self._string = None
self._string = value
def get_embedded_string(self):
return self._string
def set_embedded_string(self, value):
self._string = value
def __str__(self):
return "\"" + self._string + "\""
......@@ -2,24 +2,19 @@ from som.vmobjects.object import Object
class Symbol(Object):
def __init__(self, nilObject):
def __init__(self, nilObject, value):
Object.__init__(self, nilObject)
self._string = None
self._number_of_signature_arguments = 0 # updated later
self._string = value
self._number_of_signature_arguments = self._determine_number_of_signature_arguments() # updated later
def get_string(self):
# Get the string associated to this symbol
return self._string
def set_string(self, value):
# Set the string associated to this symbol
self._string = value
self._determine_number_of_signature_arguments()
def _determine_number_of_signature_arguments(self):
# Check for binary signature
if self.is_binary_signature():
self._number_of_signature_arguments = 2
return 2
else:
# Count the colons in the signature string
number_of_colons = 0
......@@ -30,12 +25,11 @@ class Symbol(Object):
number_of_colons += 1
# The number of arguments is equal to the number of colons plus one
self._number_of_signature_arguments = number_of_colons + 1
return number_of_colons + 1
def get_number_of_signature_arguments(self):
return self._number_of_signature_arguments
def is_binary_signature(self):
# Check the individual characters of the string
for c in self._string:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment