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 | #include "avmshell.h" |
42 | |
43 | #ifndef AVMSHELL_BUILD1 |
44 | #error "This file is only for use with avmshell" |
45 | #endif |
46 | |
47 | namespace avmplus |
48 | { |
49 | using namespace avmshell; |
50 | |
51 | DomainObject::DomainObject(VTable *vtable, ScriptObject *delegate) |
52 | : ScriptObject(vtable, delegate) |
53 | , domainEnv(delegate->core()->codeContext()->domainEnv()) |
54 | , domainToplevel(delegate->toplevel()) |
55 | { |
56 | } |
57 | |
58 | void DomainObject::init(DomainObject* parentDomain) |
59 | { |
60 | ShellCore* core = (ShellCore*) this->core(); |
61 | |
62 | DomainEnv* baseDomainEnv = parentDomain ? |
63 | (DomainEnv*)parentDomain->domainEnv : |
64 | (DomainEnv*)NULL__null; |
65 | Domain* baseDomain = baseDomainEnv ? |
66 | baseDomainEnv->domain() : |
67 | NULL__null; |
68 | |
69 | domainToplevel = parentDomain ? |
70 | (Toplevel*)parentDomain->domainToplevel : |
71 | core->createShellToplevel(); |
72 | |
73 | Domain* domain = Domain::newDomain(core, baseDomain); |
74 | domainEnv = DomainEnv::newDomainEnv(core, domain, parentDomain ? (DomainEnv*)parentDomain->domainEnv : (DomainEnv*)NULL__null); |
75 | } |
76 | |
77 | Atom DomainObject::loadBytes(ByteArrayObject* b, uint32_t swfVersion) |
78 | { |
79 | AvmCore* core = this->core(); |
80 | if (!b) |
81 | toplevel()->throwTypeError(kNullArgumentError, core->toErrorString("bytes")); |
82 | |
83 | |
84 | size_t len = b->get_length(); |
85 | ScriptBuffer code = core->newScriptBuffer(len); |
86 | VMPI_memcpy::memcpy(code.getBuffer(), &b->GetByteArray()[0], len); |
87 | |
88 | Toplevel* toplevel = domainToplevel; |
89 | ApiVersion apiVersion = core->getApiVersionFromCallStack(); |
90 | |
91 | |
92 | PoolObject* pool = core->parseActionBlock(code, |
93 | 0, |
94 | toplevel, |
95 | domainEnv->domain(), |
96 | NULL__null, |
97 | apiVersion); |
98 | |
99 | |
100 | |
101 | const BugCompatibility* bugCompatibility = toplevel->abcEnv()->codeContext()->bugCompatibility(); |
102 | if (swfVersion != 0) |
103 | { |
104 | |
105 | for (int j = 0; j < BugCompatibility::VersionCount; ++j) |
106 | { |
107 | if (BugCompatibility::kNames[j] == swfVersion) |
108 | { |
109 | bugCompatibility = core->createBugCompatibility((BugCompatibility::Version)j); |
110 | goto done; |
111 | } |
112 | } |
113 | |
114 | toplevel->throwTypeError(kInvalidArgumentError, core->toErrorString("swfVersion")); |
115 | } |
116 | done: |
117 | |
118 | ShellCodeContext* codeContext = new (core->GetGC()) ShellCodeContext(domainEnv, bugCompatibility); |
119 | return core->handleActionPool(pool, toplevel, codeContext); |
120 | } |
121 | |
122 | ScriptObject* DomainObject::finddef(const Multiname& multiname, |
123 | DomainEnv* domainEnv) |
124 | { |
125 | Toplevel* toplevel = this->toplevel(); |
126 | |
127 | ScriptEnv* script = core()->domainMgr()->findScriptEnvInDomainEnvByMultiname(domainEnv, multiname); |
128 | if (script == (ScriptEnv*)BIND_AMBIGUOUS) |
129 | toplevel->throwReferenceError(kAmbiguousBindingError, multiname); |
130 | |
131 | if (script == (ScriptEnv*)BIND_NONE) |
132 | toplevel->throwReferenceError(kUndefinedVarError, multiname); |
133 | |
134 | if (script->global == NULL__null) |
135 | { |
136 | script->initGlobal(); |
137 | script->coerceEnter(script->global->atom()); |
138 | } |
139 | |
140 | return script->global; |
141 | } |
142 | |
143 | ClassClosure* DomainObject::getClass(Stringp name) |
144 | { |
145 | Toplevel* toplevel = this->toplevel(); |
146 | AvmCore* core = toplevel->core(); |
147 | |
148 | if (name == NULL__null) { |
| |
149 | toplevel->throwArgumentError(kNullArgumentError, core->toErrorString("name")); |
150 | } |
151 | |
152 | |
153 | |
154 | int dot = name->lastIndexOf(core->cachedChars[(int)'.']); |
155 | |
156 | |
157 | |
158 | |
159 | Namespace* ns; |
160 | Stringp className; |
161 | if (dot >= 0) { |
| |
162 | Stringp uri = core->internString(name->substring(0, dot)); |
163 | ns = core->internNamespace(core->newNamespace(uri, Namespace::NS_Public, core->getApiVersionFromCallStack())); |
164 | className = core->internString(name->substring(dot+1, name->length())); |
165 | } else { |
166 | ns = core->findPublicNamespace(); |
167 | className = core->internString(name); |
168 | } |
169 | |
170 | Multiname multiname(ns, className); |
171 | |
172 | ScriptObject *container = finddef(multiname, domainEnv); |
173 | if (!container) { |
| |
174 | toplevel->throwTypeError(kClassNotFoundError, core->toErrorString(&multiname)); |
175 | } |
176 | Atom atom = toplevel->getproperty(container->atom(), |
177 | &multiname, |
178 | container->vtable); |
| 4 | Access to field 'vtable' results in a dereference of a null pointer (loaded from variable 'container') |
|
179 | |
180 | |
181 | |
182 | |
183 | |
184 | return toplevel->builtinClasses()->get_ClassClass()->coerceToType(atom); |
185 | } |
186 | |
187 | DomainClass::DomainClass(VTable *cvtable) |
188 | : ClassClosure(cvtable) |
189 | { |
190 | createVanillaPrototype(); |
191 | } |
192 | |
193 | DomainObject* DomainClass::get_currentDomain() |
194 | { |
195 | return (DomainObject*) newInstance(); |
196 | } |
197 | |
198 | int DomainClass::get_MIN_DOMAIN_MEMORY_LENGTH() |
199 | { |
200 | return DomainEnv::GLOBAL_MEMORY_MIN_SIZE; |
201 | } |
202 | |
203 | ByteArrayObject* DomainObject::get_domainMemory() const |
204 | { |
205 | return (ByteArrayObject*)domainEnv->get_globalMemory(); |
206 | } |
207 | |
208 | void DomainObject::set_domainMemory(ByteArrayObject* mem) |
209 | { |
210 | if(!domainEnv->set_globalMemory(mem)) |
211 | toplevel()->throwError(kEndOfFileError); |
212 | } |
213 | } |