Commit 02436edc authored by zmo@google.com's avatar zmo@google.com

2010-08-18 Zhenyao Mo <zmo@google.com>

        Reviewed by Kenneth Russell.

        Implement strict type checking in js bindings for WebGL functions
        https://bugs.webkit.org/show_bug.cgi?id=44202

        Test: fast/canvas/webgl/bad-arguments-test.html

        * bindings/js/JSWebGLRenderingContextCustom.cpp: Add type check for wrapper types and DOMString and throw error in case of mismatch.
        (WebCore::JSWebGLRenderingContext::getAttachedShaders):
        (WebCore::JSWebGLRenderingContext::getProgramParameter):
        (WebCore::JSWebGLRenderingContext::getShaderParameter):
        (WebCore::JSWebGLRenderingContext::getUniform):
        (WebCore::dataFunctionf):
        (WebCore::dataFunctioni):
        (WebCore::dataFunctionMatrix):
        * bindings/scripts/CodeGeneratorJS.pm: Ditto.
        * bindings/scripts/CodeGeneratorV8.pm: Ditto.
        * bindings/v8/custom/V8WebGLRenderingContextCustom.cpp: Ditto.
        (WebCore::V8WebGLRenderingContext::getAttachedShadersCallback):
        (WebCore::V8WebGLRenderingContext::getProgramParameterCallback):
        (WebCore::V8WebGLRenderingContext::getShaderParameterCallback):
        (WebCore::V8WebGLRenderingContext::getUniformCallback):
        (WebCore::vertexAttribAndUniformHelperf):
        (WebCore::uniformHelperi):
        (WebCore::uniformMatrixHelper):
        * html/canvas/WebGLRenderingContext.idl: Add attribute StrictTypeChecking for WebGL functions.
2010-08-18  Zhenyao Mo  <zmo@google.com>

        Reviewed by Kenneth Russell.

        Implement strict type checking in js bindings for WebGL functions
        https://bugs.webkit.org/show_bug.cgi?id=44202

        * fast/canvas/webgl/bad-arguments-test-expected.txt: Added.
        * fast/canvas/webgl/bad-arguments-test.html: Added.
        * fast/canvas/webgl/error-reporting-expected.txt: Fix bugs due to strict type checking in the js bindings.
        * fast/canvas/webgl/error-reporting.html: ditto.
        * fast/canvas/webgl/gl-object-get-calls-expected.txt: ditto.
        * fast/canvas/webgl/gl-object-get-calls.html: ditto.
        * fast/canvas/webgl/null-object-behaviour-expected.txt: ditto.
        * fast/canvas/webgl/null-object-behaviour.html: ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@65689 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 6561538a
