1 : /* -*- Mode: c++; c-basic-offset: 4; tab-width: 40; indent-tabs-mode: nil -*- */
2 : /* vim: set ts=40 sw=4 et tw=99: */
3 : /* ***** BEGIN LICENSE BLOCK *****
4 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 : *
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/
10 : *
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.
15 : *
16 : * The Original Code is Mozilla WebGL impl
17 : *
18 : * The Initial Developer of the Original Code is
19 : * Mozilla Foundation
20 : * Portions created by the Initial Developer are Copyright (C) 2009
21 : * the Initial Developer. All Rights Reserved.
22 : *
23 : * Contributor(s):
24 : * Vladimir Vukicevic <vladimir@pobox.com>
25 : *
26 : * Alternatively, the contents of this file may be used under the terms of
27 : * either of the GNU General Public License Version 2 or later (the "GPL"),
28 : * or 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.
37 : *
38 : * ***** END LICENSE BLOCK ***** */
39 :
40 : #ifndef jstypedarray_h
41 : #define jstypedarray_h
42 :
43 : #include "jsapi.h"
44 : #include "jsclass.h"
45 :
46 : #include "gc/Barrier.h"
47 :
48 : typedef struct JSProperty JSProperty;
49 :
50 : namespace js {
51 :
52 : /*
53 : * ArrayBuffer
54 : *
55 : * This class holds the underlying raw buffer that the TypedArray
56 : * subclasses access. It can be created explicitly and passed to a
57 : * TypedArray subclass, or can be created implicitly by constructing a
58 : * TypedArray with a size.
59 : */
60 : struct JS_FRIEND_API(ArrayBuffer) {
61 : static Class slowClass;
62 : static JSPropertySpec jsprops[];
63 : static JSFunctionSpec jsfuncs[];
64 :
65 : static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp);
66 :
67 : static JSBool fun_slice(JSContext *cx, unsigned argc, Value *vp);
68 :
69 : static JSBool class_constructor(JSContext *cx, unsigned argc, Value *vp);
70 :
71 : static JSObject *create(JSContext *cx, int32_t nbytes, uint8_t *contents = NULL);
72 :
73 : static JSObject *createSlice(JSContext *cx, JSObject *arrayBuffer,
74 : uint32_t begin, uint32_t end);
75 :
76 : ArrayBuffer()
77 : {
78 : }
79 :
80 : ~ArrayBuffer();
81 :
82 : static void
83 : obj_trace(JSTracer *trc, JSObject *obj);
84 :
85 : static JSBool
86 : obj_lookupGeneric(JSContext *cx, JSObject *obj, jsid id,
87 : JSObject **objp, JSProperty **propp);
88 : static JSBool
89 : obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
90 : JSObject **objp, JSProperty **propp);
91 : static JSBool
92 : obj_lookupElement(JSContext *cx, JSObject *obj, uint32_t index,
93 : JSObject **objp, JSProperty **propp);
94 : static JSBool
95 : obj_lookupSpecial(JSContext *cx, JSObject *obj, SpecialId sid, JSObject **objp,
96 : JSProperty **propp);
97 :
98 : static JSBool
99 : obj_defineGeneric(JSContext *cx, JSObject *obj, jsid id, const Value *v,
100 : PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
101 : static JSBool
102 : obj_defineProperty(JSContext *cx, JSObject *obj, PropertyName *name, const Value *v,
103 : PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
104 : static JSBool
105 : obj_defineElement(JSContext *cx, JSObject *obj, uint32_t index, const Value *v,
106 : PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
107 : static JSBool
108 : obj_defineSpecial(JSContext *cx, JSObject *obj, SpecialId sid, const Value *v,
109 : PropertyOp getter, StrictPropertyOp setter, unsigned attrs);
110 :
111 : static JSBool
112 : obj_getGeneric(JSContext *cx, JSObject *obj, JSObject *receiver, jsid id, Value *vp);
113 :
114 : static JSBool
115 : obj_getProperty(JSContext *cx, JSObject *obj, JSObject *receiver, PropertyName *name,
116 : Value *vp);
117 :
118 : static JSBool
119 : obj_getElement(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index, Value *vp);
120 : static JSBool
121 : obj_getElementIfPresent(JSContext *cx, JSObject *obj, JSObject *receiver, uint32_t index,
122 : Value *vp, bool *present);
123 :
124 : static JSBool
125 : obj_getSpecial(JSContext *cx, JSObject *obj, JSObject *receiver, SpecialId sid, Value *vp);
126 :
127 : static JSBool
128 : obj_setGeneric(JSContext *cx, JSObject *obj, jsid id, Value *vp, JSBool strict);
129 : static JSBool
130 : obj_setProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *vp, JSBool strict);
131 : static JSBool
132 : obj_setElement(JSContext *cx, JSObject *obj, uint32_t index, Value *vp, JSBool strict);
133 : static JSBool
134 : obj_setSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *vp, JSBool strict);
135 :
136 : static JSBool
137 : obj_getGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
138 : static JSBool
139 : obj_getPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp);
140 : static JSBool
141 : obj_getElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
142 : static JSBool
143 : obj_getSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp);
144 :
145 : static JSBool
146 : obj_setGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
147 : static JSBool
148 : obj_setPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp);
149 : static JSBool
150 : obj_setElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
151 : static JSBool
152 : obj_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp);
153 :
154 : static JSBool
155 : obj_deleteProperty(JSContext *cx, JSObject *obj, PropertyName *name, Value *rval, JSBool strict);
156 : static JSBool
157 : obj_deleteElement(JSContext *cx, JSObject *obj, uint32_t index, Value *rval, JSBool strict);
158 : static JSBool
159 : obj_deleteSpecial(JSContext *cx, JSObject *obj, SpecialId sid, Value *rval, JSBool strict);
160 :
161 : static JSBool
162 : obj_enumerate(JSContext *cx, JSObject *obj, JSIterateOp enum_op,
163 : Value *statep, jsid *idp);
164 :
165 : static JSType
166 : obj_typeOf(JSContext *cx, JSObject *obj);
167 :
168 : static JSObject *
169 : getArrayBuffer(JSObject *obj);
170 : };
171 :
172 : /*
173 : * TypedArray
174 : *
175 : * The non-templated base class for the specific typed implementations.
176 : * This class holds all the member variables that are used by
177 : * the subclasses.
178 : */
179 :
180 : struct JS_FRIEND_API(TypedArray) {
181 : enum {
182 : TYPE_INT8 = 0,
183 : TYPE_UINT8,
184 : TYPE_INT16,
185 : TYPE_UINT16,
186 : TYPE_INT32,
187 : TYPE_UINT32,
188 : TYPE_FLOAT32,
189 : TYPE_FLOAT64,
190 :
191 : /*
192 : * Special type that's a uint8, but assignments are clamped to 0 .. 255.
193 : * Treat the raw data type as a uint8.
194 : */
195 : TYPE_UINT8_CLAMPED,
196 :
197 : TYPE_MAX
198 : };
199 :
200 : enum {
201 : /* Properties of the typed array stored in reserved slots. */
202 : FIELD_LENGTH = 0,
203 : FIELD_BYTEOFFSET,
204 : FIELD_BYTELENGTH,
205 : FIELD_TYPE,
206 : FIELD_BUFFER,
207 : FIELD_MAX,
208 : NUM_FIXED_SLOTS = 7
209 : };
210 :
211 : // and MUST NOT be used to construct new objects.
212 : static Class fastClasses[TYPE_MAX];
213 :
214 : // These are the slow/original classes, used
215 : // fo constructing new objects
216 : static Class slowClasses[TYPE_MAX];
217 :
218 : static JSPropertySpec jsprops[];
219 :
220 : static JSObject *getTypedArray(JSObject *obj);
221 :
222 : static JSBool prop_getBuffer(JSContext *cx, JSObject *obj, jsid id, Value *vp);
223 : static JSBool prop_getByteOffset(JSContext *cx, JSObject *obj, jsid id, Value *vp);
224 : static JSBool prop_getByteLength(JSContext *cx, JSObject *obj, jsid id, Value *vp);
225 : static JSBool prop_getLength(JSContext *cx, JSObject *obj, jsid id, Value *vp);
226 :
227 : static JSBool obj_lookupGeneric(JSContext *cx, JSObject *obj, jsid id,
228 : JSObject **objp, JSProperty **propp);
229 : static JSBool obj_lookupProperty(JSContext *cx, JSObject *obj, PropertyName *name,
230 : JSObject **objp, JSProperty **propp);
231 : static JSBool obj_lookupElement(JSContext *cx, JSObject *obj, uint32_t index,
232 : JSObject **objp, JSProperty **propp);
233 : static JSBool obj_lookupSpecial(JSContext *cx, JSObject *obj, SpecialId sid,
234 : JSObject **objp, JSProperty **propp);
235 :
236 : static JSBool obj_getGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
237 : static JSBool obj_getPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp);
238 : static JSBool obj_getElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
239 : static JSBool obj_getSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp);
240 :
241 : static JSBool obj_setGenericAttributes(JSContext *cx, JSObject *obj, jsid id, unsigned *attrsp);
242 : static JSBool obj_setPropertyAttributes(JSContext *cx, JSObject *obj, PropertyName *name, unsigned *attrsp);
243 : static JSBool obj_setElementAttributes(JSContext *cx, JSObject *obj, uint32_t index, unsigned *attrsp);
244 : static JSBool obj_setSpecialAttributes(JSContext *cx, JSObject *obj, SpecialId sid, unsigned *attrsp);
245 :
246 : static uint32_t getLength(JSObject *obj);
247 : static uint32_t getByteOffset(JSObject *obj);
248 : static uint32_t getByteLength(JSObject *obj);
249 : static uint32_t getType(JSObject *obj);
250 : static JSObject * getBuffer(JSObject *obj);
251 : static void * getDataOffset(JSObject *obj);
252 :
253 : public:
254 : static bool
255 : isArrayIndex(JSContext *cx, JSObject *obj, jsid id, uint32_t *ip = NULL);
256 :
257 3185 : static inline uint32_t slotWidth(int atype) {
258 3185 : switch (atype) {
259 : case js::TypedArray::TYPE_INT8:
260 : case js::TypedArray::TYPE_UINT8:
261 : case js::TypedArray::TYPE_UINT8_CLAMPED:
262 1159 : return 1;
263 : case js::TypedArray::TYPE_INT16:
264 : case js::TypedArray::TYPE_UINT16:
265 647 : return 2;
266 : case js::TypedArray::TYPE_INT32:
267 : case js::TypedArray::TYPE_UINT32:
268 : case js::TypedArray::TYPE_FLOAT32:
269 1126 : return 4;
270 : case js::TypedArray::TYPE_FLOAT64:
271 253 : return 8;
272 : default:
273 0 : JS_NOT_REACHED("invalid typed array type");
274 : return 0;
275 : }
276 : }
277 :
278 640 : static inline int slotWidth(JSObject *obj) {
279 640 : return slotWidth(getType(obj));
280 : }
281 :
282 : static int lengthOffset();
283 : static int dataOffset();
284 : };
285 :
286 : extern bool
287 : IsFastTypedArrayClass(const Class *clasp);
288 :
289 : } // namespace js
290 :
291 : /* Friend API methods */
292 :
293 : JS_FRIEND_API(JSObject *)
294 : js_InitTypedArrayClasses(JSContext *cx, JSObject *obj);
295 :
296 : JS_FRIEND_API(JSBool)
297 : js_IsTypedArray(JSObject *obj);
298 :
299 : JS_FRIEND_API(JSBool)
300 : js_IsArrayBuffer(JSObject *obj);
301 :
302 : JS_FRIEND_API(JSObject *)
303 : js_CreateArrayBuffer(JSContext *cx, uint32_t nbytes);
304 :
305 : /*
306 : * Create a new typed array of type atype (one of the TypedArray
307 : * enumerant values above), with nelements elements.
308 : */
309 : JS_FRIEND_API(JSObject *)
310 : js_CreateTypedArray(JSContext *cx, int atype, uint32_t nelements);
311 :
312 : /*
313 : * Create a new typed array of type atype (one of the TypedArray
314 : * enumerant values above), and copy in values from the given JSObject,
315 : * which must either be a typed array or an array-like object.
316 : */
317 : JS_FRIEND_API(JSObject *)
318 : js_CreateTypedArrayWithArray(JSContext *cx, int atype, JSObject *arrayArg);
319 :
320 : /*
321 : * Create a new typed array of type atype (one of the TypedArray
322 : * enumerant values above), using a given ArrayBuffer for storage.
323 : * The byteoffset and length values are optional; if -1 is passed, an
324 : * offset of 0 and enough elements to use up the remainder of the byte
325 : * array are used as the default values.
326 : */
327 : JS_FRIEND_API(JSObject *)
328 : js_CreateTypedArrayWithBuffer(JSContext *cx, int atype, JSObject *bufArg,
329 : int byteoffset, int length);
330 :
331 : extern int32_t JS_FASTCALL
332 : js_TypedArray_uint8_clamp_double(const double x);
333 :
334 : JS_FRIEND_API(JSBool)
335 : JS_IsArrayBufferObject(JSObject *obj);
336 :
337 : JS_FRIEND_API(JSObject *)
338 : JS_NewArrayBuffer(JSContext *cx, uint32_t nbytes);
339 :
340 : JS_FRIEND_API(uint32_t)
341 : JS_GetArrayBufferByteLength(JSObject *obj);
342 :
343 : JS_FRIEND_API(uint8_t *)
344 : JS_GetArrayBufferData(JSObject *obj);
345 :
346 : JS_FRIEND_API(uint32_t)
347 : JS_GetTypedArrayLength(JSObject *obj);
348 :
349 : JS_FRIEND_API(uint32_t)
350 : JS_GetTypedArrayByteOffset(JSObject *obj);
351 :
352 : JS_FRIEND_API(uint32_t)
353 : JS_GetTypedArrayByteLength(JSObject *obj);
354 :
355 : JS_FRIEND_API(uint32_t)
356 : JS_GetTypedArrayType(JSObject *obj);
357 :
358 : JS_FRIEND_API(JSObject *)
359 : JS_GetTypedArrayBuffer(JSObject *obj);
360 :
361 : JS_FRIEND_API(void *)
362 : JS_GetTypedArrayData(JSObject *obj);
363 :
364 : #endif /* jstypedarray_h */
|