[pypy-svn] r22474 - in pypy/dist/pypy/translator/js: . test

ericvrp at codespeak.net ericvrp at codespeak.net
Sat Jan 21 10:07:33 CET 2006


Author: ericvrp
Date: Sat Jan 21 10:07:32 2006
New Revision: 22474

Modified:
   pypy/dist/pypy/translator/js/codewriter.py
   pypy/dist/pypy/translator/js/funcnode.py
   pypy/dist/pypy/translator/js/optimize.py
   pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py
   pypy/dist/pypy/translator/js/test/test_stackless.py
Log:
* Support for merge if blocks.
* Cleanup stackless output when calling native javascript function.


Modified: pypy/dist/pypy/translator/js/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/js/codewriter.py	(original)
+++ pypy/dist/pypy/translator/js/codewriter.py	Sat Jan 21 10:07:32 2006
@@ -134,12 +134,14 @@
         self.append('}')
         self.skip_closeblock()
 
-    def switch(self, cond, defaultdest, value_labels):
-        if not defaultdest:
-            raise TypeError('switches must have a default case.') 
-        labels = ','.join(["'%s':%s" % (value, label) for value, label in value_labels])
-        #XXX for performance this Object should become global
-        self.append("if (!(block = {%s}[%s])) block = %s" % (labels, cond, defaultdest))
+    def switch(self, cond, mapping, default_code):
+        #XXX the performance of this code can be improved by:
+        #   1. not using eval
+        #   2. storing the object in a global variable
+        labels = ','.join(["%s:%s" % (exitcase, code) for exitcase, code in mapping])
+        self.append("var switch_code = {%s}[%s]" % (labels, cond))
+        self.append("if (!switch_code) switch_code=%s" % default_code)
+        self.append('eval(switch_code)')
 
     def openfunc(self, decl, funcnode, blocks): 
         self.decl     = decl
@@ -202,10 +204,10 @@
 
         if not exceptions:
             assert no_exception is None
-            if self.js.stackless:
+            optimized, code = optimize_call('%s = %s(%s)' % (targetvar, functionref, args))
+            if self.js.stackless and not optimized:
                 self.append("slp_stack_depth++")
-            self.append( optimize_call('%s = %s(%s)' % (targetvar, functionref, args)) )
-            if self.js.stackless:
+                self.append(code)
                 self.append("slp_stack_depth--")
                 selfdecl = self.decl.split('(')[0]
                 usedvars = ', '.join(self._usedvars.keys())
@@ -224,17 +226,21 @@
                 self.append('case %d:' % self._resume_blocknum)
                 self.indent_more()
                 self._resume_blocknum += 1
+            else:   #not stackless
+                self.append(code)
         else:
             assert no_exception is not None
             no_exception_label, no_exception_exit = no_exception
             self.append('try {')
             self.indent_more()
-            if self.js.stackless:
+            optimized, code = optimize_call('%s = %s(%s)' % (targetvar, functionref, args))
+            if self.js.stackless and not optimized:
                 self.comment('TODO: XXX stackless in combination with exceptions handling')
                 self.append("slp_stack_depth++")
-            self.append( optimize_call('%s = %s(%s)' % (targetvar, functionref, args)) )
-            if self.js.stackless:
+                self.append(code)
                 self.append("slp_stack_depth--")    #XXX we don't actually get here when an exception occurs!
+            else:
+                self.append(code)
             self._phi(no_exception_exit)
             self._goto_block(no_exception_label)
             self.indent_less()

Modified: pypy/dist/pypy/translator/js/funcnode.py
==============================================================================
--- pypy/dist/pypy/translator/js/funcnode.py	(original)
+++ pypy/dist/pypy/translator/js/funcnode.py	Sat Jan 21 10:07:32 2006
@@ -99,7 +99,7 @@
             (lltype.Signed, lltype.Unsigned, lltype.SignedLongLong,
              lltype.UnsignedLongLong, lltype.Char, lltype.UniChar):
             defaultlink = None
-            value_labels = []
+            mapping = []
             for link in block.exits:
                 if link.exitcase is 'default':
                     defaultlink = link
@@ -108,10 +108,30 @@
                 exitcase = link.llexitcase
                 if block.exitswitch.concretetype in [lltype.Char, lltype.UniChar]:
                     exitcase = ord(exitcase)
-                value_labels.append( (exitcase,
-                                      self.blockindex[link.target]) )
+                exitcase = "'%s'" % exitcase
 
-            codewriter.switch(cond, self.blockindex[defaultlink.target], value_labels)
+                try:
+                    targetvar       = link.target.inputargs[0]
+                    targetvar_value = self.db.repr_arg(link.args[0])
+                    s = "%s=%s;" % (targetvar, targetvar_value)
+                except:
+                    s = ''
+                targetblock = self.blockindex[link.target]
+
+                code = "'%sblock=%s'" % (s, targetblock)
+                mapping.append( (exitcase, code) )
+
+            try:
+                default_targetvar       = defaultlink.target.inputargs[0]
+                default_targetvar_value = self.db.repr_arg(defaultlink.args[0])
+                s = "%s=%s;" % (default_targetvar, default_targetvar_value)
+            except:
+                s = ''
+            default_targetblock     = self.blockindex[defaultlink.target]
+            default_code  = "'%sblock=%s'" % (s, default_targetblock)
+            if block.exitswitch.concretetype == lltype.Char:
+                cond = "%s.charCodeAt(0)" % cond
+            codewriter.switch(cond, mapping, default_code)
 
         else:
            raise BranchException("exitswitch type '%s' not supported" %

Modified: pypy/dist/pypy/translator/js/optimize.py
==============================================================================
--- pypy/dist/pypy/translator/js/optimize.py	(original)
+++ pypy/dist/pypy/translator/js/optimize.py	Sat Jan 21 10:07:32 2006
@@ -6,7 +6,8 @@
     'll_streq__rpy_stringPtr_rpy_stringPtr',
     'll_str__IntegerR_SignedConst_Signed',
     'll_chr2str__Char',
-    'll_issubclass__object_vtablePtr_object_vtablePtr'  #TODO
+    'll_issubclass__object_vtablePtr_object_vtablePtr',
+    'll_str__FloatR_FloatConst_Float',
 ]
 
 
