Author: Lars Wassermann <lars.wasserm...@gmail.com>
Branch: 
Changeset: r417:ca22950ac473
Date: 2013-05-24 18:21 +0200
http://bitbucket.org/pypy/lang-smalltalk/changeset/ca22950ac473/

Log:    changes needed to make the vm translateable:
        - added intmask call when creating Smallintegers, thus asserting the
        type for the translator
        - added some more such calls
        - restructured primitiveFileStdioHandles to allow calls to module sys
        to be in global scope...

diff --git a/spyvm/model.py b/spyvm/model.py
--- a/spyvm/model.py
+++ b/spyvm/model.py
@@ -147,7 +147,7 @@
     _immutable_fields_ = ["value"]
 
     def __init__(self, value):
-        self.value = value
+        self.value = intmask(value)
 
     def getclass(self, space):
         return space.w_SmallInteger
@@ -244,7 +244,7 @@
     _attrs_ = ["value", "_exposed_size"]
 
     def __init__(self, value, size=4):
-        self.value = value
+        self.value = intmask(value)
         self._exposed_size = size
 
     def fillin(self, space, g_self):
@@ -267,7 +267,6 @@
         return "W_LargePositiveInteger1Word(%d)" % r_uint(self.value)
 
     def lshift(self, space, shift):
-        from rpython.rlib.rarithmetic import 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)
@@ -729,12 +728,11 @@
         self.bytes[n0] = character
 
     def short_at0(self, space, index0):
-        from rpython.rlib.rarithmetic import intmask
         byte_index0 = index0 * 2
         byte0 = ord(self.getchar(byte_index0))
         byte1 = ord(self.getchar(byte_index0 + 1)) << 8
         if byte1 & 0x8000 != 0:
-            byte1 = intmask(0xffff0000 | byte1)
+            byte1 = intmask(-65536 | byte1) # -65536 = 0xffff0000
         return space.wrap_int(byte1 | byte0)
 
     def short_atput0(self, space, index0, w_value):
@@ -818,13 +816,13 @@
         self.words[n] = r_uint(word)
 
     def short_at0(self, space, index0):
-        word = self.getword(index0 / 2)
+        word = intmask(self.getword(index0 / 2))
         if index0 % 2 == 0:
             short = word & 0xffff
         else:
             short = (word >> 16) & 0xffff
         if short & 0x8000 != 0:
-            short = 0xffff0000 | short
+            short = -65536 | short # -65536 = 0xffff0000
         return space.wrap_int(intmask(short))
 
     def short_atput0(self, space, index0, w_value):
@@ -833,12 +831,13 @@
         if not int_between(-32768, i_value, 0x8000):
             raise error.PrimitiveFailedError
         word_index0 = index0 / 2
-        word = self.getword(word_index0)
+        word = intmask(self.getword(word_index0))
         if index0 % 2 == 0:
-            word = (word & 0xffff0000) | (i_value & 0xffff)
+            word = (word & -65536) | (i_value & 0xffff) # -65536 = 0xffff0000
         else:
             word = (i_value << 16) | (word & 0xffff)
-        self.setword(word_index0, word)
+        value = r_uint(word)
+        self.setword(word_index0, value)
 
     def size(self):
         return len(self.words)
diff --git a/spyvm/objspace.py b/spyvm/objspace.py
--- a/spyvm/objspace.py
+++ b/spyvm/objspace.py
@@ -246,10 +246,10 @@
 
     def unwrap_int(self, w_value):
         if isinstance(w_value, model.W_SmallInteger):
-            return w_value.value
+            return intmask(w_value.value)
         elif isinstance(w_value, model.W_LargePositiveInteger1Word):
             if w_value.value >= 0:
-                return w_value.value
+                return intmask(w_value.value)
             else:
                 raise UnwrappingError("The value is negative when interpreted 
as 32bit value.")
         raise UnwrappingError("expected a W_SmallInteger or 
W_LargePositiveInteger1Word, got %s" % (w_value,))
diff --git a/spyvm/plugins/fileplugin.py b/spyvm/plugins/fileplugin.py
--- a/spyvm/plugins/fileplugin.py
+++ b/spyvm/plugins/fileplugin.py
@@ -1,4 +1,8 @@
-import os, stat
+import os, stat, sys
+
+from rpython.rlib import jit
+from rpython.rlib.listsort import TimSort
+
 from spyvm import model, error
 from spyvm.plugins.plugin import Plugin
 from spyvm.primitives import PrimitiveFailedError, index1_0
@@ -7,6 +11,10 @@
 FilePlugin = Plugin()
 os.stat_float_times(False)
 
+std_fds = [sys.stdin.fileno(),
+           sys.stdout.fileno(),
+           sys.stderr.fileno()]
+
 @FilePlugin.expose_primitive(unwrap_spec=[object])
 def primitiveDirectoryDelimitor(interp, s_frame, w_rcvr):
     return interp.space.wrap_char(os.path.sep)
@@ -22,18 +30,24 @@
     space = interp.space
     if index >= len(contents):
         return space.w_nil
-    py_name = sorted(contents)[index]
+
+    # should probably be sorted...
+    contents
+    py_name = contents[index]
     try:
         file_path = os.path.join(full_path, py_name)
     except OSError:
         raise PrimitiveFailedError
     file_info = os.stat(file_path)
-    name = space.wrap_string(py_name)
-    creationTime = smalltalk_timestamp(space, file_info.st_ctime)
-    modificationTime = smalltalk_timestamp(space, file_info.st_mtime)
-    dirFlag = space.w_true if stat.S_IFDIR & file_info.st_mode else 
space.w_false
-    fileSize = space.wrap_int(file_info.st_size)
-    return space.wrap_list([name, creationTime, modificationTime, dirFlag, 
fileSize])
+
+    w_name = space.wrap_string(py_name)
+    w_creationTime = smalltalk_timestamp(space, file_info.st_ctime)
+    w_modificationTime = smalltalk_timestamp(space, file_info.st_mtime)
+    w_dirFlag = space.w_true if stat.S_IFDIR & file_info.st_mode else 
space.w_false
+    w_fileSize = space.wrap_int(file_info.st_size)
+
+    return space.wrap_list([w_name, w_creationTime, w_modificationTime,
+                            w_dirFlag, w_fileSize])
 
 @FilePlugin.expose_primitive(unwrap_spec=[object, str, object])
 def primitiveFileOpen(interp, s_frame, w_rcvr, file_path, w_writeable_flag):
@@ -56,6 +70,7 @@
 
 @FilePlugin.expose_primitive(unwrap_spec=[object, int])
 def primitiveFileClose(interp, s_frame, w_rcvr, fd):
+    from rpython.rlib.rarithmetic import intmask
     try:
         os.close(fd)
     except OSError:
@@ -64,15 +79,47 @@
 
 @FilePlugin.expose_primitive(unwrap_spec=[object, int])
 def primitiveFileAtEnd(interp, s_frame, w_rcvr, fd):
-    py_file = os.fdopen(fd)
-    stat = os.fstat(fd)
-    if py_file.tell() >= stat.st_size:
+    file_info = os.fstat(fd)
+    if os.lseek(fd, 0, os.SEEK_CUR) >= file_info.st_size:
         return interp.space.w_true
     else:
         return interp.space.w_false
 
+@FilePlugin.expose_primitive(unwrap_spec=[object, int, object, index1_0, int])
+def primitiveFileRead(interp, s_frame, w_rcvr, fd, target, start, count):
+    if not isinstance(target, model.W_BytesObject):
+        raise PrimitiveFailedError
+    try:
+        contents = os.read(fd, count)
+    except OSError:
+        raise PrimitiveFailedError
+    space = interp.space
+    len_read = len(contents)
+    if target.size() < start + len_read:
+        raise PrimitiveFailedError
+    for i in range(len_read):
+        target.setchar(start + i, contents[i])
+    return space.wrap_int(len_read)
+
+@FilePlugin.expose_primitive(unwrap_spec=[object, int])
+def primitiveFileSize(interp, s_frame, w_rcvr, fd):
+    try:
+        file_info = os.fstat(fd)
+    except OSError:
+        raise PrimitiveFailedError
+    return interp.space.wrap_int(file_info.st_size)
+
+@FilePlugin.expose_primitive(unwrap_spec=[object])
+def primitiveFileStdioHandles(interp, s_frame, w_rcvr):
+    # This primitive may give an error-code...
+    # return an array with stdin, stdout, stderr
+    space = interp.space
+    return space.wrap_list([space.wrap_int(fd) for fd in std_fds])
+
+@jit.elidable
 def smalltalk_timestamp(space, sec_since_epoch):
     import time
     from spyvm.primitives import secs_between_1901_and_1970
-    sec_since_1901 = sec_since_epoch + secs_between_1901_and_1970
+    from rpython.rlib.rarithmetic import r_uint
+    sec_since_1901 = r_uint(sec_since_epoch + secs_between_1901_and_1970)
     return space.wrap_uint(sec_since_1901)
diff --git a/spyvm/primitives.py b/spyvm/primitives.py
--- a/spyvm/primitives.py
+++ b/spyvm/primitives.py
@@ -985,15 +985,17 @@
 
 @expose_primitive(SHORT_AT, unwrap_spec=[object, index1_0])
 def func(interp, s_frame, w_receiver, n0):
-    if not isinstance(w_receiver, (model.W_BytesObject, model.W_WordsObject)):
+    if not (isinstance(w_receiver, model.W_BytesObject)
+            or isinstance(w_receiver, model.W_WordsObject)):
         raise PrimitiveFailedError
     return w_receiver.short_at0(interp.space, n0)
 
 @expose_primitive(SHORT_AT_PUT, unwrap_spec=[object, index1_0, object])
 def func(interp, s_frame, w_receiver, n0, w_value):
-    if not isinstance(w_receiver, (model.W_BytesObject, model.W_WordsObject)):
+    if not (isinstance(w_receiver, model.W_BytesObject)
+            or isinstance(w_receiver, model.W_WordsObject)):
         raise PrimitiveFailedError
-    return w_receiver.short_atput0(interp.space, n0)
+    return w_receiver.short_atput0(interp.space, n0, w_value)
 
 
 @expose_primitive(CLONE, unwrap_spec=[object])
_______________________________________________
pypy-commit mailing list
pypy-commit@python.org
http://mail.python.org/mailman/listinfo/pypy-commit

Reply via email to