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