2010-08-18 Zhenyao Mo <zmo@google.com>
Reviewed by Kenneth Russell.
Implement strict type checking in js bindings for WebGL functions
https://bugs.webkit.org/show_bug.cgi?id=44202
* fast/canvas/webgl/bad-arguments-test-expected.txt: Added.
* fast/canvas/webgl/bad-arguments-test.html: Added.
* fast/canvas/webgl/error-reporting-expected.txt: Fix bugs due to strict type checking in the js bindings.
* fast/canvas/webgl/error-reporting.html: ditto.
* fast/canvas/webgl/gl-object-get-calls-expected.txt: ditto.
* fast/canvas/webgl/gl-object-get-calls.html: ditto.
* fast/canvas/webgl/null-object-behaviour-expected.txt: ditto.
* fast/canvas/webgl/null-object-behaviour.html: ditto.
2010-08-19 John Gregg <johnnyg@google.com>
Unreviewed, test expectations.
Tests calling WebGL APIs with wrong argument types
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS Program Compiled
PASS Shader Compiled
PASS getUniformLocation succeeded
PASS context.compileShader(argument) threw exception TypeError: Type error.
PASS context.linkProgram(argument) threw exception TypeError: Type error.
PASS context.attachShader(argument) threw exception TypeError: Type error.
PASS context.attachShader(program, argument) threw exception TypeError: Type error.
PASS context.attachShader(argument, shader) threw exception TypeError: Type error.
PASS context.detachShader(program, argument) threw exception TypeError: Type error.
PASS context.detachShader(argument, shader) threw exception TypeError: Type error.
PASS context.useProgram(argument) threw exception TypeError: Type error.
PASS context.shaderSource(argument, 'foo') threw exception TypeError: Type error.
PASS context.bindAttribLocation(argument, 0, 'foo') threw exception TypeError: Type error.
PASS context.bindBuffer(context.ARRAY_BUFFER, argument) threw exception TypeError: Type error.
PASS context.bindFramebuffer(context.FRAMEBUFFER, argument) threw exception TypeError: Type error.
PASS context.bindRenderbuffer(context.RENDERBUFFER, argument) threw exception TypeError: Type error.
PASS context.bindTexture(context.TEXTURE_2D, argument) threw exception TypeError: Type error.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, argument) threw exception TypeError: Type error.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, argument, 0) threw exception TypeError: Type error.
PASS context.uniform2fv(argument, new Float32Array([0.0, 0.0])) threw exception TypeError: Type error.
PASS context.uniform2iv(argument, new Int32Array([0, 0])) threw exception TypeError: Type error.
PASS context.uniformMatrix2fv(argument, false, new Float32Array([0.0, 0.0, 0.0, 0.0])) threw exception TypeError: Type error.
PASS context.getProgramParameter(argument, 0) threw exception TypeError: Type error.
PASS context.getShaderParameter(argument, 0) threw exception TypeError: Type error.
PASS context.getUniform(argument, loc) threw exception TypeError: Type error.
PASS context.getUniform(program, argument) threw exception TypeError: Type error.
PASS context.getUniformLocation(argument, 'u_modelViewProjMatrix') threw exception TypeError: Type error.
PASS context.getProgramInfoLog(argument) threw exception TypeError: Type error.
PASS context.getShaderInfoLog(argument) threw exception TypeError: Type error.
PASS context.getShaderSource(argument) threw exception TypeError: Type error.
PASS context.compileShader(argument) threw exception TypeError: Type error.
PASS context.linkProgram(argument) threw exception TypeError: Type error.
PASS context.attachShader(argument) threw exception TypeError: Type error.
PASS context.attachShader(program, argument) threw exception TypeError: Type error.
PASS context.attachShader(argument, shader) threw exception TypeError: Type error.
PASS context.detachShader(program, argument) threw exception TypeError: Type error.
PASS context.detachShader(argument, shader) threw exception TypeError: Type error.
PASS context.useProgram(argument) threw exception TypeError: Type error.
PASS context.shaderSource(argument, 'foo') threw exception TypeError: Type error.
PASS context.bindAttribLocation(argument, 0, 'foo') threw exception TypeError: Type error.
PASS context.bindBuffer(context.ARRAY_BUFFER, argument) threw exception TypeError: Type error.
PASS context.bindFramebuffer(context.FRAMEBUFFER, argument) threw exception TypeError: Type error.
PASS context.bindRenderbuffer(context.RENDERBUFFER, argument) threw exception TypeError: Type error.
PASS context.bindTexture(context.TEXTURE_2D, argument) threw exception TypeError: Type error.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, argument) threw exception TypeError: Type error.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, argument, 0) threw exception TypeError: Type error.
PASS context.uniform2fv(argument, new Float32Array([0.0, 0.0])) threw exception TypeError: Type error.
PASS context.uniform2iv(argument, new Int32Array([0, 0])) threw exception TypeError: Type error.
PASS context.uniformMatrix2fv(argument, false, new Float32Array([0.0, 0.0, 0.0, 0.0])) threw exception TypeError: Type error.
PASS context.getProgramParameter(argument, 0) threw exception TypeError: Type error.
PASS context.getShaderParameter(argument, 0) threw exception TypeError: Type error.
PASS context.getUniform(argument, loc) threw exception TypeError: Type error.
PASS context.getUniform(program, argument) threw exception TypeError: Type error.
PASS context.getUniformLocation(argument, 'u_modelViewProjMatrix') threw exception TypeError: Type error.
PASS context.getProgramInfoLog(argument) threw exception TypeError: Type error.
PASS context.getShaderInfoLog(argument) threw exception TypeError: Type error.
PASS context.getShaderSource(argument) threw exception TypeError: Type error.
PASS context.compileShader(argument) is undefined.
PASS context.linkProgram(argument) is undefined.
PASS context.attachShader(argument) is undefined.
PASS context.attachShader(program, argument) is undefined.
PASS context.attachShader(argument, shader) is undefined.
PASS context.detachShader(program, argument) is undefined.
PASS context.detachShader(argument, shader) is undefined.
PASS context.useProgram(argument) is undefined.
PASS context.shaderSource(argument, 'foo') is undefined.
PASS context.bindAttribLocation(argument, 0, 'foo') is undefined.
PASS context.bindBuffer(context.ARRAY_BUFFER, argument) is undefined.
PASS context.bindFramebuffer(context.FRAMEBUFFER, argument) is undefined.
PASS context.bindRenderbuffer(context.RENDERBUFFER, argument) is undefined.
PASS context.bindTexture(context.TEXTURE_2D, argument) is undefined.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, argument) is undefined.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, argument, 0) is undefined.
PASS context.uniform2fv(argument, new Float32Array([0.0, 0.0])) is undefined.
PASS context.uniform2iv(argument, new Int32Array([0, 0])) is undefined.
PASS context.uniformMatrix2fv(argument, false, new Float32Array([0.0, 0.0, 0.0, 0.0])) is undefined.
PASS context.getProgramParameter(argument, 0) is null
PASS context.getShaderParameter(argument, 0) is null
PASS context.getUniform(argument, loc) is null
PASS context.getUniform(program, argument) is null
PASS context.getUniformLocation(argument, 'u_modelViewProjMatrix') is null
PASS context.getProgramInfoLog(argument) is ''
PASS context.getShaderInfoLog(argument) is ''
PASS context.getShaderSource(argument) is ''
PASS context.compileShader(argument) is undefined.
PASS context.linkProgram(argument) is undefined.
PASS context.attachShader(argument) is undefined.
PASS context.attachShader(program, argument) is undefined.
PASS context.attachShader(argument, shader) is undefined.
PASS context.detachShader(program, argument) is undefined.
PASS context.detachShader(argument, shader) is undefined.
PASS context.useProgram(argument) is undefined.
PASS context.shaderSource(argument, 'foo') is undefined.
PASS context.bindAttribLocation(argument, 0, 'foo') is undefined.
PASS context.bindBuffer(context.ARRAY_BUFFER, argument) is undefined.
PASS context.bindFramebuffer(context.FRAMEBUFFER, argument) is undefined.
PASS context.bindRenderbuffer(context.RENDERBUFFER, argument) is undefined.
PASS context.bindTexture(context.TEXTURE_2D, argument) is undefined.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, argument) is undefined.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, argument, 0) is undefined.
PASS context.uniform2fv(argument, new Float32Array([0.0, 0.0])) is undefined.
PASS context.uniform2iv(argument, new Int32Array([0, 0])) is undefined.
PASS context.uniformMatrix2fv(argument, false, new Float32Array([0.0, 0.0, 0.0, 0.0])) is undefined.
PASS context.getProgramParameter(argument, 0) is null
PASS context.getShaderParameter(argument, 0) is null
PASS context.getUniform(argument, loc) is null
PASS context.getUniform(program, argument) is null
PASS context.getUniformLocation(argument, 'u_modelViewProjMatrix') is null
PASS context.getProgramInfoLog(argument) is ''
PASS context.getShaderInfoLog(argument) is ''
PASS context.getShaderSource(argument) is ''
PASS successfullyParsed is true
TEST COMPLETE
<html>
<head>
<link rel="stylesheet" href="../../js/resources/js-test-style.css"/>
<script src="../../js/resources/js-test-pre.js"></script>
<script src="resources/webgl-test.js"></script>
<script src="resources/webgl-test-utils.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script>
var wtu = WebGLTestUtils;
description("Tests calling WebGL APIs with wrong argument types");
var context = wtu.create3DContext();
var program = wtu.loadStandardProgram(context);
var shader = wtu.loadStandardVertexShader(context);
var shouldGenerateGLError = wtu.shouldGenerateGLError;
assertMsg(program != null, "Program Compiled");
assertMsg(shader != null, "Shader Compiled");
var loc = context.getUniformLocation(program, "u_modelViewProjMatrix");
assertMsg(loc != null, "getUniformLocation succeeded");
var arguments = [
{ value: "foo",
throw: true },
{ value: 0,
throw: true },
{ value: null,
throw: false },
{ value: undefined,
throw: false }
];
var argument;
function shouldBeEmptyString(command) {
shouldBe(command, "''");
}
for (var i = 0; i < arguments.length; ++i) {
var func, func2, func3;
if (arguments[i].throw) {
func = shouldThrow;
func2 = shouldThrow;
func3 = shouldThrow;
} else {
func = shouldBeUndefined;
func2 = shouldBeNull;
func3 = shouldBeEmptyString;
}
argument = arguments[i].value;
func("context.compileShader(argument)");
func("context.linkProgram(argument)");
func("context.attachShader(argument)");
func("context.attachShader(program, argument)");
func("context.attachShader(argument, shader)");
func("context.detachShader(program, argument)");
func("context.detachShader(argument, shader)");
func("context.useProgram(argument)");
func("context.shaderSource(argument, 'foo')");
func("context.bindAttribLocation(argument, 0, 'foo')");
func("context.bindBuffer(context.ARRAY_BUFFER, argument)");
func("context.bindFramebuffer(context.FRAMEBUFFER, argument)");
func("context.bindRenderbuffer(context.RENDERBUFFER, argument)");
func("context.bindTexture(context.TEXTURE_2D, argument)");
func("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, argument)");
func("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, argument, 0)");
func("context.uniform2fv(argument, new Float32Array([0.0, 0.0]))");
func("context.uniform2iv(argument, new Int32Array([0, 0]))");
func("context.uniformMatrix2fv(argument, false, new Float32Array([0.0, 0.0, 0.0, 0.0]))");
func2("context.getProgramParameter(argument, 0)");
func2("context.getShaderParameter(argument, 0)");
func2("context.getUniform(argument, loc)");
func2("context.getUniform(program, argument)");
func2("context.getUniformLocation(argument, 'u_modelViewProjMatrix')");
func3("context.getProgramInfoLog(argument)");
func3("context.getShaderInfoLog(argument)");
func3("context.getShaderSource(argument)");
}
successfullyParsed = true;
</script>
<script src="../../js/resources/js-test-post.js"></script>
</body>
</html>
......@@ -2,7 +2,7 @@ Tests generation of synthetic and real GL errors
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
PASS context.getError() is 0
PASS getError was expected value: NO_ERROR :
Testing getActiveAttrib
PASS context.getActiveAttrib(null, 2) is null
PASS getError was expected value: INVALID_VALUE :
......@@ -18,12 +18,12 @@ PASS context.getActiveUniform(program, 50) is null
PASS getError was expected value: INVALID_VALUE :
PASS getError was expected value: NO_ERROR :
Testing attempts to manipulate the default framebuffer
PASS context.bindFramebuffer(context.FRAMEBUFFER, 0) is undefined.
PASS context.bindFramebuffer(context.FRAMEBUFFER, null) is undefined.
PASS getError was expected value: NO_ERROR :
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0) is undefined.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, null) is undefined.
PASS getError was expected value: INVALID_OPERATION :
PASS getError was expected value: NO_ERROR :
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0) is undefined.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, null, 0) is undefined.
PASS getError was expected value: INVALID_OPERATION :
PASS getError was expected value: NO_ERROR :
PASS successfullyParsed is true
......
......@@ -21,7 +21,7 @@ var program = loadStandardProgram(context);
// discovered in the synthetic error generation and in the WebGL
// implementation itself.
shouldBe("context.getError()", "0");
glErrorShouldBe(context, context.NO_ERROR);
debug("Testing getActiveAttrib");
// Synthetic OpenGL error
......@@ -48,14 +48,14 @@ glErrorShouldBe(context, context.INVALID_VALUE);
glErrorShouldBe(context, context.NO_ERROR);
debug("Testing attempts to manipulate the default framebuffer");
shouldBeUndefined("context.bindFramebuffer(context.FRAMEBUFFER, 0)");
shouldBeUndefined("context.bindFramebuffer(context.FRAMEBUFFER, null)");
glErrorShouldBe(context, context.NO_ERROR);
shouldBeUndefined("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0)");
shouldBeUndefined("context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, null)");
// Synthetic OpenGL error
glErrorShouldBe(context, context.INVALID_OPERATION);
// Error state should be clear by this point
glErrorShouldBe(context, context.NO_ERROR);
shouldBeUndefined("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0)");
shouldBeUndefined("context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, null, 0)");
// Synthetic OpenGL error
glErrorShouldBe(context, context.INVALID_OPERATION);
// Error state should be clear by this point
......
......@@ -4,11 +4,11 @@ On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE
PASS shaders.length is 2
PASS shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag is true
PASS gl.getError() is gl.NO_ERROR
PASS getError was expected value: NO_ERROR :
PASS gl.getAttachedShaders(null) is undefined.
PASS gl.getError() is gl.INVALID_VALUE
PASS gl.getAttachedShaders(standardVert) is undefined.
PASS gl.getError() is gl.INVALID_VALUE
PASS getError was expected value: INVALID_VALUE :
PASS gl.getAttachedShaders(standardVert) threw exception TypeError: Type error.
PASS getError was expected value: NO_ERROR :
PASS gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_SIZE) is 16
PASS gl.getBufferParameter(gl.ARRAY_BUFFER, gl.BUFFER_USAGE) is gl.DYNAMIC_DRAW
PASS getError was expected value: NO_ERROR :
......@@ -75,9 +75,11 @@ PASS gl.getUniform(matProgram, mval4Loc) is [14, 15, 16, 17, 18, 19, 20, 21, 22,
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING) is buffer
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_ENABLED) is true
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_SIZE) is 4
PASS (gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == 0) || (gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == 4 * sizeInBytes(gl.FLOAT)) is true
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) is 0
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_TYPE) is gl.FLOAT
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED) is false
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) is 36
PASS gl.getVertexAttribOffset(1, gl.VERTEX_ATTRIB_ARRAY_POINTER) is 12
PASS gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_ENABLED) is false
PASS gl.getVertexAttrib(1, gl.CURRENT_VERTEX_ATTRIB) is [5, 6, 7, 8]
PASS getError was expected value: NO_ERROR :
......
......@@ -39,11 +39,11 @@ gl.linkProgram(standardProgram);
var shaders = gl.getAttachedShaders(standardProgram);
shouldBe('shaders.length', '2');
shouldBeTrue('shaders[0] == standardVert && shaders[1] == standardFrag || shaders[1] == standardVert && shaders[0] == standardFrag');
shouldBe('gl.getError()', 'gl.NO_ERROR');
glErrorShouldBe(gl, gl.NO_ERROR);
shouldBeUndefined('gl.getAttachedShaders(null)');
shouldBe('gl.getError()', 'gl.INVALID_VALUE');
shouldBeUndefined('gl.getAttachedShaders(standardVert)');
shouldBe('gl.getError()', 'gl.INVALID_VALUE');
glErrorShouldBe(gl, gl.INVALID_VALUE);
shouldThrow('gl.getAttachedShaders(standardVert)');
glErrorShouldBe(gl, gl.NO_ERROR);
// Test getBufferParameter
var buffer = gl.createBuffer();
......@@ -214,9 +214,13 @@ gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 0, 0);
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_BUFFER_BINDING)', 'buffer');
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_ENABLED)', 'true');
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_SIZE)', '4');
shouldBe('(gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == 0) || (gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE) == 4 * sizeInBytes(gl.FLOAT))', 'true');
// Stride MUST be the value the user put in.
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE)', '0');
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_TYPE)', 'gl.FLOAT');
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_NORMALIZED)', 'false');
gl.vertexAttribPointer(1, 4, gl.FLOAT, false, 36, 12);
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_STRIDE)', '36');
shouldBe('gl.getVertexAttribOffset(1, gl.VERTEX_ATTRIB_ARRAY_POINTER)', '12');
gl.disableVertexAttribArray(1);
shouldBe('gl.getVertexAttrib(1, gl.VERTEX_ATTRIB_ARRAY_ENABLED)', 'false');
gl.vertexAttrib4f(1, 5, 6, 7, 8);
......
......@@ -14,10 +14,10 @@ PASS context.detachShader(undefined, shader) was expected value: INVALID_VALUE.
PASS context.shaderSource() was expected value: INVALID_VALUE.
PASS context.shaderSource(undefined, 'foo') was expected value: INVALID_VALUE.
PASS context.bindAttribLocation(undefined, 0, 'foo') was expected value: INVALID_VALUE.
PASS context.bindBuffer(context.ARRAY_BUFFER, 0) was expected value: NO_ERROR.
PASS context.bindFramebuffer(context.FRAMEBUFFER, 0) was expected value: NO_ERROR.
PASS context.bindRenderbuffer(context.RENDERBUFFER, 0) was expected value: NO_ERROR.
PASS context.bindTexture(context.TEXTURE_2D, 0) was expected value: NO_ERROR.
PASS context.bindBuffer(context.ARRAY_BUFFER, 0) threw exception TypeError: Type error.
PASS context.bindFramebuffer(context.FRAMEBUFFER, 0) threw exception TypeError: Type error.
PASS context.bindRenderbuffer(context.RENDERBUFFER, 0) threw exception TypeError: Type error.
PASS context.bindTexture(context.TEXTURE_2D, 0) threw exception TypeError: Type error.
PASS context.bindBuffer(context.ARRAY_BUFFER, null) was expected value: NO_ERROR.
PASS context.bindFramebuffer(context.FRAMEBUFFER, null) was expected value: NO_ERROR.
PASS context.bindRenderbuffer(context.RENDERBUFFER, null) was expected value: NO_ERROR.
......@@ -26,14 +26,14 @@ PASS context.bindBuffer(context.ARRAY_BUFFER, undefined) was expected value: NO_
PASS context.bindFramebuffer(context.FRAMEBUFFER, undefined) was expected value: NO_ERROR.
PASS context.bindRenderbuffer(context.RENDERBUFFER, undefined) was expected value: NO_ERROR.
PASS context.bindTexture(context.TEXTURE_2D, undefined) was expected value: NO_ERROR.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0) was expected value: INVALID_OPERATION.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0) was expected value: INVALID_OPERATION.
PASS context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, null) was expected value: INVALID_OPERATION.
PASS context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, null, 0) was expected value: INVALID_OPERATION.
PASS context.getProgramParameter(undefined, 0) was expected value: INVALID_VALUE.
PASS context.getProgramInfoLog(undefined, 0) was expected value: INVALID_VALUE.
PASS context.getShaderParameter(undefined, 0) was expected value: INVALID_VALUE.
PASS context.getShaderInfoLog(undefined, 0) was expected value: INVALID_VALUE.
PASS context.getShaderSource(undefined) was expected value: INVALID_VALUE.
PASS context.getUniform(undefined, 0) was expected value: INVALID_VALUE.
PASS context.getUniform(undefined, null) was expected value: INVALID_VALUE.
PASS context.getUniformLocation(undefined, 'foo') was expected value: INVALID_VALUE.
check with bindings
......
......@@ -30,10 +30,10 @@ shouldGenerateGLError(context, context.INVALID_VALUE, "context.detachShader(unde
shouldGenerateGLError(context, context.INVALID_VALUE, "context.shaderSource()");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.shaderSource(undefined, 'foo')");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.bindAttribLocation(undefined, 0, 'foo')");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindBuffer(context.ARRAY_BUFFER, 0)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindFramebuffer(context.FRAMEBUFFER, 0)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindRenderbuffer(context.RENDERBUFFER, 0)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindTexture(context.TEXTURE_2D, 0)");
shouldThrow("context.bindBuffer(context.ARRAY_BUFFER, 0)");
shouldThrow("context.bindFramebuffer(context.FRAMEBUFFER, 0)");
shouldThrow("context.bindRenderbuffer(context.RENDERBUFFER, 0)");
shouldThrow("context.bindTexture(context.TEXTURE_2D, 0)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindBuffer(context.ARRAY_BUFFER, null)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindFramebuffer(context.FRAMEBUFFER, null)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindRenderbuffer(context.RENDERBUFFER, null)");
......@@ -42,14 +42,14 @@ shouldGenerateGLError(context, context.NO_ERROR, "context.bindBuffer(context.ARR
shouldGenerateGLError(context, context.NO_ERROR, "context.bindFramebuffer(context.FRAMEBUFFER, undefined)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindRenderbuffer(context.RENDERBUFFER, undefined)");
shouldGenerateGLError(context, context.NO_ERROR, "context.bindTexture(context.TEXTURE_2D, undefined)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, 0)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, 0, 0)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.framebufferRenderbuffer(context.FRAMEBUFFER, context.DEPTH_ATTACHMENT, context.RENDERBUFFER, null)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.framebufferTexture2D(context.FRAMEBUFFER, context.COLOR_ATTACHMENT0, context.TEXTURE_2D, null, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getProgramParameter(undefined, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getProgramInfoLog(undefined, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getShaderParameter(undefined, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getShaderInfoLog(undefined, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getShaderSource(undefined)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getUniform(undefined, 0)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getUniform(undefined, null)");
shouldGenerateGLError(context, context.INVALID_VALUE, "context.getUniformLocation(undefined, 'foo')");
debug("");
......@@ -64,8 +64,8 @@ shouldGenerateGLError(context, context.NO_ERROR, "context.getTexParameter(contex
debug("");
debug("check without bindings");
context.bindBuffer(context.ARRAY_BUFFER, 0);
context.bindTexture(context.TEXTURE_2D, 0);
context.bindBuffer(context.ARRAY_BUFFER, null);
context.bindTexture(context.TEXTURE_2D, null);
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.bufferData(context.ARRAY_BUFFER, 1, context.STATIC_DRAW)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.getBufferParameter(context.ARRAY_BUFFER, context.BUFFER_SIZE)");
shouldGenerateGLError(context, context.INVALID_OPERATION, "context.texImage2D(context.TEXTURE_2D, 0, context.RGBA, 1, 1, 0, context.RGBA, context.UNSIGNED_BYTE, new Uint8Array([0,0,0,0]))");
......
2010-08-18 Zhenyao Mo <zmo@google.com>
Reviewed by Kenneth Russell.
Implement strict type checking in js bindings for WebGL functions
https://bugs.webkit.org/show_bug.cgi?id=44202
Test: fast/canvas/webgl/bad-arguments-test.html
* bindings/js/JSWebGLRenderingContextCustom.cpp: Add type check for wrapper types and DOMString and throw error in case of mismatch.
(WebCore::JSWebGLRenderingContext::getAttachedShaders):
(WebCore::JSWebGLRenderingContext::getProgramParameter):
(WebCore::JSWebGLRenderingContext::getShaderParameter):
(WebCore::JSWebGLRenderingContext::getUniform):
(WebCore::dataFunctionf):
(WebCore::dataFunctioni):
(WebCore::dataFunctionMatrix):
* bindings/scripts/CodeGeneratorJS.pm: Ditto.
* bindings/scripts/CodeGeneratorV8.pm: Ditto.
* bindings/v8/custom/V8WebGLRenderingContextCustom.cpp: Ditto.
(WebCore::V8WebGLRenderingContext::getAttachedShadersCallback):
(WebCore::V8WebGLRenderingContext::getProgramParameterCallback):
(WebCore::V8WebGLRenderingContext::getShaderParameterCallback):
(WebCore::V8WebGLRenderingContext::getUniformCallback):
(WebCore::vertexAttribAndUniformHelperf):
(WebCore::uniformHelperi):
(WebCore::uniformMatrixHelper):
* html/canvas/WebGLRenderingContext.idl: Add attribute StrictTypeChecking for WebGL functions.
2010-08-19 Simon Fraser <simon.fraser@apple.com>
Fix Chromium build.
......@@ -167,6 +167,8 @@ JSValue JSWebGLRenderingContext::getAttachedShaders(ExecState* exec)
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();
......@@ -238,6 +240,8 @@ JSValue JSWebGLRenderingContext::getProgramParameter(ExecState* 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));
unsigned pname = exec->argument(1).toInt32(exec);
if (exec->hadException())
......@@ -262,6 +266,8 @@ JSValue JSWebGLRenderingContext::getShaderParameter(ExecState* 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())
......@@ -286,7 +292,11 @@ JSValue JSWebGLRenderingContext::getUniform(ExecState* 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();
......@@ -354,9 +364,11 @@ static JSC::JSValue dataFunctionf(DataFunctionToCall f, JSC::ExecState* exec, We
WebGLUniformLocation* location = 0;
long index = -1;
if (functionForUniform(f))
if (functionForUniform(f)) {
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
return throwTypeError(exec);
location = toWebGLUniformLocation(exec->argument(0));
else
} else
index = exec->argument(0).toInt32(exec);
if (exec->hadException())
......@@ -439,6 +451,8 @@ static JSC::JSValue dataFunctioni(DataFunctionToCall f, JSC::ExecState* exec, We
if (exec->argumentCount() != 2)
return throwSyntaxError(exec);
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
return throwTypeError(exec);
WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
if (exec->hadException())
......@@ -502,6 +516,8 @@ static JSC::JSValue dataFunctionMatrix(DataFunctionMatrixToCall f, JSC::ExecStat
if (exec->argumentCount() != 3)
return throwSyntaxError(exec);
if (exec->argumentCount() > 0 && !exec->argument(0).isUndefinedOrNull() && !exec->argument(0).inherits(&JSWebGLUniformLocation::s_info))
return throwTypeError(exec);
WebGLUniformLocation* location = toWebGLUniformLocation(exec->argument(0));
if (exec->hadException())
......
......@@ -1963,6 +1963,20 @@ sub GenerateImplementation
push(@implContent, " RefPtr<" . $parameter->type . "> $name = ${callbackClassName}::create(asObject(exec->argument($argsIndex)), castedThis->globalObject());\n");
}
} else {
# For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
# a TypeError is thrown instead of casting to null.
if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
my $argValue = "exec->argument($argsIndex)";
my $argType = $codeGenerator->StripModule($parameter->type);
if (!IsNativeType($argType)) {
push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.inherits(&JS${argType}::s_info))\n");
push(@implContent, " return throwVMTypeError(exec);\n");
} elsif ($codeGenerator->IsStringType($argType)) {
push(@implContent, " if (exec->argumentCount() > $argsIndex && !${argValue}.isUndefinedOrNull() && !${argValue}.isString() && !${argValue}.isObject())\n");
push(@implContent, " return throwVMTypeError(exec);\n");
}
}
push(@implContent, " " . GetNativeTypeFromSignature($parameter) . " $name = " . JSValueToNative($parameter, "exec->argument($argsIndex)") . ";\n");
# If a parameter is "an index" and it's negative it should throw an INDEX_SIZE_ERR exception.
......
......@@ -1245,6 +1245,23 @@ END
}
} else {
$implIncludes{"V8BindingMacros.h"} = 1;
# For functions with "StrictTypeChecking", if an input parameter's type does not match the signature,
# a TypeError is thrown instead of casting to null.
if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
my $argValue = "args[$paramIndex]";
my $argType = GetTypeFromSignature($parameter);
if (IsWrapperType($argType)) {
push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !V8${argType}::HasInstance($argValue)) {\n");
push(@implContentDecls, " V8Proxy::throwTypeError();\n");
push(@implContentDecls, " return notHandledByInterceptor();\n");
push(@implContentDecls, " }\n");
} elsif ($codeGenerator->IsStringType($argType)) {
push(@implContentDecls, " if (args.Length() > $paramIndex && !isUndefinedOrNull($argValue) && !${argValue}->IsString() && !${argValue}->IsObject()) {\n");
push(@implContentDecls, " V8Proxy::throwTypeError();\n");
push(@implContentDecls, " return notHandledByInterceptor();\n");
push(@implContentDecls, " }\n");
}
}
push(@implContentDecls, " EXCEPTION_BLOCK($nativeType, $parameterName, " .
JSValueToNative($parameter, "args[$paramIndex]", BasicTypeCanFailConversion($parameter) ? "${parameterName}Ok" : undef) . ");\n");
}
......@@ -2988,7 +3005,10 @@ sub RequiresCustomSignature
if (@{$function->{overloads}} > 1) {
return 0;
}
# Type checking is performed in the generated code
if ($function->signature->extendedAttributes->{"StrictTypeChecking"}) {
return 0;
}
foreach my $parameter (@{$function->parameters}) {
if ($parameter->extendedAttributes->{"Optional"} || $parameter->extendedAttributes->{"Callback"}) {
return 0;
......
......@@ -227,6 +227,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getAttachedShadersCallback(const
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);
......@@ -319,6 +323,10 @@ v8::Handle<v8::Value> V8WebGLRenderingContext::getProgramParameterCallback(const
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;
bool ok;
unsigned