[pypy-svn] r52156 - in pypy/branch/asmgcc-exceptions/pypy/translator: . c c/src goal

arigo at codespeak.net arigo at codespeak.net
Tue Mar 4 18:01:58 CET 2008


Author: arigo
Date: Tue Mar  4 18:01:57 2008
New Revision: 52156

Modified:
   pypy/branch/asmgcc-exceptions/pypy/translator/c/extfunc.py
   pypy/branch/asmgcc-exceptions/pypy/translator/c/src/exception.h
   pypy/branch/asmgcc-exceptions/pypy/translator/c/src/main.h
   pypy/branch/asmgcc-exceptions/pypy/translator/exceptiontransform.py
   pypy/branch/asmgcc-exceptions/pypy/translator/goal/targetnopstandalone.py
Log:
Hack hack hack, 100% unclean.

This version gives a slow-down with the framework GCs
because of all the int_add_ovf and int_mul_ovf which
need to set up an exception catching block.


Modified: pypy/branch/asmgcc-exceptions/pypy/translator/c/extfunc.py
==============================================================================
--- pypy/branch/asmgcc-exceptions/pypy/translator/c/extfunc.py	(original)
+++ pypy/branch/asmgcc-exceptions/pypy/translator/c/extfunc.py	Tue Mar  4 18:01:57 2008
@@ -109,12 +109,6 @@
     if not db.standalone:
         yield ('RPYTHON_PYEXCCLASS2EXC', exceptiondata.fn_pyexcclass2exc)
 
-    yield ('RPyExceptionOccurred1',    exctransformer.rpyexc_occured_ptr.value)
-    yield ('RPyFetchExceptionType',    exctransformer.rpyexc_fetch_type_ptr.value)
-    yield ('RPyFetchExceptionValue',   exctransformer.rpyexc_fetch_value_ptr.value)
-    yield ('RPyClearException',        exctransformer.rpyexc_clear_ptr.value)
-    yield ('RPyRaiseException',        exctransformer.rpyexc_raise_ptr.value)
-
     for pyexccls in exceptiondata.standardexceptions:
         exc_llvalue = exceptiondata.fn_pyexcclass2exc(
             lltype.pyobjectptr(pyexccls))

Modified: pypy/branch/asmgcc-exceptions/pypy/translator/c/src/exception.h
==============================================================================
--- pypy/branch/asmgcc-exceptions/pypy/translator/c/src/exception.h	(original)
+++ pypy/branch/asmgcc-exceptions/pypy/translator/c/src/exception.h	Tue Mar  4 18:01:57 2008
@@ -7,9 +7,9 @@
 #endif 
 
 /* just a renaming, unless DO_LOG_EXC is set */
-#define RPyExceptionOccurred RPyExceptionOccurred1
 #define RPY_DEBUG_RETURN()   /* nothing */
 
+
 #ifndef PyExceptionClass_Check    /* Python < 2.5 */
 # define PyExceptionClass_Check(x)	PyClass_Check(x)
 # define PyExceptionInstance_Check(x)	PyInstance_Check(x)
@@ -22,6 +22,63 @@
 #ifdef HAVE_RTYPER               /* RPython version of exceptions */
 /******************************************************************/
 
