[Web IDL] Pass even more types by reference
[WebKit-https.git] / Source / WebCore / bindings / js / JSWebGLRenderingContextBaseCustom.cpp
1 /*
2  * Copyright (C) 2015 Apple Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  */
25
26 #include "config.h"
27
28 #if ENABLE(WEBGL)
29 #include "JSWebGLRenderingContextBase.h"
30
31 #include "ANGLEInstancedArrays.h"
32 #include "EXTBlendMinMax.h"
33 #include "EXTFragDepth.h"
34 #include "EXTShaderTextureLOD.h"
35 #include "EXTTextureFilterAnisotropic.h"
36 #include "EXTsRGB.h"
37 #include "ExceptionCode.h"
38 #include "HTMLCanvasElement.h"
39 #include "HTMLImageElement.h"
40 #include "JSANGLEInstancedArrays.h"
41 #include "JSEXTBlendMinMax.h"
42 #include "JSEXTFragDepth.h"
43 #include "JSEXTShaderTextureLOD.h"
44 #include "JSEXTTextureFilterAnisotropic.h"
45 #include "JSEXTsRGB.h"
46 #include "JSHTMLCanvasElement.h"
47 #include "JSHTMLImageElement.h"
48 #include "JSImageData.h"
49 #include "JSOESElementIndexUint.h"
50 #include "JSOESStandardDerivatives.h"
51 #include "JSOESTextureFloat.h"
52 #include "JSOESTextureFloatLinear.h"
53 #include "JSOESTextureHalfFloat.h"
54 #include "JSOESTextureHalfFloatLinear.h"
55 #include "JSOESVertexArrayObject.h"
56 #include "JSWebGLBuffer.h"
57 #include "JSWebGLCompressedTextureATC.h"
58 #include "JSWebGLCompressedTexturePVRTC.h"
59 #include "JSWebGLCompressedTextureS3TC.h"
60 #include "JSWebGLDebugRendererInfo.h"
61 #include "JSWebGLDebugShaders.h"
62 #include "JSWebGLDepthTexture.h"
63 #include "JSWebGLDrawBuffers.h"
64 #include "JSWebGLFramebuffer.h"
65 #include "JSWebGLLoseContext.h"
66 #include "JSWebGLProgram.h"
67 #include "JSWebGLRenderbuffer.h"
68 #include "JSWebGLShader.h"
69 #include "JSWebGLTexture.h"
70 #include "JSWebGLUniformLocation.h"
71 #include "JSWebGLVertexArrayObject.h"
72 #include "JSWebGLVertexArrayObjectOES.h"
73 #include "JSWebKitCSSMatrix.h"
74 #include "NotImplemented.h"
75 #include "OESElementIndexUint.h"
76 #include "OESStandardDerivatives.h"
77 #include "OESTextureFloat.h"
78 #include "OESTextureFloatLinear.h"
79 #include "OESTextureHalfFloat.h"
80 #include "OESTextureHalfFloatLinear.h"
81 #include "OESVertexArrayObject.h"
82 #include "WebGLBuffer.h"
83 #include "WebGLCompressedTextureATC.h"
84 #include "WebGLCompressedTexturePVRTC.h"
85 #include "WebGLCompressedTextureS3TC.h"
86 #include "WebGLDebugRendererInfo.h"
87 #include "WebGLDebugShaders.h"
88 #include "WebGLDepthTexture.h"
89 #include "WebGLDrawBuffers.h"
90 #include "WebGLExtension.h"
91 #include "WebGLFramebuffer.h"
92 #include "WebGLGetInfo.h"
93 #include "WebGLLoseContext.h"
94 #include "WebGLProgram.h"
95 #include "WebGLRenderingContextBase.h"
96 #include "WebGLVertexArrayObject.h"
97 #include "WebGLVertexArrayObjectOES.h"
98 #include <runtime/Error.h>
99 #include <runtime/JSTypedArrays.h>
100 #include <runtime/TypedArrayInlines.h>
101 #include <runtime/TypedArrays.h>
102 #include <wtf/FastMalloc.h>
103
104 #if ENABLE(VIDEO)
105 #include "HTMLVideoElement.h"
106 #include "JSHTMLVideoElement.h"
107 #endif
108
109 using namespace JSC;
110
111 namespace WebCore {
112     
113 static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, const WebGLGetInfo& info)
114 {
115     switch (info.getType()) {
116     case WebGLGetInfo::kTypeBool:
117         return jsBoolean(info.getBool());
118     case WebGLGetInfo::kTypeBoolArray: {
119         MarkedArgumentBuffer list;
120         const Vector<bool>& value = info.getBoolArray();
121         for (size_t ii = 0; ii < value.size(); ++ii)
122             list.append(jsBoolean(value[ii]));
123         return constructArray(exec, 0, globalObject, list);
124     }
125     case WebGLGetInfo::kTypeFloat:
126         return jsNumber(info.getFloat());
127     case WebGLGetInfo::kTypeInt:
128         return jsNumber(info.getInt());
129     case WebGLGetInfo::kTypeNull:
130         return jsNull();
131     case WebGLGetInfo::kTypeString:
132         return jsStringWithCache(exec, info.getString());
133     case WebGLGetInfo::kTypeUnsignedInt:
134         return jsNumber(info.getUnsignedInt());
135     case WebGLGetInfo::kTypeWebGLBuffer:
136         return toJS(exec, globalObject, info.getWebGLBuffer());
137     case WebGLGetInfo::kTypeWebGLFloatArray:
138         return toJS(exec, globalObject, info.getWebGLFloatArray());
139     case WebGLGetInfo::kTypeWebGLFramebuffer:
140         return toJS(exec, globalObject, info.getWebGLFramebuffer());
141     case WebGLGetInfo::kTypeWebGLIntArray:
142         return toJS(exec, globalObject, info.getWebGLIntArray());
143         // FIXME: implement WebGLObjectArray
144         // case WebGLGetInfo::kTypeWebGLObjectArray:
145     case WebGLGetInfo::kTypeWebGLProgram:
146         return toJS(exec, globalObject, info.getWebGLProgram());
147     case WebGLGetInfo::kTypeWebGLRenderbuffer:
148         return toJS(exec, globalObject, info.getWebGLRenderbuffer());
149     case WebGLGetInfo::kTypeWebGLTexture:
150         return toJS(exec, globalObject, info.getWebGLTexture());
151     case WebGLGetInfo::kTypeWebGLUnsignedByteArray:
152         return toJS(exec, globalObject, info.getWebGLUnsignedByteArray());
153     case WebGLGetInfo::kTypeWebGLUnsignedIntArray:
154         return toJS(exec, globalObject, info.getWebGLUnsignedIntArray());
155 #if ENABLE(WEBGL2)
156     case WebGLGetInfo::kTypeWebGLVertexArrayObject:
157         return toJS(exec, globalObject, info.getWebGLVertexArrayObject());
158 #endif
159     case WebGLGetInfo::kTypeWebGLVertexArrayObjectOES:
160         return toJS(exec, globalObject, info.getWebGLVertexArrayObjectOES());
161     default:
162         notImplemented();
163         return jsUndefined();
164     }
165 }
166
167 enum ObjectType {
168     kBuffer, kRenderbuffer, kTexture, kVertexAttrib
169 };
170
171 static JSValue getObjectParameter(JSWebGLRenderingContextBase* obj, ExecState& state, ObjectType objectType)
172 {
173     if (state.argumentCount() != 2)
174         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
175     
176     ExceptionCode ec = 0;
177     WebGLRenderingContextBase& context = obj->wrapped();
178     unsigned target = state.uncheckedArgument(0).toInt32(&state);
179     if (state.hadException())
180         return jsUndefined();
181     unsigned pname = state.uncheckedArgument(1).toInt32(&state);
182     if (state.hadException())
183         return jsUndefined();
184     WebGLGetInfo info;
185     switch (objectType) {
186     case kBuffer:
187         info = context.getBufferParameter(target, pname, ec);
188         break;
189     case kRenderbuffer:
190         info = context.getRenderbufferParameter(target, pname, ec);
191         break;
192     case kTexture:
193         info = context.getTexParameter(target, pname, ec);
194         break;
195     case kVertexAttrib:
196         // target => index
197         info = context.getVertexAttrib(target, pname, ec);
198         break;
199     default:
200         notImplemented();
201         break;
202     }
203     if (ec) {
204         setDOMException(&state, ec);
205         return jsUndefined();
206     }
207     return toJS(&state, obj->globalObject(), info);
208 }
209
210 enum WhichProgramCall {
211     kProgramParameter, kUniform
212 };
213
214 static JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, WebGLExtension* extension)
215 {
216     if (!extension)
217         return jsNull();
218     switch (extension->getName()) {
219     case WebGLExtension::WebGLLoseContextName:
220         return toJS(exec, globalObject, static_cast<WebGLLoseContext*>(extension));
221     case WebGLExtension::EXTShaderTextureLODName:
222         return toJS(exec, globalObject, static_cast<EXTShaderTextureLOD*>(extension));
223     case WebGLExtension::EXTTextureFilterAnisotropicName:
224         return toJS(exec, globalObject, static_cast<EXTTextureFilterAnisotropic*>(extension));
225     case WebGLExtension::EXTsRGBName:
226         return toJS(exec, globalObject, static_cast<EXTsRGB*>(extension));
227     case WebGLExtension::EXTFragDepthName:
228         return toJS(exec, globalObject, static_cast<EXTFragDepth*>(extension));
229     case WebGLExtension::EXTBlendMinMaxName:
230         return toJS(exec, globalObject, static_cast<EXTBlendMinMax*>(extension));
231     case WebGLExtension::OESStandardDerivativesName:
232         return toJS(exec, globalObject, static_cast<OESStandardDerivatives*>(extension));
233     case WebGLExtension::OESTextureFloatName:
234         return toJS(exec, globalObject, static_cast<OESTextureFloat*>(extension));
235     case WebGLExtension::OESTextureFloatLinearName:
236         return toJS(exec, globalObject, static_cast<OESTextureFloatLinear*>(extension));
237     case WebGLExtension::OESTextureHalfFloatName:
238         return toJS(exec, globalObject, static_cast<OESTextureHalfFloat*>(extension));
239     case WebGLExtension::OESTextureHalfFloatLinearName:
240         return toJS(exec, globalObject, static_cast<OESTextureHalfFloatLinear*>(extension));
241     case WebGLExtension::OESVertexArrayObjectName:
242         return toJS(exec, globalObject, static_cast<OESVertexArrayObject*>(extension));
243     case WebGLExtension::OESElementIndexUintName:
244         return toJS(exec, globalObject, static_cast<OESElementIndexUint*>(extension));
245     case WebGLExtension::WebGLDebugRendererInfoName:
246         return toJS(exec, globalObject, static_cast<WebGLDebugRendererInfo*>(extension));
247     case WebGLExtension::WebGLDebugShadersName:
248         return toJS(exec, globalObject, static_cast<WebGLDebugShaders*>(extension));
249     case WebGLExtension::WebGLCompressedTextureATCName:
250         return toJS(exec, globalObject, static_cast<WebGLCompressedTextureATC*>(extension));
251     case WebGLExtension::WebGLCompressedTexturePVRTCName:
252         return toJS(exec, globalObject, static_cast<WebGLCompressedTexturePVRTC*>(extension));
253     case WebGLExtension::WebGLCompressedTextureS3TCName:
254         return toJS(exec, globalObject, static_cast<WebGLCompressedTextureS3TC*>(extension));
255     case WebGLExtension::WebGLDepthTextureName:
256         return toJS(exec, globalObject, static_cast<WebGLDepthTexture*>(extension));
257     case WebGLExtension::WebGLDrawBuffersName:
258         return toJS(exec, globalObject, static_cast<WebGLDrawBuffers*>(extension));
259     case WebGLExtension::ANGLEInstancedArraysName:
260         return toJS(exec, globalObject, static_cast<ANGLEInstancedArrays*>(extension));
261     }
262     ASSERT_NOT_REACHED();
263     return jsNull();
264 }
265
266 void JSWebGLRenderingContextBase::visitAdditionalChildren(SlotVisitor& visitor)
267 {
268     visitor.addOpaqueRoot(&wrapped());
269 }
270
271 JSValue JSWebGLRenderingContextBase::getAttachedShaders(ExecState& state)
272 {
273     if (state.argumentCount() < 1)
274         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
275     ExceptionCode ec = 0;
276     WebGLRenderingContextBase& context = wrapped();
277     WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0));
278     if (!program && !state.uncheckedArgument(0).isUndefinedOrNull())
279         return throwTypeError(&state);
280     Vector<RefPtr<WebGLShader>> shaders;
281     bool succeed = context.getAttachedShaders(program, shaders, ec);
282     if (ec) {
283         setDOMException(&state, ec);
284         return jsNull();
285     }
286     if (!succeed)
287         return jsNull();
288     JSC::MarkedArgumentBuffer list;
289     for (size_t ii = 0; ii < shaders.size(); ++ii)
290         list.append(toJS(&state, globalObject(), shaders[ii].get()));
291     return constructArray(&state, 0, globalObject(), list);
292 }
293
294 JSValue JSWebGLRenderingContextBase::getExtension(ExecState& state)
295 {
296     if (state.argumentCount() < 1)
297         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
298     
299     WebGLRenderingContextBase& context = wrapped();
300     const String name = state.uncheckedArgument(0).toString(&state)->value(&state);
301     if (state.hadException())
302         return jsUndefined();
303     WebGLExtension* extension = context.getExtension(name);
304     return toJS(&state, globalObject(), extension);
305 }
306
307 JSValue JSWebGLRenderingContextBase::getBufferParameter(ExecState& state)
308 {
309     return getObjectParameter(this, state, kBuffer);
310 }
311
312 JSValue JSWebGLRenderingContextBase::getFramebufferAttachmentParameter(ExecState& state)
313 {
314     if (state.argumentCount() != 3)
315         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
316     
317     ExceptionCode ec = 0;
318     WebGLRenderingContextBase& context = wrapped();
319     unsigned target = state.uncheckedArgument(0).toInt32(&state);
320     if (state.hadException())
321         return jsUndefined();
322     unsigned attachment = state.uncheckedArgument(1).toInt32(&state);
323     if (state.hadException())
324         return jsUndefined();
325     unsigned pname = state.uncheckedArgument(2).toInt32(&state);
326     if (state.hadException())
327         return jsUndefined();
328     WebGLGetInfo info = context.getFramebufferAttachmentParameter(target, attachment, pname, ec);
329     if (ec) {
330         setDOMException(&state, ec);
331         return jsUndefined();
332     }
333     return toJS(&state, globalObject(), info);
334 }
335
336 JSValue JSWebGLRenderingContextBase::getParameter(ExecState& state)
337 {
338     if (state.argumentCount() != 1)
339         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
340     
341     ExceptionCode ec = 0;
342     WebGLRenderingContextBase& context = wrapped();
343     unsigned pname = state.uncheckedArgument(0).toInt32(&state);
344     if (state.hadException())
345         return jsUndefined();
346     WebGLGetInfo info = context.getParameter(pname, ec);
347     if (ec) {
348         setDOMException(&state, ec);
349         return jsUndefined();
350     }
351     return toJS(&state, globalObject(), info);
352 }
353
354 JSValue JSWebGLRenderingContextBase::getProgramParameter(ExecState& state)
355 {
356     if (state.argumentCount() != 2)
357         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
358     
359     ExceptionCode ec = 0;
360     WebGLRenderingContextBase& context = wrapped();
361     WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0));
362     if (!program && !state.uncheckedArgument(0).isUndefinedOrNull())
363         return throwTypeError(&state);
364     unsigned pname = state.uncheckedArgument(1).toInt32(&state);
365     if (state.hadException())
366         return jsUndefined();
367     WebGLGetInfo info = context.getProgramParameter(program, pname, ec);
368     if (ec) {
369         setDOMException(&state, ec);
370         return jsUndefined();
371     }
372     return toJS(&state, globalObject(), info);
373 }
374
375 JSValue JSWebGLRenderingContextBase::getRenderbufferParameter(ExecState& state)
376 {
377     return getObjectParameter(this, state, kRenderbuffer);
378 }
379
380 JSValue JSWebGLRenderingContextBase::getShaderParameter(ExecState& state)
381 {
382     if (state.argumentCount() != 2)
383         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
384     
385     ExceptionCode ec = 0;
386     WebGLRenderingContextBase& context = wrapped();
387     if (!state.uncheckedArgument(0).isUndefinedOrNull() && !state.uncheckedArgument(0).inherits(JSWebGLShader::info()))
388         return throwTypeError(&state);
389     WebGLShader* shader = JSWebGLShader::toWrapped(state.uncheckedArgument(0));
390     unsigned pname = state.uncheckedArgument(1).toInt32(&state);
391     if (state.hadException())
392         return jsUndefined();
393     WebGLGetInfo info = context.getShaderParameter(shader, pname, ec);
394     if (ec) {
395         setDOMException(&state, ec);
396         return jsUndefined();
397     }
398     return toJS(&state, globalObject(), info);
399 }
400
401 JSValue JSWebGLRenderingContextBase::getSupportedExtensions(ExecState& state)
402 {
403     WebGLRenderingContextBase& context = wrapped();
404     if (context.isContextLost())
405         return jsNull();
406     Vector<String> value = context.getSupportedExtensions();
407     MarkedArgumentBuffer list;
408     for (size_t ii = 0; ii < value.size(); ++ii)
409         list.append(jsStringWithCache(&state, value[ii]));
410     return constructArray(&state, 0, globalObject(), list);
411 }
412
413 JSValue JSWebGLRenderingContextBase::getTexParameter(ExecState& state)
414 {
415     return getObjectParameter(this, state, kTexture);
416 }
417
418 JSValue JSWebGLRenderingContextBase::getUniform(ExecState& state)
419 {
420     if (state.argumentCount() != 2)
421         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
422     
423     ExceptionCode ec = 0;
424     WebGLRenderingContextBase& context = wrapped();
425     WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0));
426     if (!program && !state.uncheckedArgument(0).isUndefinedOrNull())
427         return throwTypeError(&state);
428     WebGLUniformLocation* location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(1));
429     if (!location && !state.uncheckedArgument(1).isUndefinedOrNull())
430         return throwTypeError(&state);
431     WebGLGetInfo info = context.getUniform(program, location, ec);
432     if (ec) {
433         setDOMException(&state, ec);
434         return jsUndefined();
435     }
436     return toJS(&state, globalObject(), info);
437 }
438
439 JSValue JSWebGLRenderingContextBase::getVertexAttrib(ExecState& state)
440 {
441     return getObjectParameter(this, state, kVertexAttrib);
442 }
443
444 template<typename T, size_t inlineCapacity>
445 bool toVector(JSC::ExecState& state, JSC::JSValue value, Vector<T, inlineCapacity>& vector)
446 {
447     if (!value.isObject())
448         return false;
449     
450     JSC::JSObject* object = asObject(value);
451     int32_t length = object->get(&state, state.vm().propertyNames->length).toInt32(&state);
452     
453     if (!vector.tryReserveCapacity(length))
454         return false;
455     vector.resize(length);
456     
457     for (int32_t i = 0; i < length; ++i) {
458         JSC::JSValue v = object->get(&state, i);
459         if (state.hadException())
460             return false;
461         vector[i] = static_cast<T>(v.toNumber(&state));
462     }
463     
464     return true;
465 }
466
467 enum DataFunctionToCall {
468     f_uniform1v, f_uniform2v, f_uniform3v, f_uniform4v,
469     f_vertexAttrib1v, f_vertexAttrib2v, f_vertexAttrib3v, f_vertexAttrib4v
470 };
471
472 enum DataFunctionMatrixToCall {
473     f_uniformMatrix2fv, f_uniformMatrix3fv, f_uniformMatrix4fv
474 };
475
476 static bool functionForUniform(DataFunctionToCall f)
477 {
478     switch (f) {
479     case f_uniform1v:
480     case f_uniform2v:
481     case f_uniform3v:
482     case f_uniform4v:
483         return true;
484     default: break;
485     }
486     return false;
487 }
488
489 static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState& state, WebGLRenderingContextBase& context)
490 {
491     if (state.argumentCount() != 2)
492         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
493     
494     WebGLUniformLocation* location = 0;
495     long index = -1;
496     
497     if (functionForUniform(f)) {
498         location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(0));
499         if (!location && !state.uncheckedArgument(0).isUndefinedOrNull())
500             return throwTypeError(&state);
501     } else
502         index = state.uncheckedArgument(0).toInt32(&state);
503     
504     if (state.hadException())
505         return jsUndefined();
506     
507     RefPtr<Float32Array> webGLArray = toFloat32Array(state.uncheckedArgument(1));
508     if (state.hadException())
509         return jsUndefined();
510     
511     ExceptionCode ec = 0;
512     if (webGLArray) {
513         switch (f) {
514         case f_uniform1v:
515             context.uniform1fv(location, *webGLArray, ec);
516             break;
517         case f_uniform2v:
518             context.uniform2fv(location, *webGLArray, ec);
519             break;
520         case f_uniform3v:
521             context.uniform3fv(location, *webGLArray, ec);
522             break;
523         case f_uniform4v:
524             context.uniform4fv(location, *webGLArray, ec);
525             break;
526         case f_vertexAttrib1v:
527             context.vertexAttrib1fv(index, *webGLArray);
528             break;
529         case f_vertexAttrib2v:
530             context.vertexAttrib2fv(index, *webGLArray);
531             break;
532         case f_vertexAttrib3v:
533             context.vertexAttrib3fv(index, *webGLArray);
534             break;
535         case f_vertexAttrib4v:
536             context.vertexAttrib4fv(index, *webGLArray);
537             break;
538         }
539         
540         setDOMException(&state, ec);
541         return jsUndefined();
542     }
543     
544     Vector<float, 64> array;
545     if (!toVector(state, state.uncheckedArgument(1), array))
546         return throwTypeError(&state);
547     
548     switch (f) {
549     case f_uniform1v:
550         context.uniform1fv(location, array.data(), array.size(), ec);
551         break;
552     case f_uniform2v:
553         context.uniform2fv(location, array.data(), array.size(), ec);
554         break;
555     case f_uniform3v:
556         context.uniform3fv(location, array.data(), array.size(), ec);
557         break;
558     case f_uniform4v:
559         context.uniform4fv(location, array.data(), array.size(), ec);
560         break;
561     case f_vertexAttrib1v:
562         context.vertexAttrib1fv(index, array.data(), array.size());
563         break;
564     case f_vertexAttrib2v:
565         context.vertexAttrib2fv(index, array.data(), array.size());
566         break;
567     case f_vertexAttrib3v:
568         context.vertexAttrib3fv(index, array.data(), array.size());
569         break;
570     case f_vertexAttrib4v:
571         context.vertexAttrib4fv(index, array.data(), array.size());
572         break;
573     }
574     
575     setDOMException(&state, ec);
576     return jsUndefined();
577 }
578
579 static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState& state, WebGLRenderingContextBase& context)
580 {
581     if (state.argumentCount() != 2)
582         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
583     
584     WebGLUniformLocation* location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(0));
585     if (!location && !state.uncheckedArgument(0).isUndefinedOrNull())
586         return throwTypeError(&state);
587     
588     RefPtr<Int32Array> webGLArray = toInt32Array(state.uncheckedArgument(1));
589     
590     ExceptionCode ec = 0;
591     if (webGLArray) {
592         switch (f) {
593         case f_uniform1v:
594             context.uniform1iv(location, *webGLArray, ec);
595             break;
596         case f_uniform2v:
597             context.uniform2iv(location, *webGLArray, ec);
598             break;
599         case f_uniform3v:
600             context.uniform3iv(location, *webGLArray, ec);
601             break;
602         case f_uniform4v:
603             context.uniform4iv(location, *webGLArray, ec);
604             break;
605         default:
606             break;
607         }
608         
609         setDOMException(&state, ec);
610         return jsUndefined();
611     }
612     
613     
614     Vector<int, 64> array;
615     if (!toVector(state, state.uncheckedArgument(1), array))
616         return throwTypeError(&state);
617     
618     switch (f) {
619     case f_uniform1v:
620         context.uniform1iv(location, array.data(), array.size(), ec);
621         break;
622     case f_uniform2v:
623         context.uniform2iv(location, array.data(), array.size(), ec);
624         break;
625     case f_uniform3v:
626         context.uniform3iv(location, array.data(), array.size(), ec);
627         break;
628     case f_uniform4v:
629         context.uniform4iv(location, array.data(), array.size(), ec);
630         break;
631     default:
632         break;
633     }
634     
635     setDOMException(&state, ec);
636     return jsUndefined();
637 }
638
639 static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState& state, WebGLRenderingContextBase& context)
640 {
641     if (state.argumentCount() != 3)
642         return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
643     
644     WebGLUniformLocation* location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(0));
645     if (!location && !state.uncheckedArgument(0).isUndefinedOrNull())
646         return throwTypeError(&state);
647     
648     bool transpose = state.uncheckedArgument(1).toBoolean(&state);
649     if (state.hadException())
650         return jsUndefined();
651     
652     RefPtr<Float32Array> webGLArray = toFloat32Array(state.uncheckedArgument(2));
653     
654     ExceptionCode ec = 0;
655     if (webGLArray) {
656         switch (f) {
657         case f_uniformMatrix2fv:
658             context.uniformMatrix2fv(location, transpose, *webGLArray, ec);
659             break;
660         case f_uniformMatrix3fv:
661             context.uniformMatrix3fv(location, transpose, *webGLArray, ec);
662             break;
663         case f_uniformMatrix4fv:
664             context.uniformMatrix4fv(location, transpose, *webGLArray, ec);
665             break;
666         }
667         
668         setDOMException(&state, ec);
669         return jsUndefined();
670     }
671     
672     Vector<float, 64> array;
673     if (!toVector(state, state.uncheckedArgument(2), array))
674         return throwTypeError(&state);
675     
676     switch (f) {
677     case f_uniformMatrix2fv:
678         context.uniformMatrix2fv(location, transpose, array.data(), array.size(), ec);
679         break;
680     case f_uniformMatrix3fv:
681         context.uniformMatrix3fv(location, transpose, array.data(), array.size(), ec);
682         break;
683     case f_uniformMatrix4fv:
684         context.uniformMatrix4fv(location, transpose, array.data(), array.size(), ec);
685         break;
686     }
687     
688     setDOMException(&state, ec);
689     return jsUndefined();
690 }
691
692 JSC::JSValue JSWebGLRenderingContextBase::uniform1fv(JSC::ExecState& state)
693 {
694     return dataFunctionf(f_uniform1v, state, wrapped());
695 }
696
697 JSC::JSValue JSWebGLRenderingContextBase::uniform1iv(JSC::ExecState& state)
698 {
699     return dataFunctioni(f_uniform1v, state, wrapped());
700 }
701
702 JSC::JSValue JSWebGLRenderingContextBase::uniform2fv(JSC::ExecState& state)
703 {
704     return dataFunctionf(f_uniform2v, state, wrapped());
705 }
706
707 JSC::JSValue JSWebGLRenderingContextBase::uniform2iv(JSC::ExecState& state)
708 {
709     return dataFunctioni(f_uniform2v, state, wrapped());
710 }
711
712 JSC::JSValue JSWebGLRenderingContextBase::uniform3fv(JSC::ExecState& state)
713 {
714     return dataFunctionf(f_uniform3v, state, wrapped());
715 }
716
717 JSC::JSValue JSWebGLRenderingContextBase::uniform3iv(JSC::ExecState& state)
718 {
719     return dataFunctioni(f_uniform3v, state, wrapped());
720 }
721
722 JSC::JSValue JSWebGLRenderingContextBase::uniform4fv(JSC::ExecState& state)
723 {
724     return dataFunctionf(f_uniform4v, state, wrapped());
725 }
726
727 JSC::JSValue JSWebGLRenderingContextBase::uniform4iv(JSC::ExecState& state)
728 {
729     return dataFunctioni(f_uniform4v, state, wrapped());
730 }
731
732 JSC::JSValue JSWebGLRenderingContextBase::uniformMatrix2fv(JSC::ExecState& state)
733 {
734     return dataFunctionMatrix(f_uniformMatrix2fv, state, wrapped());
735 }
736
737 JSC::JSValue JSWebGLRenderingContextBase::uniformMatrix3fv(JSC::ExecState& state)
738 {
739     return dataFunctionMatrix(f_uniformMatrix3fv, state, wrapped());
740 }
741
742 JSC::JSValue JSWebGLRenderingContextBase::uniformMatrix4fv(JSC::ExecState& state)
743 {
744     return dataFunctionMatrix(f_uniformMatrix4fv, state, wrapped());
745 }
746
747 JSC::JSValue JSWebGLRenderingContextBase::vertexAttrib1fv(JSC::ExecState& state)
748 {
749     return dataFunctionf(f_vertexAttrib1v, state, wrapped());
750 }
751
752 JSC::JSValue JSWebGLRenderingContextBase::vertexAttrib2fv(JSC::ExecState& state)
753 {
754     return dataFunctionf(f_vertexAttrib2v, state, wrapped());
755 }
756
757 JSC::JSValue JSWebGLRenderingContextBase::vertexAttrib3fv(JSC::ExecState& state)
758 {
759     return dataFunctionf(f_vertexAttrib3v, state, wrapped());
760 }
761
762 JSC::JSValue JSWebGLRenderingContextBase::vertexAttrib4fv(JSC::ExecState& state)
763 {
764     return dataFunctionf(f_vertexAttrib4v, state, wrapped());
765 }
766
767 } // namespace WebCore
768
769 #endif // ENABLE(WEBGL)