Commits

Lars Wassermann committed ee98414 Merge

merge with bit_shift fix

Comments (0)

Files changed (6)

         return "W_LargePositiveInteger1Word(%d)" % r_uint(self.value)
 
     def lshift(self, space, shift):
-        from rpython.rlib.rarithmetic import intmask, r_uint
+        from rpython.rlib.rarithmetic import ovfcheck, intmask, r_uint
         # shift > 0, therefore the highest bit of upperbound is not set,
         # i.e. upperbound is positive
         upperbound = intmask(r_uint(-1) >> shift)
         if 0 <= self.value <= upperbound:
-            shifted = intmask(self.value << shift)
+            try:
+                shifted = intmask(ovfcheck(self.value << shift))
+            except OverflowError:
+                raise error.PrimitiveFailedError()
             return space.wrap_positive_32bit_int(shifted)
         else:
             raise error.PrimitiveFailedError()

spyvm/primitives.py

 prim_table_implemented_only = []
 
 # indicates that what is pushed is an index1, but it is unwrapped and
-# converted to an index0 
+# converted to an index0
 index1_0 = object()
 char = object()
 pos_32bit_int = object()
     if argument == 0:
         raise PrimitiveFailedError()
     return interp.space.wrap_int(receiver // argument)
-    
+
 # #// -- return the result of a division, rounded towards negative infinite
 @expose_primitive(QUO, unwrap_spec=[int, int])
 def func(interp, s_frame, receiver, argument):
     if argument == 0:
         raise PrimitiveFailedError()
     return interp.space.wrap_int(receiver // argument)
-    
+
 # #bitShift: -- return the shifted value
 @expose_primitive(BIT_SHIFT, unwrap_spec=[object, int])
 def func(interp, s_frame, receiver, argument):
-    # Failing! Use ovfcheck_lfshift
-    # (http://codespeak.net/pypy/dist/pypy/doc/coding-guide.html#integer-types)
-    if argument > 0:
-        return receiver.lshift(interp.space, argument)
+    from rpython.rlib.rarithmetic import LONG_BIT
+    if -LONG_BIT < argument < LONG_BIT:
+        # overflow-checking done in lshift implementations
+        if argument > 0:
+            return receiver.lshift(interp.space, argument)
+        else:
+            return receiver.rshift(interp.space, -argument)
     else:
-        return receiver.rshift(interp.space, -argument)
+        raise PrimitiveFailedError()
 
 # ___________________________________________________________________________
 # Float Primitives
 ARRAY_BECOME_ONE_WAY = 72     # Blue Book: primitiveBecome
 INST_VAR_AT = 73
 INST_VAR_AT_PUT = 74
-AS_OOP = 75                  
+AS_OOP = 75
 STORE_STACKP = 76             # Blue Book: primitiveAsObject
 SOME_INSTANCE = 77
 NEXT_INSTANCE = 78
         if not rgc.get_gcflag_extra(gcref):
             rgc.toggle_gcflag_extra(gcref)
             w_obj = rgc.try_cast_gcref_to_instance(model.W_Object, gcref)
-            if (w_obj is not None and w_obj.has_class() 
+            if (w_obj is not None and w_obj.has_class()
                 and w_obj.getclass(interp.space) is w_class):
                 match_w.append(w_obj)
             pending.extend(rgc.get_rpy_referents(gcref))
 # I/O Primitives
 
 MOUSE_POINT = 90
-TEST_DISPLAY_DEPTH = 91 
+TEST_DISPLAY_DEPTH = 91
 SET_DISPLAY_MODE = 92
 INPUT_SEMAPHORE = 93
 GET_NEXT_EVENT = 94
 
 @expose_primitive(STRING_REPLACE, unwrap_spec=[object, index1_0, index1_0, object, index1_0])
 def func(interp, s_frame, w_rcvr, start, stop, w_replacement, repStart):
-    """replaceFrom: start to: stop with: replacement startingAt: repStart 
-    Primitive. This destructively replaces elements from start to stop in the 
-    receiver starting at index, repStart, in the collection, replacement. Answer 
-    the receiver. Range checks are performed in the primitive only. Essential 
+    """replaceFrom: start to: stop with: replacement startingAt: repStart
+    Primitive. This destructively replaces elements from start to stop in the
+    receiver starting at index, repStart, in the collection, replacement. Answer
+    the receiver. Range checks are performed in the primitive only. Essential
     for Pharo Candle Symbols.
     | index repOff |
     repOff := repStart - start.
         whileTrue: [self at: index put: (replacement at: repOff + index)]"""
     if (start < 0 or start - 1 > stop or repStart < 0):
         raise PrimitiveFailedError()
-    # This test deliberately test for equal W_Object class. The Smalltalk classes 
+    # This test deliberately test for equal W_Object class. The Smalltalk classes
     # might be different (e.g. Symbol and ByteString)
     if w_rcvr.__class__ is not w_replacement.__class__:
         raise PrimitiveFailedError()
 def func(interp, s_frame, argument_count):
     if argument_count == 0:
         s_frame.pop()
-        return interp.space.wrap_string(interp.image_name)        
+        return interp.space.wrap_string(interp.image_name)
     elif argument_count == 1:
         pass # XXX
     raise PrimitiveFailedError
 FLOAT_GREATEROREQUAL = 46
 FLOAT_EQUAL = 47
 FLOAT_NOTEQUAL = 48
-    
+
 bool_ops = {
     LESSTHAN: operator.lt,
     GREATERTHAN: operator.gt,
             w_res = interp.space.wrap_bool(res)
             return w_res
     make_func(op)
-    
+
 # ___________________________________________________________________________
 # Quick Push Const Primitives
 
     (PUSH_TWO, "w_two"),
     ]:
     make_push_const_func(code, name)
-        
+
 # ___________________________________________________________________________
 # Control Primitives
 
     if not w_block_ctx.getclass(interp.space).is_same_object(
         interp.space.w_BlockContext):
         raise PrimitiveFailedError()
-    
+
     assert isinstance(w_block_ctx, model.W_PointersObject)
 
     s_block_ctx = w_block_ctx.as_blockcontext_get_shadow(interp.space)
 
     if len(args_w) != exp_arg_cnt:
         raise PrimitiveFailedError()
-    
+
     # Push all the items from the array
     for i in range(exp_arg_cnt):
         s_block_ctx.push(args_w[i])
     if not (outer_ctxt_class is space.w_MethodContext
                 or outer_ctxt_class is space.w_BlockContext):
         raise PrimitiveFailedError()
-    
+
     # additionally to the smalltalk implementation, this also pushes
     # args and copiedValues
     s_new_frame = block.asContextWithSender(s_frame.w_self(), args_w)

spyvm/squeakimage.py

                 return swapped_chrs2int(data_peek)
             else:
                 return chrs2int(data_peek)
-    
+
 
     def next(self):
         integer = self.peek()
 if sys.maxint == 2 ** 63 - 1:
     image_versions.update({
    -0x5ff6ff0000000000:
-    # signed version of 0xA009010000000000: 
+    # signed version of 0xA009010000000000:
                         ImageVersion(68000, False, True,  False, False),
     0x00000000000109A2: ImageVersion(68002, True,  True,  True,  False),
    -0x5df6ff0000000000:
-    # signed version of 0xA209010000000000: 
-			ImageVersion(68002, False, True,  True,  False),
+    # signed version of 0xA209010000000000:
+                        ImageVersion(68002, False, True,  True,  False),
     0x00000000000109A3: ImageVersion(68003, True,  True,  True,  True ),
    -0x5cf6ff0000000000:
-    # signed version of 0xA309010000000000: 
-			ImageVersion(68003, False, True,  True,  True ),
+    # signed version of 0xA309010000000000:
+                        ImageVersion(68003, False, True,  True,  True ),
 })
 
-    
+
 def version(magic):
     ver = image_versions.get(magic, None)
     if ver is None:
                     pass # raise original error
         raise
 
-    
-    
+
+
 def reader_for_image(space, stream):
     ver = version_from_stream(stream)
     if not ver.is_big_endian:
     return ImageReader(space, stream, ver)
 
 class ImageReader(object):
-    
+
     def __init__(self, space, stream, version):
         self.space = space
         self.stream = stream
 
     def iscompact(self):
         return 0 < self.classid < 32
-
-

spyvm/test/test_miniimage.py

     return perform(space.wrap_string(name), "asSymbol")
 
 def open_miniimage(space):
-    return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open()))
+    return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open(mode="rb")))
 
 def get_reader():
     return reader
-    
+
 def get_image():
     return image
-    
+
 def get_float_class():
     image = get_image()
     return image.special(constants.SO_FLOAT_CLASS)
 
 # ------ tests ------------------------------------------
-        
+
 def test_miniimageexists():
     assert mini_image.check(dir=False)
 
     assert reader.oldbaseaddress == -1221464064
     assert reader.specialobjectspointer == -1221336216
 
-def test_read_all_header(): 
+def test_read_all_header():
     reader = open_miniimage(space)
     reader.read_header()
     next = reader.stream.peek()
-    assert next != 0 #expects object header, which must not be 0x00000000 
-      
-      
+    assert next != 0 #expects object header, which must not be 0x00000000
+
+
 def test_all_pointers_are_valid():
     reader = get_reader()
     for each in reader.chunks.itervalues():
-        if each.format < 5: 
+        if each.format < 5:
             for pointer in each.data:
                 if (pointer & 1) != 1:
-                    assert pointer in reader.chunks   
-    
-    
+                    assert pointer in reader.chunks
+
+
 def test_there_are_31_compact_classes():
     reader = get_reader()
     assert len(reader.compactclasses) == 31
-    
+
 def test_float_class_size():
     w_float_class = get_float_class()
     assert w_float_class.size() == 9
     w_float_class_name = w_float_class.fetch(space, 6)
     assert isinstance(w_float_class_name, model.W_BytesObject)
     assert w_float_class_name.bytes == list("Float")
-    
+
 def test_str_w_object():
     w_float_class = get_float_class()
     w_float_class.as_class_get_shadow(space)
     w = image.special(constants.SO_TRUE)
     w.shadow_of_my_class(space)
     assert str(w) == "a True" #yes, with article
-    
+
 def test_scheduler():
     image = get_image()
     w = image.special(constants.SO_SCHEDULERASSOCIATIONPOINTER)
     w0 = w.fetch(space, 0)
-    assert str(w0) == "Processor" 
+    assert str(w0) == "Processor"
     w0 = w.fetch(space, 1)
     w0.shadow_of_my_class(space)
-    assert str(w0) == "a ProcessorScheduler" 
-   
+    assert str(w0) == "a ProcessorScheduler"
+
 def test_special_classes0():
     image = get_image()
     # w = image.special(constants.SO_BITMAP_CLASS)
-    # assert str(w) == "Bitmap class" 
+    # assert str(w) == "Bitmap class"
     w = image.special(constants.SO_SMALLINTEGER_CLASS)
-    assert str(w) == "SmallInteger class" 
+    assert str(w) == "SmallInteger class"
     w = image.special(constants.SO_STRING_CLASS)
-    assert str(w) == "String class" 
+    assert str(w) == "String class"
     w = image.special(constants.SO_ARRAY_CLASS)
-    assert str(w) == "Array class" 
+    assert str(w) == "Array class"
     w = image.special(constants.SO_FLOAT_CLASS)
-    assert str(w) == "Float class" 
+    assert str(w) == "Float class"
     w = image.special(constants.SO_METHODCONTEXT_CLASS)
-    assert str(w) == "MethodContext class" 
+    assert str(w) == "MethodContext class"
     w = image.special(constants.SO_BLOCKCONTEXT_CLASS)
-    assert str(w) == "BlockContext class" 
+    assert str(w) == "BlockContext class"
     w = image.special(constants.SO_POINT_CLASS)
-    assert str(w) == "Point class" 
+    assert str(w) == "Point class"
     w = image.special(constants.SO_LARGEPOSITIVEINTEGER_CLASS)
-    assert str(w) == "LargePositiveInteger class" 
+    assert str(w) == "LargePositiveInteger class"
     w = image.special(constants.SO_MESSAGE_CLASS)
-    assert str(w) == "Message class" 
+    assert str(w) == "Message class"
 
     # to be continued
 
     SO_LOW_SPACE_SEMAPHORE = 17
     SO_SEMAPHORE_CLASS = 18
     SO_CHARACTER_CLASS = 19"""
-    
+
 def test_name_of_shadow_of_specials():
     image = get_image()
     w_doesnot = image.special(constants.SO_DOES_NOT_UNDERSTAND)
     w = image.special(constants.SO_DOES_NOT_UNDERSTAND)
     assert str(w) == "doesNotUnderstand:"
     assert str(w.getclass(space)) == "Symbol class" # for some strange reason not a symbol
-    
-    
+
+
     """
     SO_DOES_NOT_UNDERSTAND = 20
     SO_CANNOT_RETURN = 21
     SO_A_POINT = 33
     SO_CANNOT_INTERPRET = 34
     SO_A_METHODCONTEXT = 35 # deprecated in closure images
-    SO_BLOCKCLOSURE_CLASS = 36 
+    SO_BLOCKCLOSURE_CLASS = 36
     SO_A_BLOCKCONTEXT = 37 # deprecated in closure images
     SO_EXTERNAL_OBJECTS_ARRAY = 38
     SO_PSEUDOCONTEXT_CLASS = 39
     assert w_true.is_same_object(space.w_true)
     w_false = image.special(constants.SO_FALSE)
     assert w_false.is_same_object(space.w_false)
-    
+
 def test_runimage():
     py.test.skip("This method actually runs an image. Fails since no graphical primitives yet")
     from spyvm import wrapper
     interp.interpret_with_w_frame(w_ctx)
 
 def test_compile_method():
-    sourcecode = """fib 
-                        ^self < 2 
-                            ifTrue: [ 1 ] 
+    sourcecode = """fib
+                        ^self < 2
+                            ifTrue: [ 1 ]
                             ifFalse: [ (self - 1) fib + (self - 2) fib ]"""
     perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None))
     assert perform(w(10), "fib").is_same_object(w(89))
 
 
-def w(any): 
+def w(any):
     # XXX could put this on the space?
     if any is None:
         return space.w_nil
     if isinstance(any, str):
         # assume never have strings of length 1
-        if len(any) == 1: 
+        if len(any) == 1:
             return space.wrap_chr(any)
         else:
             return space.wrap_string(any)
     if isinstance(any, bool):
         return space.wrap_bool(any)
-    if isinstance(any, int):    
+    if isinstance(any, int):
         return space.wrap_int(any)
     if isinstance(any, float):
         return space.wrap_float(any)
     else:
-        raise Exception    
+        raise Exception
 
 def test_become():
     sourcecode = """
       (p1 -> p2 = a)       ifFalse: [^10].
       (p1 == a key)        ifFalse: [^11].
       (p2 == a value)      ifFalse: [^12].
-  
+
       ^42"""
     perform(w(10).getclass(space), "compile:classified:notifying:", w(sourcecode), w('pypy'), w(None))
     w_result = perform(w(10), "testBecome")
     interp.step(s_ctx)
     assert s_ctx.top().value == 2
     interp.step(s_ctx)
-    assert s_ctx.top().value == 3
+    assert s_ctx.top().value == 3

spyvm/tool/analyseimage.py

 import py
-from spyvm import squeakimage 
-from spyvm import constants 
-from spyvm import model 
-from spyvm import interpreter 
+from spyvm import squeakimage
+from spyvm import constants
+from spyvm import model
+from spyvm import interpreter
 import sys
 
 image_dir = py.path.local(__file__).dirpath().dirpath().dirpath('images')
 minitest_image = image_dir.join('minitest.image')
 
 def get_miniimage(space):
-    return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open()))
+    return squeakimage.reader_for_image(space, squeakimage.Stream(mini_image.open(mode="rb")))
 
 def get_minitestimage(space):
-    return squeakimage.reader_for_image(space, squeakimage.Stream(minitest_image.open()))
+    return squeakimage.reader_for_image(space, squeakimage.Stream(minitest_image.open(mode="rb")))
 
 def create_image(space, image_reader):
     image_reader.initialize()
-    
+
     image = squeakimage.SqueakImage()
     image.from_reader(space, image_reader)
     return image

targetimageloadingsmalltalk.py

         path = "Squeak.image"
 
     try:
-        f = open_file_as_stream(path, buffering=0)
+        f = open_file_as_stream(path, mode="rb", buffering=0)
     except OSError as e:
         os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path))
         return 1