[pypy-svn] r68647 - in pypy/branch/msvc-asmgcroot/pypy/translator/c: . gcc
afa at codespeak.net
afa at codespeak.net
Mon Oct 19 19:36:00 CEST 2009
Author: afa
Date: Mon Oct 19 19:35:59 2009
New Revision: 68647
Modified:
pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py
pypy/branch/msvc-asmgcroot/pypy/translator/c/genc.py
Log:
More progress towards generating a correct gcmaptable.s file
Modified: pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py (original)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/gcc/trackgcroot.py Mon Oct 19 19:35:59 2009
@@ -6,8 +6,6 @@
from pypy.translator.c.gcc.instruction import *
LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
-r_functionstart_elf = re.compile(r"\t.type\s+"+LABEL+",\s*[@]function\s*$")
-r_functionend_elf = re.compile(r"\t.size\s+"+LABEL+",\s*[.]-"+LABEL+"\s*$")
# darwin
r_textstart = re.compile(r"\t.text\s*$")
@@ -24,7 +22,6 @@
'const_data'
]
r_sectionstart = re.compile(r"\t\.("+'|'.join(OTHERSECTIONS)+").*$")
-r_functionstart_darwin = re.compile(r"_(\w+):\s*$")
OFFSET_LABELS = 2**30
@@ -660,14 +657,17 @@
class ElfFunctionGcRootTracker(FunctionGcRootTracker):
format = 'elf'
- ESP = '%esp'
- OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])'
- LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
+ ESP = '%esp'
+ OPERAND = r'(?:[-\w$%+.:@"]+(?:[(][\w%,]+[)])?|[(][\w%,]+[)])'
+ LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
+
+ r_functionstart = re.compile(r"\t.type\s+"+LABEL+",\s*[@]function\s*$")
+ r_functionend = re.compile(r"\t.size\s+"+LABEL+",\s*[.]-"+LABEL+"\s*$")
def __init__(self, lines, filetag=0):
- match = r_functionstart_elf.match(lines[0])
+ match = self.r_functionstart.match(lines[0])
funcname = match.group(1)
- match = r_functionend_elf.match(lines[-1])
+ match = self.r_functionend.match(lines[-1])
assert funcname == match.group(1)
assert funcname == match.group(2)
super(ElfFunctionGcRootTracker, self).__init__(
@@ -683,9 +683,11 @@
class DarwinFunctionGcRootTracker(ElfFunctionGcRootTracker):
format = 'darwin'
+ r_functionstart = re.compile(r"_(\w+):\s*$")
+
def __init__(self, lines, filetag=0):
- match = r_functionstart_darwin.match(lines[0])
- funcname = '_'+match.group(1)
+ match = self.r_functionstart.match(lines[0])
+ funcname = '_' + match.group(1)
FunctionGcRootTracker.__init__(self, funcname, lines, filetag)
class Mingw32FunctionGcRootTracker(DarwinFunctionGcRootTracker):
@@ -694,18 +696,19 @@
class MsvcFunctionGcRootTracker(FunctionGcRootTracker):
format = 'msvc'
- r_functionstart = re.compile(r"PUBLIC\t"+LABEL+"$")
+ r_functionstart = re.compile(LABEL+r"\s+PROC\s*(:?;.+)\n$")
+ r_functionend = re.compile(LABEL+r"\s+ENDP\s*$")
ESP = 'esp'
- OPERAND = r'(?:\w+|(?:DWORD PTR )?[_\w$]*\[[-+\w0-9]+\])'
- LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
+ OPERAND = r'(?:(:?WORD|DWORD|BYTE) PTR |OFFSET )?[_\w?@$]*(?:[-+0-9]+)?(:?\[[-+*\w0-9]+\])?'
+ LABEL = r'([a-zA-Z_$.][a-zA-Z0-9_$@.]*)'
@classmethod
def init_regexp(cls):
super(MsvcFunctionGcRootTracker, cls).init_regexp()
- cls.r_binaryinsn = re.compile(r"\t[a-z]\w*\s+(?P<target>"+cls.OPERAND+"),\s*(?P<source>"+cls.OPERAND+")\s*(?:;.+)?$")
- cls.r_jump = re.compile(r"\tj\w+\s+(?:SHORT )?"+LABEL+"\s*$")
+ cls.r_binaryinsn = re.compile(r"\t[a-z]\w*\s+(?P<target>"+cls.OPERAND+r"),\s*(?P<source>"+cls.OPERAND+r")\s*(?:;.+)?$")
+ cls.r_jump = re.compile(r"\tj\w+\s+(?:SHORT |DWORD PTR )?"+LABEL+"\s*$")
def __init__(self, lines, filetag=0):
match = self.r_functionstart.match(lines[0])
@@ -720,6 +723,10 @@
locals()['visit_' + name] = getattr(FunctionGcRootTracker,
'visit_' + name + 'l')
+ visit_npad = FunctionGcRootTracker.visit_nop
+ # probably not GC pointers
+ visit_cdq = FunctionGcRootTracker.visit_nop
+
def extract_immediate(self, value):
try:
return int(value)
@@ -774,14 +781,14 @@
functionlines = []
in_function = False
for line in iterlines:
- if r_functionstart_elf.match(line):
+ if cls.FunctionGcRootTracker.r_functionstart.match(line):
assert not in_function, (
"missed the end of the previous function")
yield False, functionlines
in_function = True
functionlines = []
functionlines.append(line)
- if r_functionend_elf.match(line):
+ if cls.FunctionGcRootTracker.r_functionend.match(line):
assert in_function, (
"missed the start of the current function")
yield True, functionlines
@@ -810,7 +817,7 @@
functionlines = []
in_text = False
in_function = False
- elif in_text and r_functionstart_darwin.match(line):
+ elif in_text and cls.FunctionGcRootTracker.r_functionstart.match(line):
yield in_function, functionlines
functionlines = []
in_function = True
@@ -838,7 +845,7 @@
in_text = True
elif r_sectionstart.match(line):
in_text = False
- elif in_text and r_functionstart_darwin.match(line):
+ elif in_text and cls.FunctionGcRootTracker.r_functionstart.match(line):
yield in_function, functionlines
functionlines = []
in_function = True
@@ -850,6 +857,33 @@
format = "msvc"
FunctionGcRootTracker = MsvcFunctionGcRootTracker
+ @classmethod
+ def find_functions(cls, iterlines):
+ functionlines = []
+ in_function = False
+ for line in iterlines:
+ if cls.FunctionGcRootTracker.r_functionstart.match(line):
+ assert not in_function, (
+ "missed the end of the previous function")
+ yield False, functionlines
+ in_function = True
+ functionlines = []
+ functionlines.append(line)
+ if cls.FunctionGcRootTracker.r_functionend.match(line):
+ assert in_function, (
+ "missed the start of the current function")
+ yield True, functionlines
+ in_function = False
+ functionlines = []
+ assert not in_function, (
+ "missed the end of the previous function")
+ yield False, functionlines
+
+ def process_function(self, lines, entrypoint, filename):
+ entrypoint = '_' + entrypoint
+ return super(MsvcAssemblerParser, self).process_function(
+ lines, entrypoint, filename)
+
PARSERS = {
'elf': ElfAssemblerParser,
'darwin': DarwinAssemblerParser,
@@ -885,98 +919,214 @@
shapes = {}
shapelines = []
shapeofs = 0
- def _globalname(name):
- if self.format in ('darwin', 'mingw32'):
- return '_' + name
- return name
+ def _globalname(name, disp=""):
+ if self.format in ('darwin', 'mingw32', 'msvc'):
+ name = '_' + name
+
+ if disp:
+ return "%s + %s" % (name, disp)
+ else:
+ return name
+
def _globl(name):
- print >> output, "\t.globl %s" % _globalname(name)
+ if self.format == 'msvc':
+ print >> output, "PUBLIC %s" % _globalname(name)
+ else:
+ print >> output, "\t.globl %s" % _globalname(name)
def _label(name):
print >> output, "%s:" % _globalname(name)
def _variant(**kwargs):
txt = kwargs[self.format]
print >> output, "\t%s" % txt
- print >> output, "\t.text"
+ def _comment(comment):
+ if self.format == 'msvc':
+ print >> output, "; %s" % comment
+ else:
+ print >> output, "/* %s */" % comment
+
+ def _movl(source, target, comment):
+ if self.format == 'msvc':
+ print >> output, "\tmov\t%s, %s\t\t; %s" % (target, source, comment)
+ else:
+ print >> output, "\tmovl\t%s, %s\t\t/* %s */ " % (source, target, comment)
+
+ def _pushl(source, comment):
+ if self.format == 'msvc':
+ print >> output, "\tpush\t%s\t\t; %s" % (source, comment)
+ else:
+ print >> output, "\tpushl\t%s\t\t/* %s */ " % (target, comment)
+
+ def _popl(source, comment):
+ if self.format == 'msvc':
+ print >> output, "\tpop\t%s\t\t; %s" % (source, comment)
+ else:
+ print >> output, "\tpopl\t%s\t\t/* %s */ " % (target, comment)
+
+
+ def _register(name, disp=""):
+ if self.format == 'msvc':
+ if disp:
+ return "DWORD PTR [%s+%s]" % (name, disp)
+ else:
+ return name
+ else:
+ if disp:
+ return "%s(%%%s)" % (disp, name)
+ else:
+ return '%' + name
+
+ def _offset(name):
+ if self.format == 'msvc':
+ return "OFFSET %s" % _globalname(name)
+ else:
+ return "$%s" % _globalname(name)
+
+ def _call(arg, comment):
+ return "call\t%s\t\t;%s" % (arg, comment)
+
+ def _indirectjmp(arg):
+ if self.format == 'msvc':
+ return arg
+ else:
+ return "*%" + arg
+
+ if self.format == 'msvc':
+ print >> output, """\
+ TITLE gcmaptable.s
+ .686P
+ .XMM
+ .model flat
+ """
+
+ _variant(elf='\t.text',
+ darwin='\t.text',
+ mingw32='\t.text',
+ msvc='_TEXT\tSEGMENT')
+
+ _globl('__gcrootanchor')
+
_globl('pypy_asm_stackwalk')
_variant(elf='.type pypy_asm_stackwalk, @function',
darwin='',
- mingw32='')
+ mingw32='',
+ msvc='')
_label('pypy_asm_stackwalk')
- print >> output, """\
- /* See description in asmgcroot.py */
- movl 4(%esp), %edx /* my argument, which is the callback */
- movl %esp, %eax /* my frame top address */
- pushl %eax /* ASM_FRAMEDATA[6] */
- pushl %ebp /* ASM_FRAMEDATA[5] */
- pushl %edi /* ASM_FRAMEDATA[4] */
- pushl %esi /* ASM_FRAMEDATA[3] */
- pushl %ebx /* ASM_FRAMEDATA[2] */
-
- /* Add this ASM_FRAMEDATA to the front of the circular linked */
- /* list. Let's call it 'self'. */
- movl __gcrootanchor+4, %eax /* next = gcrootanchor->next */
- pushl %eax /* self->next = next */
- pushl $__gcrootanchor /* self->prev = gcrootanchor */
- movl %esp, __gcrootanchor+4 /* gcrootanchor->next = self */
- movl %esp, (%eax) /* next->prev = self */
-
- /* note: the Mac OS X 16 bytes aligment must be respected. */
- call *%edx /* invoke the callback */
-
- /* Detach this ASM_FRAMEDATA from the circular linked list */
- popl %esi /* prev = self->prev */
- popl %edi /* next = self->next */
- movl %edi, 4(%esi) /* prev->next = next */
- movl %esi, (%edi) /* next->prev = prev */
-
- popl %ebx /* restore from ASM_FRAMEDATA[2] */
- popl %esi /* restore from ASM_FRAMEDATA[3] */
- popl %edi /* restore from ASM_FRAMEDATA[4] */
- popl %ebp /* restore from ASM_FRAMEDATA[5] */
- popl %ecx /* ignored ASM_FRAMEDATA[6] */
- /* the return value is the one of the 'call' above, */
- /* because %eax (and possibly %edx) are unmodified */
- ret
-""".replace("__gcrootanchor", _globalname("__gcrootanchor"))
+ _comment("See description in asmgcroot.py")
+ _movl(_register("esp", disp="4"), _register("edx"), "my argument, which is the callback")
+ _movl(_register("esp"), _register("eax"), "my frame top address")
+ _pushl(_register("eax"), "ASM_FRAMEDATA[6]")
+ _pushl(_register("ebp"), "ASM_FRAMEDATA[5]")
+ _pushl(_register("edi"), "ASM_FRAMEDATA[4]")
+ _pushl(_register("esi"), "ASM_FRAMEDATA[3]")
+ _pushl(_register("ebx"), "ASM_FRAMEDATA[2]")
+
+ print >> output
+ _comment("Add this ASM_FRAMEDATA to the front of the circular linked")
+ _comment("list. Let's call it 'self'.")
+ print >> output
+ _movl(_globalname("__gcrootanchor", disp=4), _register("eax"), "next = gcrootanchor->next")
+ _pushl(_register("eax"), "self->next = next")
+ _pushl(_offset("__gcrootanchor"), "self->prev = gcrootanchor")
+ _movl(_register("esp"), _globalname("__gcrootanchor", disp=4), "gcrootanchor->next = self")
+ _movl(_register("esp"), _register("eax", "0"), "next->prev = self")
+ print >> output
+
+ _comment("note: the Mac OS X 16 bytes aligment must be respected.")
+ _call(_indirectjmp("edx"), "invoke the callback")
+ print >> output
+
+ _comment("Detach this ASM_FRAMEDATA from the circular linked list")
+ _popl(_register("esi"), "prev = self->prev")
+ _popl(_register("edi"), "next = self->next")
+ _movl(_register("edi"), _register("esi", disp="4"), "prev->next = next")
+ _movl(_register("esi"), _register("edi", disp="0"), "next->prev = prev")
+ print >> output
+
+ _popl(_register("ebx"), "restore from ASM_FRAMEDATA[2]")
+ _popl(_register("esi"), "restore from ASM_FRAMEDATA[3]")
+ _popl(_register("edi"), "restore from ASM_FRAMEDATA[4]")
+ _popl(_register("ebp"), "restore from ASM_FRAMEDATA[5]")
+ _popl(_register("ecx"), "restore from ASM_FRAMEDATA[6]")
+ _comment("the return value is the one of the 'call' above,")
+ _comment("because %eax (and possibly %edx) are unmodified")
+
+ print >> output, "\tret"
+
_variant(elf='.size pypy_asm_stackwalk, .-pypy_asm_stackwalk',
darwin='',
- mingw32='')
- print >> output, '\t.data'
- print >> output, '\t.align\t4'
- _globl('__gcrootanchor')
- _label('__gcrootanchor')
- print >> output, """\
- /* A circular doubly-linked list of all */
- /* the ASM_FRAMEDATAs currently alive */
+ mingw32='',
+ msvc='')
+
+ if self.format == 'msvc':
+ for label, state, is_range in self.gcmaptable:
+ print >> output, "EXTERN %s:NEAR" % label
+
+ if self.format == 'msvc':
+ print >> output, '_DATA SEGMENT'
+
+ _comment("A circular doubly-linked list of all")
+ _comment("the ASM_FRAMEDATAs currently alive")
+ if self.format == 'msvc':
+ print >> output, '%s DD ?' % _globalname("__gcrootanchor")
+ print >> output, '\tDD FLAT:___gcrootanchor ; prev'
+ print >> output, '\tDD FLAT:___gcrootanchor ; next'
+ else:
+ print >> output, '\t.data'
+ print >> output, '\t.align\t4'
+ _label('__gcrootanchor')
+ print >> output, """\
.long\t__gcrootanchor /* prev */
.long\t__gcrootanchor /* next */
""".replace("__gcrootanchor", _globalname("__gcrootanchor"))
+
_globl('__gcmapstart')
- _label('__gcmapstart')
+ if self.format == 'msvc':
+ print >> output, '%s DD ?' % _globalname('__gcmapstart')
+ else:
+ _label('__gcmapstart')
for label, state, is_range in self.gcmaptable:
try:
n = shapes[state]
except KeyError:
n = shapes[state] = shapeofs
bytes = [str(b) for b in compress_callshape(state)]
- shapelines.append('\t/*%d*/\t.byte\t%s\n' % (
- shapeofs,
- ', '.join(bytes)))
+ if self.format == 'msvc':
+ shapelines.append('\tDD\t%s\t;%s\n' % (
+ ', '.join(bytes),
+ shapeofs))
+ else:
+ shapelines.append('\t/*%d*/\t.byte\t%s\n' % (
+ shapeofs,
+ ', '.join(bytes)))
shapeofs += len(bytes)
if is_range:
n = ~ n
- print >> output, '\t.long\t%s-%d' % (label, OFFSET_LABELS)
- print >> output, '\t.long\t%d' % (n,)
+ if self.format == 'msvc':
+ print >> output, '\tDD\t%s-%d' % (label, OFFSET_LABELS)
+ print >> output, '\tDD\t%d' % (n,)
+ else:
+ print >> output, '\t.long\t%s-%d' % (label, OFFSET_LABELS)
+ print >> output, '\t.long\t%d' % (n,)
+
_globl('__gcmapend')
_label('__gcmapend')
_variant(elf='.section\t.rodata',
darwin='.const',
- mingw32='')
+ mingw32='',
+ msvc='')
+
_globl('__gccallshapes')
- _label('__gccallshapes')
+ if self.format == 'msvc':
+ print >> output, '%s DD ?' % _globalname('__gccallshapes')
+ else:
+ _label('__gccallshapes')
output.writelines(shapelines)
+ if self.format == 'msvc':
+ print >> output, "_DATA ENDS"
+ print >> output, "END"
+
def process(self, iterlines, newfile, entrypoint='main', filename='?'):
parser = PARSERS[format](verbose=self.verbose, shuffle=self.shuffle)
for in_function, lines in parser.find_functions(iterlines):
@@ -1010,6 +1160,7 @@
else:
FUNCTIONS_NOT_RETURNING = {
'_abort': None,
+ '__imp__abort': None,
'__exit': None,
'__assert': None,
'__wassert': None,
@@ -1169,7 +1320,7 @@
if sys.platform == 'darwin':
format = 'darwin'
elif sys.platform == 'win32':
- format = 'mingw32'
+ format = 'msvc'
else:
format = 'elf'
tracker = GcRootTracker(verbose=verbose, shuffle=shuffle, format=format)
Modified: pypy/branch/msvc-asmgcroot/pypy/translator/c/genc.py
==============================================================================
--- pypy/branch/msvc-asmgcroot/pypy/translator/c/genc.py (original)
+++ pypy/branch/msvc-asmgcroot/pypy/translator/c/genc.py Mon Oct 19 19:35:59 2009
@@ -493,7 +493,6 @@
mk.definition('ASMLBLFILES', lblsfiles)
mk.definition('GCMAPFILES', gcmapfiles)
mk.definition('DEBUGFLAGS', '-O2 -fomit-frame-pointer -g')
- mk.definition('OBJECTS', '$(ASMLBLFILES) gcmaptable.s')
if sys.platform == 'win32':
python = sys.executable.replace('\\', '/') + ' '
@@ -501,13 +500,20 @@
python = ''
if self.translator.platform.name == 'msvc':
+ lblofiles = ['%s.lbl.obj' % (cfile[:-2],) for cfile in mk.cfiles]
+ mk.definition('ASMLBLOBJFILES', lblofiles)
+ mk.definition('OBJECTS', '$(ASMLBLOBJFILES) gcmaptable.obj')
+ mk.rule('.SUFFIXES', '.s')
+ mk.rule('.s.obj', '',
+ 'c:\masm32\bin\ml $(CFLAGS) /Zm /coff /Fo$@ /c $< $(INCLUDEDIRS)')
mk.rule('.c.gcmap', '',
['$(CC) $(CFLAGS) /c /FAs /Fa$*.s $< $(INCLUDEDIRS)',
- python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $*.s > $@']
+ 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $*.s > $@']
)
mk.rule('gcmaptable.s', '$(GCMAPFILES)',
- python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@')
+ 'cmd /c ' + python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py $(GCMAPFILES) > $@')
else:
+ mk.definition('OBJECTS', '$(ASMLBLFILES) gcmaptable.s')
mk.rule('%.s', '%.c', '$(CC) $(CFLAGS) -frandom-seed=$< -o $@ -S $< $(INCLUDEDIRS)')
mk.rule('%.lbl.s %.gcmap', '%.s',
python + '$(PYPYDIR)/translator/c/gcc/trackgcroot.py -t $< > $*.gcmap')
More information about the Pypy-commit
mailing list