File: Engine.h

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (339 lines) | stat: -rw-r--r-- 9,127 bytes parent folder | download
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
#pragma once

#include "Gc/Gc.h"
#include "BootStatus.h"
#include "World.h"
#include "Scope.h"
#include "BuiltIn.h"
#include "VTableCall.h"
#include "SharedLibs.h"
#include "Code/Arena.h"
#include "Code/RefSource.h"
#include "Code/Reference.h"
#include "Utils/Lock.h"
#include "Utils/StackInfo.h"

namespace storm {

	class Thread;
	class Package;
	class NameSet;
	class ScopeLookup;
	class StdIo;
	class TextInput;
	class TextOutput;
	class Visibility;

	/**
	 * Defines the root object of the compiler. This object contains everything needed by the
	 * compiler itself, and shall be kept alive as long as anything from the compiler is used. Two
	 * separate instances of this class can be used as two completely separate runtime environments.
	 *
	 * TODO? Break this into two parts; one that contains stuff needed from external libraries, and
	 * one that is central to the compiler.
	 */
	class Engine : NoCopy {
	private:
		// The ID of this engine. Used in shared libraries. This must be the first member of the
		// Engine class.
		Nat id;

	public:
		// Threading mode for the engine.
		enum ThreadMode {
			// Create a new main thread for the compiler (this is the storm::Compiler thread) to use
			// for compiling code. This means that the compiler will manage itself, but care must be
			// taken not to manipulate anything below the engine in another thread.
			newMain,

			// Reuses the caller of the constructor as the compiler thread (storm::Compiler). This
			// makes it easier to interface with the compiler itself, since all calls can be made
			// directly into the compiler, but care must be taken to allow the compiler to process
			// any messages sent to the compiler by calling UThread::leave(), or make the thread
			// wait in a os::Lock or os::Sema for events.
			reuseMain,
		};

		// Callback for creating an Url for the root.
		typedef Url *(*CreateRootUrl)(Engine &e, void *param);

		// Create the engine.
		// 'root' is the location of the root package directory on disk. The package 'core' is
		// assumed to be found as a subdirectory of the given root path.
		// 'stackBase' is the base of the current thread's stack. Eg. the address of argc and/or
		// argv or some other variable allocated on the stack near 'main'.
		Engine(const wchar *root, ThreadMode mode, void *stackBase);

		// Create the engine. This overload accepts a function that will be called whenever the
		// Engine needs to know the Url of the root of the name tree.
		Engine(CreateRootUrl createRoot, void *callbackParam, ThreadMode mode, void *stackBase);

		// Destroy. This will wait until all threads have terminated properly.
		~Engine();

		// Interface to the GC we're using.
		Gc gc;

		// Get a C++ type by its id.
		Type *cppType(Nat id) const;

		// Get a C++ template by its id.
		TemplateList *cppTemplate(Nat id) const;

		// Get a C++ named thread by its id.
		Thread *cppThread(Nat id) const;

		// Current boot status.
		inline BootStatus boot() const { return bootStatus; }
		inline bool has(BootStatus s) { return boot() >= s; }

		// Advance boot status.
		void advance(BootStatus to);

		// Run the function for all named objects in the cache.
		typedef void (*NamedFn)(Named *);
		void forNamed(NamedFn fn);

		// Get the one and only pointer handle for TObject.
		const Handle &tObjHandle();

		// Get a handle usable to treat regular objects as references in hash containers.
		const Handle &refObjHandle();

		// The threadgroup which all threads spawned from here shall belong to.
		os::ThreadGroup threadGroup;

		// The lock that is used to synchronize thread creation in storm::Thread::thread().
		// A regular util::Lock is used since it needs to be recursive when threads are reused.
		util::Lock threadLock;


		/**
		 * Packages.
		 *
		 * All package lookup performed from here will completely disregard visibility; they are
		 * indended for 'supervisor' usage.
		 */

		// Get the root package.
		Package *package();

		// Get the core package. Stored specially since it is often needed.
		Package *corePackage();

		// Get a package relative to the root. If 'create', the package will be created. No
		// parameters are supported in the name.
		Package *package(SimpleName *name, bool create = false);

		// Find a NameSet relative to the root. If 'create', creates packages along the way.
		NameSet *nameSet(SimpleName *name, bool create = false);
		NameSet *nameSet(SimpleName *name, NameSet *root, bool create = false);

		// Parse a string into a simple name and get the corresponding package.
		Package *package(const wchar *name);

		// Get the package corresponding to a certain path. Will try to load any packages not
		// already loaded. Returns null if none is found.
		MAYBE(Package *) package(Url *path);

		// Access the global map of packages.
		Map<Url *, Package *> *pkgMap();

