-
Notifications
You must be signed in to change notification settings - Fork 10
Expand file tree
/
Copy pathmain.py
More file actions
executable file
·166 lines (143 loc) · 5.49 KB
/
Copy pathmain.py
File metadata and controls
executable file
·166 lines (143 loc) · 5.49 KB
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
from rpython.rlib import jit
from rpython.rtyper.lltypesystem import rffi, lltype, llmemory
import vectormath
from evaluator.loader import TraceEntry
import uv_stream
import base
import space
import time
import module_resolution
import os
import pathobj
import rlibuv as uv
from stdlib import api # XXX: perhaps give every module an init?
# Probably better way is to move the path resolution from api into here.
import core
import uv_logging
@jit.dont_look_inside # cast_ptr_to_adr
def wakeup_sleeper(handle):
ec = core.get_ec()
task = ec.uv_sleepers.pop( rffi.cast_ptr_to_adr(handle) )
ec.enqueue(task)
uv.timer_stop(handle)
uv.close(rffi.cast(uv.handle_ptr, handle), uv.free)
inf = float("inf")
def new_entry_point(config, default_lever_path=u''):
import naming
naming.breath_first_search(base.module, 1.0)
def entry_point(raw_argv):
lever_path = os.environ.get('LEVER_PATH')
if lever_path is None:
lever_path = pathobj.parse(default_lever_path)
else:
lever_path = pathobj.os_parse(lever_path.decode('utf-8'))
lever_path = pathobj.concat(pathobj.getcwd(), lever_path)
# This should happen only once.
uv_loop = uv.default_loop()
uv_idler = uv.malloc_bytes(uv.idle_ptr, uv.handle_size(uv.IDLE))
uv.idle_init(uv_loop, uv_idler)
uv_stdin = initialize_stdio(uv_loop, 0, 1)
uv_stdout = initialize_stdio(uv_loop, 1, 0)
uv_stderr = initialize_stdio(uv_loop, 2, 0)
base.module.setattr_force(u"stdin", uv_stdin)
base.module.setattr_force(u"stdout", uv_stdout)
base.module.setattr_force(u"stderr", uv_stderr)
base.module.setattr_force(u"runtime_path", lever_path)
ec = core.init_executioncontext(config, lever_path, uv_loop, uv_idler)
core.g.log = log = uv_logging.Logger(ec, uv_stdout, uv_stderr)
core.g.finalizer_ec = ec
api.init(lever_path)
vectormath.init_random()
argv = [normal_startup]
for arg in raw_argv[1:]:
argv.append(space.String(arg.decode('utf-8')))
core.schedule(argv)
live = True
while live:
uv.run(ec.uv_loop, uv.RUN_DEFAULT)
live = core.enqueue_for_exit(ec)
#uv.loop_close(ec.uv_loop)
uv.tty_reset_mode()
log.last_chance_logging()
return ec.exit_status
return entry_point
@space.Builtin
def normal_startup(argv):
if len(argv) > 0:
main_script = argv[0]
else:
main_script = pathobj.concat(core.get_ec().lever_path, pathobj.parse(u"app/main.lc"))
main_script = space.String(pathobj.os_stringify(main_script))
module = module_resolution.start(main_script)
try:
main_func = module.getattr(u"main")
except space.Unwinder as unwinder:
pass # in this case main_func just isn't in the module.
else:
main_func.call([space.List(argv)])
return space.null
class Suspended(object):
_immutable_fields_ = ['wakeup', 'greenlet']
def __init__(self, wakeup, greenlet):
assert isinstance(greenlet, Greenlet)
self.wakeup = wakeup
self.greenlet = greenlet
@base.builtin
def sleep(argv):
if len(argv) == 1:
return sleep_greenlet(argv)
elif len(argv) == 2:
return sleep_callback(argv)
else:
raise space.OldError(u"expected 1 or 2 arguments to sleep(), got %d" % len(argv))
@space.signature(space.Float)
@jit.dont_look_inside # cast_ptr_to_adr
def sleep_greenlet(duration):
ec = core.get_ec()
if ec.current == ec.eventloop:
raise space.OldError(u"bad context for greenlet sleep")
assert ec.current.is_exhausted() == False
uv_sleeper = uv.malloc_bytes(uv.timer_ptr, uv.handle_size(uv.TIMER))
ec.uv_sleepers[rffi.cast_ptr_to_adr(uv_sleeper)] = ec.current
uv.timer_init(ec.uv_loop, uv_sleeper)
uv.timer_start(uv_sleeper, wakeup_sleeper, int(duration.number*1000), 0)
return core.switch([ec.eventloop])
@space.signature(space.Float, space.Object)
@jit.dont_look_inside # cast_ptr_to_adr
def sleep_callback(duration, func):
ec = core.get_ec()
uv_sleeper = uv.malloc_bytes(uv.timer_ptr, uv.handle_size(uv.TIMER))
ec.uv_sleepers[rffi.cast_ptr_to_adr(uv_sleeper)] = core.to_greenlet([func])
uv.timer_init(ec.uv_loop, uv_sleeper)
uv.timer_start(uv_sleeper, wakeup_sleeper, int(duration.number*1000), 0)
return space.null
# This is a rare case when it's better to do nothing than
# something, even if it means that we won't get any
# diagnostics of the error.
def initialize_stdio(uv_loop, fd, readable):
from uv_stream import TTY, Pipe
from stdlib.fs import File, ReadStream, WriteStream
handle_type = uv.guess_handle(fd)
if handle_type == uv.TTY:
tty = lltype.malloc(uv.tty_ptr.TO, flavor="raw", zero=True)
status = uv.tty_init(uv_loop, tty, fd, readable)
if status < 0:
lltype.free(tty, flavor='raw')
return space.null
return TTY(tty, fd)
elif handle_type == uv.NAMED_PIPE:
pipe = lltype.malloc(uv.pipe_ptr.TO, flavor="raw", zero=True)
status = uv.pipe_init(uv_loop, pipe, 1)
if status >= 0:
status = uv.pipe_open(pipe, fd)
if status < 0:
lltype.free(pipe, flavor='raw')
return space.null
return Pipe(pipe)
elif handle_type == uv.FILE:
if readable != 0:
return ReadStream(File(fd), 0)
else:
return WriteStream(File(fd), 0)
else:
return space.null