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

ericvrp at codespeak.net ericvrp at codespeak.net
Fri Oct 7 12:07:59 CEST 2005


Author: ericvrp
Date: Fri Oct  7 12:07:58 2005
New Revision: 18256

Added:
   pypy/dist/pypy/translator/js/test/test_runtest.py
      - copied, changed from r18227, pypy/dist/pypy/translator/js/test/test_trivial.py
Removed:
   pypy/dist/pypy/translator/js/test/test_trivial.py
Modified:
   pypy/dist/pypy/translator/js/codewriter.py
   pypy/dist/pypy/translator/js/exception.py
   pypy/dist/pypy/translator/js/gc.py
   pypy/dist/pypy/translator/js/js.py
   pypy/dist/pypy/translator/js/log.py
   pypy/dist/pypy/translator/js/test/runtest.py
Log:
Lots of changes
All 'old' code is still put in the js code for documentation purposes.



Modified: pypy/dist/pypy/translator/js/codewriter.py
==============================================================================
--- pypy/dist/pypy/translator/js/codewriter.py	(original)
+++ pypy/dist/pypy/translator/js/codewriter.py	Fri Oct  7 12:07:58 2005
@@ -18,7 +18,7 @@
         self.f.write(line + '\n')
 
     def comment(self, line, indent=True):
-        line = ";; " + line
+        line = "// " + line
         if indent:
             self.indent(line)
         else:
@@ -32,60 +32,55 @@
 
     def label(self, name):
         self.newline()
-        self.append("    %s:" % name)
+        self.append("// QQQ    %s:" % name)
 
     def globalinstance(self, name, typeandata):
-        self.append("%s = %s global %s" % (name, "internal", typeandata))
+        self.append("// QQQ %s = %s global %s" % (name, "internal", typeandata))
 
     def structdef(self, name, typereprs):
-        self.append("%s = type { %s }" %(name, ", ".join(typereprs)))
+        self.append("// QQQ %s = type { %s }" %(name, ", ".join(typereprs)))
 
     def arraydef(self, name, lentype, typerepr):
-        self.append("%s = type { %s, [0 x %s] }" % (name, lentype, typerepr))
+        self.append("// QQQ %s = type { %s, [0 x %s] }" % (name, lentype, typerepr))
 
     def funcdef(self, name, rettyperepr, argtypereprs):