		/**
		 * Scopes.
		 */

		// Get the root scope.
		Scope scope();

		// Get the default scope lookup.
		ScopeLookup *scopeLookup();

		/**
		 * Code generation.
		 */

		// The arena used for code generation for this platform.
		code::Arena *arena();

		// VTable call stubs.
		VTableCalls *vtableCalls();

		// Get the one and only Handle object for void.
		const Handle &voidHandle();

		// Get a reference to a function in the runtime.
		code::Ref ref(builtin::BuiltIn ref);

		// Default visibility objects.
		enum VisType {
			vPublic,
			vTypePrivate,
			vTypeProtected,
			vPackagePrivate,
			vFilePrivate,

			// Should be last.
			visCount,
		};

		// Get a visibility object.
		Visibility *visibility(VisType type);

		// Get the StdIo object.
		StdIo *stdIo();

		// Get stdin, stdout and stderr. Note: get/set from Storm using interface in Lib/Io.h.
		TextInput *stdIn();
		TextOutput *stdOut();
		TextOutput *stdError();

		// Set std streams.
		void stdIn(TextInput *to);
		void stdOut(TextOutput *to);
		void stdError(TextOutput *to);

		// Get/set argv array. Interface for accessing it is in Lib/Argv.h
		// These functions are atomic. The getter might return null.
		Array<Str *> *argv();
		void argv(Array<Str *> *val);

		// Get 'TypeDesc' objects that are frequently used in the system.
		code::TypeDesc *ptrDesc();
		code::TypeDesc *voidDesc();

		// Get a single shared instance of a function that reads objects from references.
		Function *readObjFn();
		Function *readTObjFn();

		// Load a shared library.
		SharedLib *loadShared(Url *file);

		// Functions called on thread attach/detach.
		void attachThread();
		void detachThread();

		// Get all threads in the system. Used to generate stack traces.
		vector<os::Thread> allThreads();

	private:
		// The compiler C++ world.
		World world;

		// How far along in the boot process?
		BootStatus bootStatus;

		/**
		 * GC:d objects.
		 */
		struct GcRoot {
			// Handle for TObject.
			Handle *tObjHandle;

			// Handle for reference hashes to Objects.
			Handle *refObjHandle;

			// Void handle.
			Handle *voidHandle;

			// Root package.
			Package *root;

			// Core package (populated on demand).
			Package *corePkg;

			// Quick lookup from path to package.
			Map<Url *, Package *> *pkgMap;

			// Root scope lookup.
			ScopeLookup *rootLookup;

			// Arena.
			code::Arena *arena;

			// VTableCalls.
			code::VTableCalls *vtableCalls;

			// References.
			code::RefSource *refs[builtin::count];

			// TypeDesc objects that are used a lot throughout the system.
			code::TypeDesc *ptrDesc;
			code::TypeDesc *voidDesc;

			// Read Objects or TObjects from references.
			Function *readObj;
			Function *readTObj;

			// Default visibility objects.
			Visibility *visibility[visCount];

			// Handles to readers for stdin, stdout and stderror.
			TextInput *stdIn;
			TextOutput *stdOut;
			TextOutput *stdError;

			// Argv visible to the system.
			Array<Str *> *argv;
		};

		GcRoot o;

		// Root for GcRoot.
		Gc::Root *objRoot;

		// Loaded libraries.
		SharedLibs libs;

		// Standard IO thread.
		StdIo *ioThread;

		// Lock used for syncronizing object creation.
		util::Lock createLock;

		// Create references.
		code::RefSource *createRef(builtin::BuiltIn which);

		// Create visibility objects.
		Visibility *createVisibility(VisType t);

		// Plug into the stack traces in order to properly scan the stack traces.
		class StormInfo : public StackInfo {
		public:
			StormInfo(Gc &gc);
			~StormInfo();

			// Clear all allocations from the MPS.
			void clear();

			virtual void alloc(StackFrame *frames, nat count) const;
			virtual void free(StackFrame *frames, nat count) const;

			virtual bool translate(void *ip, void *&fnBase, int &offset) const;
			virtual void format(GenericOutput &to, void *fnBase, int offset) const;

		private:
			Gc &gc;

			// Current allocations.
			typedef map<size_t, Gc::Root *> RootMap;
			mutable RootMap roots;
		};

		// StormInfo instance and ID.
		StormInfo stackInfo;
		int stackId;

		// Create the engine.
		void create(CreateRootUrl createRoot, void *rootParam, ThreadMode mode, void *stackBase);

		// Cleanup code.
		void destroy();
	};


	STORM_PKG(core);
	// Force garbage collection from Storm.
	void STORM_FN gc(EnginePtr e);

}