Skip to content

Commit

Permalink
Split primitives into multiple modules #14
Browse files Browse the repository at this point in the history
  • Loading branch information
fniephaus committed Apr 25, 2016
1 parent 700b557 commit 40f99cd
Show file tree
Hide file tree
Showing 27 changed files with 2,661 additions and 2,489 deletions.
64 changes: 34 additions & 30 deletions rsqueakvm/interpreter_bytecodes.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from rsqueakvm import primitives, wrapper, error
from rsqueakvm import wrapper, error
from rsqueakvm.model.compiled_methods import W_CompiledMethod
from rsqueakvm.model.pointers import W_PointersObject
from rsqueakvm.prims import constants as pc
from rsqueakvm.prims import prim_table, prim_holder
from rsqueakvm.prims.shared import exitFromHeadlessExecution
from rsqueakvm.storage_classes import ClassShadow
from rsqueakvm.storage_contexts import ContextPartShadow, DirtyContext

from rsqueakvm.util.bitmanipulation import splitter

from rpython.rlib import objectmodel, unroll, jit


# unrolling_zero has been removed from rlib at some point.
if hasattr(unroll, "unrolling_zero"):
unrolling_zero = unroll.unrolling_zero
Expand Down Expand Up @@ -41,13 +45,13 @@ def bytecode_implementation_wrapper(self, interp, current_bytecode):
return bytecode_implementation_decorator

def make_call_primitive_bytecode(primitive, selector, argcount, store_pc=False):
func = primitives.prim_table[primitive]
func = prim_table[primitive]
@bytecode_implementation()
def callPrimitive(self, interp, current_bytecode):
# WARNING: this is used for bytecodes for which it is safe to
# directly call the primitive. In general, it is not safe: for
# example, depending on the type of the receiver, bytecodePrimAt
# may invoke primitives.AT, primitives.STRING_AT, or anything
# may invoke pc.AT, pc.STRING_AT, or anything
# else that the user put in a class in an 'at:' method.
# The rule of thumb is that primitives with only int and float
# in their unwrap_spec are safe.
Expand All @@ -66,10 +70,10 @@ def callClassbasedPrimitive(self, interp, current_bytecode):
receiver_class = rcvr.getclass(self.space)
try:
if receiver_class is getattr(self.space, a_class_name):
func = primitives.prim_table[a_primitive]
func = prim_table[a_primitive]
return func(interp, self, argcount)
elif receiver_class is getattr(self.space, alternative_class_name):
func = primitives.prim_table[alternative_primitive]
func = prim_table[alternative_primitive]
return func(interp, self, argcount)
except error.PrimitiveFailedError:
pass
Expand All @@ -79,7 +83,7 @@ def callClassbasedPrimitive(self, interp, current_bytecode):

# Some selectors cannot be overwritten, therefore no need to handle PrimitiveFailed.
def make_quick_call_primitive_bytecode(primitive_index, argcount):
func = primitives.prim_table[primitive_index]
func = prim_table[primitive_index]
@bytecode_implementation()
def quick_call_primitive_bytecode(self, interp, current_bytecode):
return func(interp, self, argcount)
Expand Down Expand Up @@ -399,7 +403,7 @@ def _doesNotUnderstand(self, w_selector, argcount, interp, receiver):
self.pop() # The receiver, already known.

if interp.space.headless.is_set():
primitives.exitFromHeadlessExecution(self, "doesNotUnderstand:", w_message)
exitFromHeadlessExecution(self, "doesNotUnderstand:", w_message)
return self._sendSpecialSelector(interp, receiver, "doesNotUnderstand", [w_message])

def _mustBeBoolean(self, interp, receiver):
Expand All @@ -411,7 +415,7 @@ def _call_primitive(self, code, interp, argcount, w_method, w_selector):
interp.print_padded("-> primitive %d \t(in %s, named %s)" % (
code, self.w_method().get_identifier_string(),
w_selector.selector_string()))
func = primitives.prim_holder.prim_table[code]
func = prim_holder.prim_table[code]
try:
# note: argcount does not include rcvr
# the primitive pushes the result (if any) onto the stack itself
Expand Down Expand Up @@ -615,22 +619,22 @@ def longJumpIfFalseBytecode(self, interp, current_bytecode, parameter):

