1. Pypy
  2. Untitled project
  3. pypy

Source

pypy / pypy / translator / driver.py

Samuele Pedroni 402c7b0 
Armin Rigo 7eb3656 

Samuele Pedroni 402c7b0 
Ronny Pfannschmi… c2c9753 
Samuele Pedroni 402c7b0 

Maciej Fijalkows… 8bcb6b5 
Armin Rigo d171584 
Samuele Pedroni 402c7b0 
Armin Rigo cbe232f 
Armin Rigo 5dc7e89 
Maciej Fijalkows… e7b8954 
Samuele Pedroni 402c7b0 






James Lan 6cf85e6 
Maciej Fijalkows… b5a2e0b 
James Lan 6cf85e6 








Samuele Pedroni 402c7b0 



Samuele Pedroni acc3486 






Armin Rigo f00564e 
Maciej Fijalkows… 0054616 
Samuele Pedroni 0ccfc65 











Maciej Fijalkows… 75307d4 
Samuele Pedroni 0ccfc65 


Amaury Forgeot d… c16499d 
Maciej Fijalkows… 75307d4 
Samuele Pedroni 0ccfc65 





Samuele Pedroni 402c7b0 
Samuele Pedroni b2d9f53 
Samuele Pedroni 402c7b0 
Anders Chrigströ… bc34283 
Anders Chrigströ… 112186e 
Carl Friedrich B… e820a54 

Maciej Fijalkows… 8bcb6b5 
Samuele Pedroni 402c7b0 



Carl Friedrich B… e820a54 
Armin Rigo cbe232f 
Maciej Fijalkows… b5a2e0b 
Carl Friedrich B… e820a54 





Maciej Fijalkows… e7b8954 
Armin Rigo 3af86a8 
Armin Rigo 491d731 
Armin Rigo 3af86a8 
Samuele Pedroni 402c7b0 









Anders Chrigströ… bc34283 
Samuele Pedroni acc3486 

Samuele Pedroni 402c7b0 
Samuele Pedroni acc3486 


Samuele Pedroni 402c7b0 

Samuele Pedroni acc3486 
Samuele Pedroni 402c7b0 

Samuele Pedroni acc3486 


David Schneider 83dbfcb 

Samuele Pedroni acc3486 
David Schneider 83dbfcb 
Anders Chrigströ… 112186e 
Carl Friedrich B… d807839 
Samuele Pedroni acc3486 

Carl Friedrich B… e820a54 
Samuele Pedroni acc3486 










Anders Chrigströ… bc34283 



Samuele Pedroni b2d9f53 


Carl Friedrich B… e820a54 


Samuele Pedroni acc3486 

Carl Friedrich B… e820a54 

Samuele Pedroni acc3486 
Samuele Pedroni 402c7b0 

Samuele Pedroni acc3486 

Samuele Pedroni 402c7b0 

Samuele Pedroni acc3486 







Samuele Pedroni 402c7b0 







Maciej Fijalkows… e8aee8a 
Samuele Pedroni 402c7b0 


Maciej Fijalkows… 40f5bd1 
Samuele Pedroni 402c7b0 
Maciej Fijalkows… 40f5bd1 






Samuele Pedroni 402c7b0 

Carl Friedrich B… e820a54 
Samuele Pedroni 402c7b0 






Alexander Schrem… 7b71bc6 
Samuele Pedroni 402c7b0 


Antonio Cuni 4ed903b 
Maciej Fijalkows… e7b8954 










Samuele Pedroni 402c7b0 
Samuele Pedroni 0ccfc65 

Antonio Cuni 4ed903b 
Maciej Fijalkows… e7b8954 
Antonio Cuni 4ed903b 

Maciej Fijalkows… e7b8954 
Antonio Cuni 4ed903b 
Samuele Pedroni 0ccfc65 




Ronny Pfannschmi… c2c9753 
Samuele Pedroni 0ccfc65 

















Anders Chrigströ… c54c547 






Samuele Pedroni 402c7b0 



Maciej Fijalkows… 0054616 








Samuele Pedroni 402c7b0 






Armin Rigo 5dc7e89 

Maciej Fijalkows… 8bcb6b5 
Samuele Pedroni 0ccfc65 
Maciej Fijalkows… 8bcb6b5 

Maciej Fijalkows… 0054616 



Maciej Fijalkows… 8bcb6b5 







Maciej Fijalkows… 75307d4 
Armin Rigo 5dc7e89 
Maciej Fijalkows… 75307d4 




Armin Rigo 5dc7e89 
Samuele Pedroni 402c7b0 

James Lan 6cf85e6 
Antonio Cuni c4187b9 
Maciej Fijalkows… e436aa0 

Samuele Pedroni 402c7b0 





Antonio Cuni 4ed903b 
Maciej Fijalkows… e7b8954 





Antonio Cuni 4ed903b 

Maciej Fijalkows… e7b8954 


