[pypy-svn] r65666 - in pypy/branch/pyjitpl5-experiments/pypy/jit/backend: llvm test

arigo at codespeak.net arigo at codespeak.net
Mon Jun 8 18:24:35 CEST 2009


Author: arigo
Date: Mon Jun  8 18:24:34 2009
New Revision: 65666

Modified:
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
   pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py
Log:
Unicode strings.


Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/compile.py	Mon Jun  8 18:24:34 2009
@@ -153,11 +153,9 @@
         ty = llvm_rffi.LLVMTypeOf(value_ref)
         if ty == self.cpu.ty_int:
             return value_ref
-        elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char:
+        else:
             return llvm_rffi.LLVMBuildZExt(self.builder, value_ref,
                                            self.cpu.ty_int, "")
-        else:
-            raise AssertionError("type is not an int nor a bit")
 
     def getbitarg(self, v):
         try:
@@ -172,11 +170,9 @@
         ty = llvm_rffi.LLVMTypeOf(value_ref)
         if ty == self.cpu.ty_bit:
             return value_ref
-        elif ty == self.cpu.ty_int or ty == self.cpu.ty_char:
+        else:
             return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
                                             self.cpu.ty_bit, "")
-        else:
-            raise AssertionError("type is not an int nor a bit")
 
     def getchararg(self, v):
         try:
@@ -191,7 +187,7 @@
         ty = llvm_rffi.LLVMTypeOf(value_ref)
         if ty == self.cpu.ty_char:
             return value_ref
-        elif ty == self.cpu.ty_int:
+        elif ty == self.cpu.ty_int or ty == self.cpu.ty_unichar:
             return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
                                             self.cpu.ty_char, "")
         elif ty == self.cpu.ty_bit:
@@ -200,6 +196,28 @@
         else:
             raise AssertionError("type is not an int nor a bit")
 
+    def getunichararg(self, v):
+        try:
+            value_ref = self.vars[v]
+        except KeyError:
+            assert isinstance(v, ConstInt)
+            return self.cpu._make_const_unichar(v.value)
+        else:
+            return self._cast_to_unichar(value_ref)
+
+    def _cast_to_unichar(self, value_ref):
+        ty = llvm_rffi.LLVMTypeOf(value_ref)
+        if ty == self.cpu.ty_unichar:
+            return value_ref
+        elif ty == self.cpu.ty_int:
+            return llvm_rffi.LLVMBuildTrunc(self.builder, value_ref,
+                                            self.cpu.ty_char, "")
+        elif ty == self.cpu.ty_bit or ty == self.cpu.ty_char:
+            return llvm_rffi.LLVMBuildZExt(self.builder, value_ref,
+                                           self.cpu.ty_char, "")
+        else:
+            raise AssertionError("type is not an int nor a bit")
+
     def getptrarg(self, v):
         try:
             value_ref = self.vars[v]
@@ -210,7 +228,8 @@
             ty = llvm_rffi.LLVMTypeOf(value_ref)
             assert (ty != self.cpu.ty_int and
                     ty != self.cpu.ty_bit and
-                    ty != self.cpu.ty_char)
+                    ty != self.cpu.ty_char and
+                    ty != self.cpu.ty_unichar)
             return value_ref
 
     for _opname, _llvmname in [('INT_ADD', 'Add'),
@@ -482,7 +501,9 @@
         loc, _ = self._generate_field_gep(op.args[0], op.descr)
         self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
 
-    generate_GETFIELD_GC_PURE = generate_GETFIELD_GC
+    generate_GETFIELD_GC_PURE  = generate_GETFIELD_GC
+    generate_GETFIELD_RAW      = generate_GETFIELD_GC
+    generate_GETFIELD_RAW_PURE = generate_GETFIELD_GC
 
     def generate_SETFIELD_GC(self, op):
         loc, tyval = self._generate_field_gep(op.args[0], op.descr)
@@ -608,40 +629,70 @@
             value_ref = self.getintarg(op.args[2])
         llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
 
-    def generate_STRLEN(self, op):
+    def _generate_str_unicode_len(self, op, ty, const_index_length):
         array = llvm_rffi.LLVMBuildBitCast(self.builder,
                                            self.getptrarg(op.args[0]),
-                                           self.cpu.ty_string_ptr, "")
+                                           ty, "")
         indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 2,
                                 flavor='raw')
         indices[0] = self.cpu.const_zero
