forked from adobe-flash/avmplus
-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathShellCore.h
260 lines (223 loc) · 9.75 KB
/
ShellCore.h
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
/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef __avmshell_core__
#define __avmshell_core__
// Ugly, ugly hack
namespace avmplus
{
namespace ST_avmplus_vector_accessors
{
class ST_avmplus_vector_accessors;
}
namespace ST_mmgc_dependent
{
class ST_mmgc_dependent;
}
}
namespace avmshell
{
/**
* Settings for ShellCore. The command line parser uses this, but the initial state
* is set in ShellCore.cpp, and it's propagated throughout various parts of the
* system. Partly duplicates the functionality in AvmCore::config, and some settings
* are copied from ShellCoreSettings into that structure when a new core is created.
*
* We try to avoid conditional compilation here, as there's only ever one of these
* structures floating around and the savings would be minuscule.
*
* FIXME: the naming of many fields could be much better, and they should be documented.
*/
class ShellCoreSettings
{
public:
ShellCoreSettings();
char** arguments; // non-terminated array of argument values, never NULL
int numargs; // number of entries in 'arguments'
bool nodebugger;
int astrace_console;
uint32_t do_verbose; // copy to config
const char* verboseOnlyArg; // copy to config (raw unprocessed)
bool enter_debugger_on_launch;
bool interrupts; // copy to config
bool verifyall; // copy to config
bool verifyonly; // copy to config
bool verifyquiet; // copy to config
bool greedy; // copy to each GC
bool nogc; // copy to each GC
bool incremental; // copy to each GC
bool exactgc; // copy to each GC
bool drc; // copy to each GC
bool drcValidation; // copy to each GC
int32_t markstackAllowance; // copy to each GC;
bool fixedcheck; // copy to each GC
int gcthreshold; // copy to each GC
int langID; // copy to ShellCore?
bool jitordie; // copy to config
bool do_testSWFHasAS3;
avmplus::Runmode runmode; // copy to config
#ifdef VMCFG_NANOJIT
nanojit::Config njconfig; // copy to config
avmplus::JitConfig jitconfig; // copy to config
bool osr_enabled; // copy to config
uint32_t osr_threshold; // copy to config
uint32_t jitprof_level; // Log level for jit profiling
const char* policyRulesArg; // copy to config (raw unprocessed)
#endif
avmplus::AvmCore::CacheSizes cacheSizes; // Default to unlimited
const char* st_component;
const char* st_category;
const char* st_name;
avmplus::ApiVersionSeries apiVersionSeries;
avmplus::ApiVersion apiVersion;
avmplus::BugCompatibility::Version swfVersion;
MMgc::GCConfig::GCMode gcMode()
{
if (nogc) return MMgc::GCConfig::kDisableGC;
else if (greedy) return MMgc::GCConfig::kGreedyGC;
else if (incremental) return MMgc::GCConfig::kIncrementalGC;
else return MMgc::GCConfig::kNonincrementalGC;
}
};
class ShellCodeContext : public avmplus::CodeContext
{
public:
inline ShellCodeContext(avmplus::DomainEnv* env, const avmplus::BugCompatibility* bugCompatibility)
: avmplus::CodeContext(env, bugCompatibility) { }
};
/**
* ShellCore provides typical housekeeping tasks around an AvmCore, lightweight
* embedders may prefer to use this rather than to subclass AvmCore themselves
* and do all the housekeeping that results. The shell uses this; see the
* shell code for typical usage patterns.
*/
class ShellCore : public avmplus::AvmCore
{
friend class SystemClass;
friend class avmplus::DomainObject;
friend class avmplus::ST_avmplus_vector_accessors::ST_avmplus_vector_accessors;
friend class avmplus::ST_mmgc_dependent::ST_mmgc_dependent;
friend class Shell; // access to shell_toplevel
public:
/**
* Create a new core with the given GC (one gc per core).
*
* Requires: MMGC_ENTER and MMGC_GCENTER(gc) on the stack.
*/
ShellCore(MMgc::GC *gc, avmplus::ApiVersionSeries apiVersionSeries);
/**
* Initialize the new core from the settings. This creates a top-level
* environment and performs other housekeeping.
*
* Requires: MMGC_ENTER and MMGC_GCENTER(gc) on the stack.
*/
ShellToplevel* setup(const ShellCoreSettings& settings);
/**
* Load the contents from the file and run them in the context of this core's
* top level. The file may contain ABC bytecode, a SWF containing a single DoABC
* tag, or (if the run-time compiler is present) ActionScript source code.
*
* Requires: MMGC_ENTER and MMGC_GCENTER(gc) on the stack.
*/
int evaluateFile(ShellCoreSettings& settings, const char* filename);
int evaluateScriptBuffer(avmplus::ScriptBuffer& buffer, bool enter_debugger_on_launch);
#ifdef VMCFG_EVAL
/**
* Load ActionScript source code from the string and run it in the
* context of this core's top level. Note the string must have been
* created in the context of the GC in this ShellCore instance.
*
* Requires: MMGC_ENTER and MMGC_GCENTER(gc) on the stack.
*/
void evaluateString(avmplus::String* input, bool record_time=false);
#endif
#ifdef AVMSHELL_PROJECTOR_SUPPORT
int executeProjector(char *executablePath);
#endif
#ifdef VMCFG_SELFTEST
void executeSelftest(ShellCoreSettings& settings);
#endif
avmplus::PoolObject* getShellPool() { return shellPool; }
avmshell::SystemClass* getSystemClass() { return systemClass; }
#ifdef AVMSHELL_PROJECTOR_SUPPORT
static bool isValidProjectorFile(const char* filename);
#endif
/*virtual*/ inline avmplus::ApiVersion getDefaultAPI() { return this->defaultAPIVersion; }
inline avmplus::BugCompatibility::Version getDefaultBugCompatibilityVersion() const { return defaultBugCompatibilityVersion; }
protected:
virtual void setStackLimit() = 0;
virtual avmplus::Toplevel* createToplevel(avmplus::AbcEnv* abcEnv);
#ifdef DEBUGGER
virtual avmplus::Debugger* createDebugger(int tracelevel)
{
AvmAssert(allowDebugger >= 0);
return allowDebugger ? DebugCLI::create(GetGC(), this, (avmplus::Debugger::TraceLevel)tracelevel) : NULL;
}
#endif
#ifdef VMCFG_EVAL
virtual avmplus::String* readFileForEval(avmplus::String* referencing_filename, avmplus::String* filename);
#endif
private:
static void interruptTimerCallback(void* data);
ShellToplevel* createShellToplevel();
void interrupt(avmplus::Toplevel*, InterruptReason);
void stackOverflow(avmplus::Toplevel *toplevel);
void setEnv(avmplus::Toplevel *toplevel, int argc, char *argv[]);
void initShellPool();
int handleArbitraryExecutableContent(bool do_testSWFHasAS3, avmplus::ScriptBuffer& code, const char * filename);
#ifdef VMCFG_EVAL
avmplus::String* decodeBytesAsUTF16String(uint8_t* bytes, uint32_t nbytes, bool terminate=false);
#endif // VMCFG_EVAL
#ifdef DEBUGGER
DebugCLI* debugCLI() { return (DebugCLI*)debugger(); }
#endif
#ifdef AVMPLUS_VERBOSE
virtual const char* identifyDomain(avmplus::Domain* domain);
#endif
SystemClass* systemClass;
avmplus::PoolObject* shellPool;
avmplus::GCOutputStream *consoleOutputStream;
bool gracePeriod;
bool inStackOverflow;
int allowDebugger;
ShellToplevel* shell_toplevel;
avmplus::DomainEnv* shell_domainEnv;
avmplus::Domain* shell_domain;
// Note that this has been renamed to emphasize the fact that it is
// the CodeContext/DomainEnv that user code will run in (as opposed
// to the Shell's builtin classes, eg System, File, Domain).
ShellCodeContext* user_codeContext;
avmplus::ApiVersion defaultAPIVersion;
avmplus::BugCompatibility::Version defaultBugCompatibilityVersion;
};
class GC_CPP_EXACT(ShellToplevel, avmplus::Toplevel)
{
friend class ShellCore;
private:
ShellToplevel(avmplus::AbcEnv* abcEnv);
public:
REALLY_INLINE static ShellToplevel* create(MMgc::GC* gc, avmplus::AbcEnv* abcEnv)
{
return new (gc, MMgc::kExact) ShellToplevel(abcEnv);
}
ShellCore* core() const {
return (ShellCore*)Toplevel::core();
}
GCRef<avmplus::ClassClosure> workerClass() const
{
return shellClasses->get_WorkerClass();
}
GCRef<avmplus::ClassClosure> workerDomainClass() const
{
return shellClasses->get_WorkerDomainClass();
}
GCRef<avmplus::ScriptObject> constructWorkerObject() const;
private:
GC_DATA_BEGIN(ShellToplevel)
GCMember<avmplus::shell_toplevelClassManifest> GC_POINTER(shellClasses);
GC_DATA_END(ShellToplevel)
};
}
#endif /* __avmshell_core__ */