# ====== Bytecodes implemented with primitives and message sends ======

bytecodePrimAdd = make_call_primitive_bytecode(primitives.ADD, "+", 1)
bytecodePrimSubtract = make_call_primitive_bytecode(primitives.SUBTRACT, "-", 1)
bytecodePrimLessThan = make_call_primitive_bytecode (primitives.LESSTHAN, "<", 1)
bytecodePrimGreaterThan = make_call_primitive_bytecode(primitives.GREATERTHAN, ">", 1)
bytecodePrimLessOrEqual = make_call_primitive_bytecode(primitives.LESSOREQUAL, "<=", 1)
bytecodePrimGreaterOrEqual = make_call_primitive_bytecode(primitives.GREATEROREQUAL, ">=", 1)
bytecodePrimEqual = make_call_primitive_bytecode(primitives.EQUAL, "=", 1)
bytecodePrimNotEqual = make_call_primitive_bytecode(primitives.NOTEQUAL, "~=", 1)
bytecodePrimMultiply = make_call_primitive_bytecode(primitives.MULTIPLY, "*", 1)
bytecodePrimDivide = make_call_primitive_bytecode(primitives.DIVIDE, "/", 1)
bytecodePrimMod = make_call_primitive_bytecode(primitives.MOD, "\\\\", 1)
bytecodePrimMakePoint = make_call_primitive_bytecode(primitives.MAKE_POINT, "@", 1)
bytecodePrimBitShift = make_call_primitive_bytecode(primitives.BIT_SHIFT, "bitShift:", 1)
bytecodePrimDiv = make_call_primitive_bytecode(primitives.DIV, "//", 1)
bytecodePrimBitAnd = make_call_primitive_bytecode(primitives.BIT_AND, "bitAnd:", 1)
bytecodePrimBitOr = make_call_primitive_bytecode(primitives.BIT_OR, "bitOr:", 1)
bytecodePrimAdd = make_call_primitive_bytecode(pc.ADD, "+", 1)
bytecodePrimSubtract = make_call_primitive_bytecode(pc.SUBTRACT, "-", 1)
bytecodePrimLessThan = make_call_primitive_bytecode(pc.LESSTHAN, "<", 1)
bytecodePrimGreaterThan = make_call_primitive_bytecode(pc.GREATERTHAN, ">", 1)
bytecodePrimLessOrEqual = make_call_primitive_bytecode(pc.LESSOREQUAL, "<=", 1)
bytecodePrimGreaterOrEqual = make_call_primitive_bytecode(pc.GREATEROREQUAL, ">=", 1)
bytecodePrimEqual = make_call_primitive_bytecode(pc.EQUAL, "=", 1)
bytecodePrimNotEqual = make_call_primitive_bytecode(pc.NOTEQUAL, "~=", 1)
bytecodePrimMultiply = make_call_primitive_bytecode(pc.MULTIPLY, "*", 1)
bytecodePrimDivide = make_call_primitive_bytecode(pc.DIVIDE, "/", 1)
bytecodePrimMod = make_call_primitive_bytecode(pc.MOD, "\\\\", 1)
bytecodePrimMakePoint = make_call_primitive_bytecode(pc.MAKE_POINT, "@", 1)
bytecodePrimBitShift = make_call_primitive_bytecode(pc.BIT_SHIFT, "bitShift:", 1)
bytecodePrimDiv = make_call_primitive_bytecode(pc.DIV, "//", 1)
bytecodePrimBitAnd = make_call_primitive_bytecode(pc.BIT_AND, "bitAnd:", 1)
bytecodePrimBitOr = make_call_primitive_bytecode(pc.BIT_OR, "bitOr:", 1)

