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.

integer_primitives.py 7.12 KB
Newer Older
Stefan Marr's avatar
Stefan Marr committed
1 2
from rpython.rlib.rarithmetic import ovfcheck
from rpython.rlib.rbigint import rbigint
Stefan Marr's avatar
Stefan Marr committed
3
from som.primitives.primitives import Primitives
Stefan Marr's avatar
Stefan Marr committed
4
from som.vmobjects.integer import Integer
Stefan Marr's avatar
Stefan Marr committed
5 6
from som.vmobjects.primitive   import Primitive
from som.vmobjects.double      import Double
Stefan Marr's avatar
Stefan Marr committed
7
from som.vmobjects.string      import String
Stefan Marr's avatar
Stefan Marr committed
8
from som.vmobjects.block       import block_evaluate
Stefan Marr's avatar
Stefan Marr committed
9 10 11

import math

Stefan Marr's avatar
Stefan Marr committed
12

13 14
def _asString(ivkbl, frame, interpreter):
    rcvr = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
15
    frame.push(rcvr.prim_as_string(interpreter.get_universe()))
16

Stefan Marr's avatar
Stefan Marr committed
17

18 19
def _sqrt(ivkbl, frame, interpreter):
    rcvr = frame.pop()
20 21 22 23 24
    res = math.sqrt(rcvr.get_embedded_integer())
    if res == float(int(res)):
        frame.push(interpreter.get_universe().new_integer(int(res)))
    else:
        frame.push(interpreter.get_universe().new_double(res))
25

Stefan Marr's avatar
Stefan Marr committed
26

27 28
def _atRandom(ivkbl, frame, interpreter):
    rcvr = frame.pop()
Tobias Pape's avatar
Tobias Pape committed
29 30
    frame.push(interpreter.get_universe().new_integer(int(
        rcvr.get_embedded_integer() * interpreter.get_universe().random.random())))
31

Stefan Marr's avatar
Stefan Marr committed
32