Antonio Cuni 4ed903b 
Maciej Fijalkows… e7b8954 
Maciej Fijalkows… 40f5bd1 
Maciej Fijalkows… e7b8954 


Amaury Forgeot d… a1819d0 
Maciej Fijalkows… e7b8954 
Maciej Fijalkows… e3cc12e 
Maciej Fijalkows… e7b8954 
Samuele Pedroni 402c7b0 



Alexander Schrem… 4e82813 

Samuele Pedroni 402c7b0 



James Lan 6cf85e6 

Samuele Pedroni acc3486 
Maciej Fijalkows… e436aa0 

Samuele Pedroni acc3486 
Alex Gaynor 93966c0 
Samuele Pedroni 402c7b0 
James Lan 6cf85e6 

Samuele Pedroni acc3486 
Maciej Fijalkows… e436aa0 

Niklaus Haldiman… 1c7bb59 

Alex Gaynor 93966c0 
Niklaus Haldiman… 1c7bb59 
James Lan 6cf85e6 
Armin Rigo f4b9995 
Maciej Fijalkows… e436aa0 


Armin Rigo f4b9995 



Armin Rigo 06afa7d 
Carl Friedrich B… 84272e4 
Armin Rigo f4b9995 

Anders Chrigströ… 112186e 
James Lan 6cf85e6 
Antonio Cuni c6b9073 
Maciej Fijalkows… e436aa0 


Antonio Cuni c6b9073 




Antonio Cuni 547e16f 
Antonio Cuni c6b9073 


James Lan 6cf85e6 
Amaury Forgeot d… 9e6a7b5 











James Lan 6cf85e6 

Samuele Pedroni acc3486 
Maciej Fijalkows… e436aa0 

Samuele Pedroni 402c7b0 
Carl Friedrich B… e820a54 
Samuele Pedroni 402c7b0 
James Lan 6cf85e6 

Antonio Cuni 1f0fdb7 
Maciej Fijalkows… e436aa0 

Antonio Cuni 1f0fdb7 
Antonio Cuni a9c0689 
Antonio Cuni 1f0fdb7 

James Lan 6cf85e6 

Samuele Pedroni acc3486 
Carl Friedrich B… 528ab96 
Armin Rigo f00564e 

Carl Friedrich B… 528ab96 

Maciej Fijalkows… b5a2e0b 

Armin Rigo 5704ca9 




Maciej Fijalkows… b5a2e0b 
Armin Rigo 5704ca9 
Maciej Fijalkows… b5a2e0b 
James Lan 6cf85e6 


Samuele Pedroni 402c7b0 
Maciej Fijalkows… e436aa0 

Samuele Pedroni 402c7b0 



Maciej Fijalkows… 576f966 






Armin Rigo 4ac21ef 
Maciej Fijalkows… 576f966 





Armin Rigo 491d731 

Samuele Pedroni 402c7b0 



James Lan 6cf85e6 

Maciej Fijalkows… e436aa0 


Samuele Pedroni 402c7b0 

Samuele Pedroni b2d9f53 



Benjamin Peterso… a57fe1c 





Antonio Cuni 8fea483 
Armin Rigo 7eb3656 



Antonio Cuni dc1afc1 

Antonio Cuni 5747f30 
Armin Rigo 7eb3656 




Benjamin Peterso… a57fe1c 
Armin Rigo 7eb3656 
Samuele Pedroni 402c7b0 
Maciej Fijalkows… e436aa0 

Armin Rigo c1683af 
Benjamin Peterso… a57fe1c 

Maciej Fijalkows… 75307d4 
Maciej Fijalkows… e7b8954 



Benjamin Peterso… a57fe1c 
mattip d6ccb30 
mattip cbfdff9 

Armin Rigo c1683af 
Maciej Fijalkows… 863156d 
Samuele Pedroni 402c7b0 

Alex Gaynor 041189d 
Maciej Fijalkows… e436aa0 



Samuele Pedroni 402c7b0 
Maciej Fijalkows… e7b8954 
Maciej Fijalkows… 40f5bd1 
Maciej Fijalkows… e7b8954 

Armin Rigo 4ac21ef 
Maciej Fijalkows… 40f5bd1 



Maciej Fijalkows… 1dd0eec 
Samuele Pedroni 402c7b0 
James Lan 6cf85e6 
Samuele Pedroni acc3486 
Samuele Pedroni 402c7b0 





Armin Rigo c084920 
Samuele Pedroni 402c7b0 





James Lan 6cf85e6 
Antonio Cuni eed0696 

Antonio Cuni 25addad 

Antonio Cuni 4ed903b 









Antonio Cuni eed0696 


Alex Gaynor 041189d 
Antonio Cuni eed0696 
Antonio Cuni 547de9f 
Antonio Cuni eed0696 


Antonio Cuni c4187b9 
Armin Rigo cbe232f 
Antonio Cuni 547de9f 
Antonio Cuni c4187b9 
Antonio Cuni eed0696 
Maciej Fijalkows… 40f5bd1 
Armin Rigo cbe232f 
Antonio Cuni eed0696 
Armin Rigo cbe232f 