bytecodePrimAt = make_send_selector_bytecode("at:", 1)
bytecodePrimAtPut = make_send_selector_bytecode("at:put:", 2)
Expand All @@ -639,12 +643,12 @@ def longJumpIfFalseBytecode(self, interp, current_bytecode, parameter):
bytecodePrimNextPut = make_send_selector_bytecode("nextPut:", 1)
bytecodePrimAtEnd = make_send_selector_bytecode("atEnd", 0)

bytecodePrimEquivalent = make_quick_call_primitive_bytecode(primitives.EQUIVALENT, 1)
bytecodePrimClass = make_quick_call_primitive_bytecode(primitives.CLASS, 0)
bytecodePrimEquivalent = make_quick_call_primitive_bytecode(pc.EQUIVALENT, 1)
bytecodePrimClass = make_quick_call_primitive_bytecode(pc.CLASS, 0)

bytecodePrimBlockCopy = make_call_primitive_bytecode(primitives.BLOCK_COPY, "blockCopy:", 1)
bytecodePrimValue = make_call_primitive_bytecode_classbased("w_BlockContext", primitives.VALUE, "w_BlockClosure", primitives.CLOSURE_VALUE, "value", 0)
bytecodePrimValueWithArg = make_call_primitive_bytecode_classbased("w_BlockContext", primitives.VALUE, "w_BlockClosure", primitives.CLOSURE_VALUE_, "value:", 1)
bytecodePrimBlockCopy = make_call_primitive_bytecode(pc.BLOCK_COPY, "blockCopy:", 1)
bytecodePrimValue = make_call_primitive_bytecode_classbased("w_BlockContext", pc.VALUE, "w_BlockClosure", pc.CLOSURE_VALUE, "value", 0)
bytecodePrimValueWithArg = make_call_primitive_bytecode_classbased("w_BlockContext", pc.VALUE, "w_BlockClosure", pc.CLOSURE_VALUE_, "value:", 1)

bytecodePrimDo = make_send_selector_bytecode("do:", 1)
bytecodePrimNew = make_send_selector_bytecode("new", 0)
Expand Down
6 changes: 4 additions & 2 deletions rsqueakvm/interpreter_debugging.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import pdb

from rsqueakvm import primitives, error
from rsqueakvm import error
from rsqueakvm.model.pointers import W_PointersObject
from rsqueakvm.prims import constants as pc, prim_table
from rsqueakvm.storage_contexts import ContextPartShadow


# This module patches up the interpreter and adds breakpoints at certain execution points.
# Only usable in interpreted mode due to pdb.
# To use, execute one of following after interpreter.py is loaded:
Expand Down Expand Up @@ -109,4 +111,4 @@ def meth(interp, s_frame, argcount, w_method=None):
raise e
return meth

primitives.prim_table[primitives.EXTERNAL_CALL] = failed_named_primitive(primitives.prim_table[primitives.EXTERNAL_CALL])
prim_table[pc.EXTERNAL_CALL] = failed_named_primitive(prim_table[pc.EXTERNAL_CALL])
3 changes: 2 additions & 1 deletion rsqueakvm/plugins/fileplugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,12 @@
import stat
import sys

from rsqueakvm.error import PrimitiveFailedError
from rsqueakvm.model.display import W_DisplayBitmap
from rsqueakvm.model.numeric import W_Float, W_LargePositiveInteger1Word
from rsqueakvm.model.variable import W_BytesObject, W_WordsObject
from rsqueakvm.plugins.plugin import Plugin
from rsqueakvm.primitives import PrimitiveFailedError, index1_0
from rsqueakvm.prims import index1_0
from rsqueakvm.util.system import IS_WINDOWS

