Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / core / Toplevel.h
blob60b61bb8ab836a0e6735c944b8012b163dbc5810
1 /* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */
2 /* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
14 * License.
16 * The Original Code is [Open Source Virtual Machine.].
18 * The Initial Developer of the Original Code is
19 * Adobe System Incorporated.
20 * Portions created by the Initial Developer are Copyright (C) 2004-2006
21 * the Initial Developer. All Rights Reserved.
23 * Contributor(s):
24 * Adobe AS3 Team
26 * Alternatively, the contents of this file may be used under the terms of
27 * either the GNU General Public License Version 2 or later (the "GPL"), or
28 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
29 * in which case the provisions of the GPL or the LGPL are applicable instead
30 * of those above. If you wish to allow use of your version of this file only
31 * under the terms of either the GPL or the LGPL, and not to allow others to
32 * use your version of this file under the terms of the MPL, indicate your
33 * decision by deleting the provisions above and replace them with the notice
34 * and other provisions required by the GPL or the LGPL. If you do not delete
35 * the provisions above, a recipient may use your version of this file under
36 * the terms of any one of the MPL, the GPL or the LGPL.
38 * ***** END LICENSE BLOCK ***** */
40 #ifndef __avmplus_Toplevel__
41 #define __avmplus_Toplevel__
44 namespace avmplus
46 class VectorClass;
47 class builtinClassManifest;
49 /**
50 * class Toplevel
52 class GC_CPP_EXACT(Toplevel, MMgc::GCFinalizedObject)
54 friend class ClassManifestBase;
55 protected:
56 Toplevel(AbcEnv* abcEnv);
57 public:
58 static Toplevel* create(MMgc::GC* gc, AbcEnv* abcEnv);
60 GCRef<builtinClassManifest> builtinClasses() const;
62 void init_mainEntryPoint(ScriptEnv* main, builtinClassManifest* builtins);
64 AbcEnv* abcEnv() const;
65 DomainEnv* domainEnv() const;
66 AvmCore* core() const;
67 MMgc::GC* gc() const;
68 ScriptObject* global() const;
69 Atom atom() const;
71 // these are now all just convenience legacy wrappers
72 // around builtinClasses()->get_SomeClass()
73 GCRef<ArgumentErrorClass> argumentErrorClass() const;
74 GCRef<ArrayClass> arrayClass() const;
75 GCRef<BooleanClass> booleanClass() const;
76 GCRef<ByteArrayClass> byteArrayClass() const;
77 GCRef<ClassClass> classClass() const;
78 GCRef<EOFErrorClass> eofErrorClass() const;
79 GCRef<IOErrorClass> ioErrorClass() const;
80 GCRef<MemoryErrorClass> memoryErrorClass() const;
81 GCRef<DateClass> dateClass() const;
82 GCRef<DoubleVectorClass> doubleVectorClass() const;
83 GCRef<ErrorClass> errorClass() const;
84 GCRef<EvalErrorClass> evalErrorClass() const;
85 GCRef<FunctionClass> functionClass() const;
86 GCRef<IntClass> intClass() const;
87 GCRef<IntVectorClass> intVectorClass() const;
88 GCRef<MethodClosureClass> methodClosureClass() const;
89 GCRef<NamespaceClass> namespaceClass() const;
90 GCRef<NumberClass> numberClass() const;
91 GCRef<ObjectVectorClass> objectVectorClass() const;
92 GCRef<QNameClass> qnameClass() const;
93 GCRef<RangeErrorClass> rangeErrorClass() const;
94 GCRef<ReferenceErrorClass> referenceErrorClass() const;
95 GCRef<RegExpClass> regexpClass() const;
96 GCRef<SecurityErrorClass> securityErrorClass() const;
97 GCRef<StringClass> stringClass() const;
98 GCRef<SyntaxErrorClass> syntaxErrorClass() const;
99 GCRef<TypeErrorClass> typeErrorClass() const;
100 GCRef<UIntClass> uintClass() const;
101 GCRef<UIntVectorClass> uintVectorClass() const;
102 GCRef<URIErrorClass> uriErrorClass() const;
103 GCRef<VectorClass> vectorClass() const;
104 GCRef<VerifyErrorClass> verifyErrorClass() const;
105 GCRef<XMLClass> xmlClass() const;
106 GCRef<XMLListClass> xmlListClass() const;
108 void throwVerifyError(int id) const;
109 void throwVerifyError(int id, Stringp arg1) const;
110 void throwVerifyError(int id, Stringp arg1, Stringp arg2) const;
111 void throwVerifyError(int id, Stringp arg1, Stringp arg2, Stringp arg3) const;
113 void throwTypeError(int id) const;
114 void throwTypeError(int id, Stringp arg1) const;
115 void throwTypeError(int id, Stringp arg1, Stringp arg2) const;
116 void throwTypeErrorWithName(int id, const char* namestr) const;
118 void throwError(int id) const;
119 void throwError(int id, Stringp arg1) const;
120 void throwError(int id, Stringp arg1, Stringp arg2) const;
122 void throwArgumentError(int id) const;
123 void throwArgumentError(int id, Stringp arg1) const;
124 void throwArgumentError(int id, const char *arg1) const;
125 void throwArgumentError(int id, Stringp arg1, Stringp arg2) const;
127 void throwRangeError(int id) const;
128 void throwRangeError(int id, Stringp arg1) const;
129 void throwRangeError(int id, Stringp arg1, Stringp arg2) const;
130 void throwRangeError(int id, Stringp arg1, Stringp arg2, Stringp arg3) const;
132 void throwReferenceError(int id, const Multiname* multiname, const Traits* traits) const;
133 void throwReferenceError(int id, const Multiname* multiname) const;
135 void throwReferenceError(int id, const Multiname& multiname, const Traits* traits) const;
136 void throwReferenceError(int id, const Multiname& multiname) const;
138 void throwReferenceError(int id, String* name, const Traits* traits) const;
139 void throwReferenceError(int id, String* name) const;
141 inline Toplevel* toplevel() { return this; }
142 inline const Toplevel* toplevel() const { return this; }
144 REALLY_INLINE void checkNull(void* instance, const char* name)
146 if (instance == NULL)
147 throwNullPointerError(name);
150 void FASTCALL throwNullPointerError(const char* name);
152 void FASTCALL throwMemoryError(int id);
153 void FASTCALL throwIOError(int id);
154 void FASTCALL throwEOFError(int id);
157 // methods that used to be on AvmCore but depend on the caller's environment
159 ScriptObject* toPrototype(Atom atom);
160 VTable* toVTable(Atom atom);
162 /** toObject + get traits */
163 Traits* toTraits(Atom atom);
166 * OP_call.
168 * this = atomv[0]
169 * arg1 = atomv[1]
170 * argN = atomv[argc]
172 Atom op_call(Atom method,
173 int argc,
174 Atom* atomv);
177 * OP_construct.
179 * this = atomv[0] (ignored)
180 * arg1 = atomv[1]
181 * argN = atomv[argc]
183 Atom op_construct(Atom ctor,
184 int argc,
185 Atom* atomv);
188 /** Implementation of OP_callproperty */
189 Atom callproperty(Atom base, const Multiname* name, int argc, Atom* atomv, VTable* vtable);
191 /** Implementation of OP_constructprop */
192 Atom constructprop(const Multiname* name, int argc, Atom* atomv, VTable* vtable);
195 * OP_applytype.
197 * arg1 = atomv[0]
198 * argN = atomv[argc-1]
200 Atom op_applytype(Atom obj,
201 int argc,
202 Atom* atomv);
205 * Implements the ToAttributeName API as specified in E4X 10.5.1, pg 37
207 QNameObject* ToAttributeName (Atom arg);
208 QNameObject* ToAttributeName (const Stringp arg);
211 * Implements the ToXMLName API as specified in E4X 10.6.1, page 38
213 void ToXMLName (const Atom arg, Multiname& m);
216 * E4X support for coercing regular Multinames into E4X specific ones
218 void CoerceE4XMultiname (const Multiname *m, Multiname &out);
221 * operator instanceof from ES3
223 Atom instanceof(Atom atom, Atom ctor);
225 /** returns the instance traits of the factorytype of the passed atom */
226 Traits* toClassITraits(Atom atom);
229 * operator in from ES3
231 Atom in_operator(Atom name, Atom obj);
233 public:
234 /** legacy wrapper around coerce() from instr.h */
235 Atom coerce(Atom atom, Traits* expected) const;
238 * Reads a property from an object, with the property
239 * to retrieve specified by its binding.
240 * The binding was likely retrieved using getBinding.
241 * @param obj Object to retrieve property from
242 * @param b The binding of the property
243 * @param traits The traits of the object
245 Atom getproperty(Atom obj, const Multiname* name, VTable* vtable);
248 * Determines if a specified object has a specified property
249 * where the property is specified by a multiname.
250 * @param obj Object on which to look for the property
251 * @param multiname The name of the property
252 * @param vtable The vtable of the object
253 * @return true if the object has a readable property with the
254 specified name, false otherwise.
256 bool hasproperty(Atom obj, const Multiname* multiname, VTable* vtable);
259 * Delete a specified property on a specified object,where the property is specified
260 * by a multiname.
261 * @param obj Object on which to look for the specified property.
262 * @param multiname The name of the property
263 * @param vtable The vtable of the object
264 * @return true if the property is deleted. false if the property cannot be deleted.
266 bool deleteproperty( Atom obj, const Multiname* multiname, VTable* vtable ) const;
268 void setproperty(Atom obj, const Multiname* multiname, Atom value, VTable* vtable) const;
269 void setproperty_b(Atom obj, const Multiname* multiname, Atom value, VTable* vtable, Binding b) const;
272 * operator +
274 Atom add2(Atom lhs, Atom rhs);
277 * Implements the GetDefaultNamespace API as specified in E4X 12.1.1, pg 59
280 Namespace *getDefaultNamespace();
283 * Retrieve a binding for a property of a class.
284 * This differs from the other overload of getBinding
285 * in that it takes a multiname instead of a name/ns
286 * pair.
287 * The returned binding can then be used to read/write
288 * the property
289 * @param traits The traits of the class
290 * @param multiname The multiname of the property
292 Binding getBinding(Traits* traits, const Multiname* multiname) const;
294 // like getBinding, but do extra work to find the initial declarer of the member
295 Binding getBindingAndDeclarer(Traits* traits, const Multiname& multiname, Traitsp& declarer) const;
298 * @name ECMA-262 Appendix B.2 extensions
299 * Extensions to ECMAScript, in ECMA-262 Appendix B.2
301 /*@{*/
302 static Stringp escape(ScriptObject*, Stringp in);
303 static Stringp unescape(ScriptObject*, Stringp in);
304 /*@}*/
307 * E262-3 eval, but for the top level only (no lexical capture)
309 static Atom eval(ScriptObject*, Atom in);
312 * This is a variant of escape() which doesn't encode
313 * Unicode characters using the %u sequence
315 Stringp escapeBytes(Stringp in);
318 * @name Toplevel Function Properties
319 * Function properties of the global object (ECMA 15.1.2)
321 /*@{*/
322 static Stringp decodeURI(ScriptObject*, Stringp uri);
323 static Stringp decodeURIComponent(ScriptObject*, Stringp uri);
324 static Stringp encodeURI(ScriptObject*, Stringp uri);
325 static Stringp encodeURIComponent(ScriptObject*, Stringp uri);
326 static bool isNaN(ScriptObject*, double d);
327 static bool isFinite(ScriptObject*, double d);
328 static double parseInt(ScriptObject*, Stringp in, int radix);
329 static double parseFloat(ScriptObject*, Stringp in);
330 static bool bugzilla(ScriptObject*, int32_t n);
331 /*@}*/
333 // For E4X
334 static bool isXMLName(ScriptObject*, Atom v);
336 unsigned int readU30(const uint8_t *&p) const;
338 // subclasses can override this to check for security violations
339 // and prohibit certain operations. default implementation always
340 // allows but FlashPlayer takes advantage of this.
341 virtual bool sampler_trusted(ScriptObject* /*sampler*/);
343 ScopeChain* toplevel_scope();
345 // -------------------------------------------------------
348 // These methods are used by DataIO to handle conversion to/from specific
349 // non-Unicode text encodings. The default implementation understands nothing, and
350 // always returns 0.
352 // Subclasses may implement a larger set of codepages (see http://en.wikipedia.org/wiki/Code_page)
353 // but should ensure that any recognized by charsetToCodepage()
354 // are also handled by the conversion routines. They should also
355 // ensure to return zero for illegal input.
357 // Note that there may be multiple charset strings that map to
358 // the same codepage; this is fine (although the defaults
359 // above don't express all known acceptable charset equivalents)
361 virtual uint32_t charsetToCodepage(String* charset);
364 // Read length bytes from the DataInput and convert it to a String
365 // under the assumption it is formatted in the given codepage.
366 // and return it as a String.
368 // codepage can be assumed to be a value returned by the charsetToCodepage() method.
370 // Note that the implementation is not allowed to call DataInput::ReadMultiByte.
372 // If the data is malformed (e.g., is not valid for the
373 // given codepage), this method may return an arbitrary
374 // string or throw an error, but it must never return null.
375 // (Returning an arbitrary string seems odd, but is the behavior
376 // in certain existing versions of Flash, so must be kept legal.)
378 virtual String* readMultiByte(uint32_t codepage, uint32_t length, DataInput* input);
381 // Convert the given (Unicode) String into the given codepage and write it to the given DataOutput.
383 // codepage can be assumed to be a value returned by the charsetToCodepage() method.
385 // Note that the implementation is not allowed to call DataOutut::WriteMultiByte.
387 // If the data is malformed (e.g., is not valid for the
388 // given codepage), this method may write an arbitrary
389 // string to the DataOutput.
390 // (Returning an arbitrary string seems odd, but is the behavior
391 // in certain existing versions of Flash, so must be kept legal.)
393 virtual void writeMultiByte(uint32_t codepage, String* str, DataOutput* output);
395 // -------------------------------------------------------
398 // If a ByteArray doesn't begin with a BOM, Flash may want ByteArray.toString()
399 // to attempt a conversion from the system's default codepage as though the data
400 // is MBCS. If such a conversion is desirable and possible, you should return the
401 // result as a String. If the conversion is either impossible or undesirable, return NULL.
403 virtual String* tryFromSystemCodepage(const uint8_t* data);
405 // -------------------------------------------------------
408 // Deserialize an Atom value from the input using the specified encoding.
409 // If the encoding is not valid, or the input stream is malformed, throw an error.
411 // Note that the implementation is not allowed to call DataInput::ReadObject.
413 // Note that the default implementation always throws an error; this is
414 // simply a hook for embedders to use for custom implementations.
416 virtual Atom readObject(ObjectEncoding encoding, DataInput* input);
419 // Serialize the given Atom value into the output using the specified encoding.
420 // If the encoding is not valid, throw an error.
422 // Note that the implementation is not allowed to call DataOutput::WriteObject.
424 // Note that the default implementation always throws an error; this is
425 // simply a hook for embedders to use for custom implementations.
427 virtual void writeObject(ObjectEncoding encoding, DataOutput* output, Atom a);
429 // -------------------------------------------------------
432 // This is called anytime a ByteArrayObject (or subclass thereof) is created;
433 // it allows the ByteArray to be pre-initialized (eg via SetCopyOnWriteData),
434 // most typically if it is a subclass that is bound to a particular data set.
435 // (Most typically this is done via ByteArrayAsset in Flex code.) The relevant
436 // mapping tables don't exist in the VM proper, so this is a no-op in current Tamarin.
438 virtual void byteArrayCreated(ByteArrayObject* byteArrayObject);
440 // -------------------------------------------------------
443 protected:
444 ClassClosure* findClassInScriptEnv(int class_id, ScriptEnv* env);
446 private:
448 static int parseHexChar(wchar c);
449 static Stringp decode(AvmCore* core, Stringp in, bool decodeURIComponentFlag);
450 static Stringp encode(AvmCore* core, Stringp in, bool encodeURIComponentFlag);
452 static const uint32_t unescaped[];
453 static const uint32_t uriUnescaped[];
454 static const uint32_t uriReservedPlusPound[];
456 static bool contains(const uint32_t *uriSet, uint32_t ch);
458 // ------------------------ DATA SECTION BEGIN
459 GC_DATA_BEGIN(Toplevel)
461 private:
462 DWB(AbcEnv*) GC_POINTER(_abcEnv);
463 DWB(ScriptEnv*) GC_POINTER(_mainEntryPoint);
464 DWB(builtinClassManifest*) GC_POINTER(_builtinClasses);
465 public:
466 DWB(VTable*) GC_POINTER(object_ivtable);
467 DWB(VTable*) GC_POINTER(class_ivtable);
468 DWB(ScopeChain*) GC_POINTER(object_cscope);
469 DWB(ScopeChain*) GC_POINTER(vectorobj_cscope);
470 DWB(ScopeChain*) GC_POINTER(vectorobj_iscope);
471 public:
472 // objectClass is still needed for bootstrapping
473 // the VM; it's still public because of 100's of
474 // to-be-expunged references in Flash/AIR
475 DRCWB(ObjectClass*) GC_POINTER(objectClass);
476 private:
477 // This are also needed for bootstrapping, but shouldn't be accessible
478 // to the general public.
479 // NB: if you add or change these, you may need to
480 // update ClassManifestBase::lazyInitClass.
481 friend class ClassClass;
482 friend class FunctionClass;
483 friend class MethodEnv;
484 DRCWB(ClassClass*) GC_POINTER(_classClass);
485 DRCWB(FunctionClass*) GC_POINTER(_functionClass);
486 private:
487 // These exist solely for CodegenLIR to access
488 // NB: if you add or change these, you may need to
489 // update ClassManifestBase::lazyInitClass.
490 friend class CodegenLIR;
491 friend class BooleanClass;
492 friend class NamespaceClass;
493 friend class NumberClass;
494 friend class IntClass;
495 friend class UIntClass;
496 friend class StringClass;
497 DRCWB(BooleanClass*) GC_POINTER(_booleanClass);
498 DRCWB(NamespaceClass*) GC_POINTER(_namespaceClass);
499 DRCWB(NumberClass*) GC_POINTER(_numberClass);
500 DRCWB(IntClass*) GC_POINTER(_intClass);
501 DRCWB(UIntClass*) GC_POINTER(_uintClass);
502 DRCWB(StringClass*) GC_POINTER(_stringClass);
504 GC_DATA_END(Toplevel)
505 // ------------------------ DATA SECTION END
509 #endif /* __avmplus_Toplevel__ */