Antonio Cuni f3debaa 








Antonio Cuni 10c9922 

Antonio Cuni f3debaa 
Armin Rigo cbe232f 
Antonio Cuni 2df1730 
Antonio Cuni cd6e921 
Maciej Fijalkows… b5a2e0b 




Antonio Cuni 9be389d 











Maciej Fijalkows… b5a2e0b 
Antonio Cuni 937d429 
Armin Rigo cbe232f 


Antonio Cuni 4ed903b 





Antonio Cuni 8255616 





Antonio Cuni d71f862 
Antonio Cuni 4ed903b 
James Lan 6cf85e6 
Antonio Cuni f1e1464 


Antonio Cuni eed0696 
Antonio Cuni f1e1464 
Maciej Fijalkows… 40f5bd1 

Antonio Cuni f1e1464 



James Lan 6cf85e6 
Antonio Cuni f1e1464 
Antonio Cuni 547de9f 
Toby Watson 2087798 
Antonio Cuni f1e1464 
Toby Watson 2087798 
Antonio Cuni 547de9f 


Antonio Cuni f1e1464 
Maciej Fijalkows… 40f5bd1 
Antonio Cuni 3f2847e 
Antonio Cuni f1e1464 
Antonio Cuni 3f2847e 
Benjamin Peterso… 487ce4b 
Antonio Cuni 3f2847e 


Antonio Cuni 607ad91 

Antonio Cuni 3f2847e 









Antonio Cuni cd6e921 
Maciej Fijalkows… b5a2e0b 





Antonio Cuni 3f2847e 










Antonio Cuni 607ad91 
Benjamin Peterso… 487ce4b 
Antonio Cuni 607ad91 




Antonio Cuni 3f2847e 

Antonio Cuni 607ad91 



Antonio Cuni 3f2847e 




James Lan 6cf85e6 
Antonio Cuni f1e1464 

Antonio Cuni eed0696 
Samuele Pedroni 402c7b0 








Anders Chrigströ… 112186e 
Samuele Pedroni 402c7b0 


Carl Friedrich B… e820a54 

Samuele Pedroni 402c7b0 
Anders Chrigströ… bc34283 
Samuele Pedroni 402c7b0 


Carl Friedrich B… e820a54 
Anders Chrigströ… bc34283 
Antonio Cuni fc63e3e 


Antonio Cuni 547de9f 


Samuele Pedroni defebc9 


Samuele Pedroni 402c7b0 


















Samuele Pedroni acc3486 

Samuele Pedroni 402c7b0 


Maciej Fijalkows… b5a2e0b 

Samuele Pedroni 402c7b0 
Carl Friedrich B… e820a54 
Samuele Pedroni 402c7b0 










Maciej Fijalkows… 75307d4 
Samuele Pedroni 402c7b0 
  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
import sys, os
import os.path
import shutil

from pypy.translator.translator import TranslationContext
from pypy.translator.tool.taskengine import SimpleTaskEngine
from pypy.translator.goal import query
from pypy.translator.goal.timing import Timer
from pypy.annotation.listdef import s_list_of_strings
from pypy.annotation import policy as annpolicy
from pypy.tool.udir import udir
from pypy.tool.debug_print import debug_start, debug_print, debug_stop
from pypy.rlib.entrypoint import secondary_entrypoints

import py
from pypy.tool.ansi_print import ansi_log
log = py.log.Producer("translation")
py.log.setconsumer("translation", ansi_log)


def taskdef(deps, title, new_state=None, expected_states=[],
            idemp=False, earlycheck=None):
    def decorator(taskfunc):
        taskfunc.task_deps = deps
        taskfunc.task_title = title
        taskfunc.task_newstate = None
        taskfunc.task_expected_states = expected_states
        taskfunc.task_idempotent = idemp
        taskfunc.task_earlycheck = earlycheck
        return taskfunc
    return decorator

# TODO:
# sanity-checks using states

_BACKEND_TO_TYPESYSTEM = {
    'c': 'lltype',
}

def backend_to_typesystem(backend):
    return _BACKEND_TO_TYPESYSTEM.get(backend, 'ootype')

# set of translation steps to profile
PROFILE = set([])

class Instrument(Exception):
    pass


class ProfInstrument(object):
    name = "profinstrument"
    def __init__(self, datafile, compiler):
        self.datafile = datafile
        self.compiler = compiler

    def first(self):
        return self.compiler._build()

    def probe(self, exe, args):
        env = os.environ.copy()
        env['PYPY_INSTRUMENT_COUNTERS'] = str(self.datafile)
        self.compiler.platform.execute(exe, args, env=env)
        
    def after(self):
        # xxx
        os._exit(0)