-        indices[1] = self.cpu.const_string_index_length
+        indices[1] = const_index_length
         loc = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 2, "")
         lltype.free(indices, flavor='raw')
         self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
 
-    def _generate_string_gep(self, v_string, v_index):
+    def generate_STRLEN(self, op):
+        self._generate_str_unicode_len(op, self.cpu.ty_string_ptr,
+                                       self.cpu.const_string_index_length)
+
+    def generate_UNICODELEN(self, op):
+        self._generate_str_unicode_len(op, self.cpu.ty_unicode_ptr,
+                                       self.cpu.const_unicode_index_length)
+
+    def _generate_string_unicode_gep(self, v_string, v_index,
+                                     ty, const_index_array):
         array = llvm_rffi.LLVMBuildBitCast(self.builder,
                                            self.getptrarg(v_string),
-                                           self.cpu.ty_string_ptr, "")
+                                           ty, "")
         indices = lltype.malloc(rffi.CArray(llvm_rffi.LLVMValueRef), 3,
                                 flavor='raw')
         indices[0] = self.cpu.const_zero
-        indices[1] = self.cpu.const_string_index_array
+        indices[1] = const_index_array
         indices[2] = self.getintarg(v_index)
         location = llvm_rffi.LLVMBuildGEP(self.builder, array, indices, 3, "")
         lltype.free(indices, flavor='raw')
         return location
 
     def generate_STRGETITEM(self, op):
-        loc = self._generate_string_gep(op.args[0], op.args[1])
+        loc = self._generate_string_unicode_gep(
+            op.args[0], op.args[1],
+            self.cpu.ty_string_ptr,
+            self.cpu.const_string_index_array)
+        self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
+
+    def generate_UNICODEGETITEM(self, op):
+        loc = self._generate_string_unicode_gep(
+            op.args[0], op.args[1],
+            self.cpu.ty_unicode_ptr,
+            self.cpu.const_unicode_index_array)
         self.vars[op.result] = llvm_rffi.LLVMBuildLoad(self.builder, loc, "")
 
     def generate_STRSETITEM(self, op):
-        loc = self._generate_string_gep(op.args[0], op.args[1])
+        loc = self._generate_string_unicode_gep(
+            op.args[0], op.args[1],
+            self.cpu.ty_string_ptr,
+            self.cpu.const_string_index_array)
         value_ref = self.getchararg(op.args[2])
         llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
 
+    def generate_UNICODESETITEM(self, op):
+        loc = self._generate_string_unicode_gep(
+            op.args[0], op.args[1],
+            self.cpu.ty_unicode_ptr,
+            self.cpu.const_unicode_index_array)
+        value_ref = self.getunichararg(op.args[2])
+        llvm_rffi.LLVMBuildStore(self.builder, value_ref, loc, "")
+
 # ____________________________________________________________
 
 class MissingOperation(Exception):

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/llvm/runner.py	Mon Jun  8 18:24:34 2009
@@ -1,6 +1,7 @@
 import sys
 from pypy.rpython.lltypesystem import lltype, llmemory, rffi, rclass, rstr
 from pypy.rlib.objectmodel import we_are_translated
+from pypy.rlib import runicode
 from pypy.jit.metainterp.history import AbstractDescr, INT
 from pypy.jit.metainterp.history import BoxInt, BoxPtr
 from pypy.jit.backend import model
@@ -39,12 +40,19 @@
             self.size_of_int = 4
         else:
             self.size_of_int = 8
