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