To protect your data, the CISO officer has suggested users to enable GitLab 2FA as soon as possible.

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