[pypy-commit] lang-smalltalk storage-context-state: Merged.

anton_gulenko noreply at buildbot.pypy.org
Tue Jul 22 23:27:24 CEST 2014


Author: Anton Gulenko <anton.gulenko at googlemail.com>
Branch: storage-context-state
Changeset: r941:4e7e88455fcc
Date: 2014-07-22 23:12 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/4e7e88455fcc/

Log:	Merged.

diff --git a/images/Squeak4.5-noBitBlt.changes b/images/Squeak4.5-noBitBlt.changes
--- a/images/Squeak4.5-noBitBlt.changes
+++ b/images/Squeak4.5-noBitBlt.changes
@@ -12620,4 +12620,15 @@
 	
 	1 to: self splayTreeSize do: [:i |
 		self insertNewNode.
-	]! !

----SNAPSHOT----{15 July 2014 . 6:10:56 pm} Squeak4.5-noBitBlt.image priorSource: 15894330!
\ No newline at end of file
+	]! !

----SNAPSHOT----{15 July 2014 . 6:10:56 pm} Squeak4.5-noBitBlt.image priorSource: 15894330!
+
+----QUIT/NOSAVE----{21 July 2014 . 4:18:39 pm} Squeak4.5-noBitBlt.image priorSource: 15894825!

----STARTUP----{21 July 2014 . 6:19:06 pm} as C:\Dev\lang-smalltalk\images\Squeak4.5-noBitBlt.image!

!WeakMessageSend methodsFor: 'private' stamp: 'ag 7/21/2014 18:20' prior: 34321504!
withEnsuredReceiverAndArgumentsDo: aBlock otherwise: altBlock
	"Grab real references to receiver and arguments. If they still exist, evaluate aBlock."

	"Return if my receiver has gone away"
	| r a |
	r := self receiver.
	r ifNil: [ ^altBlock value ].

	"Make sure that my arguments haven't gone away"
	arguments ifNil: [ ^ altBlock value ].
	a := Array withAll: arguments.
	a with: shouldBeNil do: [ :arg :flag |
		arg ifNil: [ flag ifFalse: [ ^altBlock value ]]
	].

	^aBlock value: r value: a! !

----QUIT----{21 July 2014 . 6:20:43 pm} Squeak4.5-noBitBlt.image priorSource: 15894825!
+
+----QUIT/NOSAVE----{21 July 2014 . 4:21:36 pm} Squeak4.5-noBitBlt.image priorSource: 15895702!

----STARTUP----{21 July 2014 . 6:21:54 pm} as C:\Dev\lang-smalltalk\images\Squeak4.5-noBitBlt.image!

!WeakMessageSend methodsFor: 'comparing' stamp: 'ag 7/21/2014 18:22' prior: 33144463!
= anObject
	"Compare equal to equivalent MessageSend"
	^ anObject isMessageSend
		and: [self receiver == anObject receiver
		and: [selector == anObject selector
		and: [(Array withAll: self arguments) = (Array withAll: anObject arguments)]]]
! !
!WeakMessageSend methodsFor: 'private' stamp: 'ag 7/21/2014 18:23' prior: 49449636!
withEnsuredReceiverAndArgumentsDo: aBlock otherwise: altBlock
	"Grab real references to receiver and arguments. If they still exist, evaluate aBlock."

	"Return if my receiver has gone away"
	| r a |
	r := self receiver.
	r ifNil: [ ^altBlock value ].

	"Make sure that my arguments haven't gone away"
	a := Array withAll: self arguments.
	a with: shouldBeNil do: [ :arg :flag |
		arg ifNil: [ flag ifFalse: [ ^altBlock value ]]
	].

	^aBlock value: r value: a! !

----QUIT----{21 July 2014 . 6:23:49 pm} Squeak4.5-noBitBlt.image priorSource: 15895702!

----STARTUP----{21 July 2014 . 6:31:05 pm} as C:\Dev\lang-smalltalk\images\Squeak4.5-noBitBlt.image!

!WeakMessageSend methodsFor: 'accessing' stamp: 'ag 7/21/2014 18:31'!
shouldBeNil
	
	^ shouldBeNil ifNil: [ Array new ]! !
!WeakMessageSend methodsFor: 'private' stamp: 'ag 7/21/2014 18:31' prior: 33148869!
isAnyArgumentGarbage
	"Make sure that my arguments haven't gone away"
	arguments ifNotNil: [
		arguments with: self shouldBeNil do: [ :arg :flag |
			(flag not and: [arg isNil])
				ifTrue: [^true]
		]
	].
	^false
! !
!WeakMessageSend methodsFor: 'private' stamp: 'ag 7/21/2014 18:31' prior: 49450841!
withEnsuredReceiverAndArgumentsDo: aBlock otherwise: altBlock
	"Grab real references to receiver and arguments. If they still exist, evaluate aBlock."

	"Return if my receiver has gone away"
	| r a |
	r := self receiver.
	r ifNil: [ ^altBlock value ].

	"Make sure that my arguments haven't gone away"
	a := Array withAll: self arguments.
	a with: self shouldBeNil do: [ :arg :flag |
		arg ifNil: [ flag ifFalse: [ ^altBlock value ]]
	].

	^aBlock value: r value: a! !
!WeakMessageSend methodsFor: 'private' stamp: 'ag 7/21/2014 18:32' prior: 34360552!
withEnsuredReceiverAndArgumentsDo: aBlock withEnoughArguments: anArray otherwise: altBlock
	"call the selector with enough arguments from arguments and anArray"
	| r selfArgs enoughArgs |
	r := self receiver.
	r ifNil: [ ^altBlock value ].
	
	selfArgs := self arguments.
	selfArgs with: self shouldBeNil do: [ :arg :flag |
		arg ifNil: [ flag ifFalse: [ ^altBlock value ]]
	].

	enoughArgs := Array new: selector numArgs.
	enoughArgs replaceFrom: 1
		to: ( selfArgs size min: enoughArgs size)
		with: selfArgs
		startingAt: 1.
	enoughArgs size > selfArgs size ifTrue: [
		enoughArgs replaceFrom: selfArgs size + 1
			to: (selfArgs size + anArray size min: enoughArgs size)
			with: anArray
			startingAt: 1.
	].
	^aBlock value: r value: enoughArgs! !

