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 ***** */
44 #include "VectorClass-impl.h"
48 // Force explicit instantiations for various non-inlined methods;
49 // some compilers don't need this, but some do.
51 template class TypedVectorClass
<IntVectorObject
>;
52 template class TypedVectorClass
<UIntVectorObject
>;
53 template class TypedVectorClass
<DoubleVectorObject
>;
54 template class TypedVectorClass
<ObjectVectorObject
>;
56 template class TypedVectorObject
< DataList
<int32_t> >;
57 template class TypedVectorObject
< DataList
<uint32_t> >;
58 template class TypedVectorObject
< DataList
<double> >;
59 template class TypedVectorObject
< AtomList
>;
64 // ----------------------------
67 // sets index to the uint32_t value of name, if it can be converted
68 // isNumber is set to true if name was a number (whether it was a uint32_t value or not)
69 VectorBaseObject::VectorIndexStatus
VectorBaseObject::getVectorIndex(Atom name
, uint32_t& index
) const
71 if (AvmCore::getIndexFromAtom(name
, &index
))
75 else if (AvmCore::isString(name
))
77 Stringp s
= core()->string(name
);
78 wchar c
= s
->charAt(0);
79 // Does it look like a number?
80 if (s
->length() > 0 && c
>= '0' && c
<= '9')
82 double const index_d
= s
->toNumber();
83 if (!MathUtils::isNaN(index_d
))
85 // name is a string that looks like a number
86 // Note: convert using int, not uint, as it's much faster
87 int32_t const index_i
= int32_t(index_d
);
88 index
= uint32_t(index_i
);
89 return (double(index_i
) == index_d
) ? kValidNumber
: kInvalidNumber
;
96 // ----------------------------
98 VectorClass::VectorClass(VTable
*vtable
)
99 : ClassClosure(vtable
)
101 setPrototypePtr(toplevel()->objectClass
->construct());
104 /*static*/ Stringp
VectorClass::makeVectorClassName(AvmCore
* core
, Traits
* t
)
106 Stringp s
= core
->newConstantStringLatin1("Vector.<");
107 s
= s
->append(t
->formatClassName());
108 s
= s
->append(core
->newConstantStringLatin1(">"));
109 // all callers want it interned, so let's do it here
110 return core
->internString(s
);
113 ClassClosure
* VectorClass::getTypedVectorClass(ClassClosure
* typeClass
)
115 ClassClosure
* result
= NULL
;
116 Toplevel
* toplevel
= this->toplevel();
117 if (typeClass
== NULL
)
119 result
= toplevel
->objectVectorClass();
121 else if (typeClass
== toplevel
->intClass())
123 result
= toplevel
->intVectorClass();
125 else if (typeClass
== toplevel
->uintClass())
127 result
= toplevel
->uintVectorClass();
129 else if (typeClass
== toplevel
->numberClass())
131 result
= toplevel
->doubleVectorClass();
135 // if we have an object, we must have an itraits (otherwise the typearg is not a Class)
136 Traits
* typeTraits
= typeClass
->vtable
->traits
->itraits
;
138 toplevel
->throwVerifyError(kCorruptABCError
);
140 Domain
* typeDomain
= typeClass
->traits()->pool
->domain
;
141 if ((result
= typeDomain
->getParameterizedType(typeClass
)) == NULL
)
143 Stringp fullname
= VectorClass::makeVectorClassName(core(), typeTraits
);
145 VTable
* vt
= this->vtable
->newParameterizedVTable(typeTraits
, fullname
);
147 vt
->ivtable
->createInstanceProc
= ClassClosure::impossibleCreateInstanceProc
;
148 ObjectVectorClass
* parameterizedVector
= ObjectVectorClass::create(vt
->gc(), vt
);
149 parameterizedVector
->m_typeTraits
= typeClass
? typeClass
->traits()->itraits
: NULL
;
150 parameterizedVector
->setDelegate(toplevel
->classClass()->prototypePtr());
152 // Is this right? Should each instantiation get its own prototype?
153 parameterizedVector
->setPrototypePtr(toplevel
->objectVectorClass()->prototypePtr());
154 typeDomain
->addParameterizedType(typeClass
, parameterizedVector
);
156 result
= parameterizedVector
;
159 AvmAssert(result
!= NULL
);
163 Atom
VectorClass::applyTypeArgs(int argc
, Atom
* argv
)
165 Toplevel
* toplevel
= this->toplevel();
167 // Vector only takes 1 type argument
171 toplevel
->typeErrorClass()->throwError(kWrongTypeArgCountError
, traits()->formatClassName(), core()->toErrorString(1), core()->toErrorString(argc
));
174 Atom
const typeAtom
= argv
[0];
176 ClassClosure
* typeClass
= NULL
;
177 if (!ISNULL(typeAtom
))
179 if (atomKind(typeAtom
) != kObjectType
)
180 toplevel
->throwVerifyError(kCorruptABCError
);
182 typeClass
= (ClassClosure
*)AvmCore::atomToScriptObject(typeAtom
);
183 if (!typeClass
->vtable
->traits
->itraits
)
184 toplevel
->throwVerifyError(kCorruptABCError
);
186 return getTypedVectorClass(typeClass
)->atom();
189 Atom
VectorClass::construct(int /*argc*/, Atom
* /*argv*/)
191 toplevel()->throwTypeError(kConstructOfNonFunctionError
);
192 return undefinedAtom
;
195 // FIXME: this could return a non-ObjectVectorObject, so we should really
196 // return VectorBaseObject instead.
197 ObjectVectorObject
* VectorClass::newVector(ClassClosure
* type
, uint32_t length
)
199 ClassClosure
* vc
= getTypedVectorClass(type
);
200 Atom args
[2] = { nullObjectAtom
, core()->uintToAtom(length
) };
201 return (ObjectVectorObject
*)AvmCore::atomToScriptObject(vc
->construct(1, args
));
204 // ----------------------------
206 IntVectorClass::IntVectorClass(VTable
* vtable
)
207 : TypedVectorClass
<IntVectorObject
>(vtable
)
209 // This is an ugly hack: Vector<> doesn't work properly with the ClassManifest setup,
210 // because the name it returns for itself isn't the name listed for finddef.
211 // To work around this (and maintain legacy internal behavior), we pre-emptively
212 // enter the Vector classes into the table upon first creation. (Arguably the name
213 // lookup issue should be fixed.)
214 toplevel()->builtinClasses()->fillInClass(avmplus::NativeID::abcclass___AS3___vec_Vector_int
, this);
215 this->m_typeTraits
= toplevel()->intClass()->traits()->itraits
;
218 Atom
IntVectorClass::construct(int argc
, Atom
* argv
)
220 return constructImpl(argc
, argv
);
223 // ----------------------------
225 UIntVectorClass::UIntVectorClass(VTable
* vtable
)
226 : TypedVectorClass
<UIntVectorObject
>(vtable
)
228 // This is an ugly hack: Vector<> doesn't work properly with the ClassManifest setup,
229 // because the name it returns for itself isn't the name listed for finddef.
230 // To work around this (and maintain legacy internal behavior), we pre-emptively
231 // enter the Vector classes into the table upon first creation. (Arguably the name
232 // lookup issue should be fixed.)
233 toplevel()->builtinClasses()->fillInClass(avmplus::NativeID::abcclass___AS3___vec_Vector_uint
, this);
234 this->m_typeTraits
= toplevel()->uintClass()->traits()->itraits
;
237 Atom
UIntVectorClass::construct(int argc
, Atom
* argv
)
239 return constructImpl(argc
, argv
);
242 // ----------------------------
244 DoubleVectorClass::DoubleVectorClass(VTable
* vtable
)
245 : TypedVectorClass
<DoubleVectorObject
>(vtable
)
247 // This is an ugly hack: Vector<> doesn't work properly with the ClassManifest setup,
248 // because the name it returns for itself isn't the name listed for finddef.
249 // To work around this (and maintain legacy internal behavior), we pre-emptively
250 // enter the Vector classes into the table upon first creation. (Arguably the name
251 // lookup issue should be fixed.)
252 toplevel()->builtinClasses()->fillInClass(avmplus::NativeID::abcclass___AS3___vec_Vector_double
, this);
253 this->m_typeTraits
= toplevel()->numberClass()->traits()->itraits
;
256 Atom
DoubleVectorClass::construct(int argc
, Atom
* argv
)
258 return constructImpl(argc
, argv
);
261 // ----------------------------
263 ObjectVectorClass::ObjectVectorClass(VTable
* vtable
)
264 : TypedVectorClass
<ObjectVectorObject
>(vtable
)
266 // This is an ugly hack: Vector<> doesn't work properly with the ClassManifest setup,
267 // because the name it returns for itself isn't the name listed for finddef.
268 // To work around this (and maintain legacy internal behavior), we pre-emptively
269 // enter the Vector classes into the table upon first creation. (Arguably the name
270 // lookup issue should be fixed.)
271 toplevel()->builtinClasses()->fillInClass(avmplus::NativeID::abcclass___AS3___vec_Vector_object
, this);
272 this->m_typeTraits
= toplevel()->objectClass
->traits()->itraits
;
275 Atom
ObjectVectorClass::construct(int argc
, Atom
* argv
)
277 return constructImpl(argc
, argv
);
280 // ----------------------------
282 IntVectorObject::IntVectorObject(VTable
* ivtable
, ScriptObject
* delegate
)
283 : TypedVectorObject
< DataList
<int32_t> >(ivtable
, delegate
)
287 IntVectorObject
* IntVectorObject::newThisType()
289 return (IntVectorObject
*)_newVector();
292 // ----------------------------
294 UIntVectorObject::UIntVectorObject(VTable
* ivtable
, ScriptObject
* delegate
)
295 : TypedVectorObject
< DataList
<uint32_t> >(ivtable
, delegate
)
299 UIntVectorObject
* UIntVectorObject::newThisType()
301 return (UIntVectorObject
*)_newVector();
304 // ----------------------------
306 DoubleVectorObject::DoubleVectorObject(VTable
* ivtable
, ScriptObject
* delegate
)
307 : TypedVectorObject
< DataList
<double> >(ivtable
, delegate
)
311 DoubleVectorObject
* DoubleVectorObject::newThisType()
313 return (DoubleVectorObject
*)_newVector();
316 // ----------------------------
318 ObjectVectorObject::ObjectVectorObject(VTable
* ivtable
, ScriptObject
* delegate
)
319 : TypedVectorObject
< AtomList
>(ivtable
, delegate
)
323 ObjectVectorObject
* ObjectVectorObject::newThisType()
325 return (ObjectVectorObject
*)_newVector();