This repository has been archived by the owner on Nov 21, 2017. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathexecution.hppy
262 lines (220 loc) · 6.29 KB
/
execution.hppy
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
/*
* Copyright (c) 2011, 2012 Timo Savola
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*/
#ifndef CONCRETE_EXECUTION_HPP
#define CONCRETE_EXECUTION_HPP
#include <cstdint>
#include <concrete/pointer.hpp>
#include <concrete/list.hpp>
#include <concrete/objects/code.hpp>
#include <concrete/objects/dict.hpp>
#include <concrete/objects/object.hpp>
#include <concrete/objects/tuple.hpp>
namespace concrete {
/**
* Function call state.
*/
class ExecutionFrame: public Pointer {
{{{ DeclarePointer("ExecutionFrame") }}}
friend class Execution;
/**
* Get the return value of a finished function call.
*/
Object result();
/**
* Visit all object references in this and its parent frames.
*/
template <typename Visitor> void visit(Visitor &v) const;
protected:
/**
* @var MaxBlocks
* Maximum depth of the block stack (per frame).
*/
enum { MaxBlocks = 20 };
/**
* @struct concrete::ExecutionFrame::Block
* Represents an active control block within a function.
*/
struct Block;
/**
* Create a frame. It's not yet attached to an executor.
* @return new reference owned by the caller
*/
static ExecutionFrame New(const ExecutionFrame &parent,
const CodeObject &code,
const DictObject &dict);
/**
* Read from and advance the current bytecode position.
*/
template <typename T> T load_bytecode();
/**
* Replace the current bytecode position.
*/
void jump_absolute(unsigned int target);
/**
* Advance the current bytecode position.
*/
void jump_forward(unsigned int delta);
/**
* Add an object at the top of the object stack.
*/
void push(const Object &object);
/**
* Refer to the object at the top of the object stack.
*/
Object peek() const;
/**
* Remove and return the object at the top of the object stack.
*/
Object pop();
/**
* Add a Block referring to the current bytecode position at the top of
* the block stack.
*/
void push_block(unsigned int delta);
/**
* Direct access to the Block at the top of the block stack.
* @return short-term reference to Arena memory
*/
const Block &peek_block() const;
/**
* Remove the Block at the top of the block stack.
*/
void pop_block();
};
/**
* Executor for a function call stack. Implements a Python bytecode
* interpreter.
*/
class Execution: public ListNode<Execution> {
{{{ DeclarePointer("Execution", "ListNode<Execution>") }}}
/**
* Create an executor for a Python module.
* @return new reference owned by the caller
*/
static Execution New(const CodeObject &code);
/**
* Create an executor for a Python function.
* @return new reference owned by the caller
*/
static Execution New(const CodeObject &code, const DictObject &dict);
/**
* Create an executor for a Python callable.
* @param args contains a CallableObject followed by its arguments
* @return new reference owned by the caller
*/
static Execution NewCall(const TupleObject &args);
/**
* Execute an instruction or resume a continuation.
* @return false if the executor finished
*/
bool execute();
/**
* Set up a nested function call. Execution keeps a reference to the
* new frame until it's finished, but the caller must destroy it.
*/
ExecutionFrame new_frame(const CodeObject &code, const DictObject &dict);
/**
* Visit all object references in the call stack.
*/
template <typename Visitor> void visit(Visitor &v) const;
protected:
/**
* @return true if the Python object is not false
*/
static bool Nonzero(Object object);
/**
* Current frame.
*/
ExecutionFrame frame() const;
/**
* Current function's code.
*/
CodeObject code() const;
/**
* Current local variables.
*/
DictObject dict() const;
/**
* Start a Continuation.
* @param callable
* @param not_filter causes the not-operator to be applied to the
* call's result before it's pushed on the stack
*/
void initiate_call(const Object &callable, bool not_filter = false);
/**
* Start a Continuation.
* @param callable
* @param args
* @param not_filter causes the not-operator to be applied to the
* call's result before it's pushed on the stack
*/
void initiate_call(const Object &callable, const TupleObject &args, bool not_filter = false);
/**
* Start a Continuation.
* @param callable
* @param args
* @param kwargs
* @param not_filter causes the not-operator to be applied to the
* call's result before it's pushed on the stack
*/
void initiate_call(const Object &callable,
const TupleObject &args,
const DictObject &kwargs,
bool not_filter = false);
/**
* Continue the current Continuation (if any).
* @return false if there was no continuation
*/
bool resume_call();
/**
* Add an object at the top of the current frame's stack.
*/
void push(const Object &object);
/**
* Refer to the object at the top of the current frame's stack.
*/
Object peek() const;
/**
* Remove and return the object at the top of the current frame's
* stack.
*/
Object pop();
/**
* Execute the next bytecode instruction.
*/
void execute_op();
void op_pop_top();
void op_rot_two();
void op_rot_three();
void op_rot_four();
void op_dup_top();
void op_binary_add();
void op_pop_block();
void op_return_value();
void op_store_name(unsigned int namei);
void op_load_const(unsigned int consti);
void op_load_name(unsigned int namei);
void op_load_attr(unsigned int namei);
void op_compare_op(unsigned int opname);
void op_import_name(unsigned int namei);
void op_import_from(unsigned int namei);
void op_jump_forward(unsigned int delta);
void op_jump_if_false_or_pop(unsigned int target);
void op_jump_if_true_or_pop(unsigned int target);
void op_jump_absolute(unsigned int target);
void op_pop_jump_if_false(unsigned int target);
void op_pop_jump_if_true(unsigned int target);
void op_setup_loop(unsigned int delta);
void op_load_fast(unsigned int var_num);
void op_store_fast(unsigned int var_num);
void op_call_function(uint16_t argc);
void op_make_function(uint16_t argc);
};
} // namespace
#endif