Commits

Maciej Fijalkowski committed 33301a2

basic bytearray creation

  • Participants
  • Parent commits 5769354
  • Branches rpython-bytearray

Comments (0)

Files changed (8)

File pypy/rpython/lltypesystem/rbytearray.py

+
+from pypy.rpython.rbytearray import AbstractByteArrayRepr
+from pypy.rpython.lltypesystem import lltype
+
+BYTEARRAY = lltype.GcArray(lltype.Char)
+
+class ByteArrayRepr(AbstractByteArrayRepr):
+    lowleveltype = lltype.Ptr(BYTEARRAY)
+
+    def convert_const(self, value):
+        if value is None:
+            return lltype.nullptr(BYTEARRAY)
+        p = lltype.malloc(BYTEARRAY, len(value))
+        for i, c in enumerate(value):
+            p[i] = chr(c)
+        return p
+
+bytearray_repr = ByteArrayRepr()
+
+def hlbytearray(ll_b):
+    b = bytearray()
+    for i in range(len(ll_b)):
+        b.append(ll_b[i])
+    return b

File pypy/rpython/lltypesystem/rstr.py

 from pypy.rpython.lltypesystem.lltype import \
      GcStruct, Signed, Array, Char, UniChar, Ptr, malloc, \
      Bool, Void, GcArray, nullptr, cast_primitive, typeOf,\
-     staticAdtMethod, GcForwardReference
+     staticAdtMethod, GcForwardReference, malloc
 from pypy.rpython.rmodel import Repr
 from pypy.rpython.lltypesystem import llmemory
 from pypy.tool.sourcetools import func_with_new_name
             s.chars[i] = cast_primitive(UniChar, str.chars[i])
         return s
 
+    def ll_str2bytearray(str):
+        from pypy.rpython.lltypesystem.rbytearray import BYTEARRAY
+        
+        lgt = len(str.chars)
+        b = malloc(BYTEARRAY, lgt)
+        for i in range(lgt):
+            b[i] = str.chars[i]
+        return b
+
     @jit.elidable
     def ll_strhash(s):
         # unlike CPython, there is no reason to avoid to return -1

File pypy/rpython/rbuiltin.py

 def rtype_builtin_unicode(hop):
     return hop.args_r[0].rtype_unicode(hop)
 
+def rtype_builtin_bytearray(hop):
+    return hop.args_r[0].rtype_bytearray(hop)
+
 def rtype_builtin_list(hop):
     return hop.args_r[0].rtype_bltn_list(hop)
 

File pypy/rpython/rbytearray.py

+
+from pypy.rpython.rmodel import Repr
+from pypy.annotation import model as annmodel
+
+class AbstractByteArrayRepr(Repr):
+    pass
+
+class __extend__(annmodel.SomeByteArray):
+    def rtyper_makekey(self):
+        return self.__class__,
+
+    def rtyper_makerepr(self, rtyper):
+        return rtyper.type_system.rbytearray.bytearray_repr

File pypy/rpython/rstr.py

         hop.exception_is_here()
         return hop.gendirectcall(self.ll.ll_str2unicode, v_str)
 
+    def rtype_bytearray(self, hop):
+        if hop.args_s[0].is_constant():
+            # convertion errors occur during annotation, so cannot any more:
+            hop.exception_cannot_occur()
+            return hop.inputconst(hop.r_result, hop.s_result.const)
+        hop.exception_is_here()
+        return hop.gendirectcall(self.ll.ll_str2bytearray,
+                                 hop.inputarg(hop.args_r[0].repr, 0))
+
     def rtype_method_decode(self, hop):
         if not hop.args_s[1].is_constant():
             raise TyperError("encoding must be a constant")

File pypy/rpython/rtyper.py

 # and the rtyper_chooserepr() methods
 from pypy.rpython import rint, rbool, rfloat
 from pypy.rpython import rrange
-from pypy.rpython import rstr, rdict, rlist
+from pypy.rpython import rstr, rdict, rlist, rbytearray
 from pypy.rpython import rclass, rbuiltin, rpbc
 from pypy.rpython import rexternalobj
 from pypy.rpython import rptr

File pypy/rpython/test/test_rbytearray.py

+
+from pypy.rpython.test.tool import BaseRtypingTest, LLRtypeMixin
+from pypy.rpython.lltypesystem.rbytearray import hlbytearray
+
+class TestByteArray(BaseRtypingTest, LLRtypeMixin):
+    def test_bytearray_creation(self):
+        def f(x):
+            if x:
+                b = bytearray(str(x))
+            else:
+                b = bytearray("def")
+            return b
+        ll_res = self.interpret(f, [0])
+        assert hlbytearray(ll_res) == "def"
+        ll_res = self.interpret(f, [1])
+        assert hlbytearray(ll_res) == "1"

File pypy/rpython/typesystem.py

                 return None
         if name in ('rclass', 'rpbc', 'rbuiltin', 'rtuple', 'rlist',
                     'rslice', 'rdict', 'rrange', 'rstr', 'rgeneric',
-                    'll_str', 'rbuilder', 'rvirtualizable2',
+                    'll_str', 'rbuilder', 'rvirtualizable2', 'rbytearray',
                     'exceptiondata'):
             mod = load(name)
             if mod is not None: