|
1 /* |
|
2 * Copyright (C) 2009 Apple Inc. All rights reserved. |
|
3 * Copyright (C) 2009 Google Inc. All rights reserved. |
|
4 * |
|
5 * Redistribution and use in source and binary forms, with or without |
|
6 * modification, are permitted provided that the following conditions |
|
7 * are met: |
|
8 * 1. Redistributions of source code must retain the above copyright |
|
9 * notice, this list of conditions and the following disclaimer. |
|
10 * 2. Redistributions in binary form must reproduce the above copyright |
|
11 * notice, this list of conditions and the following disclaimer in the |
|
12 * documentation and/or other materials provided with the distribution. |
|
13 * |
|
14 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY |
|
15 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
16 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
17 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
18 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
19 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
20 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
21 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
24 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
25 */ |
|
26 |
|
27 #ifndef JSArrayBufferViewHelper_h |
|
28 #define JSArrayBufferViewHelper_h |
|
29 |
|
30 #include "ArrayBufferView.h" |
|
31 #include "ExceptionCode.h" |
|
32 #include "JSArrayBuffer.h" |
|
33 #include "JSDOMBinding.h" |
|
34 #include <interpreter/CallFrame.h> |
|
35 #include <runtime/ArgList.h> |
|
36 #include <runtime/Error.h> |
|
37 #include <runtime/JSObject.h> |
|
38 #include <runtime/JSValue.h> |
|
39 |
|
40 namespace WebCore { |
|
41 |
|
42 template <class T> |
|
43 JSC::JSValue setWebGLArrayHelper(JSC::ExecState* exec, T* impl, T* (*conversionFunc)(JSC::JSValue)) |
|
44 { |
|
45 if (exec->argumentCount() < 1) |
|
46 return JSC::throwSyntaxError(exec); |
|
47 |
|
48 T* array = (*conversionFunc)(exec->argument(0)); |
|
49 if (array) { |
|
50 // void set(in WebGL<T>Array array, [Optional] in unsigned long offset); |
|
51 unsigned offset = 0; |
|
52 if (exec->argumentCount() == 2) |
|
53 offset = exec->argument(1).toInt32(exec); |
|
54 ExceptionCode ec = 0; |
|
55 impl->set(array, offset, ec); |
|
56 setDOMException(exec, ec); |
|
57 return JSC::jsUndefined(); |
|
58 } |
|
59 |
|
60 if (exec->argument(0).isObject()) { |
|
61 // void set(in sequence<long> array, [Optional] in unsigned long offset); |
|
62 JSC::JSObject* array = JSC::asObject(exec->argument(0)); |
|
63 uint32_t offset = 0; |
|
64 if (exec->argumentCount() == 2) |
|
65 offset = exec->argument(1).toInt32(exec); |
|
66 uint32_t length = array->get(exec, JSC::Identifier(exec, "length")).toInt32(exec); |
|
67 if (offset > impl->length() |
|
68 || offset + length > impl->length() |
|
69 || offset + length < offset) |
|
70 setDOMException(exec, INDEX_SIZE_ERR); |
|
71 else { |
|
72 for (uint32_t i = 0; i < length; i++) { |
|
73 JSC::JSValue v = array->get(exec, i); |
|
74 if (exec->hadException()) |
|
75 return JSC::jsUndefined(); |
|
76 impl->set(i + offset, v.toNumber(exec)); |
|
77 } |
|
78 } |
|
79 |
|
80 return JSC::jsUndefined(); |
|
81 } |
|
82 |
|
83 return JSC::throwSyntaxError(exec); |
|
84 } |
|
85 |
|
86 // Template function used by XXXArrayConstructors. |
|
87 // If this returns 0, it will already have thrown a JavaScript exception. |
|
88 template<class C, typename T> |
|
89 PassRefPtr<ArrayBufferView> constructArrayBufferView(JSC::ExecState* exec) |
|
90 { |
|
91 // There are 3 constructors: |
|
92 // |
|
93 // 1) (in int size) |
|
94 // 2) (in ArrayBuffer buffer, [Optional] in int offset, [Optional] in unsigned int length) |
|
95 // 3) (in sequence<T>) - This ends up being a JS "array-like" object |
|
96 // |
|
97 RefPtr<C> arrayObject; |
|
98 |
|
99 // For the 0 args case, just create a zero-length view. We could |
|
100 // consider raising a SyntaxError for this case, but not all |
|
101 // JavaScript DOM bindings can distinguish between "new |
|
102 // <Type>Array()" and what occurs when a previously-constructed |
|
103 // ArrayBufferView is returned to JavaScript; e.g., from |
|
104 // "array.slice()". |
|
105 if (exec->argumentCount() < 1) |
|
106 return C::create(0); |
|
107 |
|
108 if (exec->argument(0).isNull()) { |
|
109 // Invalid first argument |
|
110 throwTypeError(exec); |
|
111 return 0; |
|
112 } |
|
113 |
|
114 if (exec->argument(0).isObject()) { |
|
115 RefPtr<ArrayBuffer> buffer = toArrayBuffer(exec->argument(0)); |
|
116 if (buffer) { |
|
117 unsigned offset = (exec->argumentCount() > 1) ? exec->argument(1).toUInt32(exec) : 0; |
|
118 unsigned int length = (buffer->byteLength() - offset) / sizeof(T); |
|
119 if (exec->argumentCount() > 2) |
|
120 length = exec->argument(2).toUInt32(exec); |
|
121 PassRefPtr<ArrayBufferView> array = C::create(buffer, offset, length); |
|
122 if (!array) |
|
123 setDOMException(exec, INDEX_SIZE_ERR); |
|
124 return array; |
|
125 } |
|
126 |
|
127 JSC::JSObject* array = asObject(exec->argument(0)); |
|
128 unsigned length = array->get(exec, JSC::Identifier(exec, "length")).toUInt32(exec); |
|
129 void* tempValues; |
|
130 if (!tryFastCalloc(length, sizeof(T)).getValue(tempValues)) { |
|
131 JSC::throwError(exec, createError(exec, "Error")); |
|
132 return 0; |
|
133 } |
|
134 |
|
135 OwnFastMallocPtr<T> values(static_cast<T*>(tempValues)); |
|
136 for (unsigned i = 0; i < length; ++i) { |
|
137 JSC::JSValue v = array->get(exec, i); |
|
138 if (exec->hadException()) |
|
139 return 0; |
|
140 values.get()[i] = static_cast<T>(v.toNumber(exec)); |
|
141 } |
|
142 |
|
143 PassRefPtr<ArrayBufferView> result = C::create(values.get(), length); |
|
144 if (!result) |
|
145 setDOMException(exec, INDEX_SIZE_ERR); |
|
146 return result; |
|
147 } |
|
148 |
|
149 int length = exec->argument(0).toInt32(exec); |
|
150 PassRefPtr<ArrayBufferView> result; |
|
151 if (length >= 0) |
|
152 result = C::create(static_cast<unsigned>(length)); |
|
153 if (!result) |
|
154 throwError(exec, createRangeError(exec, "ArrayBufferView size is not a small enough positive integer.")); |
|
155 return result; |
|
156 } |
|
157 |
|
158 } // namespace WebCore |
|
159 |
|
160 #endif // JSArrayBufferViewHelper_h |