[pypy-svn] r68348 - in pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc: . test/darwin
afa at codespeak.net
afa at codespeak.net
Mon Oct 12 18:18:26 CEST 2009
Author: afa
Date: Mon Oct 12 18:18:24 2009
New Revision: 68348
Added:
pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/test/darwin/track_switch0.s
Modified:
pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/trackgcroot.py
Log:
Handle table-based switches on Darwin: where the address is computed in several instructions,
we walk backwards to find all possible inputs for the indirect jump, and use the first label we meet.
Added: pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/test/darwin/track_switch0.s
==============================================================================
--- (empty file)
+++ pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/test/darwin/track_switch0.s Mon Oct 12 18:18:24 2009
@@ -0,0 +1,94 @@
+_pypy_g_MetaInterp_prepare_resume_from_failure:
+ subl $28, %esp
+ movl %ebx, 20(%esp)
+ movl %esi, 24(%esp)
+ call L2245
+"L00000000130$pb":
+L2245:
+ popl %ebx
+ movl 32(%esp), %edx
+L2231:
+ movl 36(%esp), %eax
+ subl $6, %eax
+ cmpl $7, %eax
+ jbe L2244
+L2243:
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ ret
+ .align 4,0x90
+L2244:
+ movl L2237-"L00000000130$pb"(%ebx,%eax,4), %eax
+ addl %ebx, %eax
+ jmp *%eax
+ .align 2,0x90
+L2237:
+ .long L2233-"L00000000130$pb"
+ .long L2234-"L00000000130$pb"
+ .long L2243-"L00000000130$pb"
+ .long L2243-"L00000000130$pb"
+ .long L2243-"L00000000130$pb"
+ .long L2235-"L00000000130$pb"
+ .long L2235-"L00000000130$pb"
+ .long L2236-"L00000000130$pb"
+L2236:
+ movl %edx, 32(%esp)
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ jmp L_pypy_g_MetaInterp_raise_overflow_error$stub
+L2235:
+ movl %edx, 32(%esp)
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ jmp L_pypy_g_MetaInterp_handle_exception$stub
+L2234:
+ movl 16(%edx), %eax
+ movl 8(%eax), %edx
+ movl 4(%eax), %eax
+ movl 4(%edx,%eax,4), %eax
+ movl %eax, 32(%esp)
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ jmp L_pypy_g_MIFrame_dont_follow_jump$stub
+L2233:
+ movl 16(%edx), %eax
+ movl 8(%eax), %edx
+ movl 4(%eax), %eax
+ movl 4(%edx,%eax,4), %esi
+ movl 8(%esi), %ecx
+ movl 52(%esi), %eax
+ testl %eax, %eax
+ js L2238
+ movl %eax, %edx
+L2240:
+ cmpb $0, 12(%ecx,%edx)
+ je L2241
+L2242:
+ movl L_pypy_g_exceptions_AssertionError$non_lazy_ptr-"L00000000130$pb"(%ebx), %eax
+ movl %eax, 36(%esp)
+ movl L_pypy_g_exceptions_AssertionError_vtable$non_lazy_ptr-"L00000000130$pb"(%ebx), %eax
+ movl %eax, 32(%esp)
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ jmp L_pypy_g_RPyRaiseException$stub
+L2241:
+ incl %eax
+ movl %eax, 52(%esi)
+ movl %esi, (%esp)
+ call L_pypy_g_MIFrame_load_3byte$stub
+ ;; expected {28(%esp) | 20(%esp), 24(%esp), %edi, %ebp | }
+ movl %eax, 52(%esi)
+ movl 20(%esp), %ebx
+ movl 24(%esp), %esi
+ addl $28, %esp
+ ret
+L2238:
+ movl %eax, %edx
+ addl 8(%ecx), %edx
+ jmp L2240
+ .align 4,0x90
Modified: pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/trackgcroot.py
==============================================================================
--- pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/trackgcroot.py (original)
+++ pypy/branch/asmgcc-mingw32-2/pypy/translator/c/gcc/trackgcroot.py Mon Oct 12 18:18:24 2009
@@ -37,6 +37,8 @@
r_jmp_switch = re.compile(r"\tjmp\t[*]"+LABEL+"[(]")
r_jmptable_item = re.compile(r"\t.long\t"+LABEL+"\s*$")
r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text")
+r_jmptable_item = re.compile(r"\t.long\t"+LABEL+"(-\"[A-Za-z0-9$]+\")?\s*$")
+r_jmptable_end = re.compile(r"\t.text|\t.section\s+.text|"+LABEL)
r_binaryinsn = re.compile(r"\t[a-z]\w*\s+("+OPERAND+"),\s*("+OPERAND+")\s*$")
LOCALVAR = r"%eax|%edx|%ecx|%ebx|%esi|%edi|%ebp|\d*[(]%esp[)]"
LOCALVARFP = LOCALVAR + r"|-?\d*[(]%ebp[)]"
@@ -462,6 +464,11 @@
def fixlocalvars(self):
def fixvar(localvar):
+ if localvar is None:
+ return None
+ elif isinstance(localvar, (list, tuple)):
+ return [fixvar(var) for var in localvar]
+
match = r_localvar_esp.match(localvar)
if match:
if localvar == '0(%esp)': # for pushl and popl, by
@@ -597,6 +604,7 @@
def visit_addl(self, line, sign=+1):
match = r_binaryinsn.match(line)
+ source = match.group(1)
target = match.group(2)
if target == '%esp':
count = match.group(1)
@@ -605,7 +613,7 @@
return InsnCannotFollowEsp()
return InsnStackAdjust(sign * int(count[1:]))
elif self.r_localvar.match(target):
- return InsnSetLocal(target)
+ return InsnSetLocal(target, [source, target])
else:
return []
@@ -624,6 +632,7 @@
match = r_binaryinsn.match(line)
if not match:
raise UnrecognizedOperation(line)
+ source = match.group(1)
target = match.group(2)
if self.r_localvar.match(target):
return InsnSetLocal(target)
@@ -694,7 +703,7 @@
if self.r_localvar.match(source):
return [InsnCopyLocal(source, target)]
else:
- return [InsnSetLocal(target)]
+ return [InsnSetLocal(target, [source])]
else:
return []
@@ -742,31 +751,38 @@
return InsnRet()
def visit_jmp(self, line):
- tablelabel = None
+ tablelabels = []
match = r_jmp_switch.match(line)
if match:
# this is a jmp *Label(%index), used for table-based switches.
# Assume that the table is just a list of lines looking like
# .long LABEL or .long 0, ending in a .text or .section .text.hot.
- tablelabel = match.group(1)
+ tablelabels.append(match.group(1))
elif r_unaryinsn_star.match(line):
# maybe a jmp similar to the above, but stored in a
# registry:
# movl L9341(%eax), %eax
# jmp *%eax
operand = r_unaryinsn_star.match(line).group(1)[1:]
- prev_line = self.lines[self.currentlineno-1]
- match = r_insn.match(prev_line)
- binaryinsn = r_binaryinsn.match(prev_line)
- if (match and binaryinsn and
- match.group(1) == 'movl' and binaryinsn.group(2) == operand
- and '(' in binaryinsn.group(1)):
- tablelabel = binaryinsn.group(1).split('(')[0]
- if tablelabel not in self.labels:
- # Probably an indirect tail-call.
- tablelabel = None
- if tablelabel:
- tablelin = self.labels[tablelabel].lineno + 1
+ def walker(insn, locs):
+ sources = []
+ for loc in locs:
+ sources.extend(insn.all_sources_of(loc))
+ for source in sources:
+ label_match = re.compile(LABEL).match(source)
+ if label_match:
+ tablelabels.append(label_match.group(0))
+ return
+ yield tuple(sources)
+ insn = InsnStop()
+ insn.previous_insns = [self.insns[-1]]
+ self.walk_instructions_backwards(walker, insn, (operand,))
+
+ # Probably an indirect tail-call.
+ tablelabels = [label for label in tablelabels if label in self.labels]
+ assert len(tablelabels) <= 1
+ if tablelabels:
+ tablelin = self.labels[tablelabels[0]].lineno + 1
while not r_jmptable_end.match(self.lines[tablelin]):
match = r_jmptable_item.match(self.lines[tablelin])
if not match:
@@ -920,6 +936,13 @@
def source_of(self, localvar, tag):
return localvar
+ def all_sources_of(self, localvar):
+ source = self.source_of(localvar, None)
+ if source is somenewvalue:
+ return []
+ else:
+ return [source]
+
class Label(Insn):
_args_ = ['label', 'lineno']
def __init__(self, label, lineno):
@@ -952,14 +975,19 @@
return self.arguments[localvar]
class InsnSetLocal(Insn):
- _args_ = ['target']
- _locals_ = ['target']
- def __init__(self, target):
+ _args_ = ['target', 'sources']
+ _locals_ = ['target', 'sources']
+ def __init__(self, target, sources=()):
self.target = target
+ self.sources = sources
def source_of(self, localvar, tag):
if localvar == self.target:
return somenewvalue
return localvar
+ def all_sources_of(self, localvar):
+ if localvar == self.target:
+ return self.sources
+ return [localvar]
class InsnCopyLocal(Insn):
_args_ = ['source', 'target']
More information about the Pypy-commit
mailing list