Author: Manuel Jacob
Branch: refactor-translator
Changeset: r68769:e22c2e78adfb
Date: 2014-01-19 21:03 +0100
http://bitbucket.org/pypy/pypy/changeset/e22c2e78adfb/
Log: Rewrite main() in RPython. Add enough hacks to make translation of
simple programs work. Remove some code in
rpython/translator/c/extfunc.py that is unnecessary now.
diff --git a/rpython/translator/c/extfunc.py b/rpython/translator/c/extfunc.py
--- a/rpython/translator/c/extfunc.py
+++ b/rpython/translator/c/extfunc.py
@@ -1,4 +1,5 @@
import types
+from rpython.annotator import model as annmodel
from rpython.flowspace.model import FunctionGraph
from rpython.rtyper.lltypesystem import lltype
from rpython.translator.c.support import cdecl
@@ -14,61 +15,9 @@
#______________________________________________________
-def find_list_of_str(rtyper):
- for r in rtyper.reprs.itervalues():
- if isinstance(r, rlist.ListRepr) and r.item_repr is rstr.string_repr:
- return r.lowleveltype.TO
- return None
-
def predeclare_common_types(db, rtyper):
# Common types
yield ('RPyString', STR)
- LIST_OF_STR = find_list_of_str(rtyper)
- if LIST_OF_STR is not None:
- yield ('RPyListOfString', LIST_OF_STR)
-
-def predeclare_utility_functions(db, rtyper):
- # Common utility functions
- def RPyString_New(length=lltype.Signed):
- return mallocstr(length)
-
- # !!!
- # be extremely careful passing a gc tracked object
- # from such an helper result to another one
- # as argument, this could result in leaks
- # Such result should be only from C code
- # returned directly as results
-
- LIST_OF_STR = find_list_of_str(rtyper)
- if LIST_OF_STR is not None:
- p = lltype.Ptr(LIST_OF_STR)
-
- def _RPyListOfString_New(length=lltype.Signed):
- return LIST_OF_STR.ll_newlist(length)
-
- def _RPyListOfString_SetItem(l=p,
- index=lltype.Signed,
- newstring=lltype.Ptr(STR)):
- rlist.ll_setitem_nonneg(rlist.dum_nocheck, l, index, newstring)
-
- def _RPyListOfString_GetItem(l=p,
- index=lltype.Signed):
- return rlist.ll_getitem_fast(l, index)
-
- def _RPyListOfString_Length(l=p):
- return rlist.ll_length(l)
-
- for fname, f in locals().items():
- if isinstance(f, types.FunctionType):
- # XXX this is painful :(
- if (LIST_OF_STR, fname) in db.helper2ptr:
- yield (fname, db.helper2ptr[LIST_OF_STR, fname])
- else:
- # hack: the defaults give the type of the arguments
- graph = rtyper.annotate_helper(f, f.func_defaults)
- db.helper2ptr[LIST_OF_STR, fname] = graph
- yield (fname, graph)
-
def predeclare_extfuncs(db, rtyper):
modules = {}
@@ -106,17 +55,18 @@
for exccls in exceptiondata.standardexceptions:
exc_llvalue = exceptiondata.get_standard_ll_exc_instance_by_class(
exccls)
+
rtyper.getrepr(annmodel.lltype_to_annotation(lltype.typeOf(exc_llvalue)))
# strange naming here because the macro name must be
# a substring of PyExc_%s
name = exccls.__name__
if exccls.__module__ != 'exceptions':
name = '%s_%s' % (exccls.__module__.replace('.', '__'), name)
yield ('RPyExc_%s' % name, exc_llvalue)
+ rtyper.call_all_setups()
def predeclare_all(db, rtyper):
for fn in [predeclare_common_types,
- predeclare_utility_functions,
predeclare_exception_data,
predeclare_extfuncs,
]:
@@ -126,7 +76,6 @@
def get_all(db, rtyper):
for fn in [predeclare_common_types,
- predeclare_utility_functions,
predeclare_exception_data,
predeclare_extfuncs,
]:
diff --git a/rpython/translator/c/genc.py b/rpython/translator/c/genc.py
--- a/rpython/translator/c/genc.py
+++ b/rpython/translator/c/genc.py
@@ -226,7 +226,6 @@
if db is None:
db = self.build_database()
- pf = self.getentrypointptr()
if self.modulename is None:
self.modulename = uniquemodulename('testing')
modulename = self.modulename
@@ -248,16 +247,14 @@
if not self.standalone:
assert not self.config.translation.instrument
else:
- defines['PYPY_STANDALONE'] = db.get(pf)
if self.config.translation.instrument:
defines['PYPY_INSTRUMENT'] = 1
if CBuilder.have___thread:
if not self.config.translation.no__thread:
defines['USE___THREAD'] = 1
if self.config.translation.shared:
- defines['PYPY_MAIN_FUNCTION'] = "pypy_main_startup"
self.eci = self.eci.merge(ExternalCompilationInfo(
- export_symbols=["pypy_main_startup", "pypy_debug_file"]))
+ export_symbols=["rpython_main", "pypy_debug_file"]))
self.eci, cfile, extra = gen_source(db, modulename, targetdir,
self.eci, defines=defines,
split=self.split)
@@ -303,10 +300,11 @@
and profbased[0] is ProfOpt)
def getentrypointptr(self):
- # XXX check that the entrypoint has the correct
- # signature: list-of-strings -> int
- bk = self.translator.annotator.bookkeeper
- return getfunctionptr(bk.getdesc(self.entrypoint).getuniquegraph())
+ from rpython.translator.gensupp import make_main
+ # XXX: only framework for now
+ setup = self.db.gctransformer.frameworkgc_setup_ptr.value
+ graph = make_main(self.translator, setup, self.entrypoint)
+ return getfunctionptr(graph)
def cmdexec(self, args='', env=None, err=False, expect_crash=False):
assert self._compiled
@@ -742,8 +740,8 @@
def add_extra_files(eci):
srcdir = py.path.local(__file__).join('..', 'src')
files = [
- srcdir / 'entrypoint.c', # ifdef PYPY_STANDALONE
- srcdir / 'allocator.c', # ifdef PYPY_STANDALONE
+ srcdir / 'main.c',
+ srcdir / 'allocator.c',
srcdir / 'mem.c',
srcdir / 'exception.c',
srcdir / 'rtyper.c',
diff --git a/rpython/translator/c/src/allocator.c
b/rpython/translator/c/src/allocator.c
--- a/rpython/translator/c/src/allocator.c
+++ b/rpython/translator/c/src/allocator.c
@@ -1,6 +1,5 @@
/* allocation functions */
#include "common_header.h"
-#ifdef PYPY_STANDALONE
#include <stdlib.h>
#if defined(PYPY_USE_TRIVIAL_MALLOC)
@@ -24,5 +23,3 @@
# include "src/obmalloc.c"
#endif
-
-#endif /* PYPY_STANDALONE */
diff --git a/rpython/translator/c/src/entrypoint.c
b/rpython/translator/c/src/entrypoint.c
deleted file mode 100644
--- a/rpython/translator/c/src/entrypoint.c
+++ /dev/null
@@ -1,89 +0,0 @@
-#include "common_header.h"
-#ifdef PYPY_STANDALONE
-#include "structdef.h"
-#include "forwarddecl.h"
-#include "preimpl.h"
-#include <src/entrypoint.h>
-#include <src/commondefs.h>
-#include <src/mem.h>
-#include <src/instrument.h>
-#include <src/rtyper.h>
-#include <src/exception.h>
-#include <src/debug_traceback.h>
-
-#include <stdlib.h>
-#include <stdio.h>
-
-#ifdef __GNUC__
-/* Hack to prevent this function from being inlined. Helps asmgcc
- because the main() function has often a different prologue/epilogue. */
-int pypy_main_function(int argc, char *argv[]) __attribute__((__noinline__));
-#endif
-
-# ifdef PYPY_USE_ASMGCC
-# include "structdef.h"
-# include "forwarddecl.h"
-# endif
-
-int pypy_main_function(int argc, char *argv[])
-{
- char *errmsg;
- int i, exitcode;
- RPyListOfString *list;
-
-#ifdef PYPY_USE_ASMGCC
-
pypy_g_rpython_rtyper_lltypesystem_rffi_StackCounter.sc_inst_stacks_counter++;
-#endif
- pypy_asm_stack_bottom();
-#ifdef PYPY_X86_CHECK_SSE2_DEFINED
- pypy_x86_check_sse2();
-#endif
- instrument_setup();
-
-#ifndef MS_WINDOWS
- /* this message does no longer apply to win64 :-) */
- if (sizeof(void*) != SIZEOF_LONG) {
- errmsg = "only support platforms where sizeof(void*) == sizeof(long),"
- " for now";
- goto error;
- }
-#endif
-
- errmsg = RPython_StartupCode();
- if (errmsg) goto error;
-
- list = _RPyListOfString_New(argc);
- if (RPyExceptionOccurred()) goto memory_out;
- for (i=0; i<argc; i++) {
- RPyString *s = RPyString_FromString(argv[i]);
- if (RPyExceptionOccurred()) goto memory_out;
- _RPyListOfString_SetItem(list, i, s);
- }
-
- exitcode = STANDALONE_ENTRY_POINT(list);
-
- pypy_debug_alloc_results();
-
- if (RPyExceptionOccurred()) {
- /* print the RPython traceback */
- pypy_debug_catch_fatal_exception();
- }
-
- pypy_malloc_counters_results();
-
- return exitcode;
-
- memory_out:
- errmsg = "out of memory";
- error:
- fprintf(stderr, "Fatal error during initialization: %s\n", errmsg);
- abort();
- return 1;
-}
-
-int PYPY_MAIN_FUNCTION(int argc, char *argv[])
-{
- return pypy_main_function(argc, argv);
-}
-
-#endif /* PYPY_STANDALONE */
diff --git a/rpython/translator/c/src/entrypoint.h
b/rpython/translator/c/src/entrypoint.h
deleted file mode 100644
--- a/rpython/translator/c/src/entrypoint.h
+++ /dev/null
@@ -1,13 +0,0 @@
-#ifdef PYPY_STANDALONE
-
-#ifndef STANDALONE_ENTRY_POINT
-# define STANDALONE_ENTRY_POINT PYPY_STANDALONE
-#endif
-
-#ifndef PYPY_MAIN_FUNCTION
-#define PYPY_MAIN_FUNCTION main
-#endif
-
-char *RPython_StartupCode(void);
-int PYPY_MAIN_FUNCTION(int argc, char *argv[]);
-#endif /* PYPY_STANDALONE */
diff --git a/rpython/translator/c/src/g_include.h
b/rpython/translator/c/src/g_include.h
--- a/rpython/translator/c/src/g_include.h
+++ b/rpython/translator/c/src/g_include.h
@@ -32,9 +32,6 @@
# include "src/debug_traceback.h"
# include "src/allocator.h"
-#ifdef PYPY_STANDALONE
-# include "src/entrypoint.h"
-#endif
/* suppress a few warnings in the generated code */
#ifdef MS_WINDOWS
diff --git a/rpython/translator/c/src/main.c b/rpython/translator/c/src/main.c
new file mode 100644
--- /dev/null
+++ b/rpython/translator/c/src/main.c
@@ -0,0 +1,5 @@
+int rpython_main(int argc, char *argv[]);
+
+int main(int argc, char *argv[]) {
+ return rpython_main(argc, argv);
+}
diff --git a/rpython/translator/c/src/rtyper.c
b/rpython/translator/c/src/rtyper.c
--- a/rpython/translator/c/src/rtyper.c
+++ b/rpython/translator/c/src/rtyper.c
@@ -36,11 +36,3 @@
free(dump);
}
}
-
-RPyString *RPyString_FromString(char *buf)
-{
- int length = strlen(buf);
- RPyString *rps = RPyString_New(length);
- memcpy(rps->rs_chars.items, buf, length);
- return rps;
-}
diff --git a/rpython/translator/c/src/rtyper.h
b/rpython/translator/c/src/rtyper.h
--- a/rpython/translator/c/src/rtyper.h
+++ b/rpython/translator/c/src/rtyper.h
@@ -11,4 +11,3 @@
char *RPyString_AsCharP(RPyString *rps);
void RPyString_FreeCache(void);
-RPyString *RPyString_FromString(char *buf);
diff --git a/rpython/translator/c/src/support.c
b/rpython/translator/c/src/support.c
--- a/rpython/translator/c/src/support.c
+++ b/rpython/translator/c/src/support.c
@@ -1,5 +1,8 @@
#include "common_header.h"
#include <src/support.h>
+#include <src/commondefs.h>
+#include <src/mem.h>
+#include <src/instrument.h>
/************************************************************/
/*** C header subsection: support functions ***/
@@ -23,3 +26,26 @@
abort();
}
+
+void rpython_special_startup()
+{
+#ifdef PYPY_X86_CHECK_SSE2_DEFINED
+ pypy_x86_check_sse2();
+#endif
+ instrument_setup();
+
+#ifndef MS_WINDOWS
+ /* this message does no longer apply to win64 :-) */
+ if (sizeof(void*) != SIZEOF_LONG) {
+ fprintf(stderr, "Only support platforms where sizeof(void*) == "
+ "sizeof(long), for now\n");
+ abort();
+ }
+#endif
+}
+
+void rpython_special_shutdown()
+{
+ pypy_debug_alloc_results();
+ pypy_malloc_counters_results();
+}
diff --git a/rpython/translator/c/src/support.h
b/rpython/translator/c/src/support.h
--- a/rpython/translator/c/src/support.h
+++ b/rpython/translator/c/src/support.h
@@ -63,3 +63,6 @@
# define RPyNLenItem(array, index) ((array)->items[index])
# define RPyBareItem(array, index) ((array)[index])
#endif
+
+void rpython_special_startup();
+void rpython_special_shutdown();
diff --git a/rpython/translator/gensupp.py b/rpython/translator/gensupp.py
--- a/rpython/translator/gensupp.py
+++ b/rpython/translator/gensupp.py
@@ -2,6 +2,13 @@
Some support for genxxx implementations of source generators.
Another name could be genEric, but well...
"""
+from os import write
+
+from rpython.annotator import model as annmodel
+from rpython.rtyper.annlowlevel import MixLevelHelperAnnotator
+from rpython.rtyper.lltypesystem import rffi, lltype
+from rpython.rtyper.lltypesystem.lloperation import llop
+
def uniquemodulename(name, SEEN=set()):
# never reuse the same module name within a Python session!
@@ -116,3 +123,35 @@
self.mapping[name] = ret
return ret
+
+rpython_special_startup = rffi.llexternal(
+ 'rpython_special_startup', [], lltype.Void, _nowrapper=True)
+rpython_special_shutdown = rffi.llexternal(
+ 'rpython_special_shutdown', [], lltype.Void, _nowrapper=True)
+
+def make_main(translator, setup, entrypoint):
+ def rpython_main(argc, argv):
+ rffi.stackcounter.stacks_counter += 1
+ llop.gc_stack_bottom(lltype.Void)
+ rpython_special_startup()
+ try:
+ if setup is not None:
+ setup()
+ args = [rffi.charp2str(argv[i]) for i in range(argc)]
+ exitcode = entrypoint(args)
+ except Exception as e:
+ write(2, 'DEBUG: An uncaught exception was raised in entrypoint: '
+ + str(e) + '\n')
+ return 1
+ rpython_special_shutdown();
+ return exitcode
+ rpython_main.c_name = 'rpython_main'
+
+ mixlevelannotator = MixLevelHelperAnnotator(translator.rtyper)
+ arg1 = annmodel.lltype_to_annotation(rffi.INT)
+ arg2 = annmodel.lltype_to_annotation(rffi.CCHARPP)
+ res = annmodel.lltype_to_annotation(lltype.Signed)
+ graph = mixlevelannotator.getgraph(rpython_main, [arg1, arg2], res)
+ mixlevelannotator.finish()
+ mixlevelannotator.backend_optimize()
+ return graph
diff --git a/rpython/translator/platform/posix.py
b/rpython/translator/platform/posix.py
--- a/rpython/translator/platform/posix.py
+++ b/rpython/translator/platform/posix.py
@@ -172,12 +172,6 @@
if shared:
m.definition('SHARED_IMPORT_LIB', libname),
- m.definition('PYPY_MAIN_FUNCTION', "pypy_main_startup")
- m.rule('main.c', '',
- 'echo "'
- 'int $(PYPY_MAIN_FUNCTION)(int, char*[]); '
- 'int main(int argc, char* argv[]) '
- '{ return $(PYPY_MAIN_FUNCTION)(argc, argv); }" > $@')
m.rule('$(DEFAULT_TARGET)', ['$(TARGET)', 'main.o'],
'$(CC_LINK) $(LDFLAGS_LINK) main.o -L.
-l$(SHARED_IMPORT_LIB) -o $@')
_______________________________________________
pypy-commit mailing list
[email protected]
https://mail.python.org/mailman/listinfo/pypy-commit