+
+#define OP_RPYEXC_TRY(tag, result_evalue)                               \
+  ;                                                                     \
+  struct rpyjmpbuf_s rpyjmpbuf##tag;                                    \
+  rpyjmpbuf##tag.prev = rpyjmp_head;                                    \
+  rpyjmp_head = &rpyjmpbuf##tag;                                        \
+  asm volatile("xorl	%%ebx, %%ebx\n\
+	movl	%%esp, %1\n\
+	movl	%%ebp, %2\n\
+	movl	$0f, %3\n\
+0:" :                                                                   \
+               "=b"(result_evalue) :                                    \
+               "m"(rpyjmpbuf##tag.esp),                                 \
+               "m"(rpyjmpbuf##tag.ebp),                                 \
+               "m"(rpyjmpbuf##tag.resumeaddr) :                         \
+               "eax", "edx", "ecx", "esi", "edi", "memory", "cc")
+
+#define OP_RPYEXC_ENDTRY(tag, r)  rpyjmp_head = rpyjmpbuf##tag.prev
+
+#define OP_RPYEXC_RAISE(evalue, r)       rpyexc_raise(evalue, __FUNCTION__)
+#define RPyRaiseException(etype, evalue) rpyexc_raise(evalue, __FUNCTION__)
+
+struct rpyjmpbuf_s {
+  struct rpyjmpbuf_s* prev;
+  void* esp;
+  void* ebp;
+  void* resumeaddr;
+};
+
+extern struct rpyjmpbuf_s *rpyjmp_head;
+void rpyexc_raise(RPYTHON_EXCEPTION evalue, const char* funcname)
+     __attribute__ ((noreturn));
+
+#ifndef PYPY_NOT_MAIN_FILE
+struct rpyjmpbuf_s *rpyjmp_head = NULL;
+void rpyexc_raise(RPYTHON_EXCEPTION evalue, const char *funcname)
+{
+  if (rpyjmp_head == NULL)
+    {
+      fprintf(stderr, "Fatal RPython error in %s: %s\n",
+              funcname, RPYTHON_TYPE_OF_EXC_INST(evalue)->ov_name->items);
+      exit(1);
+    }
+  asm volatile("movl	%0, %%esp\n\
+	movl	%1, %%ebp\n\
+	jmp	*%2" : :
+               "g"(rpyjmp_head->esp),
+               "g"(rpyjmp_head->ebp),
+               "g"(rpyjmp_head->resumeaddr),
+               "b"(evalue));
+  abort();
+}
+#endif
+
+
+
+
 #ifdef DO_LOG_EXC
 #undef RPyExceptionOccurred
 #undef RPY_DEBUG_RETURN

Modified: pypy/branch/asmgcc-exceptions/pypy/translator/c/src/main.h
==============================================================================
--- pypy/branch/asmgcc-exceptions/pypy/translator/c/src/main.h	(original)
+++ pypy/branch/asmgcc-exceptions/pypy/translator/c/src/main.h	Tue Mar  4 18:01:57 2008
@@ -27,22 +27,14 @@
     if (errmsg) goto error;
 
     list = _RPyListOfString_New(argc);
-    if (RPyExceptionOccurred()) goto memory_out;
+    //if (RPyExceptionOccurred()) goto memory_out;
     for (i=0; i<argc; i++) {
         RPyString *s = RPyString_FromString(argv[i]);
-        if (RPyExceptionOccurred()) goto memory_out;
+        //if (RPyExceptionOccurred()) goto memory_out;
         _RPyListOfString_SetItem(list, i, s);
     }
 
     exitcode = STANDALONE_ENTRY_POINT(list);
-    if (RPyExceptionOccurred()) {
-        /* fish for the exception type, at least */
-#ifndef AVR
-        fprintf(stderr, "Fatal RPython error: %s\n",
-                RPyFetchExceptionType()->ov_name->items);
-#endif
-        exitcode = 1;
-    }
     return exitcode;
 
  memory_out:

Modified: pypy/branch/asmgcc-exceptions/pypy/translator/exceptiontransform.py
==============================================================================
--- pypy/branch/asmgcc-exceptions/pypy/translator/exceptiontransform.py	(original)
+++ pypy/branch/asmgcc-exceptions/pypy/translator/exceptiontransform.py	Tue Mar  4 18:01:57 2008
@@ -52,89 +52,12 @@
         edata = translator.rtyper.getexceptiondata()
         self.lltype_of_exception_value = edata.lltype_of_exception_value
         self.lltype_of_exception_type = edata.lltype_of_exception_type
-        self.mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
-        exc_data, null_type, null_value = self.setup_excdata()
+        self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
 
-        rclass = translator.rtyper.type_system.rclass
         runtime_error_def = translator.annotator.bookkeeper.getuniqueclassdef(RuntimeError)
         runtime_error_ll_exc = edata.get_standard_ll_exc_instance(translator.rtyper, runtime_error_def)
-        runtime_error_ll_exc_type = rclass.ll_inst_type(runtime_error_ll_exc)
-
-        def rpyexc_occured():
-            exc_type = exc_data.exc_type
-            return bool(exc_type)
-
-        def rpyexc_fetch_type():
-            return exc_data.exc_type
-
-        def rpyexc_fetch_value():
-            return exc_data.exc_value
-
-        def rpyexc_clear():
-            exc_data.exc_type = null_type
-            exc_data.exc_value = null_value
-
-        def rpyexc_raise(etype, evalue):
-            # assert(!RPyExceptionOccurred());
-            exc_data.exc_type = etype
-            exc_data.exc_value = evalue
-
-        def rpyexc_fetch_exception():
-            evalue = rpyexc_fetch_value()
-            rpyexc_clear()
-            return evalue
-        
-        def rpyexc_restore_exception(evalue):
-            if evalue:
-                rpyexc_raise(rclass.ll_inst_type(evalue), evalue)
-
-        def rpyexc_raise_runtime_error():
-            rpyexc_raise(runtime_error_ll_exc_type, runtime_error_ll_exc)
-
-        self.rpyexc_occured_ptr = self.build_func(
-            "RPyExceptionOccurred",
-            rpyexc_occured,
-            [], lltype.Bool)
-
-        self.rpyexc_fetch_type_ptr = self.build_func(
-            "RPyFetchExceptionType",
-            rpyexc_fetch_type,
-            [], self.lltype_of_exception_type)
-
-        self.rpyexc_fetch_value_ptr = self.build_func(
-            "RPyFetchExceptionValue",
-            rpyexc_fetch_value,
-            [], self.lltype_of_exception_value)
-
-        self.rpyexc_clear_ptr = self.build_func(
-            "RPyClearException",
-            rpyexc_clear,
-            [], lltype.Void)
-
-        self.rpyexc_raise_ptr = self.build_func(
-            "RPyRaiseException",
-            rpyexc_raise,
-            [self.lltype_of_exception_type, self.lltype_of_exception_value],
-            lltype.Void,
-            jitcallkind='rpyexc_raise') # for the JIT
-
-        self.rpyexc_raise_runtime_error_ptr = self.build_func(
-            "RPyRaiseRuntimeError",
-            rpyexc_raise_runtime_error,
-            [], lltype.Void)
-
-        self.rpyexc_fetch_exception_ptr = self.build_func(
-            "RPyFetchException",
-            rpyexc_fetch_exception,
-            [], self.lltype_of_exception_value)
-
-        self.rpyexc_restore_exception_ptr = self.build_func(
-            "RPyRestoreException",
-            rpyexc_restore_exception,
-            [self.lltype_of_exception_value], lltype.Void)
-
-        self.mixlevelannotator.finish()
-        self.lltype_to_classdef = translator.rtyper.lltype_to_classdef_mapping()
+        self.c_runtime_error = (
+            Constant(runtime_error_ll_exc, self.lltype_of_exception_value))
 
     def build_func(self, name, fn, inputtypes, rettype, **kwds):
         l2a = annmodel.lltype_to_annotation
@@ -159,7 +82,7 @@
             return
         else:
             self.raise_analyzer.analyze_direct_call(graph)
-            graph.exceptiontransformed = self.exc_data_ptr
+            graph.exceptiontransformed = True
 
         self.always_exc_clear = always_exc_clear
         join_blocks(graph)
@@ -184,8 +107,8 @@
                 # the graph was not stackless-transformed
                 # so we need to raise a RuntimeError in any
                 # case
-                block.operations[i].opname = "direct_call"
-                block.operations[i].args = [self.rpyexc_raise_runtime_error_ptr]
+                block.operations[i].opname = "rpyexc_raise"
+                block.operations[i].args = [self.c_runtime_error]
 
     def replace_fetch_restore_operations(self, block):
         # the gctransformer will create these operations.  It looks as if the
@@ -193,12 +116,9 @@
         # put them in a new graph, so all transformations will run again.
         for i in range(len(block.operations)):
             if block.operations[i].opname == 'gc_fetch_exception':
-                block.operations[i].opname = "direct_call"
-                block.operations[i].args = [self.rpyexc_fetch_exception_ptr]
-
+                XXX
             if block.operations[i].opname == 'gc_restore_exception':
-                block.operations[i].opname = "direct_call"
-                block.operations[i].args.insert(0, self.rpyexc_restore_exception_ptr)
+                XXX
 
     def transform_block(self, graph, block):
         need_exc_matching = False
@@ -223,13 +143,13 @@
             if not self.raise_analyzer.can_raise(op):
                 continue
 
-            splitlink = split_block(None, block, i+1)
-            afterblock = splitlink.target
-            if lastblock is block:
-                lastblock = afterblock
-
-            self.gen_exc_check(block, graph.returnblock, afterblock)
-            n_gen_exc_checks += 1
+            #splitlink = split_block(None, block, i+1)
+            #afterblock = splitlink.target
+            #if lastblock is block:
+            #    lastblock = afterblock
+            #
+            #self.gen_exc_check(block, graph.returnblock, afterblock)
+            #n_gen_exc_checks += 1
         if need_exc_matching:
             assert lastblock.exitswitch == c_last_exception
             if not self.raise_analyzer.can_raise(lastblock.operations[-1]):
@@ -253,7 +173,7 @@
         result = Variable()
         result.concretetype = lltype.Void
         block.operations = [SpaceOperation(
-           "direct_call", [self.rpyexc_raise_ptr] + block.inputargs, result)]
+           "rpyexc_raise", [block.inputargs[1]], result)]
         l = Link([error_constant(graph.returnblock.inputargs[0].concretetype)], graph.returnblock)
         block.recloseblock(l)
 
@@ -270,6 +190,8 @@
         inliner.inline_once(block, len(block.operations)-1)
         #block.exits[0].exitcase = block.exits[0].llexitcase = False
 
+    try_counter = 0
+
     def create_proxy_graph(self, op):
         """ creates a graph which calls the original function, checks for
         raised exceptions, fetches and then raises them again. If this graph is
@@ -279,6 +201,7 @@
         result = copyvar(None, op.result)
         opargs = []
         inputargs = []
+        noexcinputargs = []
         callargs = []
         ARGTYPES = []
         for var in op.args:
@@ -286,35 +209,62 @@
                 v = Variable()
                 v.concretetype = var.concretetype
                 inputargs.append(v)
-                opargs.append(v)
+                v2 = Variable()
+                v2.concretetype = var.concretetype
+                noexcinputargs.append(v2)
+                opargs.append(v2)
                 callargs.append(var)
                 ARGTYPES.append(var.concretetype)
             else:
                 opargs.append(var)
-        newop = SpaceOperation(op.opname, opargs, result)
+
+        c_tag = Constant(self.try_counter, lltype.Signed)
+        self.try_counter += 1
+
+        llops = rtyper.LowLevelOpList(None)
+        v_excvalue = llops.genop('rpyexc_try', [c_tag],
+                                 resulttype = self.lltype_of_exception_value)
+        v_isnull = llops.genop('ptr_iszero', [v_excvalue],
+                               resulttype = lltype.Bool)
+        var_value = copyvar(None, v_excvalue)
+
         startblock = Block(inputargs)
-        startblock.operations.append(newop) 
+        startblock.operations[:] = llops
+        startblock.exitswitch = v_isnull
+
+        noexcblock = Block(noexcinputargs)
+        excblock = Block([var_value])
+
+        noexclink = Link(list(inputargs), noexcblock)
+        exclink = Link([v_excvalue], excblock)
+
+        noexclink.llexitcase = noexclink.exitcase = True
+        exclink  .llexitcase = exclink  .exitcase = False
+
         newgraph = FunctionGraph("dummy_exc1", startblock)
-        startblock.closeblock(Link([result], newgraph.returnblock))
+        startblock.closeblock(exclink, noexclink)
         newgraph.returnblock.inputargs[0].concretetype = op.result.concretetype
-        self.gen_exc_check(startblock, newgraph.returnblock)
-        excblock = Block([])
+
+        newop = SpaceOperation(op.opname, opargs, result)
+        noexcblock.operations.append(newop)
+        llops = rtyper.LowLevelOpList(None)
+        llops.genop('rpyexc_endtry', [c_tag])
+        noexcblock.operations.extend(llops)
+        noexcblock.closeblock(Link([result], newgraph.returnblock))
 
         llops = rtyper.LowLevelOpList(None)
-        var_value = self.gen_getfield('exc_value', llops)
-        var_type  = self.gen_getfield('exc_type' , llops)
-        self.gen_setfield('exc_value', self.c_null_evalue, llops)
-        self.gen_setfield('exc_type',  self.c_null_etype,  llops)
+        c_typeptr = Constant("typeptr", lltype.Void)
+        var_type = llops.genop("getfield", [var_value, c_typeptr],
+                               resulttype = self.lltype_of_exception_type)
         excblock.operations[:] = llops
         newgraph.exceptblock.inputargs[0].concretetype = self.lltype_of_exception_type
         newgraph.exceptblock.inputargs[1].concretetype = self.lltype_of_exception_value
         excblock.closeblock(Link([var_type, var_value], newgraph.exceptblock))
-        startblock.exits[True].target = excblock
-        startblock.exits[True].args = []
         fptr = self.constant_func("dummy_exc1", ARGTYPES, op.result.concretetype, newgraph)
         return newgraph, SpaceOperation("direct_call", [fptr] + callargs, op.result) 
 
     def gen_exc_check(self, block, returnblock, normalafterblock=None):
+        XXX
         #var_exc_occured = Variable()
         #var_exc_occured.concretetype = lltype.Bool
         #block.operations.append(SpaceOperation("safe_call", [self.rpyexc_occured_ptr], var_exc_occured))
@@ -379,37 +329,11 @@
 
 class LLTypeExceptionTransformer(BaseExceptionTransformer):
 
-    def setup_excdata(self):
-        EXCDATA = lltype.Struct('ExcData',
-            ('exc_type',  self.lltype_of_exception_type),
-            ('exc_value', self.lltype_of_exception_value))
-        self.EXCDATA = EXCDATA
-
-        exc_data = lltype.malloc(EXCDATA, immortal=True)
-        null_type = lltype.nullptr(self.lltype_of_exception_type.TO)
-        null_value = lltype.nullptr(self.lltype_of_exception_value.TO)
-
-        self.exc_data_ptr = exc_data
-        self.cexcdata = Constant(exc_data, lltype.Ptr(self.EXCDATA))
-        self.c_null_etype = Constant(null_type, self.lltype_of_exception_type)
-        self.c_null_evalue = Constant(null_value, self.lltype_of_exception_value)
-
-        return exc_data, null_type, null_value
-
     def constant_func(self, name, inputtypes, rettype, graph, **kwds):
         FUNC_TYPE = lltype.FuncType(inputtypes, rettype)
         fn_ptr = lltype.functionptr(FUNC_TYPE, name, graph=graph, **kwds)
         return Constant(fn_ptr, lltype.Ptr(FUNC_TYPE))
 
-    def gen_getfield(self, name, llops):
-        c_name = inputconst(lltype.Void, name)
-        return llops.genop('getfield', [self.cexcdata, c_name],
-                           resulttype = getattr(self.EXCDATA, name))
-
-    def gen_setfield(self, name, v_value, llops):
-        c_name = inputconst(lltype.Void, name)
-        llops.genop('setfield', [self.cexcdata, c_name, v_value])
-
     def gen_isnull(self, v, llops):
         return llops.genop('ptr_iszero', [v], lltype.Bool)
 

Modified: pypy/branch/asmgcc-exceptions/pypy/translator/goal/targetnopstandalone.py
==============================================================================
--- pypy/branch/asmgcc-exceptions/pypy/translator/goal/targetnopstandalone.py	(original)
+++ pypy/branch/asmgcc-exceptions/pypy/translator/goal/targetnopstandalone.py	Tue Mar  4 18:01:57 2008
@@ -14,8 +14,18 @@
 
 # __________  Entry point  __________
 
+def foobar(n):
+    if n > 0:
+        return foobar(n-1)+n
+    else:
+        return 0
+
 def entry_point(argv):
-    debug("hello world")
+    try:
+        foobar(5000000)
+    except RuntimeError:
+        debug("bigbig")
+    debug("hello world: %d" % foobar(5))
     return 0
 
 # _____ Define and setup target ___



More information about the Pypy-commit mailing list