07cf16db52498c28ba5ab16ee806224c1230dece
[nit.git] / src / debugger_socket.nit
1 # This file is part of NIT ( http://www.nitlanguage.org ).
2 #
3 # Copyright 2014 Johan Kayser <kayser.johan@gmail.com>
4 #
5 # Licensed under the Apache License, Version 2.0 (the "License");
6 # you may not use this file except in compliance with the License.
7 # You may obtain a copy of the License at
8 #
9 # http://www.apache.org/licenses/LICENSE-2.0
10 #
11 # Unless required by applicable law or agreed to in writing, software
12 # distributed under the License is distributed on an "AS IS" BASIS,
13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 # See the License for the specific language governing permissions and
15 # limitations under the License.
16
17 # Debugging of a nit program using sockets.
18 module debugger_socket
19
20 intrude import debugger
21 import websocket
22
23 redef class ToolContext
24 # --socket
25 var opt_socket_mode = new OptionBool("Launches the target program with raw output on the network via sockets", "--socket")
26
27 # --websocket
28 var opt_websocket_mode = new OptionBool("Launches the target program with output on the network via websockets", "--websocket")
29
30 # --port
31 var opt_debug_port: OptionInt = new OptionInt("Sets the debug port (Defaults to 22125) - Must be contained between 0 and 65535", 22125, "--port")
32
33 redef init
34 do
35 super
36 self.option_context.add_option(self.opt_socket_mode)
37 self.option_context.add_option(self.opt_websocket_mode)
38 self.option_context.add_option(self.opt_debug_port)
39 end
40 end
41
42 redef class ModelBuilder
43 # Execute the program from the entry point (Sys::main) of the `mainmodule`
44 # `arguments` are the command-line arguments in order
45 # REQUIRE that:
46 # 1. the AST is fully loaded.
47 # 2. the model is fully built.
48 # 3. the instructions are fully analysed.
49 redef fun run_debugger(mainmodule: MModule, arguments: Array[String])
50 do
51 var time0 = get_time
52 self.toolcontext.info("*** START INTERPRETING ***", 1)
53
54 var interpreter = new Debugger(self, mainmodule, arguments)
55
56 set_stdstreams
57
58 init_naive_interpreter(interpreter, mainmodule)
59
60 close_stdstreams
61
62 var time1 = get_time
63 self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
64 end
65
66 redef fun run_debugger_autorun(mainmodule: MModule, arguments: Array[String])
67 do
68 var time0 = get_time
69 self.toolcontext.info("*** START INTERPRETING ***", 1)
70
71 var interpreter = new Debugger(self, mainmodule, arguments)
72 interpreter.autocontinue = true
73
74 set_stdstreams
75
76 init_naive_interpreter(interpreter, mainmodule)
77
78 close_stdstreams
79
80 var time1 = get_time
81 self.toolcontext.info("*** END INTERPRETING: {time1-time0} ***", 2)
82 end
83
84 redef fun run_naive_interpreter(mmod, args)
85 do
86 set_stdstreams
87 super
88 end
89
90 fun set_stdstreams
91 do
92 if self.toolcontext.opt_socket_mode.value then
93 var sock = new Socket.server(toolcontext.opt_debug_port.value, 1)
94 var ns = sock.accept
95 sock.close
96 sys.set_io(ns,ns,ns)
97 else if self.toolcontext.opt_websocket_mode.value then
98 var websock = new WebSocket(toolcontext.opt_debug_port.value, 1)
99 websock.accept
100 sys.set_io(websock,websock,websock)
101 end
102 end
103
104 fun close_stdstreams
105 do
106 if sys.stdin isa WebSocket or sys.stdin isa Socket then
107 sys.stdin.close
108 sys.stdout.close
109 sys.stderr.close
110 end
111 end
112 end
113
114 redef class Sys
115 private fun set_io(istream: PollableIStream, ostream: OStream, errstream: OStream)
116 do
117 self.stdin = istream
118 self.stdout = ostream
119 self.stderr = ostream
120 end
121 end