@@ -16,33 +17,34 @@
     params               = [param.strip() for param in params[:-1].split(',')]
 
     if funcname == 'll_strlen__rpy_stringPtr':
-        return '%s = %s.chars.length' % (targetvar, params[0])
+        return True, '%s = %s.chars.length' % (targetvar, params[0])
 
     elif funcname == 'll_strconcat__rpy_stringPtr_rpy_stringPtr':   
         #XXX javascript of ll_strconcat__rpy_stringPtr_rpy_stringPtr actually does not work, FIX IT!
         #    by outcommenting this code end running js/test/test_genllvm.py -k test_simple_chars
         p = '%s.chars' % '.chars + '.join(params)
-        return '%s = new Object({hash:0, chars:%s})' % (targetvar, p)
+        return True, '%s = new Object({hash:0, chars:%s})' % (targetvar, p)
         
     elif funcname == 'll_stritem_nonneg__rpy_stringPtr_Signed':
-        return '%s = %s.chars[%s]' % (targetvar, params[0], params[1])
+        return True, '%s = %s.chars[%s]' % (targetvar, params[0], params[1])
 
     elif funcname == 'll_stritem__rpy_stringPtr_Signed':
         s, i = params
-        return '%s = %s.chars[%s >= 0 ? %s : %s + %s.chars.length]' % (targetvar, s, i, i, i, s)
+        return True, '%s = %s.chars[%s >= 0 ? %s : %s + %s.chars.length]' % (targetvar, s, i, i, i, s)
 
     elif funcname == 'll_streq__rpy_stringPtr_rpy_stringPtr':
         s0, s1 = params
-        return '%s = (%s == %s) || (%s && %s && %s.chars == %s.chars)' %\
+        return True, '%s = (%s == %s) || (%s && %s && %s.chars == %s.chars)' %\
                 (targetvar, s0,s1, s0,s1, s0,s1)
 
-    elif funcname == 'll_str__IntegerR_SignedConst_Signed':
-        return '%s = new Object({hash:0, chars:%s + ""})' % (targetvar, params[0])
+    elif funcname in ('ll_str__IntegerR_SignedConst_Signed',
+                      'll_str__FloatR_FloatConst_Float'):
+        return True, '%s = new Object({hash:0, chars:%s + ""})' % (targetvar, params[0])
 
     elif funcname == 'll_chr2str__Char':
-        return '%s = new Object({hash:0, chars:%s})' % (targetvar, params[0])
+        return True, '%s = new Object({hash:0, chars:%s})' % (targetvar, params[0])
 
-    return '%s = %s(%s)' % (targetvar, funcname, ', '.join(params))
+    return False, '%s = %s(%s)' % (targetvar, funcname, ', '.join(params))
 
 def optimize_filesize(filename):
     f = open(filename, "r")

Modified: pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py	(original)
+++ pypy/dist/pypy/translator/js/test/test_merge_if_blocks.py	Sat Jan 21 10:07:32 2006
@@ -15,19 +15,17 @@
         assert simple(i) == merge_if_blocks_simple(i)
 
 def test_merge_if_blocks_basic():
-    py.test.skip("merge_if_block failing because link exit values are not used")
     def merge_if_blocks_basic(i):
         if i == 5:
             return 1005
         elif i == 8:
             return 1008
         return 2222
-    basic  = compile_function(merge_if_blocks_basic , [int], view=True)
+    basic  = compile_function(merge_if_blocks_basic , [int])
     for i in range(-20,20):
         assert basic(i) == merge_if_blocks_basic(i)
 
 def test_merge_if_blocks_chr():
-    py.test.skip("merge_if_block failing because link exit values are not used")
     def merge_if_blocks_chr(i):
         c = chr(i)
         if c == '\x05':
@@ -40,7 +38,6 @@
         assert basic(i) == merge_if_blocks_chr(i)
 
 def test_merge_if_blocks_uni():
-    py.test.skip("merge_if_block failing because link exit values are not used")
     def merge_if_blocks_uni(i):
         c = unichr(i)
         if c == u'\x05':
@@ -54,7 +51,6 @@
 
 
 def test_merge_if_blocks_many():
-    py.test.skip("merge_if_block failing because link exit values are not used")
     def merge_if_blocks_many(i):
         if i == 0:
             return 1000 

Modified: pypy/dist/pypy/translator/js/test/test_stackless.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/test_stackless.py	(original)
+++ pypy/dist/pypy/translator/js/test/test_stackless.py	Sat Jan 21 10:07:32 2006
@@ -68,8 +68,6 @@
     assert data.strip() == '100'
 
 def test_stackless_arguments():
-    py.test.skip("stackless feature incomplete (empty Object mallocs)")
-
     def f(n, d, t):
         if n > 0:
             res = f(n-1, d, t)



More information about the Pypy-commit mailing list