from rpython.rlib import jit, rarithmetic
Expand Down
26 changes: 12 additions & 14 deletions rsqueakvm/plugins/large_integer.py
Original file line number Diff line number Diff line change
@@ -1,17 +1,15 @@
from rsqueakvm.primitives import prim_table, \
BIT_AND, BIT_OR, BIT_XOR, BIT_SHIFT, ADD, SUBTRACT, DIVIDE, MULTIPLY, \
pos_32bit_int
from rsqueakvm.error import PrimitiveFailedError
from rsqueakvm.plugins.plugin import Plugin
from rsqueakvm.prims import constants as pc, prim_table

LargeIntegerPlugin = Plugin()

LargeIntegerPlugin = Plugin()

bitops = {
'primDigitBitAnd': BIT_AND,
'primDigitBitOr': BIT_OR,
'primDigitBitXor': BIT_XOR,
'primDigitBitShiftMagnitude': BIT_SHIFT,
'primDigitBitAnd': pc.BIT_AND,
'primDigitBitOr': pc.BIT_OR,
'primDigitBitXor': pc.BIT_XOR,
'primDigitBitShiftMagnitude': pc.BIT_SHIFT,
}
for name, primitive in bitops.items():
def make_func(primitive):
Expand All @@ -23,8 +21,8 @@ def func(interp, s_frame, argcount):
make_func(primitive)

negOps = {
'primDigitDivNegative': DIVIDE,
'primDigitMultiplyNegative': MULTIPLY
'primDigitDivNegative': pc.DIVIDE,
'primDigitMultiplyNegative': pc.MULTIPLY
}
for name, primitive in negOps.items():
def make_func(primitive):
Expand All @@ -39,8 +37,8 @@ def func(interp, s_frame, argcount):
make_func(primitive)

ops = {
'primDigitAdd': ADD,
'primDigitSubtract': SUBTRACT,
'primDigitAdd': pc.ADD,
'primDigitSubtract': pc.SUBTRACT,
}
for name, primitive in ops.items():
def make_func(primitive):
Expand All @@ -51,8 +49,8 @@ def func(interp, s_frame, argcount):
if 2 < argcount or argcount < 1:
raise PrimitiveFailedError
rcvr = s_frame.peek(argcount).unwrap_longlong(interp.space)
arg = s_frame.peek(argcount - 1).unwrap_longlong(interp.space)
if (rcvr < 0 and arg >= 0) or (rcvr >= 0 and arg < 0):
arg = s_frame.peek(argcount - 1).unwrap_longlong(interp.space)
if (rcvr < 0 and arg >= 0) or (rcvr >= 0 and arg < 0):
raise PrimitiveFailedError
return primfunc(interp, s_frame, argcount)
func.func_name = name
Expand Down
2 changes: 1 addition & 1 deletion rsqueakvm/plugins/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ def _find_prim(self, name):
return self.prims.get(name, None)

def expose_primitive(self, wrap_func=None, **kwargs):
from rsqueakvm.primitives import wrap_primitive, unwrap_alternatives
from rsqueakvm.prims import wrap_primitive, unwrap_alternatives
if not wrap_func:
if kwargs.get('unwrap_specs', None):
wrap_func = unwrap_alternatives
Expand Down
4 changes: 2 additions & 2 deletions rsqueakvm/plugins/squeak_plugin_proxy.py
Original file line number Diff line number Diff line change
Expand Up @@ -298,14 +298,14 @@ def slotSizeOf(w_object):

@expose_on_virtual_machine_proxy([oop, int], oop)
def stObjectat(w_object, n0):
from rsqueakvm.primitives import assert_valid_index
from rsqueakvm.prims import assert_valid_index
space = IProxy.space
n0 = assert_valid_index(space, n0, w_object)
return w_object.at0(space, n0)

@expose_on_virtual_machine_proxy([oop, int, oop], oop)
def stObjectatput(w_object, n0, w_value):
from rsqueakvm.primitives import assert_valid_index
from rsqueakvm.prims import assert_valid_index
space = IProxy.space
n0 = assert_valid_index(space, n0, w_object)
w_object.atput0(space, n0, w_value)
Expand Down
Loading

0 comments on commit 40f99cd

Please sign in to comment.