Author: Lars Wassermann <lars.wasserm...@gmail.com>
Branch: 
Changeset: r154:9e0d98ab4de6
Date: 2013-03-08 17:12 +0100
http://bitbucket.org/pypy/lang-smalltalk/changeset/9e0d98ab4de6/

Log:    merged

diff --git a/images/mini.image b/images/mini.image
index 
ef63740cadf1c61bd59bdf34a7ff21a801cc727d..4e0739b0aa769798ae904fee0eff0b0eac8c8368
GIT binary patch

[cut]

diff --git a/spyvm/interpreter.py b/spyvm/interpreter.py
--- a/spyvm/interpreter.py
+++ b/spyvm/interpreter.py
@@ -70,6 +70,9 @@
                     s_new_context.mark_returned()
                     s_new_context = s_sender
                 s_new_context.push(nlr.value)
+            except ProcessSwitch, p:
+                self.remaining_stack_depth = self.max_stack_depth
+                s_new_context = p.s_new_context
 
     def c_loop(self, s_context):
         # padding = ' ' * (self.max_stack_depth - self.remaining_stack_depth)
@@ -146,11 +149,17 @@
 class StackOverflow(Exception):
     def __init__(self, s_top_context):
         self.s_context = s_top_context
+
 class Return(Exception):
     def __init__(self, object, s_context):
         self.value = object
         self.s_target_context = s_context
 
+class ProcessSwitch(Exception):
+    def __init__(self, s_context):
+        self.s_new_context = s_context
+
+
 def make_call_primitive_bytecode(primitive, selector, argcount):
     def callPrimitive(self, interp, current_bytecode):
         # WARNING: this is used for bytecodes for which it is safe to
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -1,3 +1,4 @@
+import os
 import inspect
 import math
 import operator
@@ -753,10 +754,40 @@
 DIRECTORY_LOOKUP = 162
 DIRECTORY_DELTE = 163
 
+@expose_primitive(FILE_CLOSE, unwrap_spec=[object, int])
+def func(interp, s_frame, w_rcvr, fd):
+    try:
+        os.close(fd)
+    except OSError:
+        raise PrimitiveFailedError()
+    return w_rcvr
+
+@expose_primitive(FILE_OPEN, unwrap_spec=[object, str, object])
+def func(interp, s_frame, w_rcvr, filename, w_writeable_flag):
+    if w_writeable_flag is interp.space.w_true:
+        mode = os.O_RDWR | os.O_CREAT | os.O_TRUNC
+    else:
+        mode = os.O_RDONLY
+    try:
+        fd = os.open(filename, mode, 0666)
+    except OSError:
+        raise PrimitiveFailedError()
+    return interp.space.wrap_int(fd)
+
+@expose_primitive(FILE_WRITE, unwrap_spec=[object, int, str, int, int])
+def func(interp, s_frame, w_rcvr, fd, src, start, count):
+    start = start - 1
+    end = start + count
+    if end < 0 or start < 0:
+        raise PrimitiveFailedError()
+    try:
+        os.write(fd, src[start:end])
+    except OSError:
+        raise PrimitiveFailedError()
+    return w_rcvr
 
 @expose_primitive(DIRECTORY_DELIMITOR, unwrap_spec=[object])
 def func(interp, s_frame, _):
-    import os.path
     return interp.space.wrap_char(os.path.sep)
 
 
diff --git a/spyvm/test/test_miniimage.py b/spyvm/test/test_miniimage.py
--- a/spyvm/test/test_miniimage.py
+++ b/spyvm/test/test_miniimage.py
@@ -47,9 +47,9 @@
 def test_read_header():
     reader = open_miniimage(space)
     reader.read_header()
-    assert reader.endofmemory == 0x93174
-    assert reader.oldbaseaddress == 0x6649000
-    assert reader.specialobjectspointer == 0x6668380
+    assert reader.endofmemory == 655196
+    assert reader.oldbaseaddress == -1220960256
+    assert reader.specialobjectspointer == -1220832384
 
 def test_read_all_header(): 
     reader = open_miniimage(space)
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,4 +1,5 @@
 import py
+import os
 import math
 from spyvm.primitives import prim_table, PrimitiveFailedError
 from spyvm import model, shadow, interpreter
@@ -32,7 +33,9 @@
     if isinstance(x, str): return space.wrap_string(x)
     if isinstance(x, list): return space.wrap_list(x)
     raise NotImplementedError
-    
+
+IMAGENAME = "anImage.image"
+
 def mock(stack, context = None):
     mapped_stack = [wrap(x) for x in stack]
     if context is None:
