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
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.
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__
47 class builtinClassManifest
;
52 class GC_CPP_EXACT(Toplevel
, MMgc::GCFinalizedObject
)
54 friend class ClassManifestBase
;
56 Toplevel(AbcEnv
* abcEnv
);
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;
68 ScriptObject
* global() 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
);
172 Atom
op_call(Atom method
,
179 * this = atomv[0] (ignored)
183 Atom
op_construct(Atom ctor
,
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
);
198 * argN = atomv[argc-1]
200 Atom
op_applytype(Atom obj
,
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
);
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
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;
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
287 * The returned binding can then be used to read/write
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
302 static Stringp
escape(ScriptObject
*, Stringp in
);
303 static Stringp
unescape(ScriptObject
*, Stringp in
);
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)
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
);
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
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 // -------------------------------------------------------
444 ClassClosure
* findClassInScriptEnv(int class_id
, ScriptEnv
* env
);
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
)
462 DWB(AbcEnv
*) GC_POINTER(_abcEnv
);
463 DWB(ScriptEnv
*) GC_POINTER(_mainEntryPoint
);
464 DWB(builtinClassManifest
*) GC_POINTER(_builtinClasses
);
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
);
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
);
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
);
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__ */