class TranslationDriver(SimpleTaskEngine):
    _backend_extra_options = {}

    def __init__(self, setopts=None, default_goal=None,
                 disable=[],
                 exe_name=None, extmod_name=None,
                 config=None, overrides=None):
        self.timer = Timer()
        SimpleTaskEngine.__init__(self)

        self.log = log

        if config is None:
            from pypy.config.pypyoption import get_pypy_config
            config = get_pypy_config(translating=True)
        self.config = config
        if overrides is not None:
            self.config.override(overrides)

        if setopts is not None:
            self.config.set(**setopts)

        self.exe_name = exe_name
        self.extmod_name = extmod_name

        self.done = {}

        self.disable(disable)

        if default_goal:
            default_goal, = self.backend_select_goals([default_goal])
            if default_goal in self._maybe_skip():
                default_goal = None
        
        self.default_goal = default_goal
        self.extra_goals = []
        self.exposed = []

        # expose tasks
        def expose_task(task, backend_goal=None):
            if backend_goal is None:
                backend_goal = task
            def proc():
                return self.proceed(backend_goal)
            self.exposed.append(task)
            setattr(self, task, proc)

        backend, ts = self.get_backend_and_type_system()
        for task in self.tasks:
            explicit_task = task
            if task == 'annotate':
                expose_task(task)
            else:
                task, postfix = task.split('_')
                if task in ('rtype', 'backendopt', 'llinterpret',
                            'pyjitpl'):
                    if ts:
                        if ts == postfix:
                            expose_task(task, explicit_task)
                    else:
                        expose_task(explicit_task)
                elif task in ('source', 'compile', 'run'):
                    if backend:
                        if backend == postfix:
                            expose_task(task, explicit_task)
                    elif ts:
                        if ts == backend_to_typesystem(postfix):
                            expose_task(explicit_task)
                    else:
                        expose_task(explicit_task)

    def set_extra_goals(self, goals):
        self.extra_goals = goals

    def set_backend_extra_options(self, extra_options):
        self._backend_extra_options = extra_options
        
    def get_info(self): # XXX more?
        d = {'backend': self.config.translation.backend}
        return d

    def get_backend_and_type_system(self):
        type_system = self.config.translation.type_system
        backend = self.config.translation.backend
        return backend, type_system

    def backend_select_goals(self, goals):
        backend, ts = self.get_backend_and_type_system()
        postfixes = [''] + ['_'+p for p in (backend, ts) if p]
        l = []
        for goal in goals:
            for postfix in postfixes:
                cand = "%s%s" % (goal, postfix)
                if cand in self.tasks:
                    new_goal = cand
                    break
            else:
                raise Exception, "cannot infer complete goal from: %r" % goal 
            l.append(new_goal)
        return l

    def disable(self, to_disable):
        self._disabled = to_disable

    def _maybe_skip(self):
        maybe_skip = []
        if self._disabled:
             for goal in self.backend_select_goals(self._disabled):
                 maybe_skip.extend(self._depending_on_closure(goal))
        return dict.fromkeys(maybe_skip).keys()


    def setup(self, entry_point, inputtypes, policy=None, extra={}, empty_translator=None):
        standalone = inputtypes is None
        self.standalone = standalone

        if standalone:
            # the 'argv' parameter
            inputtypes = [s_list_of_strings]
        self.inputtypes = inputtypes

        if policy is None:
            policy = annpolicy.AnnotatorPolicy()
        self.policy = policy

        self.extra = extra

        if empty_translator:
            translator = empty_translator
        else:
            translator = TranslationContext(config=self.config)

        self.entry_point = entry_point
        self.translator = translator
        self.libdef = None
        self.secondary_entrypoints = []

        if self.config.translation.secondaryentrypoints:
            for key in self.config.translation.secondaryentrypoints.split(","):
                try:
                    points = secondary_entrypoints[key]
                except KeyError:
                    raise KeyError(
                        "Entrypoints not found. I only know the keys %r." %
                        (", ".join(secondary_entrypoints.keys()), ))
                self.secondary_entrypoints.extend(points)

        self.translator.driver_instrument_result = self.instrument_result

    def setup_library(self, libdef, policy=None, extra={}, empty_translator=None):
        """ Used by carbon python only. """
        self.setup(None, None, policy, extra, empty_translator)
        self.libdef = libdef
        self.secondary_entrypoints = libdef.functions

    def instrument_result(self, args):
        backend, ts = self.get_backend_and_type_system()
        if backend != 'c' or sys.platform == 'win32':
            raise Exception("instrumentation requires the c backend"
                            " and unix for now")

        datafile = udir.join('_instrument_counters')
        makeProfInstrument = lambda compiler: ProfInstrument(datafile, compiler)

        pid = os.fork()
        if pid == 0:
            # child compiling and running with instrumentation
            self.config.translation.instrument = True
            self.config.translation.instrumentctl = (makeProfInstrument,
                                                     args)
            raise Instrument
        else:
            pid, status = os.waitpid(pid, 0)
            if os.WIFEXITED(status):
                status = os.WEXITSTATUS(status)
                if status != 0:
                    raise Exception, "instrumentation child failed: %d" % status
            else:
                raise Exception, "instrumentation child aborted"
            import array, struct
            n = datafile.size()//struct.calcsize('L')
            datafile = datafile.open('rb')
            counters = array.array('L')
            counters.fromfile(datafile, n)
            datafile.close()
            return counters

    def info(self, msg):
        log.info(msg)

    def _profile(self, goal, func):
        from cProfile import Profile
        from pypy.tool.lsprofcalltree import KCacheGrind
        d = {'func':func}
        prof = Profile()
        prof.runctx("res = func()", globals(), d)
        KCacheGrind(prof).output(open(goal + ".out", "w"))
        return d['res']

    def _do(self, goal, func, *args, **kwds):
        title = func.task_title
        if goal in self.done:
            self.log.info("already done: %s" % title)
            return
        else:
            self.log.info("%s..." % title)
        debug_start('translation-task')
        debug_print('starting', goal)
        self.timer.start_event(goal)
        try:
            instrument = False
            try:
                if goal in PROFILE:
                    res = self._profile(goal, func)
                else:
                    res = func()
            except Instrument:
                instrument = True
            if not func.task_idempotent:
                self.done[goal] = True
            if instrument:
                self.proceed('compile')
                assert False, 'we should not get here'
        finally:
            try:
                debug_stop('translation-task')
                self.timer.end_event(goal)
            except (KeyboardInterrupt, SystemExit):
                raise
            except:
                pass
        #import gc; gc.dump_rpy_heap('rpyheap-after-%s.dump' % goal)
        return res

    @taskdef([], "Annotating&simplifying")
    def task_annotate(self):
        """ Annotate
        """
        # includes annotation and annotatation simplifications
        translator = self.translator
        policy = self.policy
        self.log.info('with policy: %s.%s' % (policy.__class__.__module__, policy.__class__.__name__))

        annotator = translator.buildannotator(policy=policy)

        if self.secondary_entrypoints is not None:
            for func, inputtypes in self.secondary_entrypoints:
                if inputtypes == Ellipsis:
                    continue
                rettype = annotator.build_types(func, inputtypes, False)

        if self.entry_point:
            s = annotator.build_types(self.entry_point, self.inputtypes)
            translator.entry_point_graph = annotator.bookkeeper.getdesc(self.entry_point).getuniquegraph()
        else:
            s = None

        self.sanity_check_annotation()
        if self.entry_point and self.standalone and s.knowntype != int:
            raise Exception("stand-alone program entry point must return an "
                            "int (and not, e.g., None or always raise an "
                            "exception).")
        annotator.complete()
        annotator.simplify()
        return s


    def sanity_check_annotation(self):
        translator = self.translator
        irreg = query.qoutput(query.check_exceptblocks_qgen(translator))
        if irreg:
            self.log.info("Some exceptblocks seem insane")

        lost = query.qoutput(query.check_methods_qgen(translator))
        assert not lost, "lost methods, something gone wrong with the annotation of method defs"

    RTYPE = 'rtype_lltype'
    @taskdef(['annotate'], "RTyping")
    def task_rtype_lltype(self):
        """ RTyping - lltype version
        """
        rtyper = self.translator.buildrtyper(type_system='lltype')
        rtyper.specialize(dont_simplify_again=True)

    OOTYPE = 'rtype_ootype'
    @taskdef(['annotate'], "ootyping")
    def task_rtype_ootype(self):
        """ RTyping - ootype version
        """
        # Maybe type_system should simply be an option used in task_rtype
        rtyper = self.translator.buildrtyper(type_system="ootype")
        rtyper.specialize(dont_simplify_again=True)

    @taskdef([RTYPE], "JIT compiler generation")
    def task_pyjitpl_lltype(self):
        """ Generate bytecodes for JIT and flow the JIT helper functions
        ootype version
        """
        get_policy = self.extra['jitpolicy']
        self.jitpolicy = get_policy(self)
        #
        from pypy.jit.metainterp.warmspot import apply_jit
        apply_jit(self.translator, policy=self.jitpolicy,
                  backend_name=self.config.translation.jit_backend, inline=True)
        #
        self.log.info("the JIT compiler was generated")

    @taskdef([OOTYPE], "JIT compiler generation")
    def task_pyjitpl_ootype(self):
        """ Generate bytecodes for JIT and flow the JIT helper functions
        ootype version
        """
        get_policy = self.extra['jitpolicy']
        self.jitpolicy = get_policy(self)
        #
        from pypy.jit.metainterp.warmspot import apply_jit
        apply_jit(self.translator, policy=self.jitpolicy,
                  backend_name='cli', inline=True) #XXX
        #
        self.log.info("the JIT compiler was generated")

    @taskdef([RTYPE], "test of the JIT on the llgraph backend")
    def task_jittest_lltype(self):
        """ Run with the JIT on top of the llgraph backend
        """
        # parent process loop: spawn a child, wait for the child to finish,
        # print a message, and restart
        from pypy.translator.goal import unixcheckpoint
        unixcheckpoint.restartable_point(auto='run')
        # load the module pypy/jit/tl/jittest.py, which you can hack at
        # and restart without needing to restart the whole translation process
        from pypy.jit.tl import jittest
        jittest.jittest(self)

    BACKENDOPT = 'backendopt_lltype'
    @taskdef([RTYPE, '??pyjitpl_lltype', '??jittest_lltype'], "lltype back-end optimisations")
    def task_backendopt_lltype(self):
        """ Run all backend optimizations - lltype version
        """
        from pypy.translator.backendopt.all import backend_optimizations
        backend_optimizations(self.translator)

    OOBACKENDOPT = 'backendopt_ootype'
    @taskdef([OOTYPE], "ootype back-end optimisations")
    def task_backendopt_ootype(self):
        """ Run all backend optimizations - ootype version
        """
        from pypy.translator.backendopt.all import backend_optimizations
        backend_optimizations(self.translator)


    STACKCHECKINSERTION = 'stackcheckinsertion_lltype'
    @taskdef(['?'+BACKENDOPT, RTYPE, 'annotate'], "inserting stack checks")
    def task_stackcheckinsertion_lltype(self):
        from pypy.translator.transform import insert_ll_stackcheck
        count = insert_ll_stackcheck(self.translator)
        self.log.info("inserted %d stack checks." % (count,))
        

    def possibly_check_for_boehm(self):
        if self.config.translation.gc == "boehm":
            from pypy.rpython.tool.rffi_platform import configure_boehm
            from pypy.translator.platform import CompilationError
            try:
                configure_boehm(self.translator.platform)
            except CompilationError, e:
                i = 'Boehm GC not installed.  Try e.g. "translate.py --gc=hybrid"'
                raise Exception(str(e) + '\n' + i)

    @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE, '?annotate'],
        "Creating database for generating c source",
        earlycheck = possibly_check_for_boehm)
    def task_database_c(self):
        """ Create a database for further backend generation
        """
        translator = self.translator
        if translator.annotator is not None:
            translator.frozen = True

        standalone = self.standalone

        if standalone:
            from pypy.translator.c.genc import CStandaloneBuilder
            cbuilder = CStandaloneBuilder(self.translator, self.entry_point,
                                          config=self.config,
                      secondary_entrypoints=self.secondary_entrypoints)
        else:
            from pypy.translator.c.dlltool import CLibraryBuilder
            functions = [(self.entry_point, None)] + self.secondary_entrypoints
            cbuilder = CLibraryBuilder(self.translator, self.entry_point,
                                       functions=functions,
                                       name='libtesting',
                                       config=self.config)
        if not standalone:     # xxx more messy
            cbuilder.modulename = self.extmod_name
        database = cbuilder.build_database()
        self.log.info("database for generating C source was created")
        self.cbuilder = cbuilder
        self.database = database

    @taskdef(['database_c'], "Generating c source")
    def task_source_c(self):
        """ Create C source files from the generated database
        """
        cbuilder = self.cbuilder
        database = self.database
        if self._backend_extra_options.get('c_debug_defines', False):
            defines = cbuilder.DEBUG_DEFINES
        else:
            defines = {}
        if self.exe_name is not None:
            exe_name = self.exe_name % self.get_info()
        else:
            exe_name = None
        c_source_filename = cbuilder.generate_source(database, defines,
                                                     exe_name=exe_name)
        self.log.info("written: %s" % (c_source_filename,))
        if self.config.translation.dump_static_data_info:
            from pypy.translator.tool.staticsizereport import dump_static_data_info
            targetdir = cbuilder.targetdir
            fname = dump_static_data_info(self.log, database, targetdir)
            dstname = self.compute_exe_name() + '.staticdata.info'
            shutil.copy(str(fname), str(dstname))
            self.log.info('Static data info written to %s' % dstname)

    def compute_exe_name(self):
        newexename = self.exe_name % self.get_info()
        if '/' not in newexename and '\\' not in newexename:
            newexename = './' + newexename
        return py.path.local(newexename)

    def create_exe(self):
        """ Copy the compiled executable into translator/goal
        """
        if self.exe_name is not None:
            exename = self.c_entryp
            newexename = mkexename(self.compute_exe_name())
            shutil.copy(str(exename), str(newexename))
            if self.cbuilder.shared_library_name is not None:
                soname = self.cbuilder.shared_library_name
                newsoname = newexename.new(basename=soname.basename)
                shutil.copy(str(soname), str(newsoname))
                self.log.info("copied: %s" % (newsoname,))
                if sys.platform == 'win32':
                    shutil.copyfile(str(soname.new(ext='lib')),
                                    str(newsoname.new(ext='lib')))
            self.c_entryp = newexename
        self.log.info('usession directory: %s' % (udir,))
        self.log.info("created: %s" % (self.c_entryp,))

    @taskdef(['source_c'], "Compiling c source")
    def task_compile_c(self):
        """ Compile the generated C code using either makefile or
        translator/platform
        """
        cbuilder = self.cbuilder
        kwds = {}
        if self.standalone and self.exe_name is not None:
            kwds['exe_name'] = self.compute_exe_name().basename
        cbuilder.compile(**kwds)

        if self.standalone:
            self.c_entryp = cbuilder.executable_name
            self.create_exe()
        else:
            self.c_entryp = cbuilder.get_entry_point()

    @taskdef([STACKCHECKINSERTION, '?'+BACKENDOPT, RTYPE], "LLInterpreting")
    def task_llinterpret_lltype(self):
        from pypy.rpython.llinterp import LLInterpreter
        py.log.setconsumer("llinterp operation", None)
        
        translator = self.translator
        interp = LLInterpreter(translator.rtyper)
        bk = translator.annotator.bookkeeper
        graph = bk.getdesc(self.entry_point).getuniquegraph()
        v = interp.eval_graph(graph,
                              self.extra.get('get_llinterp_args',
                                             lambda: [])())

        log.llinterpret.event("result -> %s" % v)

    @taskdef(["?" + OOBACKENDOPT, OOTYPE], 'Generating CLI source')
    def task_source_cli(self):
        from pypy.translator.cli.gencli import GenCli
        from pypy.translator.cli.entrypoint import get_entrypoint

        if self.entry_point is not None: # executable mode
            entry_point_graph = self.translator.graphs[0]
            entry_point = get_entrypoint(entry_point_graph)
        else:
            # library mode
            assert self.libdef is not None
            bk = self.translator.annotator.bookkeeper
            entry_point = self.libdef.get_entrypoint(bk)

        self.gen = GenCli(udir, self.translator, entry_point, config=self.config)
        filename = self.gen.generate_source()
        self.log.info("Wrote %s" % (filename,))

    @taskdef(['source_cli'], 'Compiling CLI source')
    def task_compile_cli(self):
        from pypy.translator.oosupport.support import unpatch_os
        from pypy.translator.cli.test.runtest import CliFunctionWrapper
        filename = self.gen.build_exe()
        self.c_entryp = CliFunctionWrapper(filename)
        # restore original os values
        if hasattr(self, 'old_cli_defs'):
            unpatch_os(self.old_cli_defs)
        
        self.log.info("Compiled %s" % filename)
        if self.standalone and self.exe_name:
            self.copy_cli_exe()

    def copy_cli_exe(self):
        # XXX messy
        main_exe = self.c_entryp._exe
        usession_path, main_exe_name = os.path.split(main_exe)
        pypylib_dll = os.path.join(usession_path, 'pypylib.dll')

        basename = self.exe_name % self.get_info()
        dirname = basename + '-data/'
        if '/' not in dirname and '\\' not in dirname:
            dirname = './' + dirname

        if not os.path.exists(dirname):
            os.makedirs(dirname)
        shutil.copy(main_exe, dirname)
        shutil.copy(pypylib_dll, dirname)
        if bool(os.getenv('PYPY_GENCLI_COPYIL')):
            shutil.copy(os.path.join(usession_path, 'main.il'), dirname)
        newexename = basename
        f = file(newexename, 'w')
        f.write(r"""#!/bin/bash
LEDIT=`type -p ledit`
EXE=`readlink $0`
if [ -z $EXE ]
then
    EXE=$0
fi
if  uname -s | grep -iq Cygwin
then 
    MONO=
else 
    MONO=mono
    # workaround for known mono buggy versions
    VER=`mono -V | head -1 | sed s/'Mono JIT compiler version \(.*\) (.*'/'\1/'`
    if [[ 2.1 < "$VER" && "$VER" < 2.4.3 ]]
    then
        MONO="mono -O=-branch"
    fi
fi
$LEDIT $MONO "$(dirname $EXE)/$(basename $EXE)-data/%s" "$@" # XXX doesn't work if it's placed in PATH
""" % main_exe_name)
        f.close()
        os.chmod(newexename, 0755)

    def copy_cli_dll(self):
        dllname = self.gen.outfile
        usession_path, dll_name = os.path.split(dllname)
        pypylib_dll = os.path.join(usession_path, 'pypylib.dll')
        shutil.copy(dllname, '.')
        shutil.copy(pypylib_dll, '.')
        
        # main.exe is a stub but is needed right now because it's
        # referenced by pypylib.dll.  Will be removed in the future
        translator_path, _ = os.path.split(__file__)
        main_exe = os.path.join(translator_path, 'cli/src/main.exe')
        shutil.copy(main_exe, '.')
        self.log.info("Copied to %s" % os.path.join(os.getcwd(), dllname))

    @taskdef(["?" + OOBACKENDOPT, OOTYPE], 'Generating JVM source')
    def task_source_jvm(self):
        from pypy.translator.jvm.genjvm import GenJvm
        from pypy.translator.jvm.node import EntryPoint

        entry_point_graph = self.translator.graphs[0]
        is_func = not self.standalone
        entry_point = EntryPoint(entry_point_graph, is_func, is_func)
        self.gen = GenJvm(udir, self.translator, entry_point)
        self.jvmsource = self.gen.generate_source()
        self.log.info("Wrote JVM code")

    @taskdef(['source_jvm'], 'Compiling JVM source')
    def task_compile_jvm(self):
        from pypy.translator.oosupport.support import unpatch_os
        from pypy.translator.jvm.test.runtest import JvmGeneratedSourceWrapper
        self.jvmsource.compile()
        self.c_entryp = JvmGeneratedSourceWrapper(self.jvmsource)
        # restore original os values
        if hasattr(self, 'old_cli_defs'):
            unpatch_os(self.old_cli_defs)
        self.log.info("Compiled JVM source")
        if self.standalone and self.exe_name:
            self.copy_jvm_jar()

    def copy_jvm_jar(self):
        import subprocess
        basename = self.exe_name % self.get_info()
        root = udir.join('pypy')
        manifest = self.create_manifest(root)
        jnajar = py.path.local(__file__).dirpath('jvm', 'src', 'jna.jar')
        classlist = self.create_classlist(root, [jnajar])
        jarfile = py.path.local(basename + '.jar')
        self.log.info('Creating jar file')
        oldpath = root.chdir()
        subprocess.call(['jar', 'cmf', str(manifest), str(jarfile), '@'+str(classlist)])
        oldpath.chdir()

        # create a convenience script
        newexename = basename
        f = file(newexename, 'w')
        f.write("""#!/bin/bash
LEDIT=`type -p ledit`
EXE=`readlink $0`
if [ -z $EXE ]
then
    EXE=$0
fi
$LEDIT java -Xmx256m -jar $EXE.jar "$@"
""")
        f.close()
        os.chmod(newexename, 0755)

    def create_manifest(self, root):
        filename = root.join('manifest.txt')
        manifest = filename.open('w')
        manifest.write('Main-class: pypy.Main\n\n')
        manifest.close()
        return filename

    def create_classlist(self, root, additional_jars=[]):
        import subprocess
        # first, uncompress additional jars
        for jarfile in additional_jars:
            oldpwd = root.chdir()
            subprocess.call(['jar', 'xf', str(jarfile)])
            oldpwd.chdir()
        filename = root.join('classlist.txt')
        classlist = filename.open('w')
        classfiles = list(root.visit('*.class', True))
        classfiles += root.visit('*.so', True)
        classfiles += root.visit('*.dll', True)
        classfiles += root.visit('*.jnilib', True)
        for classfile in classfiles:
            print >> classlist, classfile.relto(root)
        classlist.close()
        return filename

    @taskdef(['compile_jvm'], 'XXX')
    def task_run_jvm(self):
        pass

    def proceed(self, goals):
        if not goals:
            if self.default_goal:
                goals = [self.default_goal]
            else:
                self.log.info("nothing to do")
                return
        elif isinstance(goals, str):
            goals = [goals]
        goals.extend(self.extra_goals)
        goals = self.backend_select_goals(goals)
        return self._execute(goals, task_skip = self._maybe_skip())

    def from_targetspec(targetspec_dic, config=None, args=None,
                        empty_translator=None,
                        disable=[],
                        default_goal=None):
        if args is None:
            args = []

        driver = TranslationDriver(config=config, default_goal=default_goal,
                                   disable=disable)
        # patch some attributes of the os module to make sure they
        # have the same value on every platform.
        backend, ts = driver.get_backend_and_type_system()
        if backend in ('cli', 'jvm'):
            from pypy.translator.oosupport.support import patch_os
            driver.old_cli_defs = patch_os()
        
        target = targetspec_dic['target']
        spec = target(driver, args)

        try:
            entry_point, inputtypes, policy = spec
        except ValueError:
            entry_point, inputtypes = spec
            policy = None

        driver.setup(entry_point, inputtypes, 
                     policy=policy, 
                     extra=targetspec_dic,
                     empty_translator=empty_translator)

        return driver

    from_targetspec = staticmethod(from_targetspec)

    def prereq_checkpt_rtype(self):
        assert 'pypy.rpython.rmodel' not in sys.modules, (
            "cannot fork because the rtyper has already been imported")
    prereq_checkpt_rtype_lltype = prereq_checkpt_rtype
    prereq_checkpt_rtype_ootype = prereq_checkpt_rtype    

    # checkpointing support
    def _event(self, kind, goal, func):
        if kind == 'planned' and func.task_earlycheck:
            func.task_earlycheck(self)
        if kind == 'pre':
            fork_before = self.config.translation.fork_before
            if fork_before:
                fork_before, = self.backend_select_goals([fork_before])
                if not fork_before in self.done and fork_before == goal:
                    prereq = getattr(self, 'prereq_checkpt_%s' % goal, None)
                    if prereq:
                        prereq()
                    from pypy.translator.goal import unixcheckpoint
                    unixcheckpoint.restartable_point(auto='run')

def mkexename(name):
    if sys.platform == 'win32':
        name = name.new(ext='exe')
    return name