@@ -41,7 +44,7 @@
         frame = context
         for i in range(len(stack)):
             frame.as_context_get_shadow(space).push(stack[i])
-    interp = interpreter.Interpreter(space)
+    interp = interpreter.Interpreter(space, image_name=IMAGENAME)
     return (interp, frame, len(stack))
 
 def prim(code, stack, context = None):
@@ -428,7 +431,7 @@
 
 def test_image_name():
     w_v = prim(primitives.IMAGE_NAME, [2])
-    assert w_v.bytes == []
+    assert w_v.bytes == list(IMAGENAME)
     
 def test_clone():
     w_obj = mockclass(space, 1, 
varsized=True).as_class_get_shadow(space).new(1)
@@ -438,12 +441,69 @@
     w_obj.atput0(space, 0, space.wrap_int(2))
     assert space.unwrap_int(w_v.at0(space, 0)) == 1
     
+def test_file_open_write(monkeypatch):
+    def open_write(filename, mode):
+        assert filename == "nonexistant"
+        assert mode == os.O_RDWR | os.O_CREAT | os.O_TRUNC
+        return 42
+    monkeypatch.setattr(os, "open", open_write)
+    try:
+        w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("nonexistant"), 
space.w_true])
+    finally:
+        monkeypatch.undo()
+    assert space.unwrap_int(w_c) == 42
+
+def test_file_open_read(monkeypatch):
+    def open_read(filename, mode):
+        assert filename == "file"
+        assert mode == os.O_RDONLY
+        return 42
+    monkeypatch.setattr(os, "open", open_read)
+    try:
+        w_c = prim(primitives.FILE_OPEN, [1, space.wrap_string("file"), 
space.w_false])
+    finally:
+        monkeypatch.undo()
+    assert space.unwrap_int(w_c) == 42
+
+def test_file_close(monkeypatch):
+    def close(fd):
+        assert fd == 42
+    monkeypatch.setattr(os, "close", close)
+    try:
+        w_c = prim(primitives.FILE_CLOSE, [1, space.wrap_int(42)])
+    finally:
+        monkeypatch.undo()
+
+def test_file_write(monkeypatch):
+    def write(fd, string):
+        assert fd == 42
+        assert string == "ell"
+    monkeypatch.setattr(os, "write", write)
+    try:
+        w_c = prim(
+            primitives.FILE_WRITE,
+            [1, space.wrap_int(42), space.wrap_string("hello"), 
space.wrap_int(2), space.wrap_int(3)]
+        )
+    finally:
+        monkeypatch.undo()
+
+def test_file_write_errors(monkeypatch):
+    with py.test.raises(PrimitiveFailedError):
+        w_c = prim(
+            primitives.FILE_WRITE,
+            [1, space.wrap_int(42), space.wrap_string("hello"), 
space.wrap_int(-1), space.wrap_int(3)]
+        )
+    with py.test.raises(PrimitiveFailedError):
+        w_c = prim(
+            primitives.FILE_WRITE,
+            [1, space.wrap_int(42), space.wrap_string("hello"), 
space.wrap_int(2), space.wrap_int(-1)]
+        )
+
 def test_directory_delimitor():
     import os.path
     w_c = prim(primitives.DIRECTORY_DELIMITOR, [1])
     assert space.unwrap_char(w_c) == os.path.sep
 