-        self.append("%s = type %s (%s)" % (name, rettyperepr,
+        self.append("// QQQ %s = type %s (%s)" % (name, rettyperepr,
                                            ", ".join(argtypereprs)))
 
     def declare(self, decl, cconv=DEFAULT_CCONV):
-        self.append("declare %s %s" %(cconv, decl,))
+        self.append("// QQQ declare %s %s" %(cconv, decl,))
 
     def startimpl(self):
         self.newline()
-        self.append("implementation")
+        self.append("// QQQ implementation")
         self.newline()
 
     def br_uncond(self, blockname): 
-        self.indent("br label %%%s" %(blockname,))
+        self.indent("// QQQ br label %%%s" %(blockname,))
 
     def br(self, cond, blockname_false, blockname_true):
-        self.indent("br bool %s, label %%%s, label %%%s"
+        self.indent("// QQQ br bool %s, label %%%s, label %%%s"
                     % (cond, blockname_true, blockname_false))
 
     def switch(self, intty, cond, defaultdest, value_label):
         labels = ''
         for value, label in value_label:
             labels += ' %s %s, label %%%s' % (intty, value, label)
-        self.indent("switch %s %s, label %%%s [%s ]"
+        self.indent("// QQQ switch %s %s, label %%%s [%s ]"
                     % (intty, cond, defaultdest, labels))
 
     def openfunc(self, decl, is_entrynode=False, cconv=DEFAULT_CCONV): 
         self.newline()
-        #if is_entrynode:
-        #    linkage_type = ''
-        #else:
-        #    linkage_type = 'internal '
-        linkage_type = 'internal '
-        self.append("%s%s %s {" % (linkage_type, cconv, decl,))
+        self.append("%s {" % decl)
 
     def closefunc(self): 
         self.append("}") 
 
     def ret(self, type_, ref): 
-        if type_ == 'void':
-            self.indent("ret void")
+        if type_ == '// QQQ void':
+            self.indent("// QQQ ret void")
         else:
-            self.indent("ret %s %s" % (type_, ref))
+            self.indent("// QQQ ret %s %s" % (type_, ref))
 
     def phi(self, targetvar, type_, refs, blocknames): 
         assert targetvar.startswith('%')
@@ -94,19 +89,14 @@
             ["[%s, %%%s]" % item 
                 for item in zip(refs, blocknames)])
         s = "%s = phi %s %s" % (targetvar, type_, mergelist)
-        self.indent(s)
+        self.indent('// QQQ ' + s)
 
     def binaryop(self, name, targetvar, type_, ref1, ref2):
-        self.indent("%s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2))
+        self.indent("// QQQ %s = %s %s %s, %s" % (targetvar, name, type_, ref1, ref2))
 
     def shiftop(self, name, targetvar, type_, ref1, ref2):
-        self.indent("%s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2))
+        self.indent("// QQQ %s = %s %s %s, ubyte %s" % (targetvar, name, type_, ref1, ref2))
 
-    #from: http://llvm.cs.uiuc.edu/docs/LangRef.html
-    #The optional "tail" marker indicates whether the callee function accesses any
-    # allocas or varargs in the caller. If the "tail" marker is present, the function
-    # call is eligible for tail call optimization. Note that calls may be marked
-    # "tail" even if they do not occur before a ret instruction. 
     def call(self, targetvar, returntype, functionref, argrefs, argtypes, label=None, except_label=None, tail=DEFAULT_TAIL, cconv=DEFAULT_CCONV):
         if cconv is not 'fastcc':
             tail_ = ''
@@ -119,31 +109,31 @@
             self.genllvm.exceptionpolicy.invoke(self, targetvar, tail_, cconv, returntype, functionref, args, label, except_label)
         else:
             if returntype == 'void':
-                self.indent("%scall %s void %s(%s)" % (tail_, cconv, functionref, args))
+                self.indent("// QQQ call void %s(%s)" % (functionref, args))
             else:
-                self.indent("%s = %scall %s %s %s(%s)" % (targetvar, tail_, cconv, returntype, functionref, args))
+                self.indent("// QQQ %s = call %s %s(%s)" % (targetvar, returntype, functionref, args))
 
     def cast(self, targetvar, fromtype, fromvar, targettype):
     	if fromtype == 'void' and targettype == 'void':
 		return
-        self.indent("%(targetvar)s = cast %(fromtype)s "
+        self.indent("// QQQ %(targetvar)s = cast %(fromtype)s "
                         "%(fromvar)s to %(targettype)s" % locals())
 
     def malloc(self, targetvar, type_, size=1, atomic=False, cconv=DEFAULT_CCONV):
         for s in self.genllvm.gcpolicy.malloc(targetvar, type_, size, atomic, self.word, self.uword).split('\n'):
-            self.indent(s)
+            self.indent('// QQQ ' + s)
 
     def getelementptr(self, targetvar, type, typevar, *indices):
         word = self.word
         res = "%(targetvar)s = getelementptr %(type)s %(typevar)s, %(word)s 0, " % locals()
         res += ", ".join(["%s %s" % (t, i) for t, i in indices])
-        self.indent(res)
+        self.indent('// QQQ ' + res)
 
     def load(self, targetvar, targettype, ptr):
-        self.indent("%(targetvar)s = load %(targettype)s* %(ptr)s" % locals())
+        self.indent("// QQQ %(targetvar)s = load %(targettype)s* %(ptr)s" % locals())
 
     def store(self, valuetype, valuevar, ptr): 
-        self.indent("store %(valuetype)s %(valuevar)s, "
+        self.indent("// QQQ store %(valuetype)s %(valuevar)s, "
                     "%(valuetype)s* %(ptr)s" % locals())
 
     def debugcomment(self, tempname, len, tmpname):
@@ -151,4 +141,4 @@
         res = "%s = call ccc %(word)s (sbyte*, ...)* %%printf(" % locals()
         res += "sbyte* getelementptr ([%s x sbyte]* %s, %(word)s 0, %(word)s 0) )" % locals()
         res = res % (tmpname, len, tmpname)
-        self.indent(res)
+        self.indent('// QQQ ' + res)

Modified: pypy/dist/pypy/translator/js/exception.py
==============================================================================
--- pypy/dist/pypy/translator/js/exception.py	(original)
+++ pypy/dist/pypy/translator/js/exception.py	Fri Oct  7 12:07:58 2005
@@ -49,13 +49,13 @@
         return noresult
 
     def new(exceptionpolicy=None):  #factory
-        exceptionpolicy = exceptionpolicy or 'fast'
-        if exceptionpolicy == 'cpython':
-            from pypy.translator.llvm.exception import CPythonExceptionPolicy
-            exceptionpolicy = CPythonExceptionPolicy()
-        elif exceptionpolicy == 'fast':
-            from pypy.translator.llvm.exception import FastExceptionPolicy
-            exceptionpolicy = FastExceptionPolicy()
+        exceptionpolicy = exceptionpolicy or 'explicit'
+        if exceptionpolicy == 'invokeunwind':
+            from pypy.translator.llvm.exception import InvokeUnwindExceptionPolicy
+            exceptionpolicy = InvokeUnwindExceptionPolicy()
+        elif exceptionpolicy == 'explicit':
+            from pypy.translator.llvm.exception import ExplicitExceptionPolicy
+            exceptionpolicy = ExplicitExceptionPolicy()
         elif exceptionpolicy == 'none':
             from pypy.translator.llvm.exception import NoneExceptionPolicy
             exceptionpolicy = NoneExceptionPolicy()
@@ -70,7 +70,7 @@
         pass
 
 
-class CPythonExceptionPolicy(ExceptionPolicy):  #uses issubclass() and llvm invoke&unwind
+class InvokeUnwindExceptionPolicy(ExceptionPolicy):  #uses issubclass() and llvm invoke&unwind
     def __init__(self):
         pass
 
@@ -160,7 +160,7 @@
         return '-enable-correct-eh-support'
 
 
-class FastExceptionPolicy(ExceptionPolicy):    #uses issubclass() and last_exception tests after each call
+class ExplicitExceptionPolicy(ExceptionPolicy):    #uses issubclass() and last_exception tests after each call
     def __init__(self):
         self.invoke_count = 0
 
@@ -205,7 +205,8 @@
 
     def invoke(self, codewriter, targetvar, tail_, cconv, returntype, functionref, args, label, except_label):
         if returntype == 'void':
-            codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args))
+            if functionref != '%keepalive': #XXX I think keepalive should not be the last operation here!
+                codewriter.indent('%scall %s void %s(%s)' % (tail_, cconv, functionref, args))
         else:
             codewriter.indent('%s = %scall %s %s %s(%s)' % (targetvar, tail_, cconv, returntype, functionref, args))
         tmp = '%%invoke.tmp.%d' % self.invoke_count

Modified: pypy/dist/pypy/translator/js/gc.py
==============================================================================
--- pypy/dist/pypy/translator/js/gc.py	(original)
+++ pypy/dist/pypy/translator/js/gc.py	Fri Oct  7 12:07:58 2005
@@ -1,8 +1,5 @@
-import py
-from pypy.tool.ansi_print import ansi_log
-log = py.log.Producer("llvm")
-log.setconsumer("llvm", ansi_log)
-
+from pypy.translator.js.log import log
+log = log.gc
 
 class GcPolicy:
     def __init__(self):
@@ -27,7 +24,7 @@
         from os.path import exists
         boehm_on_path = exists('/usr/lib/libgc.so') or exists('/usr/lib/libgc.a')
         if gcpolicy == 'boehm' and not boehm_on_path:
-            log.gc.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc')
+            log.WARNING('warning: Boehm GC libary not found in /usr/lib, falling back on no gc')
             gcpolicy = 'none'
 
         if gcpolicy == 'boehm':

Modified: pypy/dist/pypy/translator/js/js.py
==============================================================================
--- pypy/dist/pypy/translator/js/js.py	(original)
+++ pypy/dist/pypy/translator/js/js.py	Fri Oct  7 12:07:58 2005
@@ -13,32 +13,20 @@
 
 import py
 
-#from pypy.translator.llvm import build_llvm_module
 from pypy.translator.llvm.database import Database 
-#from pypy.translator.llvm.pyxwrapper import write_pyx_wrapper 
 from pypy.rpython.rmodel import inputconst, getfunctionptr
 from pypy.rpython import lltype
 from pypy.tool.udir import udir
-from pypy.translator.llvm.codewriter import CodeWriter
-#from pypy.translator.llvm.codewriter import , DEFAULT_TAIL, DEFAULT_CCONV
-#from pypy.translator.llvm import extfuncnode
-#from pypy.translator.llvm.module.extfunction import extdeclarations, extfunctions, dependencies
-#from pypy.translator.llvm.node import JSNode
-#from pypy.translator.llvm.structnode import StructNode
-#from pypy.translator.llvm.externs2ll import post_setup_externs, generate_llfile
-from pypy.translator.llvm.gc import GcPolicy
-from pypy.translator.llvm.exception import ExceptionPolicy
-#from pypy.translator.translator import Translator
-
+from pypy.translator.js.codewriter import CodeWriter
+from pypy.translator.js.gc import GcPolicy
+from pypy.translator.js.exception import ExceptionPolicy
 from pypy.translator.js.log import log
 
-function_count = {}
-#llexterns_header = llexterns_functions = None
-
 
 class JS(object):   # JS = Javascript
-
-    def __init__(self, translator, func=None, gcpolicy=None, exceptionpolicy=None, debug=False):
+    function_count = {}
+    
+    def __init__(self, translator, function=None, gcpolicy=None, exceptionpolicy=None, debug=False):
         self.db = Database(self, translator)
         self.translator = translator
         self.gcpolicy = GcPolicy.new(gcpolicy)
@@ -48,10 +36,14 @@
         if debug:
             translator.checkgraphs()
 
-        if func is None:
-            func = self.translator.entrypoint
-        self.entrypoint = func
+        if function is None:
+            function= self.translator.entrypoint
+        self.entrypoint = function
 
+        self.filename = self.wrapper_filename = None
+
+    def write_source(self):
+        func = self.entrypoint
         ptr = getfunctionptr(self.translator, func)
         c = inputconst(lltype.typeOf(ptr), ptr)
         entry_point = c.value._obj
@@ -78,14 +70,14 @@
         #    llexterns_header, llexterns_functions = generate_llfile(self.db, extern_decls, support_functions, self.debug)
  
         # prevent running the same function twice in a test
-        if func.func_name in function_count:
-            postfix = '_%d' % function_count[func.func_name]
-            function_count[func.func_name] += 1
+        if func.func_name in self.function_count:
+            postfix = '_%d' % self.function_count[func.func_name]
+            self.function_count[func.func_name] += 1
         else:
             postfix = ''
-            function_count[func.func_name] = 1
-        filename = udir.join(func.func_name + postfix).new(ext='.js')
-        f = open(str(filename),'w')
+            self.function_count[func.func_name] = 1
+        self.filename = udir.join(func.func_name + postfix).new(ext='.js')
+        f = open(str(self.filename),'w')
         codewriter = CodeWriter(f, self)
         comment = codewriter.comment
         nl = codewriter.newline
@@ -148,5 +140,13 @@
         #    nl(); comment("External Function Implementation") ; nl()
         #    codewriter.append(llexterns_functions)
 
+        comment("Wrapper code for the Javascript CLI") ; nl()
+        graph        = self.db.entrynode.graph
+        startblock  = graph.startblock
+        args        = ','.join(['arguments[%d]' % i for i,v in enumerate(startblock.inputargs)])
+        wrappercode = 'pypy_%s(%s);\n' % (graph.name, args)
+        codewriter.indent(wrappercode)
+
         comment("End of file") ; nl()
-        self.filename = filename
+        log('Written:', self.filename)
+        return self.filename

Modified: pypy/dist/pypy/translator/js/log.py
==============================================================================
--- pypy/dist/pypy/translator/js/log.py	(original)
+++ pypy/dist/pypy/translator/js/log.py	Fri Oct  7 12:07:58 2005
@@ -1,4 +1,4 @@
 import py
 from pypy.tool.ansi_print import ansi_log
 log = py.log.Producer("js")
-log.setconsumer("js", ansi_log)
+py.log.setconsumer("js", ansi_log)

Modified: pypy/dist/pypy/translator/js/test/runtest.py
==============================================================================
--- pypy/dist/pypy/translator/js/test/runtest.py	(original)
+++ pypy/dist/pypy/translator/js/test/runtest.py	Fri Oct  7 12:07:58 2005
@@ -12,38 +12,26 @@
         return False
     return True
 
-def write_wrapper(js_filename):
-    jswrapper_filename = js_filename.new(ext='_wrapper.js')
-    f = open(str(jswrapper_filename), 'w')
-    f.write('print(42);\n')
-    f.close()
-    log('Written:', jswrapper_filename)
-    return jswrapper_filename
+class compile_function(object):
+    def __init__(self, function, annotation, view=False):
+        if not _CLI_is_on_path():
+            py.test.skip('Javascript CLI (js) not found')
 
-class jscallable(object):
-    def __init__(self, jswrapper_filename):
-        self.jswrapper_filename = jswrapper_filename
-        
-    def __call__(self):
-        cmd = 'js "%s"' % str(self.jswrapper_filename)
-        s   = os.popen(cmd).read()
-        e   = eval(s)
-        return e
-    
-def compile(function, annotation=[], view=False):
-    if not _CLI_is_on_path():
-        py.test.skip('Javascript CLI (js) not found')
-
-    t = Translator(function)
-    a = t.annotate(annotation)
-    a.simplify()
-    t.specialize()
-    t.backend_optimizations()
-    if view:
-        t.view()
+        t = Translator(function)
+        a = t.annotate(annotation)
+        a.simplify()
+        t.specialize()
+        t.backend_optimizations()
+        if view:
+            t.view()
+        self.js = JS(t, function)
+        self.js.write_source()
 
-    js = JS(t, function)
-    log('Written:', js.filename)
-
-    jswrapper_filename = write_wrapper(js.filename)
-    return jscallable(jswrapper_filename)
+    def __call__(self, *kwds):
+        #note: lowercase string for (py)False->(js)false, etc.
+        args = ' '.join([str(kw).lower() for kw in kwds])
+        cmd = 'js %s %s' % (self.js.filename, args)
+        log(cmd)
+        s   = os.popen(cmd).read()
+        res = eval(s)
+        return res



More information about the Pypy-commit mailing list