Author: Lars Wassermann <[email protected]>
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
[email protected]
http://mail.python.org/mailman/listinfo/pypy-commit