----QUIT----{21 July 2014 . 6:32:32 pm} Squeak4.5-noBitBlt.image priorSource: 15896872!
+
+----STARTUP----{21 July 2014 . 4:32:52 pm} as C:\Dev\lang-smalltalk\images\Squeak4.5-noBitBlt.image!
+
+
+1+1!
+
+----QUIT/NOSAVE----{21 July 2014 . 4:33:15 pm} Squeak4.5-noBitBlt.image priorSource: 15898877!
\ No newline at end of file
diff --git a/images/Squeak4.5-noBitBlt.image b/images/Squeak4.5-noBitBlt.image
index ed92c78c940799d91bb94a8ed8527076db6816c7..00843c2c83f9c11e5dcfa3b9927bd415d0a22cd8
GIT binary patch

[cut]

diff --git a/spyvm/constants.py b/spyvm/constants.py
--- a/spyvm/constants.py
+++ b/spyvm/constants.py
@@ -54,6 +54,11 @@
 BLKCLSR_NUMARGS = 2
 BLKCLSR_SIZE = 3
 
+FORM_BITS = 0
+FORM_WIDTH = 1
+FORM_HEIGHT = 2
+FORM_DEPTH = 3
+
 # ___________________________________________________________________________
 # Miscellaneous constants
 
diff --git a/spyvm/display.py b/spyvm/display.py
--- a/spyvm/display.py
+++ b/spyvm/display.py
@@ -35,12 +35,13 @@
 WindowEventPaint = 5
 WindowEventStinks = 6
 
+MINIMUM_DEPTH = 8
 
 class SDLDisplay(object):
     _attrs_ = ["screen", "width", "height", "depth", "surface", "has_surface",
                "mouse_position", "button", "key", "interrupt_key", "_defer_updates",
-               "_deferred_event", "pixelbuffer"]
-    _immutable_fields_ = ["pixelbuffer?"]
+               "_deferred_event", "bpp", "pitch"]
+    #_immutable_fields_ = ["pixelbuffer?"]
 
     def __init__(self, title):
         assert RSDL.Init(RSDL.INIT_VIDEO) >= 0
@@ -58,26 +59,27 @@
     def set_video_mode(self, w, h, d):
         assert w > 0 and h > 0
         assert d in [1, 2, 4, 8, 16, 32]
+        if d < MINIMUM_DEPTH:
+            d = MINIMUM_DEPTH
         self.width = w
         self.height = h
         self.depth = d
         flags = RSDL.HWPALETTE | RSDL.RESIZABLE | RSDL.ASYNCBLIT | RSDL.DOUBLEBUF
-        if d < 8:
-            d = 8
         self.screen = RSDL.SetVideoMode(w, h, d, flags)
         if not self.screen:
             print "Could not open display at depth %d" % d
             raise RuntimeError
-        elif d == 8:
+        elif d == MINIMUM_DEPTH:
             self.set_squeak_colormap(self.screen)
-        self.pixelbuffer = rffi.cast(rffi.UINTP, self.screen.c_pixels)
-
+        self.bpp = rffi.getintfield(self.screen.c_format, 'c_BytesPerPixel')
+        self.pitch = rffi.getintfield(self.screen, 'c_pitch')
+    
     def get_pixelbuffer(self):
-        return jit.promote(self.pixelbuffer)
-
+        return jit.promote(rffi.cast(RSDL.Uint32P, self.screen.c_pixels))
+    
     def defer_updates(self, flag):
         self._defer_updates = flag
-
+    
     def flip(self, force=False):
         if (not self._defer_updates) or force:
             RSDL.Flip(self.screen)
diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -23,7 +23,7 @@
 
 
 class Interpreter(object):
-    _immutable_fields_ = ["space", "image", "image_name",
+    _immutable_fields_ = ["space", "image",
                           "interrupt_counter_size",
                           "startup_time", "evented", "interrupts"]
 
@@ -34,12 +34,11 @@
         get_printable_location=get_printable_location
     )
 