+        if runicode.MAXUNICODE > 0xffff:
+            self.size_of_unicode = 4
+        else:
+            self.size_of_unicode = 2
         basesize, _, ofs_length = symbolic.get_array_token(
             lltype.GcArray(lltype.Signed), self.translate_support_code)
         self._fixed_array_shape = basesize, ofs_length
         basesize, _, ofs_length = symbolic.get_array_token(
             rstr.STR, self.translate_support_code)
         self._string_shape = basesize, ofs_length
+        basesize, _, ofs_length = symbolic.get_array_token(
+            rstr.UNICODE, self.translate_support_code)
+        self._unicode_shape = basesize, ofs_length
 
     def setup_once(self):
         if not we_are_translated():
@@ -55,6 +63,10 @@
             self.ty_int = llvm_rffi.LLVMInt32Type()
         else:
             self.ty_int = llvm_rffi.LLVMInt64Type()
+        if self.size_of_unicode == 2:
+            self.ty_unichar = llvm_rffi.LLVMInt16Type()
+        else:
+            self.ty_unichar = llvm_rffi.LLVMInt32Type()
         self.ty_void = llvm_rffi.LLVMVoidType()
         self.ty_bit = llvm_rffi.LLVMInt1Type()
         self.ty_char = llvm_rffi.LLVMInt8Type()
@@ -89,6 +101,13 @@
                  self._build_ty_array_ptr(shape_basesize,
                                           self.ty_char,
                                           shape_length)
+        (shape_basesize, shape_length) = self._unicode_shape
+        (self.ty_unicode_ptr,
+         self.const_unicode_index_length,
+         self.const_unicode_index_array) = \
+                 self._build_ty_array_ptr(shape_basesize,
+                                          self.ty_unichar,
+                                          shape_length)
         #
         arglist = lltype.malloc(rffi.CArray(llvm_rffi.LLVMTypeRef), 0,
                                 flavor='raw')
@@ -201,6 +220,10 @@
         assert (value & ~255) == 0, "value is not in range(256)"
         return llvm_rffi.LLVMConstInt(self.ty_char, value, True)
 
+    def _make_const_unichar(self, value):
+        #xxx assert something about 'value'
+        return llvm_rffi.LLVMConstInt(self.ty_unichar, value, True)
+
     def _make_const_bit(self, value):
         assert (value & ~1) == 0, "value is not 0 or 1"
         return llvm_rffi.LLVMConstInt(self.ty_bit, value, True)

Modified: pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py
==============================================================================
--- pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py	(original)
+++ pypy/branch/pyjitpl5-experiments/pypy/jit/backend/test/runner_test.py	Mon Jun  8 18:24:34 2009
@@ -440,6 +440,14 @@
         r = self.execute_operation(rop.STRGETITEM, [s_box, BoxInt(5)], 'int')
         assert r.value == 254
 
+    def test_unicode_basic(self):
+        u_box = self.alloc_unicode(u"hello\u1234")
+        r = self.execute_operation(rop.UNICODELEN, [u_box], 'int')
+        assert r.value == 6
+        r = self.execute_operation(rop.UNICODEGETITEM, [u_box, BoxInt(5)],
+                                   'int')
+        assert r.value == 0x1234
+
 
 class LLtypeBackendTest(BaseBackendTest):
 
@@ -502,6 +510,13 @@
         s_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, s))
         return s_box
 
+    def alloc_unicode(self, unicode):
+        u = rstr.mallocunicode(len(unicode))
+        for i in range(len(unicode)):
+            u.chars[i] = unicode[i]
+        u_box = BoxPtr(lltype.cast_opaque_ptr(llmemory.GCREF, u))
+        return u_box
+
 
     def test_casts(self):
         from pypy.rpython.lltypesystem import lltype, llmemory
@@ -562,3 +577,6 @@
 
     def alloc_string(self, string):
         py.test.skip("implement me")
+
+    def alloc_unicode(self, unicode):
+        py.test.skip("implement me")



More information about the Pypy-commit mailing list