v8::Handle<v8::Value> V8WebGLRenderingContext::getUniformCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getUniform()");

    if (args.Length() != 2) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;

    if (args.Length() > 1 && !isUndefinedOrNull(args[1]) && !V8WebGLUniformLocation::HasInstance(args[1])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    bool ok = false;
    WebGLUniformLocation* location = toWebGLUniformLocation(args[1], ok);

    WebGLGetInfo info = context->getUniform(program, location, ec);
    if (ec) {
        V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }
    return toV8Object(info);
}
v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getAttachedShaders()");

    if (args.Length() < 1) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLProgram::HasInstance(args[0])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    WebGLProgram* program = V8WebGLProgram::HasInstance(args[0]) ? V8WebGLProgram::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
    Vector<WebGLShader*> shaders;
    bool succeed = context->getAttachedShaders(program, shaders, ec);
    if (ec) {
        V8Proxy::setDOMException(ec);
        return v8::Null();
    }
    if (!succeed)
        return v8::Null();
    v8::Local<v8::Array> array = v8::Array::New(shaders.size());
    for (size_t ii = 0; ii < shaders.size(); ++ii)
        array->Set(v8::Integer::New(ii), toV8(shaders[ii]));
    return array;
}
void GraphicsContext3DInternal::paintRenderingResultsToCanvas(CanvasRenderingContext* context)
{
    HTMLCanvasElement* canvas = context->canvas();
    ImageBuffer* imageBuffer = canvas->buffer();
    unsigned char* pixels = 0;
#if PLATFORM(SKIA)
    const SkBitmap* canvasBitmap = imageBuffer->context()->platformContext()->bitmap();
    const SkBitmap* readbackBitmap = 0;
    ASSERT(canvasBitmap->config() == SkBitmap::kARGB_8888_Config);
    if (canvasBitmap->width() == m_impl->width() && canvasBitmap->height() == m_impl->height()) {
        // This is the fastest and most common case. We read back
        // directly into the canvas's backing store.
        readbackBitmap = canvasBitmap;
        m_resizingBitmap.reset();
    } else {
        // We need to allocate a temporary bitmap for reading back the
        // pixel data. We will then use Skia to rescale this bitmap to
        // the size of the canvas's backing store.
        if (m_resizingBitmap.width() != m_impl->width() || m_resizingBitmap.height() != m_impl->height()) {
            m_resizingBitmap.setConfig(SkBitmap::kARGB_8888_Config,
                                       m_impl->width(),
                                       m_impl->height());
            if (!m_resizingBitmap.allocPixels())
                return;
        }
        readbackBitmap = &m_resizingBitmap;
    }

    // Read back the frame buffer.
    SkAutoLockPixels bitmapLock(*readbackBitmap);
    pixels = static_cast<unsigned char*>(readbackBitmap->getPixels());
#elif PLATFORM(CG)
    if (m_renderOutput)
        pixels = m_renderOutput;
#else
#error Must port to your platform
#endif

    m_impl->readBackFramebuffer(pixels, 4 * m_impl->width() * m_impl->height());

#if PLATFORM(SKIA)
    if (m_resizingBitmap.readyToDraw()) {
        // We need to draw the resizing bitmap into the canvas's backing store.
        SkCanvas canvas(*canvasBitmap);
        SkRect dst;
        dst.set(SkIntToScalar(0), SkIntToScalar(0), SkIntToScalar(canvasBitmap->width()), SkIntToScalar(canvasBitmap->height()));
        canvas.drawBitmapRect(m_resizingBitmap, 0, dst);
    }
#elif PLATFORM(CG)
    if (m_renderOutput && context->is3d()) {
        WebGLRenderingContext* webGLContext = static_cast<WebGLRenderingContext*>(context);
        webGLContext->graphicsContext3D()->paintToCanvas(m_renderOutput, m_impl->width(), m_impl->height(), canvas->width(), canvas->height(), imageBuffer->context()->platformContext());
    }
#else
#error Must port to your platform
#endif
}
JSValue JSWebGLRenderingContext::getSupportedExtensions(ExecState* exec)
{
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    if (context->isContextLost())
        return jsNull();
    Vector<String> value = context->getSupportedExtensions();
    MarkedArgumentBuffer list;
    for (size_t ii = 0; ii < value.size(); ++ii)
        list.append(jsString(exec, value[ii]));
    return constructArray(exec, globalObject(), list);
}
v8::Handle<v8::Value> V8WebGLRenderingContext::getExtensionCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getExtensionCallback()");
    WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
    if (args.Length() < 1) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }
    STRING_TO_V8PARAMETER_EXCEPTION_BLOCK(V8Parameter<>, name, args[0]);
    WebGLExtension* extension = imp->getExtension(name);
    return toV8Object(extension, args.Holder());
}
JSValue JSWebGLRenderingContext::getExtension(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return throwSyntaxError(exec);

    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    const String& name = ustringToString(exec->argument(0).toString(exec));
    if (exec->hadException())
        return jsUndefined();
    WebGLExtension* extension = context->getExtension(name);
    return toJS(exec, globalObject(), extension);
}
Example #7
0
PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
{
    if (!m_context || !m_context->is3d())
       return 0;

#if ENABLE(WEBGL)    
    WebGLRenderingContext* ctx = static_cast<WebGLRenderingContext*>(m_context.get());

    return ctx->paintRenderingResultsToImageData();
#else
    return 0;
#endif
}
v8::Handle<v8::Value> V8WebGLRenderingContext::getSupportedExtensionsCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getSupportedExtensionsCallback()");
    WebGLRenderingContext* imp = V8WebGLRenderingContext::toNative(args.Holder());
    if (imp->isContextLost())
        return v8::Null();

    Vector<String> value = imp->getSupportedExtensions();
    v8::Local<v8::Array> array = v8::Array::New(value.size());
    for (size_t ii = 0; ii < value.size(); ++ii)
        array->Set(v8::Integer::New(ii), v8::String::New(fromWebCoreString(value[ii]), value[ii].length()));
    return array;
}
Example #9
0
PassRefPtr<ImageData> HTMLCanvasElement::getImageData()
{
#if ENABLE(WEBGL)
    if (!is3D())
        return nullptr;

    WebGLRenderingContext* ctx = static_cast<WebGLRenderingContext*>(m_context.get());

    return ctx->paintRenderingResultsToImageData();
#else
    return nullptr;
#endif
}
static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext& context)
{
    if (exec->argumentCount() != 2)
        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));

    WebGLUniformLocation* location = toWebGLUniformLocation(exec->uncheckedArgument(0));
    if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull())
        return throwTypeError(exec);
  
    RefPtr<Int32Array> webGLArray = toInt32Array(exec->uncheckedArgument(1));

    ExceptionCode ec = 0;
    if (webGLArray) {
        switch (f) {
        case f_uniform1v:
            context.uniform1iv(location, webGLArray.get(), ec);
            break;
        case f_uniform2v:
            context.uniform2iv(location, webGLArray.get(), ec);
            break;
        case f_uniform3v:
            context.uniform3iv(location, webGLArray.get(), ec);
            break;
        case f_uniform4v:
            context.uniform4iv(location, webGLArray.get(), ec);
            break;
        default:
            break;
        }
        
        setDOMException(exec, ec);
        return jsUndefined();
    }


    Vector<int, 64> array;
    if (!toVector(exec, exec->uncheckedArgument(1), array))
        return throwTypeError(exec);

    switch (f) {
    case f_uniform1v:
        context.uniform1iv(location, array.data(), array.size(), ec);
        break;
    case f_uniform2v:
        context.uniform2iv(location, array.data(), array.size(), ec);
        break;
    case f_uniform3v:
        context.uniform3iv(location, array.data(), array.size(), ec);
        break;
    case f_uniform4v:
        context.uniform4iv(location, array.data(), array.size(), ec);
        break;
    default:
        break;
    }
    
    setDOMException(exec, ec);
    return jsUndefined();
}
JSValue JSWebGLRenderingContext::getParameter(ExecState* exec)
{
    if (exec->argumentCount() != 1)
        return throwSyntaxError(exec);

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    unsigned pname = exec->argument(0).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    WebGLGetInfo info = context->getParameter(pname, ec);
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    return toJS(exec, globalObject(), info);
}
v8::Handle<v8::Value> V8WebGLRenderingContext::getParameterCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getParameter()");

    if (args.Length() != 1) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    unsigned pname = toInt32(args[0]);
    WebGLGetInfo info = context->getParameter(pname, ec);
    if (ec) {
        V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }
    return toV8Object(info);
}
JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* exec)
{
    if (exec->argumentCount() != 2)
        return throwSyntaxError(exec);

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLShader::s_info))
        return throwTypeError(exec);
    WebGLShader* shader = toWebGLShader(exec->argument(0));
    unsigned pname = exec->argument(1).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    return toJS(exec, globalObject(), info);
}
JSValue JSWebGLRenderingContext::getUniform(ExecState* exec)
{
    if (exec->argumentCount() != 2)
        return throwSyntaxError(exec);

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
        return throwTypeError(exec);
    WebGLProgram* program = toWebGLProgram(exec->argument(0));
    if (exec->argumentCount() > 1 && !exec->argument(1).isUndefinedOrNull() && !exec->argument(1).inherits(&JSWebGLUniformLocation::s_info))
        return throwTypeError(exec);
    WebGLUniformLocation* loc = toWebGLUniformLocation(exec->argument(1));
    if (exec->hadException())
        return jsUndefined();
    WebGLGetInfo info = context->getUniform(program, loc, ec);
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    return toJS(exec, globalObject(), info);
}
static JSValue getObjectParameter(JSWebGLRenderingContext* obj, ExecState* exec, ObjectType objectType)
{
    if (exec->argumentCount() != 2)
        return throwSyntaxError(exec);

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(obj->impl());
    unsigned target = exec->argument(0).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    unsigned pname = exec->argument(1).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    WebGLGetInfo info;
    switch (objectType) {
    case kBuffer:
        info = context->getBufferParameter(target, pname, ec);
        break;
    case kRenderbuffer:
        info = context->getRenderbufferParameter(target, pname, ec);
        break;
    case kTexture:
        info = context->getTexParameter(target, pname, ec);
        break;
    case kVertexAttrib:
        // target => index
        info = context->getVertexAttrib(target, pname, ec);
        break;
    default:
        notImplemented();
        break;
    }
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    return toJS(exec, obj->globalObject(), info);
}
JSValue JSWebGLRenderingContext::getFramebufferAttachmentParameter(ExecState* exec)
{
    if (exec->argumentCount() != 3)
        return throwError(exec, createNotEnoughArgumentsError(exec));

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    unsigned target = exec->argument(0).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    unsigned attachment = exec->argument(1).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    unsigned pname = exec->argument(2).toInt32(exec);
    if (exec->hadException())
        return jsUndefined();
    WebGLGetInfo info = context->getFramebufferAttachmentParameter(target, attachment, pname, ec);
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    return toJS(exec, globalObject(), info);
}
v8::Handle<v8::Value> V8WebGLRenderingContext::getShaderParameterCallback(const v8::Arguments& args)
{
    INC_STATS("DOM.WebGLRenderingContext.getShaderParameter()");

    if (args.Length() != 2) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLShader::HasInstance(args[0])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    WebGLShader* shader = V8WebGLShader::HasInstance(args[0]) ? V8WebGLShader::toNative(v8::Handle<v8::Object>::Cast(args[0])) : 0;
    unsigned pname = toInt32(args[1]);
    WebGLGetInfo info = context->getShaderParameter(shader, pname, ec);
    if (ec) {
        V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }
    return toV8Object(info);
}
JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return throwSyntaxError(exec);
    ExceptionCode ec = 0;
    WebGLRenderingContext* context = static_cast<WebGLRenderingContext*>(impl());
    if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLProgram::s_info))
        return throwTypeError(exec);
    WebGLProgram* program = toWebGLProgram(exec->argument(0));
    if (exec->hadException())
        return jsUndefined();
    Vector<WebGLShader*> shaders;
    bool succeed = context->getAttachedShaders(program, shaders, ec);
    if (ec) {
        setDOMException(exec, ec);
        return jsUndefined();
    }
    if (!succeed)
        return jsUndefined();
    MarkedArgumentBuffer list;
    for (size_t ii = 0; ii < shaders.size(); ++ii)
        list.append(toJS(exec, globalObject(), shaders[ii]));
    return constructArray(exec, list);
}
static v8::Handle<v8::Value> getObjectParameter(const v8::Arguments& args, ObjectType objectType)
{
    if (args.Length() != 2) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    ExceptionCode ec = 0;
    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    unsigned target = toInt32(args[0]);
    unsigned pname = toInt32(args[1]);
    WebGLGetInfo info;
    switch (objectType) {
    case kBuffer:
        info = context->getBufferParameter(target, pname, ec);
        break;
    case kRenderbuffer:
        info = context->getRenderbufferParameter(target, pname, ec);
        break;
    case kTexture:
        info = context->getTexParameter(target, pname, ec);
        break;
    case kVertexAttrib:
        // target => index
        info = context->getVertexAttrib(target, pname, ec);
        break;
    default:
        notImplemented();
        break;
    }
    if (ec) {
        V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }
    return toV8Object(info);
}
static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecState* exec, WebGLRenderingContext& context)
{
    if (exec->argumentCount() != 3)
        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));

    WebGLUniformLocation* location = toWebGLUniformLocation(exec->uncheckedArgument(0));
    if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull())
        return throwTypeError(exec);

    bool transpose = exec->uncheckedArgument(1).toBoolean(exec);
    if (exec->hadException())    
        return jsUndefined();
        
    RefPtr<Float32Array> webGLArray = toFloat32Array(exec->uncheckedArgument(2));
        
    ExceptionCode ec = 0;
    if (webGLArray) {
        switch (f) {
        case f_uniformMatrix2fv:
            context.uniformMatrix2fv(location, transpose, webGLArray.get(), ec);
            break;
        case f_uniformMatrix3fv:
            context.uniformMatrix3fv(location, transpose, webGLArray.get(), ec);
            break;
        case f_uniformMatrix4fv:
            context.uniformMatrix4fv(location, transpose, webGLArray.get(), ec);
            break;
        }
        
        setDOMException(exec, ec);
        return jsUndefined();
    }

    Vector<float, 64> array;
    if (!toVector(exec, exec->uncheckedArgument(2), array))
        return throwTypeError(exec);

    switch (f) {
    case f_uniformMatrix2fv:
        context.uniformMatrix2fv(location, transpose, array.data(), array.size(), ec);
        break;
    case f_uniformMatrix3fv:
        context.uniformMatrix3fv(location, transpose, array.data(), array.size(), ec);
        break;
    case f_uniformMatrix4fv:
        context.uniformMatrix4fv(location, transpose, array.data(), array.size(), ec);
        break;
    }

    setDOMException(exec, ec);
    return jsUndefined();
}
static v8::Handle<v8::Value> uniformMatrixHelper(const v8::Arguments& args,
                                                 int matrixSize)
{
    // Forms:
    // * glUniformMatrix2fv(GLint location, GLboolean transpose, Array data);
    // * glUniformMatrix2fv(GLint location, GLboolean transpose, Float32Array data);
    // * glUniformMatrix3fv(GLint location, GLboolean transpose, Array data);
    // * glUniformMatrix3fv(GLint location, GLboolean transpose, Float32Array data);
    // * glUniformMatrix4fv(GLint location, GLboolean transpose, Array data);
    // * glUniformMatrix4fv(GLint location, GLboolean transpose, Float32Array data);
    //
    // FIXME: need to change to accept Float32Array as well.
    if (args.Length() != 3) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());

    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    bool ok = false;
    WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);
    
    bool transpose = args[1]->BooleanValue();
    if (V8Float32Array::HasInstance(args[2])) {
        Float32Array* array = V8Float32Array::toNative(args[2]->ToObject());
        ASSERT(array != NULL);
        ExceptionCode ec = 0;
        switch (matrixSize) {
            case 2: context->uniformMatrix2fv(location, transpose, array, ec); break;
            case 3: context->uniformMatrix3fv(location, transpose, array, ec); break;
            case 4: context->uniformMatrix4fv(location, transpose, array, ec); break;
            default: ASSERT_NOT_REACHED(); break;
        }
        if (ec)
            V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }

    if (args[2].IsEmpty() || !args[2]->IsArray()) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    v8::Handle<v8::Array> array =
      v8::Local<v8::Array>::Cast(args[2]);
    uint32_t len = array->Length();
    float* data = jsArrayToFloatArray(array, len);
    if (!data) {
        // FIXME: consider different / better exception type.
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }
    ExceptionCode ec = 0;
    switch (matrixSize) {
        case 2: context->uniformMatrix2fv(location, transpose, data, len, ec); break;
        case 3: context->uniformMatrix3fv(location, transpose, data, len, ec); break;
        case 4: context->uniformMatrix4fv(location, transpose, data, len, ec); break;
        default: ASSERT_NOT_REACHED(); break;
    }
    fastFree(data);
    if (ec)
        V8Proxy::setDOMException(ec); 
    return v8::Undefined();
}
static v8::Handle<v8::Value> uniformHelperi(const v8::Arguments& args,
                                            FunctionToCall functionToCall) {
    // Forms:
    // * glUniform1iv(GLUniformLocation location, Array data);
    // * glUniform1iv(GLUniformLocation location, Int32Array data);
    // * glUniform2iv(GLUniformLocation location, Array data);
    // * glUniform2iv(GLUniformLocation location, Int32Array data);
    // * glUniform3iv(GLUniformLocation location, Array data);
    // * glUniform3iv(GLUniformLocation location, Int32Array data);
    // * glUniform4iv(GLUniformLocation location, Array data);
    // * glUniform4iv(GLUniformLocation location, Int32Array data);

    if (args.Length() != 2) {
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }

    WebGLRenderingContext* context = V8WebGLRenderingContext::toNative(args.Holder());
    if (args.Length() > 0 && !isUndefinedOrNull(args[0]) && !V8WebGLUniformLocation::HasInstance(args[0])) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    bool ok = false;
    WebGLUniformLocation* location = toWebGLUniformLocation(args[0], ok);

    if (V8Int32Array::HasInstance(args[1])) {
        Int32Array* array = V8Int32Array::toNative(args[1]->ToObject());
        ASSERT(array != NULL);
        ExceptionCode ec = 0;
        switch (functionToCall) {
            case kUniform1v: context->uniform1iv(location, array, ec); break;
            case kUniform2v: context->uniform2iv(location, array, ec); break;
            case kUniform3v: context->uniform3iv(location, array, ec); break;
            case kUniform4v: context->uniform4iv(location, array, ec); break;
            default: ASSERT_NOT_REACHED(); break;
        }
        if (ec)
            V8Proxy::setDOMException(ec);
        return v8::Undefined();
    }

    if (args[1].IsEmpty() || !args[1]->IsArray()) {
        V8Proxy::throwTypeError();
        return notHandledByInterceptor();
    }
    v8::Handle<v8::Array> array =
      v8::Local<v8::Array>::Cast(args[1]);
    uint32_t len = array->Length();
    int* data = jsArrayToIntArray(array, len);
    if (!data) {
        // FIXME: consider different / better exception type.
        V8Proxy::setDOMException(SYNTAX_ERR);
        return notHandledByInterceptor();
    }
    ExceptionCode ec = 0;
    switch (functionToCall) {
        case kUniform1v: context->uniform1iv(location, data, len, ec); break;
        case kUniform2v: context->uniform2iv(location, data, len, ec); break;
        case kUniform3v: context->uniform3iv(location, data, len, ec); break;
        case kUniform4v: context->uniform4iv(location, data, len, ec); break;
        default: ASSERT_NOT_REACHED(); break;
    }
    fastFree(data);
    if (ec)
        V8Proxy::setDOMException(ec);
    return v8::Undefined();
}
static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, WebGLRenderingContext& context)
{
    if (exec->argumentCount() != 2)
        return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec));
    
    WebGLUniformLocation* location = 0;
    long index = -1;
    
    if (functionForUniform(f)) {
        location = toWebGLUniformLocation(exec->uncheckedArgument(0));
        if (!location && !exec->uncheckedArgument(0).isUndefinedOrNull())
            return throwTypeError(exec);
    } else
        index = exec->uncheckedArgument(0).toInt32(exec);

    if (exec->hadException())
        return jsUndefined();
        
    RefPtr<Float32Array> webGLArray = toFloat32Array(exec->uncheckedArgument(1));
    if (exec->hadException())    
        return jsUndefined();
        
    ExceptionCode ec = 0;
    if (webGLArray) {
        switch (f) {
        case f_uniform1v:
            context.uniform1fv(location, webGLArray.get(), ec);
            break;
        case f_uniform2v:
            context.uniform2fv(location, webGLArray.get(), ec);
            break;
        case f_uniform3v:
            context.uniform3fv(location, webGLArray.get(), ec);
            break;
        case f_uniform4v:
            context.uniform4fv(location, webGLArray.get(), ec);
            break;
        case f_vertexAttrib1v:
            context.vertexAttrib1fv(index, webGLArray.get());
            break;
        case f_vertexAttrib2v:
            context.vertexAttrib2fv(index, webGLArray.get());
            break;
        case f_vertexAttrib3v:
            context.vertexAttrib3fv(index, webGLArray.get());
            break;
        case f_vertexAttrib4v:
            context.vertexAttrib4fv(index, webGLArray.get());
            break;
        }
        
        setDOMException(exec, ec);
        return jsUndefined();
    }

    Vector<float, 64> array;
    if (!toVector(exec, exec->uncheckedArgument(1), array))
        return throwTypeError(exec);

    switch (f) {
    case f_uniform1v:
        context.uniform1fv(location, array.data(), array.size(), ec);
        break;
    case f_uniform2v:
        context.uniform2fv(location, array.data(), array.size(), ec);
        break;
    case f_uniform3v:
        context.uniform3fv(location, array.data(), array.size(), ec);
        break;
    case f_uniform4v:
        context.uniform4fv(location, array.data(), array.size(), ec);
        break;
    case f_vertexAttrib1v:
        context.vertexAttrib1fv(index, array.data(), array.size());
        break;
    case f_vertexAttrib2v:
        context.vertexAttrib2fv(index, array.data(), array.size());
        break;
    case f_vertexAttrib3v:
        context.vertexAttrib3fv(index, array.data(), array.size());
        break;
    case f_vertexAttrib4v:
        context.vertexAttrib4fv(index, array.data(), array.size());
        break;
    }
    
    setDOMException(exec, ec);
    return jsUndefined();
}