-    def __init__(self, space, image=None, image_name="",
+    def __init__(self, space, image=None,
                 trace=False, evented=True, interrupts=True):
         # === Initialize immutable variables
         self.space = space
         self.image = image
-        self.image_name = image_name
         if image:
             self.startup_time = image.startup_time
         else:
@@ -1033,9 +1032,8 @@
 # in order to enable tracing/jumping for message sends etc.
 def debugging():
     def stepping_debugger_init(original):
-        def meth(self, space, image=None, image_name="", trace=False):
-            return_value = original(self, space, image=image,
-                                    image_name=image_name, trace=trace)
+        def meth(self, space, image=None, trace=False):
+            return_value = original(self, space, image=image, trace=trace)
             # ##############################################################
 
             self.message_stepping = False
diff --git a/spyvm/interpreter_proxy.py b/spyvm/interpreter_proxy.py
--- a/spyvm/interpreter_proxy.py
+++ b/spyvm/interpreter_proxy.py
@@ -17,7 +17,7 @@
 from rpython.rtyper.lltypesystem import lltype, rffi
 from rpython.rlib.unroll import unrolling_iterable
 
-from spyvm import error, model, objspace
+from spyvm import error, model, model_display, objspace, wrapper
 
 sqInt = rffi.INT
 sqLong = rffi.LONG
@@ -242,7 +242,7 @@
         return w_object.convert_to_c_layout()
     elif isinstance(w_object, model.W_BytesObject):
         return rffi.cast(sqIntArrayPtr, w_object.convert_to_c_layout())
-    elif isinstance(w_object, model.W_DisplayBitmap):
+    elif isinstance(w_object, model_display.W_DisplayBitmap):
         return rffi.cast(sqIntArrayPtr, w_object.convert_to_c_layout())
     else:
         raise ProxyFunctionFailed
@@ -529,7 +529,7 @@
 @expose_on_virtual_machine_proxy([], int)
 def fullDisplayUpdate():
     w_display = IProxy.space.objtable['w_display']
-    if isinstance(w_display, model.W_DisplayBitmap):
+    if isinstance(w_display, model_display.W_DisplayBitmap):
         w_display.update_from_buffer()
         w_display.flush_to_screen()
         return 0
@@ -559,16 +559,8 @@
     # display memory
     space = IProxy.space
     if w_dest_form.is_same_object(space.objtable['w_display']):
-        w_bitmap = w_dest_form.fetch(space, 0)
-        if not isinstance(w_bitmap, model.W_DisplayBitmap):
-            assert isinstance(w_bitmap, model.W_WordsObject)
-            w_display_bitmap = w_bitmap.as_display_bitmap(
-                w_dest_form,
-                IProxy.interp,
-                sdldisplay=None
-            )
-        else:
-            w_display_bitmap = w_bitmap
+        form = wrapper.FormWrapper(space, w_dest_form)
+        w_display_bitmap = form.get_display_bitmap()
         w_display_bitmap.update_from_buffer()
         w_display_bitmap.flush_to_screen()
     return 0
@@ -1008,7 +1000,7 @@
         self.argcount = 0
         self.w_method = None
         self.fail_reason = 0
-        self.trace_proxy.unset()
+        self.trace_proxy.deactivate()
 
     def call(self, signature, interp, s_frame, argcount, w_method):
         self.initialize_from_call(signature, interp, s_frame, argcount, w_method)
@@ -1050,7 +1042,7 @@
         self.argcount = argcount
         self.w_method = w_method
         self.space = interp.space
-        self.trace_proxy.set_to(interp.trace_proxy.is_set())
+        self.trace_proxy.set(interp.trace_proxy.is_set())
         # ensure that space.w_nil gets the first possible oop
         self.object_to_oop(self.space.w_nil)
 
diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -987,26 +987,6 @@
                 c_words[i] = intmask(old_words[i])
             self.words = None
             return c_words
-
-    def as_display_bitmap(self, w_form, interp, sdldisplay=None):
-        width = interp.space.unwrap_int(w_form.fetch(interp.space, 1))
-        height = interp.space.unwrap_int(w_form.fetch(interp.space, 2))
-        depth = interp.space.unwrap_int(w_form.fetch(interp.space, 3))
-        if not sdldisplay:
-            from spyvm import display
-            sdldisplay = display.SDLDisplay(interp.image_name)
-            sdldisplay.set_video_mode(width, height, depth)
-        w_display_bitmap = W_DisplayBitmap.create(
-            interp.space,
-            self.getclass(interp.space),
-            self.size(),
-            depth,
-            sdldisplay
-        )
-        for idx in range(self.size()):
-            w_display_bitmap.setword(idx, self.getword(idx))
-        w_form.store(interp.space, 0, w_display_bitmap)
-        return w_display_bitmap
     
     def _become(self, w_other):
         assert isinstance(w_other, W_WordsObject)
@@ -1019,144 +999,6 @@
         if self.words is None:
             lltype.free(self.c_words, flavor='raw')
 
-class W_DisplayBitmap(W_AbstractObjectWithClassReference):
-    _attrs_ = ['pixelbuffer', '_realsize', '_real_depth_buffer', 'display', '_depth']
-    _immutable_fields_ = ['_realsize', 'display', '_depth']
-    repr_classname = "W_DisplayBitmap"
-    
-    pixelbuffer = None
-    
-    @staticmethod
-    def create(space, w_class, size, depth, display):
-        if depth < 8:
-            return W_MappingDisplayBitmap(space, w_class, size * (8 / depth), depth, display)
-        elif depth == 8:
-            return W_8BitDisplayBitmap(space, w_class, size, depth, display)
-        elif depth == 16:
-            return W_16BitDisplayBitmap(space, w_class, size, depth, display)
-        else:
-            return W_DisplayBitmap(space, w_class, size, depth, display)
-
-    def repr_content(self):
-        return "len=%d depth=%d %s" % (self.size(), self._depth, self.str_content())
-    
-    def __init__(self, space, w_class, size, depth, display):
-        W_AbstractObjectWithClassReference.__init__(self, space, w_class)
-        self._real_depth_buffer = lltype.malloc(rffi.CArray(rffi.UINT), size, flavor='raw')
-        self._realsize = size
-        self.display = display
-        self._depth = depth
-
-    def at0(self, space, index0):
-        val = self.getword(index0)
-        return space.wrap_uint(val)
-
-    def atput0(self, space, index0, w_value):
-        word = space.unwrap_uint(w_value)
-        self.setword(index0, word)
-
-    def flush_to_screen(self):
-        self.display.flip()
-
-    def size(self):
-        return self._realsize
-        
-    def invariant(self):
-        return False
-
-    def clone(self, space):
-        w_result = W_WordsObject(space, self.getclass(space), self._realsize)
-        n = 0
-        while n < self._realsize:
-            w_result.words[n] = self.getword(n)
-            n += 1
-        return w_result
-
-    def getword(self, n):
-        assert self.size() > n >= 0
-        return self._real_depth_buffer[n]
-
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        self.display.get_pixelbuffer()[n] = word
-
-    def is_array_object(self):
-        return True
-
-    def update_from_buffer(self):
-        for i in range(self._realsize):
-            self.setword(i, self.getword(i))
-
-    def convert_to_c_layout(self):
-        return self._real_depth_buffer
-
-    def can_become(self, w_other):
-        # TODO - implement _become() for this class. Impossible due to _immutable_fields_?
-        return False
-    
-    def __del__(self):
-        lltype.free(self._real_depth_buffer, flavor='raw')
-
-
-class W_16BitDisplayBitmap(W_DisplayBitmap):
-    repr_classname = "W_16BitDisplayBitmap"
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        mask = 0b11111
-        lsb = (r_uint(word) & r_uint(0xffff0000)) >> 16
-        msb = (r_uint(word) & r_uint(0x0000ffff))
-
-        lsb = (
-            ((lsb >> 10) & mask) |
-            (((lsb >> 5) & mask) << 6) |
-            ((lsb & mask) << 11)
-        )
-        msb = (
-            ((msb >> 10) & mask) |
-            (((msb >> 5) & mask) << 6) |
-            ((msb & mask) << 11)
-        )
-
-        self.display.get_pixelbuffer()[n] = r_uint(lsb | (msb << 16))
-
-
-class W_8BitDisplayBitmap(W_DisplayBitmap):
-    repr_classname = "W_8BitDisplayBitmap"
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        self.display.get_pixelbuffer()[n] = r_uint(
-            (word >> 24) |
-            ((word >> 8) & 0x0000ff00) |
-            ((word << 8) & 0x00ff0000) |
-            (word << 24)
-        )
-
-NATIVE_DEPTH = 8
-class W_MappingDisplayBitmap(W_DisplayBitmap):
-    repr_classname = "W_MappingDisplayBitmap"
-    @jit.unroll_safe
-    def setword(self, n, word):
-        self._real_depth_buffer[n] = word
-        word = r_uint(word)
-        pos = self.compute_pos(n)
-        assert self._depth <= 4
-        rshift = 32 - self._depth
-        for i in xrange(8 / self._depth):
-            if pos >= self.size():
-                return
-            mapword = r_uint(0)
-            for i in xrange(4):
-                pixel = r_uint(word) >> rshift
-                mapword |= (r_uint(pixel) << (i * 8))
-                word <<= self._depth
-            self.display.get_pixelbuffer()[pos] = mapword
-            pos += 1
-
-    def compute_pos(self, n):
-        return n * (NATIVE_DEPTH / self._depth)
-        
-# XXX Shouldn't compiledmethod have class reference for subclassed compiled
-# methods?
 class W_CompiledMethod(W_AbstractObjectWithIdentityHash):
     """My instances are methods suitable for interpretation by the virtual machine.  This is the only class in the system whose instances intermix both indexable pointer fields and indexable integer fields.
 
@@ -1467,8 +1309,3 @@
             if isinstance(s_class, ClassShadow):
                 return "%s >> #%s" % (s_class.getname(), self.lookup_selector)
         return "#%s" % self.lookup_selector
-
-class DetachingShadowError(Exception):
-    def __init__(self, old_shadow, new_shadow_class):
-        self.old_shadow = old_shadow
-        self.new_shadow_class = new_shadow_class
diff --git a/spyvm/model_display.py b/spyvm/model_display.py
new file mode 100644
--- /dev/null
+++ b/spyvm/model_display.py
@@ -0,0 +1,196 @@
+
+from spyvm import model, constants, display
+from rpython.rlib import jit, objectmodel
+from rpython.rtyper.lltypesystem import lltype, rffi
+from rpython.rlib.rarithmetic import r_uint
+
+def from_words_object(w_obj, form):
+    depth = form.depth()
+    space = form.space
+    size = w_obj.size()
+    w_class = w_obj.getclass(space)
+    
+    if depth < 8:
+        w_display_bitmap = W_MappingDisplayBitmap(space, w_class, size, depth)
+    elif depth == 8:
+        w_display_bitmap = W_8BitDisplayBitmap(space, w_class, size, depth)
+    elif depth == 16:
+        w_display_bitmap = W_16BitDisplayBitmap(space, w_class, size, depth)
+    else:
+        w_display_bitmap = W_DisplayBitmap(space, w_class, size, depth)
+    
+    for idx in range(size):
+        w_display_bitmap.setword(idx, w_obj.getword(idx))
+    
+    return w_display_bitmap
+
+class W_DisplayBitmap(model.W_AbstractObjectWithClassReference):
+    _attrs_ = ['pixelbuffer_words', '_real_depth_buffer', '_realsize', 'display', '_depth']
+    _immutable_fields_ = ['pixelbuffer_words?', '_real_depth_buffer', '_realsize', 'display', '_depth']
+    repr_classname = "W_DisplayBitmap"
+    
+    def __init__(self, space, w_class, size, depth):
+        model.W_AbstractObjectWithClassReference.__init__(self, space, w_class)
+        self._real_depth_buffer = lltype.malloc(rffi.CArray(rffi.UINT), size, flavor='raw')
+        self._realsize = size
+        self._depth = depth
+        self.display = space.display()
+        self.relinquish_display()
+    
+    # === Object access
+    
+    def at0(self, space, index0):
+        val = self.getword(index0)
+        return space.wrap_uint(val)
+    
+    def atput0(self, space, index0, w_value):
+        word = space.unwrap_uint(w_value)
+        self.setword(index0, word)
+    
+    def getword(self, n):
+        assert self.size() > n >= 0
+        return self._real_depth_buffer[n]
+    
+    def setword(self, n, word):
+        self._real_depth_buffer[n] = word
+        if self.pixelbuffer_words > 0:
+            self.set_pixelbuffer_word(n, word)
+    
+    def size(self):
+        return self._realsize
+    
+    # === Graphics
+    
+    def pixelbuffer(self):
+        return self.display.get_pixelbuffer()
+    
+    def pixelbuffer_UCHAR(self):
+        return self.display.get_pixelbuffer_UCHAR()
+    
+    def set_pixelbuffer_word(self, n, word):
+        self.pixelbuffer()[n] = word
+    
+    def take_over_display(self):
+        # Make sure FrameWrapper.take_over_display() is called first for the correct Frame object.
+        pixel_per_word = constants.BYTES_PER_WORD / (self.display.depth / 8)
+        self.pixelbuffer_words = self.display.width * self.display.height / pixel_per_word
+        self.update_from_buffer()
+    
+    def relinquish_display(self):
+        self.pixelbuffer_words = 0
+    
+    def flush_to_screen(self):
+        self.display.flip()
+    
+    def update_from_buffer(self):
+        if self.pixelbuffer_words > 0:
+            for i in range(self.size()):
+                self.set_pixelbuffer_word(i, self.getword(i))
+    
+    # === Misc
+    
+    def invariant(self):
+        return False
+
+    def clone(self, space):
+        w_result = model.W_WordsObject(space, self.getclass(space), self.size())
+        for n in range(self.size()):
+            w_result.setword(n, self.getword(n))
+        return w_result
+    
+    def is_array_object(self):
+        return True
+
+    def convert_to_c_layout(self):
+        return self._real_depth_buffer
+
+    def can_become(self, w_other):
+        # TODO - implement _become() for this class. Impossible due to _immutable_fields_?
+        return False
+    
+    def __del__(self):
+        lltype.free(self._real_depth_buffer, flavor='raw')
+    
+    def repr_content(self):
+        return "len=%d depth=%d %s" % (self.size(), self._depth, self.str_content())
+
+class W_16BitDisplayBitmap(W_DisplayBitmap):
+    
+    repr_classname = "W_16BitDisplayBitmap"
+    
+    def set_pixelbuffer_word(self, n, word):
+        mask = 0b11111
+        lsb = (r_uint(word) & r_uint(0xffff0000)) >> 16
+        msb = (r_uint(word) & r_uint(0x0000ffff))
+        
+        # Invert order of rgb-components
+        lsb = (
+            ((lsb >> 10) & mask) |
+            (((lsb >> 5) & mask) << 6) |
+            ((lsb & mask) << 11)
+        )
+        msb = (
+            ((msb >> 10) & mask) |
+            (((msb >> 5) & mask) << 6) |
+            ((msb & mask) << 11)
+        )
+        
+        self.pixelbuffer()[n] = r_uint(lsb | (msb << 16))
+
+class W_8BitDisplayBitmap(W_DisplayBitmap):
+    
+    repr_classname = "W_8BitDisplayBitmap"
+    
+    def set_pixelbuffer_word(self, n, word):
+        # Invert the byte-order.
+        self.pixelbuffer()[n] = r_uint(
+            (word >> 24) |
+            ((word >> 8) & 0x0000ff00) |
+            ((word << 8) & 0x00ff0000) |
+            (word << 24)
+        )
+
+BITS = r_uint(32)
+class W_MappingDisplayBitmap(W_DisplayBitmap):
+    
+    repr_classname = "W_MappingDisplayBitmap"
+    _attrs_ = ['words_per_line', 'bits_in_last_word', 'pitch']
+    _immutable_fields_ = ['words_per_line?', 'bits_in_last_word?', 'pitch?']
+    
+    def __init__(self, space, w_class, size, depth):
+        assert depth in [1, 2, 4]
+        W_DisplayBitmap.__init__(self, space, w_class, size, depth)
+    
+    def take_over_display(self):
+        pitch = r_uint(self.display.pitch) # The pitch is different from the width input to SDL!
+        self.pitch = pitch
+        self.bits_in_last_word = pitch % BITS
+        self.words_per_line = r_uint((pitch - self.bits_in_last_word) / BITS)
+        if self.bits_in_last_word > 0:
+            self.words_per_line += 1
+        W_DisplayBitmap.take_over_display(self)
+    
+    @jit.unroll_safe
+    def set_pixelbuffer_word(self, n, word):
+        n = r_uint(n)
+        if ((n+1) % self.words_per_line) == 0 and self.bits_in_last_word > 0:
+            # This is the last word on the line. A few bits are cut off.
+            bits = self.bits_in_last_word
+        else:
+            bits = BITS
+        
+        word = r_uint(word)
+        pos = self.compute_pos(n)
+        buf = rffi.ptradd(self.display.screen.c_pixels, pos)
+        depth = r_uint(self._depth)
+        rshift = BITS - depth
+        for i in range(bits / depth):
+            pixel = word >> rshift
+            buf[i] = rffi.cast(rffi.UCHAR, pixel)
+            word <<= depth
+    
+    def compute_pos(self, n):
+        word_on_line = n % self.words_per_line
+        y = r_uint((n - word_on_line) / self.words_per_line)
+        x = word_on_line * BITS / r_uint(self._depth)
+        return y * self.pitch + x
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -1,30 +1,47 @@
 import os
 
-from spyvm import constants, model, shadow, wrapper, version
+from spyvm import constants, model, model_display, shadow, wrapper, version, display
 from spyvm.error import UnwrappingError, WrappingError, PrimitiveFailedError
 from rpython.rlib import jit, rpath
-from rpython.rlib.objectmodel import instantiate, specialize
+from rpython.rlib.objectmodel import instantiate, specialize, import_from_mixin
 from rpython.rlib.rarithmetic import intmask, r_uint, int_between
 
-class ConstantFlag(object):
-    """Boolean flag that can be edited, but will be promoted
+class ConstantMixin(object):
+    """Mixin for constant values that can be edited, but will be promoted
     to a constant when jitting."""
     
-    def __init__(self, set_initially=False):
-        self.flag = [set_initially]
+    def __init__(self, initial_value = None):
+        if initial_value is None:
+            initial_value = self.default_value
+        self.value = [initial_value]
     
+    def set(self, value):
+        self.value[0] = value
+    
+    def get(self):
+        value = jit.promote(self.value[0])
+        return value
+
+class ConstantFlag(object):
+    import_from_mixin(ConstantMixin)
+    default_value = False
     def is_set(self):
-        flag = jit.promote(self.flag[0])
-        return flag
+        return self.get()
+    def activate(self):
+        self.set(True)
+    def deactivate(self):
+        self.set(False)
+
+class ConstantString(object):
+    import_from_mixin(ConstantMixin)
+    default_value = ""
+    def get(self):
+        # Promoting does not work on strings...
+        return self.value[0]
     
-    def set(self):
-        self.flag[0] = True
-    
-    def unset(self):
-        self.flag[0] = False
-    
-    def set_to(self, flag):
-        self.flag[0] = flag
+class ConstantObject(object):
+    import_from_mixin(ConstantMixin)
+    default_value = None
 
 class ObjSpace(object):
     def __init__(self):
@@ -33,12 +50,14 @@
         self.no_specialized_storage = ConstantFlag()
         # This is a hack; see compile_code() in targetimageloadingsmalltalk.py
         self.suppress_process_switch = ConstantFlag()
+        self.run_spy_hacks = ConstantFlag()
         self.headless = ConstantFlag()
         
         self.classtable = {}
         self.objtable = {}
-        self._executable_path = [""] # XXX: we cannot set the attribute
-                                  # directly on the frozen objectspace
+        self._executable_path = ConstantString()
+        self._image_name = ConstantString()
+        self._display = ConstantObject()
         
         # Create the nil object.
         # Circumvent the constructor because nil is already referenced there.
@@ -61,11 +80,12 @@
                     break
         return rpath.rabspath(executable)
 
-    def runtime_setup(self, executable):
+    def runtime_setup(self, executable, image_name):
         fullpath = rpath.rabspath(self.find_executable(executable))
         i = fullpath.rfind(os.path.sep) + 1
         assert i > 0
-        self._executable_path[0] = fullpath[:i]
+        self._executable_path.set(fullpath[:i])
+        self._image_name.set(image_name)
 
     def populate_special_objects(self, specials):
         for name, idx in constants.objects_in_special_object_table.items():
@@ -74,9 +94,6 @@
                 self.objtable[name] = specials[idx]
         # XXX this is kind of hacky, but I don't know where else to get Metaclass
         self.classtable["w_Metaclass"] = self.w_SmallInteger.w_class.w_class
-        
-    def executable_path(self):
-        return self._executable_path[0]
     
     def add_bootstrap_class(self, name, cls):
         self.classtable[name] = cls
@@ -124,14 +141,8 @@
             name = "w_" + name
             if not name in self.objtable:
                 self.add_bootstrap_object(name, None)
-    
-    @specialize.arg(1)
-    def get_special_selector(self, selector):
-        i0 = constants.find_selectorindex(selector)
-        self.w_special_selectors.as_cached_object_get_shadow(self)
-        return self.w_special_selectors.fetch(self, i0)
 
-    # methods for wrapping and unwrapping stuff
+    # ============= Methods for wrapping and unwrapping stuff =============
 
     def wrap_int(self, val):
         from spyvm import constants
@@ -233,14 +244,30 @@
 
         return [w_array.at0(self, i) for i in range(w_array.size())]
 
-    def get_display(self):
-        w_display = self.objtable['w_display']
-        if w_display:
-            w_bitmap = w_display.fetch(self, 0)
-            if isinstance(w_bitmap, model.W_DisplayBitmap):
-                return w_bitmap.display
-        raise PrimitiveFailedError("No display")
-
+    # ============= Access to static information =============
+    
+    @specialize.arg(1)
+    def get_special_selector(self, selector):
+        i0 = constants.find_selectorindex(selector)
+        self.w_special_selectors.as_cached_object_get_shadow(self)
+        return self.w_special_selectors.fetch(self, i0)
+    
+    def executable_path(self):
+        return self._executable_path.get()
+    
+    def image_name(self):
+        return self._image_name.get()
+    
+    def display(self):
+        disp = self._display.get()
+        if disp is None:
+            # Create lazy to allow headless execution.
+            disp = display.SDLDisplay(self.image_name())
+            self._display.set(disp)
+        return disp
+    
+    # ============= Other Methods =============
+    
     def _freeze_(self):
         return True
 
diff --git a/spyvm/plugins/bitblt.py b/spyvm/plugins/bitblt.py
--- a/spyvm/plugins/bitblt.py
+++ b/spyvm/plugins/bitblt.py
@@ -1,4 +1,4 @@
-from spyvm import model
+from spyvm import model_display, model
 from spyvm.error import PrimitiveFailedError
 from spyvm.shadow import AbstractCachingShadow
 from spyvm.plugins.plugin import Plugin
@@ -32,7 +32,7 @@
         s_frame.push(interp.space.wrap_int(s_bitblt.bitCount))
     elif w_dest_form.is_same_object(space.objtable['w_display']):
         w_bitmap = w_dest_form.fetch(space, 0)
-        assert isinstance(w_bitmap, model.W_DisplayBitmap)
+        assert isinstance(w_bitmap, model_display.W_DisplayBitmap)
         w_bitmap.flush_to_screen()
     return w_rcvr
 
@@ -741,7 +741,7 @@
         self.w_bits = self.fetch(0)
         if self.w_bits.is_nil(self.space):
             return
-        if not (isinstance(self.w_bits, model.W_WordsObject) or isinstance(self.w_bits, model.W_DisplayBitmap)):
+        if not (isinstance(self.w_bits, model.W_WordsObject) or isinstance(self.w_bits, model_display.W_DisplayBitmap)):
             return
         self.width = self.intOrIfNil(self.fetch(1), 0)
         self.height = self.intOrIfNil(self.fetch(2), 0)
diff --git a/spyvm/plugins/vmdebugging.py b/spyvm/plugins/vmdebugging.py
--- a/spyvm/plugins/vmdebugging.py
+++ b/spyvm/plugins/vmdebugging.py
@@ -20,12 +20,12 @@
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
 def trace_proxy(interp, s_frame, w_rcvr):
-    interp.trace_proxy.set()
+    interp.trace_proxy.activate()
     return w_rcvr
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
 def untrace_proxy(interp, s_frame, w_rcvr):
-    interp.trace_proxy.unset()
+    interp.trace_proxy.deactivate()
     return w_rcvr
 
 @DebuggingPlugin.expose_primitive(unwrap_spec=[object])
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -2,7 +2,7 @@
 import inspect
 import math
 import operator
-from spyvm import model, shadow, error, constants, display
+from spyvm import model, model_display, shadow, error, constants, display
 from spyvm.error import PrimitiveFailedError, PrimitiveNotYetWrittenError
 from spyvm import wrapper
 
@@ -644,7 +644,7 @@
 
 @expose_primitive(MOUSE_POINT, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    x, y = interp.space.get_display().mouse_point()
+    x, y = interp.space.display().mouse_point()
     w_point = model.W_PointersObject(interp.space, interp.space.w_Point, 2)
     w_point.store(interp.space, 0, interp.space.wrap_int(x))
     w_point.store(interp.space, 1, interp.space.wrap_int(y))
@@ -656,7 +656,7 @@
 def func(interp, s_frame, w_rcvr, w_into):
     if not interp.evented:
         raise PrimitiveFailedError()
-    ary = interp.space.get_display().get_next_event(time=interp.time_now())
+    ary = interp.space.display().get_next_event(time=interp.time_now())
     for i in range(8):
         w_into.store(interp.space, i, interp.space.wrap_int(ary[i]))
     # XXX - hack
@@ -676,7 +676,7 @@
         w_display = interp.space.objtable['w_display']
         if w_dest_form.is_same_object(w_display):
             w_bitmap = w_display.fetch(interp.space, 0)
-            assert isinstance(w_bitmap, model.W_DisplayBitmap)
+            assert isinstance(w_bitmap, model_display.W_DisplayBitmap)
             w_bitmap.flush_to_screen()
         return w_rcvr
     except shadow.MethodNotFound:
@@ -731,45 +731,23 @@
 def func(interp, s_frame, w_rcvr):
     if interp.space.headless.is_set():
         exitFromHeadlessExecution(s_frame)
-    
     if not isinstance(w_rcvr, model.W_PointersObject) or w_rcvr.size() < 4:
         raise PrimitiveFailedError
-    # the fields required are bits (a pointer to a Bitmap), width, height, depth
-
-    # XXX: TODO get the initial image TODO: figure out whether we
-    # should decide the width an report it in the other SCREEN_SIZE
-    w_bitmap = w_rcvr.fetch(interp.space, 0)
-    width = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 1))
-    height = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 2))
-    depth = interp.space.unwrap_int(w_rcvr.fetch(interp.space, 3))
-
-    sdldisplay = None
-
-    w_prev_display = interp.space.objtable['w_display']
-    if w_prev_display:
-        w_prev_bitmap = w_prev_display.fetch(interp.space, 0)
-        if isinstance(w_prev_bitmap, model.W_DisplayBitmap):
-            sdldisplay = w_prev_bitmap.display
-            sdldisplay.set_video_mode(width, height, depth)
-
-    if isinstance(w_bitmap, model.W_DisplayBitmap):
-        assert (sdldisplay is None) or (sdldisplay is w_bitmap.display)
-        sdldisplay = w_bitmap.display
-        sdldisplay.set_video_mode(width, height, depth)
-        w_display_bitmap = w_bitmap
-    else:
-        assert isinstance(w_bitmap, model.W_WordsObject)
-        w_display_bitmap = w_bitmap.as_display_bitmap(
-            w_rcvr,
-            interp,
-            sdldisplay=sdldisplay
-        )
-
+    
+    old_display = interp.space.objtable['w_display']
+    if isinstance(old_display, model_display.W_DisplayBitmap):
+        old_display.relinquish_display()
+    interp.space.objtable['w_display'] = w_rcvr
+    
+    # TODO: figure out whether we should decide the width an report it in the SCREEN_SIZE primitive
+    form = wrapper.FormWrapper(interp.space, w_rcvr)
+    form.take_over_display()
+    w_display_bitmap = form.get_display_bitmap()
+    w_display_bitmap.take_over_display()
     w_display_bitmap.flush_to_screen()
