Merge remote-tracking branch 'redux/master' into sh4-pool
[tamarin-stm.git] / core / VectorClass.h
blob57e9ed4c2edc12a96911e73c3fa018a059a2434d
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 ***** */
41 #ifndef __avmplus_VectorClass__
42 #define __avmplus_VectorClass__
44 namespace avmplus
46 // ----------------------------
48 class GC_AS3_EXACT(VectorClass, ClassClosure)
50 protected:
51 VectorClass(VTable* vtable);
52 public:
53 REALLY_INLINE static VectorClass* create(MMgc::GC* gc, VTable* cvtable)
55 return new (gc, MMgc::kExact, cvtable->getExtraSize()) VectorClass(cvtable);
58 virtual Atom applyTypeArgs(int argc, Atom* argv);
60 ClassClosure* getTypedVectorClass(ClassClosure* typeClass);
62 static Stringp makeVectorClassName(AvmCore* core, Traits* t);
64 // make a Vector of subtype Vector<typeClass>,
65 // eg if typeClass == StringClass then return a new Vector<String>
66 ObjectVectorObject* newVector(ClassClosure* typeClass, uint32_t length = 0);
68 private:
69 GC_NO_DATA(VectorClass)
71 DECLARE_SLOTS_VectorClass;
74 // ----------------------------
76 class GC_CPP_EXACT(TypedVectorClassBase, ClassClosure)
78 protected:
79 explicit TypedVectorClassBase(VTable* vtable);
81 public:
82 Traits* getTypeTraits() const;
84 // ClassClosure overrides
85 virtual Atom call(int argc, Atom* argv);
87 // AS3 native function implementations
88 void _forEach(Atom thisAtom, ScriptObject* callback, Atom thisObject);
89 bool _every(Atom thisAtom, ScriptObject* callback, Atom thisObject);
90 bool _some(Atom thisAtom, ScriptObject* callback, Atom thisObject);
91 Atom _sort(Atom thisAtom, ArrayObject* args);
93 protected:
94 virtual Atom createAndInitVectorFromObject(ScriptObject* so, uint32_t len) = 0;
96 protected:
97 GC_DATA_BEGIN(TypedVectorClassBase)
99 DWB(Traits*) GC_POINTER(m_typeTraits);
101 GC_DATA_END(TypedVectorClassBase)
104 // ----------------------------
106 template<class OBJ>
107 class TypedVectorClass : public TypedVectorClassBase
109 friend class VectorClass;
111 protected:
112 explicit TypedVectorClass(VTable* vtable);
114 public:
115 OBJ* newVector(uint32_t length = 0, bool fixed = false);
117 virtual bool gcTrace(MMgc::GC* gc, size_t cursor)
119 return TypedVectorClassBase::gcTrace(gc, cursor);
122 protected:
123 virtual Atom createAndInitVectorFromObject(ScriptObject* so, uint32_t len);
124 Atom constructImpl(int argc, Atom* argv);
128 // ----------------------------
130 class GC_AS3_EXACT(IntVectorClass, TypedVectorClass<IntVectorObject>)
132 private:
133 explicit IntVectorClass(VTable* vtable);
134 public:
135 REALLY_INLINE static IntVectorClass* create(MMgc::GC* gc, VTable* cvtable)
137 return new (gc, MMgc::kExact, cvtable->getExtraSize()) IntVectorClass(cvtable);
140 GC_NO_DATA(IntVectorClass)
142 DECLARE_SLOTS_IntVectorClass;
145 // ----------------------------
147 class GC_AS3_EXACT(UIntVectorClass, TypedVectorClass<UIntVectorObject>)
149 private:
150 explicit UIntVectorClass(VTable* vtable);
151 public:
152 REALLY_INLINE static UIntVectorClass* create(MMgc::GC* gc, VTable* cvtable)
154 return new (gc, MMgc::kExact, cvtable->getExtraSize()) UIntVectorClass(cvtable);
157 GC_NO_DATA(UIntVectorClass)
159 DECLARE_SLOTS_UIntVectorClass;
162 // ----------------------------
164 class GC_AS3_EXACT(DoubleVectorClass, TypedVectorClass<DoubleVectorObject>)
166 private:
167 explicit DoubleVectorClass(VTable* vtable);
168 public:
169 REALLY_INLINE static DoubleVectorClass* create(MMgc::GC* gc, VTable* cvtable)
171 return new (gc, MMgc::kExact, cvtable->getExtraSize()) DoubleVectorClass(cvtable);
174 GC_NO_DATA(DoubleVectorClass)
176 DECLARE_SLOTS_DoubleVectorClass;
179 // ----------------------------
181 class GC_AS3_EXACT(ObjectVectorClass, TypedVectorClass<ObjectVectorObject>)
183 private:
184 explicit ObjectVectorClass(VTable* vtable);
185 public:
186 REALLY_INLINE static ObjectVectorClass* create(MMgc::GC* gc, VTable* cvtable)
188 return new (gc, MMgc::kExact, cvtable->getExtraSize()) ObjectVectorClass(cvtable);
191 GC_NO_DATA(ObjectVectorClass)
193 DECLARE_SLOTS_ObjectVectorClass;
196 // ----------------------------
198 struct VectorIndex
200 explicit VectorIndex(AvmCore* core, Atom name);
202 uint32_t index;
203 enum { kNotNumber, kInvalidNumber, kValidNumber } status;
206 // ----------------------------
208 template<class T>
209 struct TypedVectorConstants
211 static T nullValue();
212 static T undefinedValue();
215 // ----------------------------
217 class GC_CPP_EXACT(VectorBaseObject, ScriptObject)
219 protected:
220 explicit VectorBaseObject(VTable* ivtable, ScriptObject* delegate);
222 public:
223 // AS3 native getter/setter implementations
224 bool get_fixed() const;
225 void set_fixed(bool fixed);
227 // used by Flash code for AMF3 -- note that this is
228 // the type that the Vector contains, not the Vector itself
229 // (ie, "int" rather than "Vector<int>")
230 Traits* getTypeTraits() const;
232 // AIR needs to be able to get/set the length of an arbitrary
233 // Vector without knowing its subclass; these simply forward into the
234 // appropriate calls of the well-typed subclass.
235 virtual uint32_t getLength() const = 0;
236 virtual void setLength(uint32_t length) = 0;
238 protected:
240 Atom _mapImpl(ScriptObject* callback, Atom thisObject, VectorBaseObject* r, uint32_t len);
241 Atom _filterImpl(ScriptObject* callback, Atom thisObject, VectorBaseObject* r, uint32_t len);
243 VectorBaseObject* _newVector();
245 void checkFixed() const;
246 void FASTCALL throwFixedError() const;
248 void atomToValue(Atom atom, int32_t& value);
249 Atom valueToAtom(const int32_t& value) const;
251 void atomToValue(Atom atom, uint32_t& value);
252 Atom valueToAtom(const uint32_t& value) const;
254 void atomToValue(Atom atom, double& value);
255 Atom valueToAtom(const double& value) const;
257 void atomToValue(Atom atom, OpaqueAtom& value);
258 Atom valueToAtom(const OpaqueAtom& value) const;
260 enum VectorIndexStatus { kNotNumber, kInvalidNumber, kValidNumber };
261 VectorIndexStatus getVectorIndex(Atom name, uint32_t& index) const;
263 GC_DATA_BEGIN(VectorBaseObject)
265 DRCWB(TypedVectorClassBase*) GC_POINTER(m_vecClass);
266 bool m_fixed;
268 GC_DATA_END(VectorBaseObject)
271 // ----------------------------
273 template<class TLIST>
274 class TypedVectorObject : public VectorBaseObject
276 template<class OBJ> friend class TypedVectorClass;
277 template<class TLISTVA> friend class VectorAccessor;
279 public:
280 typedef TLIST LIST;
282 protected:
283 explicit TypedVectorObject(VTable* ivtable, ScriptObject* delegate);
285 public:
286 // overrides
287 virtual uint32_t getLength() const;
288 virtual void setLength(uint32_t length);
290 // AS3 native getter/setter implementations
291 uint32_t get_length() const;
292 void set_length(uint32_t newLength);
294 // AS3 native function implementations
295 Atom _map(ScriptObject* callback, Atom thisObject);
296 Atom _filter(ScriptObject* callback, Atom thisObject);
297 void _reverse();
298 void _spliceHelper(uint32_t insertPoint, uint32_t insertCount, uint32_t deleteCount, Atom args, uint32_t offset);
299 uint32_t AS3_push(Atom* argv, int argc);
300 typename TLIST::TYPE AS3_pop();
301 uint32_t AS3_unshift(Atom* argv, int argc);
302 typename TLIST::TYPE AS3_shift();
304 // ScriptObject method overrides
305 virtual bool hasAtomProperty(Atom name) const;
306 virtual Atom getAtomProperty(Atom name) const;
307 virtual void setAtomProperty(Atom name, Atom value);
308 virtual bool hasUintProperty(uint32_t index) const;
309 virtual Atom getUintProperty(uint32_t index) const;
310 virtual void setUintProperty(uint32_t index, Atom value);
311 virtual Atom nextName(int index);
312 virtual Atom nextValue(int index);
313 virtual int nextNameIndex(int index);
315 // "fast" methods that don't range-check in nondebug builds
316 // and are inlined; for internal use by various bits of Flash glue code
317 typename TLIST::TYPE getUintPropertyFast(uint32_t index) const;
318 void setUintPropertyFast(uint32_t index, typename TLIST::TYPE value);
320 // JIT helpers -- not for public use!
321 // (declared public only to avoid a painful 'friend' declaration)
322 typename TLIST::TYPE _getNativeIntProperty(int32_t index) const;
323 void _setNativeIntProperty(int32_t index, typename TLIST::TYPE value);
324 typename TLIST::TYPE _getNativeUintProperty(uint32_t index) const;
325 void _setNativeUintProperty(uint32_t index, typename TLIST::TYPE value);
326 bool _hasUintProperty(uint32_t index) const;
327 Atom _getUintProperty(uint32_t index) const;
328 void _setUintProperty(uint32_t index, Atom value);
329 Atom _getIntProperty(int32_t index) const;
330 void _setIntProperty(int32_t index, Atom value);
332 #ifdef DEBUGGER
333 virtual uint64_t bytesUsed() const;
334 #endif
336 private:
338 void FASTCALL throwRangeError(uint32_t index) const;
340 uint32_t checkReadIndex_u(uint32_t index) const;
341 uint32_t checkWriteIndex_u(uint32_t index) const;
343 // variant of _spliceHelper with explicit array of Atom.
344 // (Not exposed to AS3.)
345 // Note:
346 // _splice(0, 1, 0, &foo) == Array.unshift(foo)
347 // _splice(this.length, 1, 0, &foo) == Array.push(foo)
348 void _splice(uint32_t insertPoint, uint32_t insertCount, uint32_t deleteCount, const Atom* argv);
350 // _spliceHelper for when we already know that we have an object that is *not* of our Vector type.
351 void _spliceHelper_so(uint32_t insertPoint, uint32_t insertCount, uint32_t deleteCount, ScriptObject* so_args, uint32_t offset);
353 public:
354 virtual bool gcTrace(MMgc::GC* gc, size_t cursor)
356 (void)cursor;
357 VectorBaseObject::gcTrace(gc, 0);
358 m_list.gcTrace(gc);
359 return false;
362 private:
363 TLIST m_list;
366 // Some code internal to Flash/AIR needs to directly get/set the contents of Vectors;
367 // this class provides an implicit lock/unlock mechanism. We guarantee that
368 // the value returned by addr() is valid for reading/writing for the lifespan of
369 // the VectorAccessor (but only for entries 0...get_length()-1, of course).
370 // length() is identical to VectorObject::get_length() but is provided here for symmetry.
371 // This should obviously only be used in cases where performance is critical, or
372 // other circumstances requires it (eg, to pass an array of numbers to a GPU
373 // without intermediate copying). Note that it is explicitly legal to pass
374 // a NULL VectorObject to the ctor (which will cause addr() to also return NULL
375 // and length() to return 0). This class must be used only on the stack.
376 template<class TLIST>
377 class VectorAccessor
379 public:
380 explicit VectorAccessor(TypedVectorObject<TLIST>* v);
381 typename TLIST::TYPE* addr();
382 uint32_t length();
384 private:
385 TypedVectorObject<TLIST>* m_vector;
387 private:
388 void* operator new(size_t size); // unimplemented
391 // ----------------------------
393 class GC_AS3_EXACT(IntVectorObject, TypedVectorObject< DataList<int32_t> >)
395 protected:
396 explicit IntVectorObject(VTable* ivtable, ScriptObject* delegate);
398 public:
399 REALLY_INLINE static IntVectorObject* create(MMgc::GC* gc, VTable* ivtable, ScriptObject* delegate)
401 return new (gc, MMgc::kExact, ivtable->getExtraSize()) IntVectorObject(ivtable, delegate);
404 // AS3 native function implementations
405 IntVectorObject* newThisType();
407 // ------------------------ DATA SECTION BEGIN
408 private:
409 GC_NO_DATA(IntVectorObject)
411 DECLARE_SLOTS_IntVectorObject;
412 // ------------------------ DATA SECTION END
414 typedef VectorAccessor< DataList<int32_t> > IntVectorAccessor;
416 // ----------------------------
418 class GC_AS3_EXACT(UIntVectorObject, TypedVectorObject< DataList<uint32_t> >)
420 protected:
421 explicit UIntVectorObject(VTable* ivtable, ScriptObject* delegate);
423 public:
424 REALLY_INLINE static UIntVectorObject* create(MMgc::GC* gc, VTable* ivtable, ScriptObject* delegate)
426 return new (gc, MMgc::kExact, ivtable->getExtraSize()) UIntVectorObject(ivtable, delegate);
429 // AS3 native function implementations
430 UIntVectorObject* newThisType();
432 // ------------------------ DATA SECTION BEGIN
433 private:
434 GC_NO_DATA(UIntVectorObject)
436 DECLARE_SLOTS_UIntVectorObject;
437 // ------------------------ DATA SECTION END
439 typedef VectorAccessor< DataList<uint32_t> > UIntVectorAccessor;
441 // ----------------------------
443 class GC_AS3_EXACT(DoubleVectorObject, TypedVectorObject< DataList<double> >)
445 protected:
446 explicit DoubleVectorObject(VTable* ivtable, ScriptObject* delegate);
448 public:
449 REALLY_INLINE static DoubleVectorObject* create(MMgc::GC* gc, VTable* ivtable, ScriptObject* delegate)
451 return new (gc, MMgc::kExact, ivtable->getExtraSize()) DoubleVectorObject(ivtable, delegate);
454 // AS3 native function implementations
455 DoubleVectorObject* newThisType();
457 // ------------------------ DATA SECTION BEGIN
458 private:
459 GC_NO_DATA(DoubleVectorObject)
461 DECLARE_SLOTS_DoubleVectorObject;
462 // ------------------------ DATA SECTION END
464 typedef VectorAccessor< DataList<double> > DoubleVectorAccessor;
466 // ----------------------------
468 class GC_AS3_EXACT(ObjectVectorObject, TypedVectorObject< AtomList >)
470 protected:
471 explicit ObjectVectorObject(VTable* ivtable, ScriptObject* delegate);
473 public:
474 REALLY_INLINE static ObjectVectorObject* create(MMgc::GC* gc, VTable* ivtable, ScriptObject* delegate)
476 return new (gc, MMgc::kExact, ivtable->getExtraSize()) ObjectVectorObject(ivtable, delegate);
479 // AS3 native function implementations
480 ObjectVectorObject* newThisType();
482 // ------------------------ DATA SECTION BEGIN
483 private:
484 GC_NO_DATA(ObjectVectorObject)
486 DECLARE_SLOTS_ObjectVectorObject;
487 // ------------------------ DATA SECTION END
489 // This is explicitly NOT provided, as
490 // (1) there's currently no need for it, and
491 // (2) it would require WB hackery on the part of the user, which is error-prone
492 //typedef VectorAccessor<Atom> ObjectVectorAccessor;
494 // ----------------------------
497 #endif /* __avmplus_VectorClass__ */