33 34 35
def _plus(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
36
    frame.push(left.prim_add(right_obj, interpreter.get_universe()))
37

Stefan Marr's avatar
Stefan Marr committed
38

39 40 41
def _minus(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
42
    frame.push(left.prim_subtract(right_obj, interpreter.get_universe()))
43

Stefan Marr's avatar
Stefan Marr committed
44

45 46 47
def _mult(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
48
    frame.push(left.prim_multiply(right_obj, interpreter.get_universe()))
49

Stefan Marr's avatar
Stefan Marr committed
50

51 52 53
def _doubleDiv(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
54
    frame.push(left.prim_double_div(right_obj, interpreter.get_universe()))
55

Stefan Marr's avatar
Stefan Marr committed
56

57 58 59
def _intDiv(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
60
    frame.push(left.prim_int_div(right_obj, interpreter.get_universe()))
61

Stefan Marr's avatar
Stefan Marr committed
62

63 64 65
def _mod(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
66
    frame.push(left.prim_modulo(right_obj, interpreter.get_universe()))
67

Stefan Marr's avatar
Stefan Marr committed
68

69 70 71
def _and(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
72
    frame.push(left.prim_and(right_obj, interpreter.get_universe()))
73 74 75 76 77


def _equals(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
78
    frame.push(left.prim_equals(right_obj, interpreter.get_universe()))
79

Stefan Marr's avatar
Stefan Marr committed
80

81 82 83
def _lessThan(ivkbl, frame, interpreter):
    right_obj = frame.pop()
    left      = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
84
    frame.push(left.prim_less_than(right_obj, interpreter.get_universe()))
Stefan Marr's avatar
Stefan Marr committed
85

Stefan Marr's avatar
Stefan Marr committed
86

Stefan Marr's avatar
Stefan Marr committed
87 88 89 90 91 92 93 94 95 96 97
def _fromString(ivkbl, frame, interpreter):
    param = frame.pop()
    frame.pop()
    
    if not isinstance(param, String):
        frame.push(interpreter.get_universe().nilObject)
        return
    
    int_value = int(param.get_embedded_string())
    frame.push(interpreter.get_universe().new_integer(int_value))

Stefan Marr's avatar
Stefan Marr committed
98

99 100 101
def _leftShift(ivkbl, frame, interpreter):
    right = frame.pop()
    left  = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
102 103
    universe  = interpreter.get_universe()
    assert isinstance(right, Integer)
104

Stefan Marr's avatar
Stefan Marr committed
105 106 107 108 109 110 111 112
    l = left.get_embedded_integer()
    r = right.get_embedded_integer()
    try:
        result = ovfcheck(l << r)
        frame.push(universe.new_integer(result))
    except OverflowError:
        frame.push(universe.new_biginteger(
            rbigint.fromint(l).lshift(r)))
113 114 115 116 117 118 119 120 121 122


def _bitXor(ivkbl, frame, interpreter):
    right = frame.pop()
    left  = frame.pop()
    
    result = left.get_embedded_integer() ^ right.get_embedded_integer()

    frame.push(interpreter.get_universe().new_integer(result))

Stefan Marr's avatar
Stefan Marr committed
123

Stefan Marr's avatar
Stefan Marr committed
124 125
from rpython.rlib import jit

Stefan Marr's avatar
Stefan Marr committed
126

Stefan Marr's avatar
Stefan Marr committed
127
def get_printable_location(interpreter, block_method):
Stefan Marr's avatar
Stefan Marr committed
128 129
    from som.vmobjects.method import Method
    assert isinstance(block_method, Method)
130 131
    return "to:do: [%s>>%s]" % (block_method.get_holder().get_name().get_string(),
                                block_method.get_signature().get_string())
Stefan Marr's avatar
Stefan Marr committed
132 133


134
jitdriver_int = jit.JitDriver(
Stefan Marr's avatar
Stefan Marr committed
135
    greens=['interpreter', 'block_method'],
Stefan Marr's avatar
Stefan Marr committed
136 137 138 139
    reds='auto',
    # virtualizables=['frame'],
    get_printable_location=get_printable_location)

140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
jitdriver_double = jit.JitDriver(
    greens=['interpreter', 'block_method'],
    reds='auto',
    # virtualizables=['frame'],
    get_printable_location=get_printable_location)


def _toDoInt(i, top, frame, context, interpreter, block_method, universe):
    assert isinstance(i, int)
    assert isinstance(top, int)
    while i <= top:
        jitdriver_int.jit_merge_point(interpreter=interpreter,
                                      block_method=block_method)

        b = universe.new_block(block_method, context)
        frame.push(b)
        frame.push(universe.new_integer(i))
        block_evaluate(b, interpreter, frame)
        frame.pop()
        i += 1


def _toDoDouble(i, top, frame, context, interpreter, block_method, universe):
    assert isinstance(i, int)
    assert isinstance(top, float)
    while i <= top:
        jitdriver_double.jit_merge_point(interpreter=interpreter,
                                         block_method=block_method)

        b = universe.new_block(block_method, context)
        frame.push(b)
        frame.push(universe.new_integer(i))
        block_evaluate(b, interpreter, frame)
        frame.pop()
        i += 1


Stefan Marr's avatar
Stefan Marr committed
177 178 179 180
def _toDo(ivkbl, frame, interpreter):
    universe = interpreter.get_universe()
    block = frame.pop()
    limit = frame.pop()
Stefan Marr's avatar
Stefan Marr committed
181
    self  = frame.pop()  # we do leave it on there
182

Stefan Marr's avatar
Stefan Marr committed
183 184
    block_method = block.get_method()
    context      = block.get_context()
185 186

    i = self.get_embedded_integer()
187
    if isinstance(limit, Double):
188 189
        _toDoDouble(i, limit.get_embedded_double(), frame, context, interpreter,
                    block_method, universe)
190
    else:
Stefan Marr's avatar
Stefan Marr committed
191
        _toDoInt(i, limit.get_embedded_integer(), frame, context, interpreter,
192
                 block_method, universe)
193

Stefan Marr's avatar
Stefan Marr committed
194 195
    frame.push(self)

196

197
class IntegerPrimitives(Primitives):
Stefan Marr's avatar
Stefan Marr committed
198 199 200

    def install_primitives(self):
        self._install_instance_primitive(Primitive("asString", self._universe, _asString))
201
        self._install_instance_primitive(Primitive("sqrt",     self._universe, _sqrt))
Stefan Marr's avatar
Stefan Marr committed
202
        self._install_instance_primitive(Primitive("atRandom", self._universe, _atRandom))
203 204 205
        
        self._install_instance_primitive(Primitive("+",  self._universe, _plus))
        self._install_instance_primitive(Primitive("-",  self._universe, _minus))
Stefan Marr's avatar
Stefan Marr committed
206

207
        self._install_instance_primitive(Primitive("*",  self._universe, _mult))
Stefan Marr's avatar
Stefan Marr committed
208
        self._install_instance_primitive(Primitive("//", self._universe, _doubleDiv))
209 210 211 212 213
        self._install_instance_primitive(Primitive("/",  self._universe, _intDiv))
        self._install_instance_primitive(Primitive("%",  self._universe, _mod))
        self._install_instance_primitive(Primitive("&",  self._universe, _and))
        self._install_instance_primitive(Primitive("=",  self._universe, _equals))
        self._install_instance_primitive(Primitive("<",  self._universe, _lessThan))
214 215 216 217

        self._install_instance_primitive(Primitive("<<", self._universe, _leftShift))
        self._install_instance_primitive(Primitive("bitXor:", self._universe, _bitXor))

Stefan Marr's avatar
Stefan Marr committed
218 219
        self._install_instance_primitive(Primitive("to:do:", self._universe, _toDo))
        
Stefan Marr's avatar
Stefan Marr committed
220
        self._install_class_primitive(Primitive("fromString:", self._universe, _fromString))