gisele-vm 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG.md +5 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +46 -0
- data/LICENCE.md +22 -0
- data/Manifest.txt +15 -0
- data/README.md +10 -0
- data/Rakefile +11 -0
- data/bin/gvm +9 -0
- data/gisele-vm.gemspec +191 -0
- data/gisele-vm.noespec +31 -0
- data/lib/gisele-vm.rb +4 -0
- data/lib/gisele-vm/loader.rb +5 -0
- data/lib/gisele-vm/version.rb +16 -0
- data/lib/gisele/compiling.rb +3 -0
- data/lib/gisele/compiling/gisele2gts.rb +143 -0
- data/lib/gisele/compiling/gts.rb +74 -0
- data/lib/gisele/compiling/gts2bytecode.rb +127 -0
- data/lib/gisele/vm.rb +87 -0
- data/lib/gisele/vm/bytecode.rb +84 -0
- data/lib/gisele/vm/bytecode/builder.rb +77 -0
- data/lib/gisele/vm/bytecode/grammar.citrus +116 -0
- data/lib/gisele/vm/bytecode/grammar.rb +19 -0
- data/lib/gisele/vm/bytecode/grammar.sexp.yml +113 -0
- data/lib/gisele/vm/bytecode/printer.rb +35 -0
- data/lib/gisele/vm/command.rb +140 -0
- data/lib/gisele/vm/component.rb +91 -0
- data/lib/gisele/vm/console.rb +58 -0
- data/lib/gisele/vm/enacter.rb +29 -0
- data/lib/gisele/vm/errors.rb +26 -0
- data/lib/gisele/vm/event.rb +11 -0
- data/lib/gisele/vm/event_manager.rb +65 -0
- data/lib/gisele/vm/kernel.rb +58 -0
- data/lib/gisele/vm/kernel/macros.gvm +214 -0
- data/lib/gisele/vm/kernel/opcodes.rb +212 -0
- data/lib/gisele/vm/kernel/runner.rb +63 -0
- data/lib/gisele/vm/lifecycle.rb +72 -0
- data/lib/gisele/vm/logging.rb +18 -0
- data/lib/gisele/vm/null_object.rb +19 -0
- data/lib/gisele/vm/prog.rb +63 -0
- data/lib/gisele/vm/prog_list.rb +55 -0
- data/lib/gisele/vm/prog_list/memory.rb +74 -0
- data/lib/gisele/vm/prog_list/sqldb.rb +123 -0
- data/lib/gisele/vm/prog_list/storage.rb +31 -0
- data/lib/gisele/vm/proxy.rb +14 -0
- data/lib/gisele/vm/proxy/client.rb +64 -0
- data/lib/gisele/vm/proxy/server.rb +29 -0
- data/lib/gisele/vm/registry.rb +57 -0
- data/lib/gisele/vm/robustness.rb +31 -0
- data/lib/gisele/vm/simulator/resumer.rb +32 -0
- data/spec/command/gvm_compile.cmd +1 -0
- data/spec/command/gvm_compile.stdout +111 -0
- data/spec/command/gvm_gts.cmd +1 -0
- data/spec/command/gvm_gts.stdout +101 -0
- data/spec/command/gvm_help.cmd +1 -0
- data/spec/command/gvm_help.stdout +30 -0
- data/spec/command/gvm_version.cmd +1 -0
- data/spec/command/gvm_version.stdout +2 -0
- data/spec/command/test_command.rb +29 -0
- data/spec/fixtures/complete.gis +13 -0
- data/spec/fixtures/fake_component.rb +24 -0
- data/spec/fixtures/kernel.rb +39 -0
- data/spec/fixtures/ts.adl +11 -0
- data/spec/fixtures/ts.gts +20 -0
- data/spec/fixtures/ts.gvm +19 -0
- data/spec/spec_helper.rb +86 -0
- data/spec/test_examples.rb +29 -0
- data/spec/test_gisele-vm.rb +8 -0
- data/spec/unit/bytecode/builder/test_at.rb +56 -0
- data/spec/unit/bytecode/builder/test_helpers.rb +36 -0
- data/spec/unit/bytecode/builder/test_instruction.rb +35 -0
- data/spec/unit/bytecode/builder/test_to_a.rb +53 -0
- data/spec/unit/bytecode/bytecode.gvm +1 -0
- data/spec/unit/bytecode/grammar/fixtures/comments.gvm +16 -0
- data/spec/unit/bytecode/grammar/fixtures/every.gvm +46 -0
- data/spec/unit/bytecode/grammar/fixtures/singleblock.gvm +2 -0
- data/spec/unit/bytecode/grammar/fixtures/twoblocks.gvm +4 -0
- data/spec/unit/bytecode/grammar/fixtures/with_end.gvm +5 -0
- data/spec/unit/bytecode/grammar/test_array.rb +24 -0
- data/spec/unit/bytecode/grammar/test_block.rb +35 -0
- data/spec/unit/bytecode/grammar/test_boolean.rb +20 -0
- data/spec/unit/bytecode/grammar/test_constant.rb +20 -0
- data/spec/unit/bytecode/grammar/test_eol.rb +20 -0
- data/spec/unit/bytecode/grammar/test_eol_comment.rb +36 -0
- data/spec/unit/bytecode/grammar/test_file.rb +38 -0
- data/spec/unit/bytecode/grammar/test_hash.rb +33 -0
- data/spec/unit/bytecode/grammar/test_instruction.rb +32 -0
- data/spec/unit/bytecode/grammar/test_int.rb +24 -0
- data/spec/unit/bytecode/grammar/test_label.rb +24 -0
- data/spec/unit/bytecode/grammar/test_opcode.rb +23 -0
- data/spec/unit/bytecode/grammar/test_string.rb +25 -0
- data/spec/unit/bytecode/grammar/test_symbol.rb +30 -0
- data/spec/unit/bytecode/test_build.rb +36 -0
- data/spec/unit/bytecode/test_coerce.rb +41 -0
- data/spec/unit/bytecode/test_fetch.rb +20 -0
- data/spec/unit/bytecode/test_grammar.rb +30 -0
- data/spec/unit/bytecode/test_parse.rb +22 -0
- data/spec/unit/bytecode/test_plus.rb +27 -0
- data/spec/unit/bytecode/test_to_a.rb +19 -0
- data/spec/unit/bytecode/test_to_s.rb +32 -0
- data/spec/unit/command/code.gis +3 -0
- data/spec/unit/command/test_vm.rb +51 -0
- data/spec/unit/compiling/gisele2gts/test_on_par_st.rb +51 -0
- data/spec/unit/compiling/gisele2gts/test_on_seq_st.rb +46 -0
- data/spec/unit/compiling/gisele2gts/test_on_task_call_st.rb +37 -0
- data/spec/unit/compiling/gisele2gts/test_on_task_def.rb +49 -0
- data/spec/unit/compiling/gisele2gts/test_on_unit_def.rb +35 -0
- data/spec/unit/compiling/gts2bytecode/test_on_end.rb +31 -0
- data/spec/unit/compiling/gts2bytecode/test_on_event.rb +37 -0
- data/spec/unit/compiling/gts2bytecode/test_on_fork.rb +41 -0
- data/spec/unit/compiling/gts2bytecode/test_on_join.rb +42 -0
- data/spec/unit/compiling/gts2bytecode/test_on_listen.rb +36 -0
- data/spec/unit/compiling/gts2bytecode/test_on_nop.rb +30 -0
- data/spec/unit/component/test_component_name.rb +16 -0
- data/spec/unit/component/test_logging.rb +36 -0
- data/spec/unit/enacter/test_component.rb +11 -0
- data/spec/unit/event/test_to_s.rb +12 -0
- data/spec/unit/event_manager/test_component.rb +9 -0
- data/spec/unit/event_manager/test_subscribe.rb +40 -0
- data/spec/unit/event_manager/test_unsubscribe.rb +39 -0
- data/spec/unit/kernel/macros/test_fork.rb +37 -0
- data/spec/unit/kernel/macros/test_join.rb +43 -0
- data/spec/unit/kernel/macros/test_listen.rb +37 -0
- data/spec/unit/kernel/macros/test_notify.rb +57 -0
- data/spec/unit/kernel/macros/test_react.rb +47 -0
- data/spec/unit/kernel/macros/test_schedule_at.rb +30 -0
- data/spec/unit/kernel/opcodes/test_op_del.rb +42 -0
- data/spec/unit/kernel/opcodes/test_op_event.rb +25 -0
- data/spec/unit/kernel/opcodes/test_op_fetch.rb +27 -0
- data/spec/unit/kernel/opcodes/test_op_flip.rb +17 -0
- data/spec/unit/kernel/opcodes/test_op_fold.rb +29 -0
- data/spec/unit/kernel/opcodes/test_op_fork.rb +63 -0
- data/spec/unit/kernel/opcodes/test_op_forka.rb +51 -0
- data/spec/unit/kernel/opcodes/test_op_get.rb +62 -0
- data/spec/unit/kernel/opcodes/test_op_getr.rb +48 -0
- data/spec/unit/kernel/opcodes/test_op_ifenil.rb +41 -0
- data/spec/unit/kernel/opcodes/test_op_ifezero.rb +32 -0
- data/spec/unit/kernel/opcodes/test_op_invoke.rb +34 -0
- data/spec/unit/kernel/opcodes/test_op_nop.rb +18 -0
- data/spec/unit/kernel/opcodes/test_op_parent.rb +39 -0
- data/spec/unit/kernel/opcodes/test_op_pop.rb +22 -0
- data/spec/unit/kernel/opcodes/test_op_push.rb +17 -0
- data/spec/unit/kernel/opcodes/test_op_save.rb +32 -0
- data/spec/unit/kernel/opcodes/test_op_savea.rb +34 -0
- data/spec/unit/kernel/opcodes/test_op_self.rb +20 -0
- data/spec/unit/kernel/opcodes/test_op_send.rb +20 -0
- data/spec/unit/kernel/opcodes/test_op_set.rb +61 -0
- data/spec/unit/kernel/opcodes/test_op_then.rb +50 -0
- data/spec/unit/kernel/opcodes/test_op_unfold.rb +22 -0
- data/spec/unit/kernel/opcodes/test_op_uuid.rb +16 -0
- data/spec/unit/kernel/runner/test_pop.rb +26 -0
- data/spec/unit/kernel/runner/test_stack.rb +28 -0
- data/spec/unit/kernel/test_progress.rb +47 -0
- data/spec/unit/kernel/test_resume.rb +53 -0
- data/spec/unit/kernel/test_start.rb +36 -0
- data/spec/unit/prog/test_to_hash.rb +29 -0
- data/spec/unit/prog/test_waitlist_eq.rb +20 -0
- data/spec/unit/prog_list/memory/test_component.rb +9 -0
- data/spec/unit/prog_list/memory/test_fetch.rb +40 -0
- data/spec/unit/prog_list/memory/test_pick.rb +39 -0
- data/spec/unit/prog_list/memory/test_save.rb +91 -0
- data/spec/unit/prog_list/memory/test_to_relation.rb +17 -0
- data/spec/unit/prog_list/sqldb/test_component.rb +11 -0
- data/spec/unit/prog_list/sqldb/test_connect.rb +46 -0
- data/spec/unit/prog_list/test_memory.rb +9 -0
- data/spec/unit/prog_list/test_sqldb.rb +13 -0
- data/spec/unit/prog_list/test_storage.rb +51 -0
- data/spec/unit/registry/test_component.rb +9 -0
- data/spec/unit/registry/test_connect.rb +53 -0
- data/spec/unit/registry/test_disconnect.rb +51 -0
- data/spec/unit/registry/test_registration.rb +44 -0
- data/spec/unit/shared/a_component.rb +49 -0
- data/spec/unit/shared/a_storage.rb +114 -0
- data/spec/unit/test_logging.rb +46 -0
- data/spec/unit/test_prog.rb +57 -0
- data/spec/unit/test_prog_list.rb +22 -0
- data/spec/unit/vm/test_event_facace.rb +11 -0
- data/spec/unit/vm/test_initialize.rb +59 -0
- data/spec/unit/vm/test_proglist_facade.rb +21 -0
- data/tasks/debug_mail.rake +75 -0
- data/tasks/debug_mail.txt +13 -0
- data/tasks/gem.rake +73 -0
- data/tasks/spec_test.rake +71 -0
- data/tasks/unit_test.rake +76 -0
- data/tasks/yard.rake +51 -0
- metadata +493 -0
@@ -0,0 +1,212 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
class Kernel
|
4
|
+
module Opcodes
|
5
|
+
|
6
|
+
private
|
7
|
+
|
8
|
+
### GENERIC OPCODES ################################################################
|
9
|
+
|
10
|
+
# Pops a method name on the stack unless `method` is specified. Pops an array of
|
11
|
+
# argument `args`. Pops an object `receiver`. Invoke `method` on `receiver`, passing
|
12
|
+
# arguments `args`. Push the result back on the stack.
|
13
|
+
def op_send(method = nil, push_result = true)
|
14
|
+
method ||= pop
|
15
|
+
args = pop
|
16
|
+
receiver = pop
|
17
|
+
result = receiver.send(method, *args)
|
18
|
+
push result if push_result
|
19
|
+
end
|
20
|
+
|
21
|
+
# Same as `op_send` but does not keep the result on the stack.
|
22
|
+
def op_invoke(method = nil)
|
23
|
+
op_send(method, false)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Push the value of the attribute `attrname` of the top object. If `attrname` is not
|
27
|
+
# specified, pops it from the stack first.
|
28
|
+
def op_get(attrname = nil, remove=false)
|
29
|
+
attrname ||= pop
|
30
|
+
receiver = remove ? pop : peek
|
31
|
+
if receiver.respond_to?(:[])
|
32
|
+
push receiver[attrname]
|
33
|
+
elsif receiver.respond_to?(attrname)
|
34
|
+
push receiver.send(attrname)
|
35
|
+
else
|
36
|
+
raise Error, "Unable to get #{attrname} on #{receiver.inspect}"
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Same as +get+ but removes the original receiver from the stack.
|
41
|
+
def op_getr(attrname = nil)
|
42
|
+
op_get(attrname, true)
|
43
|
+
end
|
44
|
+
|
45
|
+
# If `attrname` is unspecified, pops it from the stack first. Pops a value `val`
|
46
|
+
# from the stack. Set attribute `attrname` to `val` on the top object.
|
47
|
+
def op_set(attrname = nil)
|
48
|
+
attrname ||= pop
|
49
|
+
attrvalue = pop
|
50
|
+
receiver = peek
|
51
|
+
if receiver.respond_to?(:[]=)
|
52
|
+
receiver[attrname] = attrvalue
|
53
|
+
elsif receiver.respond_to?(:"#{attrname}=")
|
54
|
+
receiver.send(:"#{attrname}=", attrvalue)
|
55
|
+
else
|
56
|
+
raise Error, "Unable to set #{attrname} on #{receiver.inspect}"
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
# If `attrname` is unspecified, pops it from the stack first. Expects an object
|
61
|
+
# responding to :delete on top of the stack. Pops it, call `delete(attrname)` on
|
62
|
+
# a duplicate and push the later back on the stack.
|
63
|
+
def op_del(attrname = nil)
|
64
|
+
attrname ||= pop
|
65
|
+
push pop.dup
|
66
|
+
peek.delete(attrname)
|
67
|
+
end
|
68
|
+
|
69
|
+
### CONTROL ########################################################################
|
70
|
+
|
71
|
+
# Does nothing at all
|
72
|
+
def op_nop
|
73
|
+
end
|
74
|
+
|
75
|
+
# Pushes opcodes at label `at` on the code queue. If `at` is unspecified, it it
|
76
|
+
# poped from the stack first
|
77
|
+
def op_then(at = nil)
|
78
|
+
enlist_bytecode_at(at || pop)
|
79
|
+
end
|
80
|
+
|
81
|
+
# If the peek object is equal to `val`, flip top operations and skip the first one.
|
82
|
+
# Otherwise skip the top operation.
|
83
|
+
def op_ifeeq(val = nil)
|
84
|
+
if peek == val
|
85
|
+
t = opcodes.shift
|
86
|
+
opcodes.shift
|
87
|
+
opcodes.unshift t
|
88
|
+
else
|
89
|
+
opcodes.shift
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
# If the peek object is nil, flip top operations and skip the first one. Otherwise
|
94
|
+
# skip the top operation.
|
95
|
+
def op_ifenil
|
96
|
+
op_ifeeq(nil)
|
97
|
+
end
|
98
|
+
|
99
|
+
# If the peek object is zero, flip top operations and skip the first one. Otherwise
|
100
|
+
# skip the top operation.
|
101
|
+
def op_ifezero
|
102
|
+
op_ifeeq(0)
|
103
|
+
end
|
104
|
+
|
105
|
+
### LIFECYCLE ######################################################################
|
106
|
+
|
107
|
+
# Puts the puid of the executing Prog on the stack
|
108
|
+
def op_puid
|
109
|
+
push puid
|
110
|
+
end
|
111
|
+
|
112
|
+
# Push the current Prog on the stack.
|
113
|
+
def op_self
|
114
|
+
push prog
|
115
|
+
end
|
116
|
+
|
117
|
+
# Pushes the parent Prog of the executing program.
|
118
|
+
def op_parent
|
119
|
+
push(prog.parent==prog.puid ? nil : vm.fetch(prog.parent))
|
120
|
+
end
|
121
|
+
|
122
|
+
# Fetches the Prog whose id is `puid` and pushes it on the stack. if `puid` is not
|
123
|
+
# specified, pops it from the stack first.
|
124
|
+
def op_fetch(puid = nil)
|
125
|
+
push vm.fetch(puid || pop)
|
126
|
+
end
|
127
|
+
|
128
|
+
def fork(at)
|
129
|
+
Prog.new({
|
130
|
+
:parent => puid,
|
131
|
+
:pc => at,
|
132
|
+
:waitfor => :enacter,
|
133
|
+
:root => prog && prog.root
|
134
|
+
})
|
135
|
+
end
|
136
|
+
private :fork
|
137
|
+
|
138
|
+
# Fork the current Prog. Set its program counter to `at` (taken from the stack if
|
139
|
+
# not specified), and mark it as schedulable by default. The resulting Prog is
|
140
|
+
# pushed on the stack. It is not saved.
|
141
|
+
def op_fork(at = nil)
|
142
|
+
push fork(at || pop)
|
143
|
+
end
|
144
|
+
|
145
|
+
# Expects an array of labels on the stack. Same as +fork+ but in array version.
|
146
|
+
# A resulting array of unsaved Prog is put back on the stack.
|
147
|
+
def op_forka(at = nil)
|
148
|
+
at ||= pop
|
149
|
+
push at.map{|l| fork(l)}
|
150
|
+
end
|
151
|
+
|
152
|
+
# Pops `n` programs from the stack and save them. Pushes their puid back on
|
153
|
+
# the stack after saving, in the original order. `n` is considered 1 if unspecified.
|
154
|
+
def op_save(n = nil)
|
155
|
+
progs = pop(n || 1)
|
156
|
+
puids = vm.save(progs)
|
157
|
+
puids.reverse.each{|puid| push(puid)}
|
158
|
+
end
|
159
|
+
|
160
|
+
# Expects an array of Progs on the stack. Similar to +save+ but in array version.
|
161
|
+
# Push the resulting puids back on the stack in an array.
|
162
|
+
def op_savea
|
163
|
+
push vm.save(pop)
|
164
|
+
end
|
165
|
+
|
166
|
+
### DATA STACK MANAGEMENT ##########################################################
|
167
|
+
|
168
|
+
# Pushes `arg` on the data stack.
|
169
|
+
def op_push(arg)
|
170
|
+
push arg
|
171
|
+
end
|
172
|
+
|
173
|
+
# Pops the top element from the stack.
|
174
|
+
def op_pop(n = nil)
|
175
|
+
pop(n)
|
176
|
+
end
|
177
|
+
|
178
|
+
# Flips the two elements on top of the stack
|
179
|
+
def op_flip
|
180
|
+
pop(2).each{|e| push(e)}
|
181
|
+
end
|
182
|
+
|
183
|
+
# Pops `n` elements from the stack, keep them in a new array and push the later
|
184
|
+
# back on the stack. If `n` is not provided, it is taken from the stack first.
|
185
|
+
def op_fold(nb = nil)
|
186
|
+
n, arr = (nb || pop), []
|
187
|
+
n.times{ arr << pop }
|
188
|
+
push arr.reverse
|
189
|
+
end
|
190
|
+
|
191
|
+
# Pops an array. Unfolds it on the stack.
|
192
|
+
def op_unfold
|
193
|
+
pop.each do |elm|
|
194
|
+
push elm
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
### EVENT HANDLING #################################################################
|
199
|
+
|
200
|
+
# Pops event arguments from the stack (an array). Send an event of the specified
|
201
|
+
# kind on the event interface. If `type` is not provided, it is first poped from
|
202
|
+
# the stack
|
203
|
+
def op_event(type = nil)
|
204
|
+
type ||= pop
|
205
|
+
args = pop
|
206
|
+
vm.event(Event.new(prog, type, args))
|
207
|
+
end
|
208
|
+
|
209
|
+
end # module Opcodes
|
210
|
+
end # class Kernel
|
211
|
+
end # class VM
|
212
|
+
end # module Gisele
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
class Kernel
|
4
|
+
class Runner
|
5
|
+
include Opcodes
|
6
|
+
|
7
|
+
attr_reader :vm
|
8
|
+
attr_reader :opcodes
|
9
|
+
attr_reader :prog
|
10
|
+
|
11
|
+
def initialize(vm = VM.new, prog = nil)
|
12
|
+
@vm = vm
|
13
|
+
@prog = prog
|
14
|
+
@stack = []
|
15
|
+
@opcodes = []
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(at = nil, stack = [])
|
19
|
+
@stack = stack
|
20
|
+
enlist_bytecode_at(at) if at
|
21
|
+
until @opcodes.empty?
|
22
|
+
op = @opcodes.shift
|
23
|
+
send :"op_#{op.first}", *op[1..-1]
|
24
|
+
end
|
25
|
+
@stack
|
26
|
+
end
|
27
|
+
|
28
|
+
private
|
29
|
+
|
30
|
+
### self
|
31
|
+
|
32
|
+
def puid
|
33
|
+
prog && prog.puid
|
34
|
+
end
|
35
|
+
|
36
|
+
### stack
|
37
|
+
|
38
|
+
def push(x)
|
39
|
+
@stack << x
|
40
|
+
end
|
41
|
+
|
42
|
+
def pop(n = nil)
|
43
|
+
if n.nil?
|
44
|
+
@stack.pop
|
45
|
+
else
|
46
|
+
n.times.map{ @stack.pop }
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
50
|
+
def peek
|
51
|
+
@stack.last
|
52
|
+
end
|
53
|
+
|
54
|
+
### code
|
55
|
+
|
56
|
+
def enlist_bytecode_at(label)
|
57
|
+
@opcodes += vm.bytecode[label]
|
58
|
+
end
|
59
|
+
|
60
|
+
end # class Runner
|
61
|
+
end # class Kernel
|
62
|
+
end # class VM
|
63
|
+
end # module Gisele
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
module Lifecycle
|
4
|
+
|
5
|
+
attr_reader :status
|
6
|
+
attr_reader :last_error
|
7
|
+
|
8
|
+
def stopped?
|
9
|
+
@status == :stopped
|
10
|
+
end
|
11
|
+
|
12
|
+
def running?
|
13
|
+
@status == :running
|
14
|
+
end
|
15
|
+
|
16
|
+
def warmup?
|
17
|
+
@status == :warmup
|
18
|
+
end
|
19
|
+
|
20
|
+
def shutdown?
|
21
|
+
@status == :shutdown
|
22
|
+
end
|
23
|
+
|
24
|
+
def run
|
25
|
+
raise InvalidStateError, "VM already running" unless stopped?
|
26
|
+
if EM.reactor_running?
|
27
|
+
starter
|
28
|
+
EM.reactor_thread.join
|
29
|
+
else
|
30
|
+
EM.error_handler do |ex|
|
31
|
+
fatal("EventMachine crashed: #{ex.message}\n" + ex.backtrace.join("\n"))
|
32
|
+
if warmup?
|
33
|
+
@status = :stopped
|
34
|
+
EM.stop_event_loop
|
35
|
+
end
|
36
|
+
end
|
37
|
+
EM::run &method(:starter)
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def stop
|
42
|
+
raise InvalidStateError, "VM not running" unless running?
|
43
|
+
@status = :shutdown
|
44
|
+
info('VM stop request received, disconnecting.')
|
45
|
+
registry.disconnect
|
46
|
+
EM.stop_event_loop
|
47
|
+
@status = :stopped
|
48
|
+
info('VM stopped successfully.')
|
49
|
+
end
|
50
|
+
|
51
|
+
private
|
52
|
+
|
53
|
+
def init_lifecycle
|
54
|
+
@status = :stopped
|
55
|
+
end
|
56
|
+
|
57
|
+
def starter
|
58
|
+
@last_error = nil
|
59
|
+
@status = :warmup
|
60
|
+
info('VM start request received, connecting.')
|
61
|
+
registry.connect
|
62
|
+
info('Gisele VM has taken stage!')
|
63
|
+
@status = :running
|
64
|
+
rescue Exception => ex
|
65
|
+
fatal("VM start failed.")
|
66
|
+
@last_error = ex
|
67
|
+
raise
|
68
|
+
end
|
69
|
+
|
70
|
+
end # module Lifecycle
|
71
|
+
end # class VM
|
72
|
+
end # module Gisele
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
module Logging
|
4
|
+
extend Forwardable
|
5
|
+
|
6
|
+
def logger=(logger)
|
7
|
+
@logger = logger
|
8
|
+
end
|
9
|
+
|
10
|
+
def logger
|
11
|
+
@logger ||= NullObject.new
|
12
|
+
end
|
13
|
+
|
14
|
+
def_delegators :logger, :debug, :info, :warn, :error, :fatal
|
15
|
+
def_delegators :logger, :debug?, :info?, :warn?, :error?, :fatal?
|
16
|
+
end # module Logging
|
17
|
+
end # class VM
|
18
|
+
end # module Gisele
|
@@ -0,0 +1,19 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
class NullObject < BasicObject
|
4
|
+
|
5
|
+
def method_missing(*args)
|
6
|
+
self
|
7
|
+
end
|
8
|
+
|
9
|
+
[ :debug?, :info?, :warn?, :error?, :fatal? ].each do |meth|
|
10
|
+
define_method(meth){ false }
|
11
|
+
end
|
12
|
+
|
13
|
+
def to_s
|
14
|
+
''
|
15
|
+
end
|
16
|
+
|
17
|
+
end # class NullObject
|
18
|
+
end # class VM
|
19
|
+
end # module Gisele
|
@@ -0,0 +1,63 @@
|
|
1
|
+
module Gisele
|
2
|
+
class VM
|
3
|
+
class Prog
|
4
|
+
attr_accessor :puid
|
5
|
+
attr_accessor :parent
|
6
|
+
attr_accessor :root
|
7
|
+
attr_accessor :pc
|
8
|
+
attr_accessor :waitfor
|
9
|
+
attr_reader :waitlist
|
10
|
+
attr_accessor :input
|
11
|
+
|
12
|
+
def initialize(attrs = {})
|
13
|
+
@puid = attrs[:puid] || nil
|
14
|
+
@parent = attrs[:parent] || @puid
|
15
|
+
@root = attrs[:root] || @puid
|
16
|
+
@pc = attrs[:pc] || :main
|
17
|
+
@waitfor = attrs[:waitfor] || :none
|
18
|
+
@waitlist = attrs[:waitlist] || {}
|
19
|
+
@input = attrs[:input] || []
|
20
|
+
end
|
21
|
+
|
22
|
+
def waitlist=(wlist)
|
23
|
+
wlist = Hash[wlist.map{|x| [x,true]}] unless Hash===wlist
|
24
|
+
@waitlist = wlist
|
25
|
+
end
|
26
|
+
|
27
|
+
def to_hash(keys = nil)
|
28
|
+
if keys
|
29
|
+
h = {}
|
30
|
+
keys.each do |k|
|
31
|
+
h[k] = instance_variable_get(:"@#{k}")
|
32
|
+
end
|
33
|
+
h
|
34
|
+
else
|
35
|
+
{ :puid => puid,
|
36
|
+
:parent => parent,
|
37
|
+
:root => root,
|
38
|
+
:pc => pc,
|
39
|
+
:waitfor => waitfor,
|
40
|
+
:waitlist => waitlist,
|
41
|
+
:input => input }
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
def dup
|
46
|
+
super.tap do |c|
|
47
|
+
c.waitlist = waitlist.dup
|
48
|
+
c.input = input.dup
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
def ==(other)
|
53
|
+
other.is_a?(Prog) and (other.to_hash == to_hash)
|
54
|
+
end
|
55
|
+
alias :eql? :==
|
56
|
+
|
57
|
+
def to_s
|
58
|
+
"Prog(#{puid.inspect})"
|
59
|
+
end
|
60
|
+
|
61
|
+
end # class Prog
|
62
|
+
end # class VM
|
63
|
+
end # module Gisele
|