WARNING! Access to this system is limited to authorised users only.
Unauthorised users may be subject to prosecution.
Unauthorised access to this system is a criminal offence under Australian law (Federal Crimes Act 1914 Part VIA)
It is a criminal offence to:
(1) Obtain access to data without authority. -Penalty 2 years imprisonment.
(2) Damage, delete, alter or insert data without authority. -Penalty 10 years imprisonment.
User activity is monitored and recorded. Anyone using this system expressly consents to such monitoring and recording.

To protect your data, the CISO officer has suggested users to enable 2FA as soon as possible.
Currently 2.2% of users enabled 2FA.

Commit a073dd36 authored by Stefan Marr's avatar Stefan Marr
Browse files

Refactoring class methods to module methods



- RPython does not support them, so we changed from the to module-level methods
Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent eb5bce49
from som.vm.universe import Universe
from som.interpreter.bytecodes import Bytecodes
from som.vm.universe import error_print, error_println, Universe
from som.interpreter.bytecodes import bytecode_as_str, bytecode_length, Bytecodes
class Disassembler(object):
def dump(clazz):
for i in range(0, clazz.get_number_of_instance_invokables()):
inv = clazz.get_instance_invokable(i)
@classmethod
def dump(cls, clazz):
for i in range(0, clazz.get_number_of_instance_invokables()):
inv = clazz.get_instance_invokable(i)
# output header and skip if the Invokable is a Primitive
error_print(str(clazz.get_name()) + ">>" +
str(inv.get_signature()) + " = ")
# output header and skip if the Invokable is a Primitive
Universe.error_print(str(clazz.get_name()) + ">>" +
str(inv.get_signature()) + " = ")
if inv.is_primitive():
error_println("<primitive>")
continue
# output actual method
dump_method(inv, "\t")
if inv.is_primitive():
Universe.error_println("<primitive>")
continue
# output actual method
cls.dump_method(inv, "\t")
def dump_method(m, indent):
error_println("(")
@classmethod
def dump_method(cls, m, indent):
Universe.error_println("(")
# output stack information
error_println("%s<%d locals, %d stack, %d bc_count>" % (indent,
m.get_number_of_locals().get_embedded_integer(),
m.get_maximum_number_of_stack_elements().get_embedded_integer(),
m.get_number_of_bytecodes()))
# output stack information
Universe.error_println("%s<%d locals, %d stack, %d bc_count>" % (indent,
m.get_number_of_locals().get_embedded_integer(),
m.get_maximum_number_of_stack_elements().get_embedded_integer(),
m.get_number_of_bytecodes()))
# output bytecodes
b = 0
while b < m.get_number_of_bytecodes():
error_print(indent)
# bytecode index
if b < 10: error_print(" ")
if b < 100: error_print(" ")
error_print(" %d:" % b)
# output bytecodes
b = 0
while b < m.get_number_of_bytecodes():
Universe.error_print(indent)
# bytecode index
if b < 10: Universe.error_print(" ")
if b < 100: Universe.error_print(" ")
Universe.error_print(" %d:" % b)
# mnemonic
bytecode = m.get_bytecode(b)
error_print(bytecode_as_str(bytecode) + " ")
# mnemonic
bytecode = m.get_bytecode(b)
Universe.error_print(Bytecodes.as_str(bytecode) + " ")
# parameters (if any)
if bytecode_length(bytecode) == 1:
error_println()
b += 1
continue
if bytecode == Bytecodes.push_local:
error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_argument:
error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_field:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.push_block:
error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ")
dump_method(m.get_constant(b), indent + "\t")
elif bytecode == Bytecodes.push_constant:
constant = m.get_constant(b)
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: (" +
str(constant.get_class().get_name()) +
") " + str(constant))
elif bytecode == Bytecodes.push_global:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.pop_local:
error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_argument:
error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_field:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.send:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.super_send:
error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
else:
error_println("<incorrect bytecode>")
b += bytecode_length(m.get_bytecode(b))
# parameters (if any)
if Bytecodes.get_bytecode_length(bytecode) == 1:
Universe.error_println()
b += 1
continue
if bytecode == Bytecodes.push_local:
Universe.error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_argument:
Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.push_field:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.push_block:
Universe.error_print("block: (index: " + str(m.get_bytecode(b + 1)) + ") ")
cls.dump_method(m.get_constant(b), indent + "\t")
elif bytecode == Bytecodes.push_constant:
constant = m.get_constant(b)
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: (" +
str(constant.get_class().get_name()) +
") " + str(constant))
elif bytecode == Bytecodes.push_global:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") value: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.pop_local:
Universe.error_println("local: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_argument:
Universe.error_println("argument: " + str(m.get_bytecode(b + 1)) +
", context: " + str(m.get_bytecode(b + 2)))
elif bytecode == Bytecodes.pop_field:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") field: " + str(m.get_holder().get_instance_field_name(m.get_bytecode(b + 1))))
elif bytecode == Bytecodes.send:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
elif bytecode == Bytecodes.super_send:
Universe.error_println("(index: " + str(m.get_bytecode(b + 1)) +
") signature: " + str(m.get_constant(b)))
else:
Universe.error_println("<incorrect bytecode>")
b += Bytecodes.get_bytecode_length(m.get_bytecode(b))
Universe.error_println(indent + ")")
error_println(indent + ")")
from som.interpreter.bytecodes import Bytecodes as BC
from som.vmobjects.primitive import Primitive
from som.interpreter.bytecodes import bytecode_length, bytecode_stack_effect, bytecode_stack_effect_depends_on_send, Bytecodes as BC
from som.vmobjects.primitive import Primitive, empty_primitive
class MethodGenerationContext(object):
......@@ -26,7 +26,7 @@ class MethodGenerationContext(object):
return self._primitive
def assemble_primitive(self, universe):
return Primitive.get_empty_primitive(self._signature.get_string(), universe)
return empty_primitive(self._signature.get_string(), universe)
def assemble(self, universe):
# create a method instance with the given number of bytecodes and literals
......@@ -63,13 +63,13 @@ class MethodGenerationContext(object):
while i < len(self._bytecode):
bc = self._bytecode[i]
if BC.stack_effect_depends_on_send(bc):
if bytecode_stack_effect_depends_on_send(bc):
signature = self._literals[self._bytecode[i + 1]]
depth += BC.get_stack_effect(bc, signature.get_number_of_signature_arguments())
depth += bytecode_stack_effect(bc, signature.get_number_of_signature_arguments())
else:
depth += BC.get_stack_effect(bc)
depth += bytecode_stack_effect(bc)
i += BC.get_bytecode_length(bc)
i += bytecode_length(bc)
if depth > max_depth:
max_depth = depth
......
from som.compiler.symbol import Symbol
from som.compiler.symbol import Symbol, symbol_as_str
from som.compiler.lexer import Lexer
from som.compiler.bytecode_generator import BytecodeGenerator
from som.compiler.method_generation_context import MethodGenerationContext
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits
class Parser(object):
......@@ -111,7 +111,7 @@ class Parser(object):
return True
err = ("Error: unexpected symbol in line %d. Expected %s, but found %s" %
(self._lexer.get_current_line_number(), Symbol.as_str(s), Symbol.as_str(self._sym)))
(self._lexer.get_current_line_number(), symbol_as_str(s), symbol_as_str(self._sym)))
if self._printable_symbol():
err += " (" + self._text + ")"
err += ": " + self._lexer.get_raw_buffer()
......@@ -121,10 +121,10 @@ class Parser(object):
if self._accept_one_of(symbol_list):
return True
expected = ", ".join([Symbol.as_str(x) for x in symbol_list])
expected = ", ".join([symbol_as_str(x) for x in symbol_list])
err = ("Error: unexpected symbol in line %d. Expected one of %s, but found %s" %
(self._lexer.get_current_line_number(), expected, Symbol.as_str(self._sym)))
(self._lexer.get_current_line_number(), expected, symbol_as_str(self._sym)))
if self._printable_symbol():
err += " (" + self._text + ")"
err += ": " + self._lexer.get_raw_buffer()
......@@ -460,7 +460,7 @@ class Parser(object):
val = self._literal_decimal()
if Integer.value_fits(val):
if integer_value_fits(val):
lit = self._universe.new_integer(val)
else:
lit = self._universe.new_biginteger(val)
......
......@@ -33,9 +33,9 @@ class Symbol(object):
KeywordSequence = 29
OperatorSequence = 30
@classmethod
def as_str(cls, symbol):
for key, val in cls.__dict__:
if val == symbol:
return key
raise ValueError('No Symbol defined for the value %d.' % symbol)
def symbol_as_str(symbol):
for key, val in Symbol.__dict__:
if val == symbol:
return key
raise ValueError('No Symbol defined for the value %d.' % symbol)
......@@ -56,28 +56,28 @@ class Bytecodes(object):
return_local : 0,
return_non_local : 0 }
@classmethod
def get_bytecode_length(cls, bytecode):
return cls._bytecode_length[bytecode]
@classmethod
def get_stack_effect(cls, bytecode, number_of_arguments_of_message_send = 0):
if cls.stack_effect_depends_on_send(bytecode):
return -number_of_arguments_of_message_send + 1 # +1 in order to account for the return value
else:
return cls._bytecode_stack_effect[bytecode]
@classmethod
def stack_effect_depends_on_send(cls, bytecode):
return cls._bytecode_stack_effect[bytecode] is cls._stack_effect_depends_on_message
def bytecode_length(bytecode):
return Bytecodes._bytecode_length[bytecode]
def bytecode_stack_effect(bytecode, number_of_arguments_of_message_send = 0):
if bytecode_stack_effect_depends_on_send(bytecode):
return -number_of_arguments_of_message_send + 1 # +1 in order to account for the return value
else:
return Bytecodes._bytecode_stack_effect[bytecode]
@classmethod
def as_str(cls, bytecode):
if not isinstance(bytecode, int):
raise ValueError('bytecode is expected to be an integer.')
def bytecode_stack_effect_depends_on_send(bytecode):
return Bytecodes._bytecode_stack_effect[bytecode] is Bytecodes._stack_effect_depends_on_message
def bytecode_as_str(bytecode):
if not isinstance(bytecode, int):
raise ValueError('bytecode is expected to be an integer.')
for key, val in Bytecodes.__dict__.iteritems():
if val == bytecode:
return key.upper()
for key, val in cls.__dict__.iteritems():
if val == bytecode:
return key.upper()
raise ValueError('No defined defined for the value %d.' % bytecode)
raise ValueError('No defined defined for the value %d.' % bytecode)
from som.interpreter.bytecodes import Bytecodes
from som.interpreter.bytecodes import bytecode_length
class Interpreter(object):
......@@ -184,10 +184,10 @@ class Interpreter(object):
bytecode = self.get_method().get_bytecode(bytecode_index)
# Get the length of the current bytecode
bytecode_length = Bytecodes.get_bytecode_length(bytecode)
bc_length = bytecode_length(bytecode)
# Compute the next bytecode index
next_bytecode_index = bytecode_index + bytecode_length
next_bytecode_index = bytecode_index + bc_length
# Update the bytecode index of the frame
self.get_frame().set_bytecode_index(next_bytecode_index)
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits
import math
......@@ -24,7 +24,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() + right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -36,7 +36,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() - right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -48,7 +48,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() * right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......@@ -60,7 +60,7 @@ class BigIntegerPrimitives(Primitives):
# Do operation and perform conversion to Integer if required
result = left.get_embedded_biginteger() / right_obj.get_embedded_value()
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vmobjects.biginteger import BigInteger
from som.vmobjects.integer import Integer
from som.vmobjects.integer import integer_value_fits, Integer
from som.vmobjects.double import Double
import math
......@@ -9,10 +9,9 @@ import random
class IntegerPrimitives(Primitives):
def _push_long_result(self, frame, result):
# Check with integer bounds and push:
if Integer.value_fits(result):
if integer_value_fits(result):
frame.push(self._universe.new_integer(result))
else:
frame.push(self._universe.new_biginteger(result))
......
from som.primitives.primitives import Primitives
from som.vmobjects.primitive import Primitive
from som.vm.universe import std_print, std_println
import time
class SystemPrimitives(Primitives):
......@@ -37,11 +39,11 @@ class SystemPrimitives(Primitives):
def _print_string(ivkbl, frame, interpreter):
argument = frame.pop()
self._universe.std_print(argument.get_embedded_string())
std_print(argument.get_embedded_string())
self._install_instance_primitive(Primitive("printString:", self._universe, _print_string))
def _print_newline(ivkbl, frame, interpreter):
self._universe.std_println()
std_println()
self._install_instance_primitive(Primitive("printNewline", self._universe, _print_newline))
def _time(ivkbl, frame, interpreter):
......
......@@ -10,7 +10,7 @@ from som.vmobjects.symbol import Symbol
from som.vmobjects.method import Method
from som.vmobjects.integer import Integer
from som.vmobjects.string import String
from som.vmobjects.block import Block
from som.vmobjects.block import Block, block_evaluation_primitive
from som.vmobjects.frame import Frame
from som.vmobjects.biginteger import BigInteger
from som.vmobjects.double import Double
......@@ -251,12 +251,12 @@ class Universe(object):
def _print_usage_and_exit(self):
# Print the usage
self.std_println("Usage: som [-options] [args...] ")
self.std_println(" ")
self.std_println("where options include: ")
self.std_println(" -cp <directories separated by " + os.pathsep + ">")
self.std_println(" set search path for application classes")
self.std_println(" -d enable disassembling")
std_println("Usage: som [-options] [args...] ")
std_println(" ")
std_println("where options include: ")
std_println(" -cp <directories separated by " + os.pathsep + ">")
std_println(" set search path for application classes")
std_println(" -d enable disassembling")
# Exit
self.exit(0)
......@@ -586,7 +586,7 @@ class Universe(object):
result = self._load_class(name, None)
# Add the appropriate value primitive to the block class
result.add_instance_primitive(Block.get_evaluation_primitive(number_of_arguments, self))
result.add_instance_primitive(block_evaluation_primitive(number_of_arguments, self))
# Insert the block class into the dictionary of globals
self.set_global(name, result)
......@@ -623,9 +623,9 @@ class Universe(object):
# Load the class from a file and return the loaded class
result = sourcecode_compiler.compile_class_from_file(cpEntry, name.get_string(), system_class, self)
if self._dump_bytecodes:
from som.compiler.disassembler import Disassembler
Disassembler.dump(result.get_class())
Disassembler.dump(result)
from som.compiler.disassembler import dump
dump(result.get_class())
dump(result)
return result
except IOError:
......@@ -639,25 +639,21 @@ class Universe(object):
# Load the class from a stream and return the loaded class
result = sourcecode_compiler.compile_class_from_string(stmt, None, self)
if self._dump_bytecodes:
from som.compiler.disassembler import Disassembler
Disassembler.dump(result)
from som.compiler.disassembler import dump
dump(result)
return result
@classmethod
def error_print(cls, msg):
print(msg, file=sys.stderr, end="")
def error_print(msg):
print(msg, file=sys.stderr, end="")
@classmethod
def error_println(cls, msg = ""):
print(msg, file=sys.stderr)
def error_println(msg = ""):
print(msg, file=sys.stderr)
@classmethod
def std_print(cls, msg):
print(msg, end="")
def std_print(msg):
print(msg, end="")
@classmethod
def std_println(cls, msg=""):
print(msg)
def std_println(msg=""):
print(msg)
def main(args):
u = Universe()
......
......@@ -63,6 +63,5 @@ class Block(Object):
# Return the signature string
return signature_string
@classmethod
def get_evaluation_primitive(cls, num_args, universe):
return cls.Evaluation(num_args, universe)
def block_evaluation_primitive(num_args, universe):
return Block.Evaluation(num_args, universe)
......@@ -19,6 +19,5 @@ class Integer(Object):
def __str__(self):
return str(self._embedded_integer)
@classmethod
def value_fits(cls, value):
return value <= 2147483647 and value > -2147483646
\ No newline at end of file
def integer_value_fits(value):
return value <= 2147483647 and value > -2147483646
......@@ -51,14 +51,14 @@ class Primitive(Object, Invokable):
# By default a primitive is not empty
return False
@classmethod
def get_empty_primitive(cls, signature_string, universe):
# Return an empty primitive with the given signature
def _invoke(ivkbl, frame, interpreter):
# Write a warning to the screen
universe.std_println("Warning: undefined primitive " +
ivkbl.get_signature().get_string() + " called")
# The empty primitives are empty
def _is_empty(self): return True
return Primitive(signature_string, universe, _invoke, _is_empty)
def empty_primitive(signature_string, universe):
# Return an empty primitive with the given signature
def _invoke(ivkbl, frame, interpreter):
# Write a warning to the screen
universe.std_println("Warning: undefined primitive " +
ivkbl.get_signature().get_string() + " called")
# The empty primitives are empty
def _is_empty(self): return True
return Primitive(signature_string, universe, _invoke, _is_empty)
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