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.

Commit 9919655b authored by Stefan Marr's avatar Stefan Marr
Browse files

Added Disassembler


Signed-off-by: default avatarStefan Marr <git@stefan-marr.de>
parent 48a46cf9
from som.vm.universe import Universe
from som.interpreter.bytecodes import Bytecodes
class Disassembler(object):
@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
Universe.error_print(str(clazz.get_name()) + ">>" +
str(inv.get_signature()) + " = ")
if inv.is_primitive():
Universe.error_println("<primitive>")
continue
# output actual method
cls.dump_method(inv, "\t")
@classmethod
def dump_method(cls, m, indent):
Universe.error_println("(")
# 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():
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)
Universe.error_print(Bytecodes.as_str(bytecode) + " ")
# 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_constant(b)))
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_constant(b)))
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 + ")")
......@@ -76,7 +76,7 @@ class Bytecodes(object):
if not isinstance(bytecode, int):
raise ValueError('bytecode is expected to be an integer.')
for key, val in cls.__dict__:
for key, val in cls.__dict__.iteritems():
if val == bytecode:
return key.upper()
......
......@@ -621,6 +621,7 @@ 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)
......@@ -635,7 +636,8 @@ class Universe(object):
def load_shell_class(self, stmt):
# Load the class from a stream and return the loaded class
result = sourcecode_compiler.compile_class_from_string(stmt, None, self)
if self._dumpBytecodes:
if self._dump_bytecodes:
from som.compiler.disassembler import Disassembler
Disassembler.dump(result)
return result
......
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