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);
}
|