+    
     if interp.image:
-        interp.image.lastWindowSize = (width << 16)  + height
-    interp.space.objtable['w_display'] = w_rcvr
-
+        interp.image.lastWindowSize = (form.width() << 16) + form.height()
     return w_rcvr
 
 @expose_primitive(STRING_REPLACE, unwrap_spec=[object, index1_0, index1_0, object, index1_0])
@@ -812,12 +790,12 @@
 
 @expose_primitive(MOUSE_BUTTONS, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    btn = interp.space.get_display().mouse_button()
+    btn = interp.space.display().mouse_button()
     return interp.space.wrap_int(btn)
 
 @expose_primitive(KBD_NEXT, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    code = interp.space.get_display().next_keycode()
+    code = interp.space.display().next_keycode()
     if code & 0xFF == 0:
         return interp.space.w_nil
     else:
@@ -825,7 +803,7 @@
 
 @expose_primitive(KBD_PEEK, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    code = interp.space.get_display().peek_keycode()
+    code = interp.space.display().peek_keycode()
     if code & 0xFF == 0:
         return interp.space.w_nil
     else:
@@ -864,8 +842,8 @@
 
 @expose_primitive(EXIT_TO_DEBUGGER, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    if not objectmodel.we_are_translated():
-        import pdb; pdb.set_trace()
+    if interp.space.headless.is_set():
+        exitFromHeadlessExecution(s_frame, "EXIT_TO_DEBUGGER")
     raise PrimitiveNotYetWrittenError()
 
 @expose_primitive(CHANGE_CLASS, unwrap_spec=[object, object], no_result=True)
@@ -987,7 +965,7 @@
 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.space.image_name())
     elif argument_count == 1:
         pass # XXX
     raise PrimitiveFailedError
@@ -1004,7 +982,7 @@
 
 @expose_primitive(DEFER_UPDATES, unwrap_spec=[object, bool])
 def func(interp, s_frame, w_receiver, flag):
-    sdldisplay = interp.space.get_display()
+    sdldisplay = interp.space.display()
     sdldisplay.defer_updates(flag)
     return w_receiver
 
@@ -1058,7 +1036,7 @@
 
 @expose_primitive(SET_INTERRUPT_KEY, unwrap_spec=[object, int])
 def func(interp, s_frame, w_rcvr, encoded_key):
-    interp.space.get_display().set_interrupt_key(interp.space, encoded_key)
+    interp.space.display().set_interrupt_key(interp.space, encoded_key)
     return w_rcvr
 
 @expose_primitive(INTERRUPT_SEMAPHORE, unwrap_spec=[object, object])
@@ -1142,7 +1120,7 @@
             raise PrimitiveFailedError
         for i in xrange(w_arg.size()):
             w_arg.setchar(i, chr(new_value))
-    elif isinstance(w_arg, model.W_WordsObject) or isinstance(w_arg, model.W_DisplayBitmap):
+    elif isinstance(w_arg, model.W_WordsObject) or isinstance(w_arg, model_display.W_DisplayBitmap):
         for i in xrange(w_arg.size()):
             w_arg.setword(i, new_value)
     else:
@@ -1531,7 +1509,7 @@
 
 @expose_primitive(FORCE_DISPLAY_UPDATE, unwrap_spec=[object])
 def func(interp, s_frame, w_rcvr):
-    interp.space.get_display().flip(force=True)
+    interp.space.display().flip(force=True)
     return w_rcvr
 
 # ___________________________________________________________________________
diff --git a/spyvm/squeakimage.py b/spyvm/squeakimage.py
--- a/spyvm/squeakimage.py
+++ b/spyvm/squeakimage.py
@@ -386,12 +386,13 @@
         self.startup_time = time.time()
 
     def run_spy_hacks(self, space):
-        pass
-        # w_display = space.objtable["w_display"]
-        # if w_display is not None and not w_display.is_nil(space):
-        #     if space.unwrap_int(w_display.fetch(space, 3)) < 8:
-        #         # non-native indexed color depth not well supported
-        #         w_display.store(space, 3, space.wrap_int(8))
+        if not space.run_spy_hacks.is_set():
+            return
+        w_display = space.objtable["w_display"]
+        if w_display is not None and not w_display.is_nil(space):
+            if space.unwrap_int(w_display.fetch(space, 3)) < 8:
+                # non-native indexed color depth not well supported
+                w_display.store(space, 3, space.wrap_int(8))
 
     def find_symbol(self, space, reader, symbol):
         w_dnu = self.special(constants.SO_DOES_NOT_UNDERSTAND)
diff --git a/spyvm/test/test_model.py b/spyvm/test/test_model.py
--- a/spyvm/test/test_model.py
+++ b/spyvm/test/test_model.py
@@ -1,5 +1,5 @@
 import py, math, socket
-from spyvm import model, shadow, objspace, error, display
+from spyvm import model, model_display, shadow, objspace, error, display
 from spyvm.shadow import MethodNotFound, WEAK_POINTERS
 from rpython.rlib.rarithmetic import intmask, r_uint
 from rpython.rtyper.lltypesystem import lltype, rffi
@@ -387,7 +387,7 @@
     d = display.SDLDisplay("test")
     d.set_video_mode(32, 10, 1)
 
-    target = model.W_DisplayBitmap.create(space, space.w_Array, 10, 1, d)
+    target = model_display.W_DisplayBitmap.create(space, space.w_Array, 10, 1, d)
     target.setword(0, r_uint(0xFF00))
     assert bin(target.getword(0)) == bin(0xFF00)
     target.setword(0, r_uint(0x00FF00FF))
@@ -404,15 +404,7 @@
         assert target.pixelbuffer[i] == 0x0
 
 def test_display_offset_computation():
-
-    def get_pixelbuffer(self):
-        return lltype.malloc(rffi.ULONGP.TO, self.width * self.height * 32, flavor='raw')
-    display.SDLDisplay.get_pixelbuffer = get_pixelbuffer
-    d = display.SDLDisplay("test")
-    d.set_video_mode(18, 5, 1)
-
-    dbitmap = model.W_DisplayBitmap.create(space, space.w_Array, 5, 1, d)
-
+    dbitmap = model_display.W_MappingDisplayBitmap(space, space.w_Array, 5, 1)
     assert dbitmap.compute_pos(0) == 0
     assert dbitmap.compute_pos(1) == 8
     assert dbitmap.size() == 5 * 8
diff --git a/spyvm/test/test_primitives.py b/spyvm/test/test_primitives.py
--- a/spyvm/test/test_primitives.py
+++ b/spyvm/test/test_primitives.py
@@ -1,5 +1,5 @@
 import py, os, math, time
-from spyvm import model, shadow, interpreter, constants, primitives, objspace, wrapper, display
+from spyvm import model, model_display, shadow, interpreter, constants, primitives, objspace, wrapper, display
 from spyvm.primitives import prim_table, PrimitiveFailedError
 from spyvm.plugins import bitblt
 from rpython.rlib.rfloat import INFINITY, NAN, isinf, isnan
@@ -47,7 +47,8 @@
         frame = context
         for i in range(len(stack)):
             frame.as_context_get_shadow(space).push(stack[i])
-    interp = TestInterpreter(space, image_name=IMAGENAME)
+    interp = TestInterpreter(space)
+    interp.space._image_name.set(IMAGENAME)
     return interp, frame, len(stack)
 
 def _prim(space, code, stack, context = None):
@@ -680,7 +681,7 @@
 
     closure = space.newClosure(w_frame, 4, 0, [])
     s_frame = w_frame.as_methodcontext_get_shadow(space)
-    interp = TestInterpreter(space, image_name=IMAGENAME)
+    interp = TestInterpreter(space)
     interp._loop = True
 
     try:
@@ -721,7 +722,7 @@
     assert space.objtable["w_display"] is mock_display
     w_bitmap = mock_display.fetch(space, 0)
     assert w_bitmap is not w_wordbmp
-    assert isinstance(w_bitmap, model.W_DisplayBitmap)
+    assert isinstance(w_bitmap, model_display.W_DisplayBitmap)
     sdldisplay = w_bitmap.display
     assert isinstance(sdldisplay, display.SDLDisplay)
 
@@ -733,7 +734,7 @@
     prim(primitives.BE_DISPLAY, [mock_display2])
     assert space.objtable["w_display"] is mock_display2
     w_bitmap2 = mock_display.fetch(space, 0)
-    assert isinstance(w_bitmap2, model.W_DisplayBitmap)
+    assert isinstance(w_bitmap2, model_display.W_DisplayBitmap)
     assert w_bitmap.display is w_bitmap2.display
     assert sdldisplay.width == 32
     assert sdldisplay.height == 10
@@ -764,7 +765,7 @@
         raise DisplayFlush
 
     try:
-        monkeypatch.setattr(space.get_display().__class__, "flip", flush_to_screen_mock)
+        monkeypatch.setattr(space.display().__class__, "flip", flush_to_screen_mock)
         with py.test.raises(DisplayFlush):
             prim(primitives.FORCE_DISPLAY_UPDATE, [mock_display])
     finally:
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -1,4 +1,4 @@
-from spyvm import model, constants
+from spyvm import model, model_display, constants
 from spyvm.error import FatalError, WrapperException, PrimitiveFailedError
 
 class Wrapper(object):
@@ -263,6 +263,30 @@
     def size(self):
         return self._w_self.size() - constants.BLKCLSR_SIZE
 
+class FormWrapper(Wrapper):
+    bits, store_bits = make_getter_setter(constants.FORM_BITS)
+    width, store_width = make_int_getter_setter(constants.FORM_WIDTH)
+    height, store_height = make_int_getter_setter(constants.FORM_HEIGHT)
+    depth, store_depth = make_int_getter_setter(constants.FORM_DEPTH)
+    
+    def create_display_bitmap(self):
+        w_display_bitmap = model_display.from_words_object(self.bits(), self)
+        self.store_bits(w_display_bitmap)
+        return w_display_bitmap
+    
+    def get_display_bitmap(self):
+        w_bitmap = self.bits()
+        if not isinstance(w_bitmap, model_display.W_DisplayBitmap):
+            w_display_bitmap = self.create_display_bitmap()
+        else:
+            w_display_bitmap = w_bitmap
+            if w_display_bitmap._depth != self.depth():
+                w_display_bitmap = self.create_display_bitmap()
+        return w_display_bitmap
+    
+    def take_over_display(self):
+        self.space.display().set_video_mode(self.width(), self.height(), self.depth())
+    
 # XXX Wrappers below are not used yet.
 class OffsetWrapper(Wrapper):
     offset_x  = make_int_getter(0)
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -36,6 +36,7 @@
             -p|--poll          - Actively poll for events. Try this if the image is not responding well.
             -i|--no-interrupts - Disable timer interrupt. Disables non-cooperative scheduling.
             -S                 - Disable specialized storage strategies; always use generic ListStorage
+            --hacks            - Enable Spy hacks. Set display color depth to 8.
             
           Logging parameters:
             -t|--trace                 - Output a trace of each message, primitive, return value and process switch.
@@ -69,7 +70,7 @@
     except error.Exit, e:
         print_error("Exited: %s" % e.msg)
         return -1
-    except Exception, e:
+    except BaseException, e:
         print_error("Exception: %s" % str(e))
         if not objectmodel.we_are_translated():
             import traceback
@@ -119,8 +120,10 @@
                 interrupts = False
             elif arg in ["-P", "--process"]:
                 headless = False
+            elif arg in ["--hacks"]:
+                space.run_spy_hacks.activate()
             elif arg in ["-S"]:
-                space.no_specialized_storage.set()
+                space.no_specialized_storage.activate()
             elif arg in ["-u"]:
                 from spyvm.plugins.vmdebugging import stop_ui_process
                 stop_ui_process()
@@ -158,10 +161,10 @@
     # Load & prepare image and environment
     image_reader = squeakimage.reader_for_image(space, squeakimage.Stream(data=imagedata))
     image = create_image(space, image_reader)
-    interp = interpreter.Interpreter(space, image, image_name=path,
+    interp = interpreter.Interpreter(space, image,
                 trace=trace, evented=not poll,
                 interrupts=interrupts)
-    space.runtime_setup(argv[0])
+    space.runtime_setup(argv[0], path)
     print_error("") # Line break after image-loading characters
     
     # Create context to be executed
@@ -174,7 +177,7 @@
             selector = compile_code(interp, w_receiver, code)
         s_frame = create_context(interp, w_receiver, selector, stringarg)
         if headless:
-            space.headless.set()
+            space.headless.activate()
             context = s_frame
         else:
             create_process(interp, s_frame)
@@ -203,7 +206,7 @@
     # registered (primitive 136 not called), so the idle process will never be left once it is entered.
     # TODO - Find a way to cleanly initialize the image, without executing the active_context of the image.
     # Instead, we want to execute our own context. Then remove this flag (and all references to it)
-    space.suppress_process_switch.set()
+    space.suppress_process_switch.activate()
     
     w_result = interp.perform(
         w_receiver_class,
@@ -215,7 +218,7 @@
     # TODO - is this expected in every image?
     if not isinstance(w_result, model.W_BytesObject) or w_result.as_string() != selector:
         raise error.Exit("Unexpected compilation result (probably failed to compile): %s" % result_string(w_result))
-    space.suppress_process_switch.unset()
+    space.suppress_process_switch.deactivate()
     
     w_receiver_class.as_class_get_shadow(space).s_methoddict().sync_method_cache()
     return selector


More information about the pypy-commit mailing list