-
 def test_primitive_closure_copyClosure():
     from test_interpreter import new_frame
     w_frame, s_frame = new_frame("<never called, but used for method 
generation>",
diff --git a/spyvm/test/test_wrapper.py b/spyvm/test/test_wrapper.py
--- a/spyvm/test/test_wrapper.py
+++ b/spyvm/test/test_wrapper.py
@@ -1,11 +1,14 @@
 import py
-from spyvm import wrapper
-from spyvm import model
+from spyvm import wrapper, model, interpreter, objspace
 from spyvm.error import WrapperException, FatalError
-from spyvm import objspace
+
+from spyvm.test.test_interpreter import new_frame as new_frame_tuple
 
 space = objspace.ObjSpace()
 
+def new_frame():
+    return new_frame_tuple("")[0]
+
 def test_simpleread():
     w_o = model.W_PointersObject(None, 2)
     w = wrapper.Wrapper(space, w_o)
@@ -143,18 +146,20 @@
         assert process.my_list() is space.w_nil
 
     def test_suspend_active(self):
-        process, old_process = self.make_processes(4, 2, space.w_false)
-        old_process.suspend(space.w_true)
+        suspended_context = new_frame()
+        process, old_process = self.make_processes(4, 2, suspended_context)
+        current_context = new_frame()
+        with py.test.raises(interpreter.ProcessSwitch):
+            old_process.suspend(current_context)
         process_list = 
wrapper.scheduler(space).get_process_list(old_process.priority())
         assert process_list.first_link() is process_list.last_link()
         assert process_list.first_link() is space.w_nil
         assert old_process.my_list() is space.w_nil
+        assert old_process.suspended_context() is current_context
         assert wrapper.scheduler(space).active_process() is process._w_self
 
-    def new_process_consistency(self, process, old_process, w_active_context,
-                                    old_active_context, new_active_context):
+    def new_process_consistency(self, process, old_process, w_active_context):
         scheduler = wrapper.scheduler(space)
-        assert w_active_context is new_active_context
         assert scheduler.active_process() is process._w_self
         priority_list = 
wrapper.scheduler(space).get_process_list(process.priority())
         assert priority_list.first_link() is priority_list.last_link()
@@ -180,23 +185,29 @@
 
 
     def test_activate(self):
-        process, old_process = self.make_processes(4, 2, space.w_false)
-        w_frame = process.activate(space.w_true)
-        self.new_process_consistency(process, old_process, w_frame,
-                                         space.w_true, space.w_false)
+        sleepingcontext = new_frame()
+        process, old_process = self.make_processes(4, 2, sleepingcontext)
+        try:
+            process.activate()
+        except interpreter.ProcessSwitch, e:
+            w_frame = e.s_new_context._w_self
+        self.new_process_consistency(process, old_process, w_frame)
 
     def test_resume(self):
-        process, old_process = self.make_processes(4, 2, space.w_false)
-        w_frame = process.resume(space.w_true)
-        self.new_process_consistency(process, old_process, w_frame,
-                                         space.w_true, space.w_false)
-        self.old_process_consistency(old_process, space.w_true)
+        sleepingcontext = new_frame()
+        currentcontext = new_frame()
+        process, old_process = self.make_processes(4, 2, sleepingcontext)
+        try:
+            process.resume(currentcontext)
+        except interpreter.ProcessSwitch, e:
+            w_frame = e.s_new_context._w_self
+        self.new_process_consistency(process, old_process, w_frame)
+        self.old_process_consistency(old_process, currentcontext)
 
         # Does not reactivate old_process because lower priority
         w_frame = old_process.resume(w_frame)
-        self.new_process_consistency(process, old_process, w_frame,
-                                         space.w_true, space.w_false)
-        self.old_process_consistency(old_process, space.w_true)
+        self.new_process_consistency(process, old_process, w_frame)
+        self.old_process_consistency(old_process, currentcontext)
 
     def test_semaphore_excess_signal(self):
         semaphore = new_semaphore()
@@ -217,8 +228,11 @@
 
     def test_semaphore_wait(self):
         semaphore = new_semaphore()
-        process, old_process = self.make_processes(4, 2, space.w_false)
-        semaphore.wait(space.w_true)
+        suspendedcontext = new_frame()
+        currentcontext = new_frame()
+        process, old_process = self.make_processes(4, 2, suspendedcontext)
+        with py.test.raises(interpreter.ProcessSwitch):
+            semaphore.wait(currentcontext)
         assert semaphore.first_link() is old_process._w_self
         assert wrapper.scheduler(space).active_process() is process._w_self
 
@@ -226,11 +240,14 @@
         semaphore = new_semaphore()
         self.space = space
         semaphore.signal(self)
-        process, old_process = self.make_processes(4, 2, space.w_false)
-        semaphore.wait(space.w_true)
+        suspendedcontext = new_frame()
+        currentcontext = new_frame()
+        process, old_process = self.make_processes(4, 2, suspendedcontext)
+        semaphore.wait(currentcontext)
         assert semaphore.is_empty_list()
         assert wrapper.scheduler(space).active_process() is old_process._w_self
-        semaphore.wait(space.w_true)
+        with py.test.raises(interpreter.ProcessSwitch):
+            semaphore.wait(currentcontext)
         assert semaphore.first_link() is old_process._w_self
         assert wrapper.scheduler(space).active_process() is process._w_self
 
@@ -238,21 +255,28 @@
 
     def test_semaphore_wait_signal(self):
         semaphore = new_semaphore()
-        process, old_process = self.make_processes(4, 2, space.w_false)
+        suspendedcontext = new_frame()
+        currentcontext = new_frame()
+        process, old_process = self.make_processes(4, 2, suspendedcontext)
 
-        semaphore.wait(space.w_true)
+        with py.test.raises(interpreter.ProcessSwitch):
+            semaphore.wait(currentcontext)
+            
         assert wrapper.scheduler(space).active_process() is process._w_self
-        semaphore.signal(space.w_true)
+        semaphore.signal(currentcontext)
         assert wrapper.scheduler(space).active_process() is process._w_self
         process_list = 
wrapper.scheduler(space).get_process_list(old_process.priority())
         assert process_list.remove_first_link_of_list() is old_process._w_self
 
         process.write(2, space.wrap_int(1))
-        old_process.resume(space.w_true)
+        with py.test.raises(interpreter.ProcessSwitch):
+            old_process.resume(currentcontext)
         assert wrapper.scheduler(space).active_process() is old_process._w_self
-        semaphore.wait(space.w_true)
+        with py.test.raises(interpreter.ProcessSwitch):
+            semaphore.wait(currentcontext)
         assert wrapper.scheduler(space).active_process() is process._w_self
-        semaphore.signal(space.w_true)
+        with py.test.raises(interpreter.ProcessSwitch):
+            semaphore.signal(currentcontext)
         assert wrapper.scheduler(space).active_process() is old_process._w_self
 
         process_list = 
wrapper.scheduler(space).get_process_list(process.priority())
diff --git a/spyvm/wrapper.py b/spyvm/wrapper.py
--- a/spyvm/wrapper.py
+++ b/spyvm/wrapper.py
@@ -71,13 +71,16 @@
         process_list = sched.get_process_list(priority)
         process_list.add_process(self._w_self)
 
-    def activate(self, w_current_frame):
+    def activate(self):
+        from spyvm.interpreter import ProcessSwitch
+        assert not self.is_active_process()
         sched = scheduler(self.space)
         sched.store_active_process(self._w_self)
         w_frame = self.suspended_context()
         self.store_suspended_context(self.space.w_nil)
         self.store_my_list(self.space.w_nil)
-        return w_frame
+        assert isinstance(w_frame, model.W_PointersObject)
+        raise ProcessSwitch(w_frame.as_context_get_shadow(self.space))
 
     def deactivate(self, w_current_frame):
         self.put_to_sleep()
@@ -90,7 +93,7 @@
         priority = self.priority()
         if priority > active_priority:
             active_process.deactivate(w_current_frame)
-            return self.activate(w_current_frame)
+            return self.activate()
         else:
             self.put_to_sleep()
             return w_current_frame
@@ -102,7 +105,8 @@
         if self.is_active_process():
             assert self.my_list().is_same_object(self.space.w_nil)
             w_process = scheduler(self.space).highest_priority_process()
-            return ProcessWrapper(self.space, 
w_process).activate(w_current_frame)
+            self.store_suspended_context(w_current_frame)
+            return ProcessWrapper(self.space, w_process).activate()
         else:
             process_list = ProcessListWrapper(self.space, self.my_list())
             process_list.remove(self._w_self)
diff --git a/targetimageloadingsmalltalk.py b/targetimageloadingsmalltalk.py
--- a/targetimageloadingsmalltalk.py
+++ b/targetimageloadingsmalltalk.py
@@ -54,7 +54,7 @@
 
 def entry_point(argv):
     idx = 1
-    image = None
+    path = None
     number = 0
     benchmark = None
 
@@ -76,20 +76,20 @@
             _arg_missing(argv, idx, arg)
             benchmark = argv[idx + 1]
             idx += 1
-        elif image is None:
-            image = argv[idx]
+        elif path is None:
+            path = argv[idx]
         else:
             _usage(argv)
             return -1
         idx += 1
 
-    if image is None:
-        image = "Squeak.image"
+    if path is None:
+        path = "Squeak.image"
 
     try:
-        f = open_file_as_stream(image)
+        f = open_file_as_stream(path)
     except OSError as e:
-        os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), image))
+        os.write(2, "%s -- %s (LoadError)\n" % (os.strerror(e.errno), path))
         return 1
     try:
         imagedata = f.readall()
@@ -98,7 +98,7 @@
 
     image_reader = squeakimage.reader_for_image(space, 
squeakimage.Stream(data=imagedata))
     image = create_image(space, image_reader)
-    interp = interpreter.Interpreter(space, image)
+    interp = interpreter.Interpreter(space, image, 
image_name=os.path.abspath(path))
     if benchmark is not None:
         return _run_benchmark(interp, number, benchmark)
     else:
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to