+2015-09-17 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r189938, r189952, and r189956.
+ https://bugs.webkit.org/show_bug.cgi?id=149329
+
+ Broke Web Workers (Requested by ap on #webkit).
+
+ Reverted changesets:
+
+ "Implement try/catch in the DFG."
+ https://bugs.webkit.org/show_bug.cgi?id=147374
+ http://trac.webkit.org/changeset/189938
+
+ "CLoop build fix after r189938."
+ http://trac.webkit.org/changeset/189952
+
+ "add a regress test for richards with try/catch."
+ https://bugs.webkit.org/show_bug.cgi?id=149301
+ http://trac.webkit.org/changeset/189956
+
2015-09-17 Chris Dumez <cdumez@apple.com>
[WebIDL] Add support for default parameter values
+++ /dev/null
-JSRegress/raytrace-with-empty-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/raytrace-with-empty-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+++ /dev/null
-JSRegress/raytrace-with-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/raytrace-with-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+++ /dev/null
-JSRegress/richards-empty-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/richards-empty-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+++ /dev/null
-JSRegress/richards-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/richards-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+++ /dev/null
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-
-function createVector(x,y,z) {
- try {
- return new Array(x,y,z);
- } catch(e) { }
-}
-
-function sqrLengthVector(self) {
- try {
- return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];
- } catch(e) { }
-}
-
-function lengthVector(self) {
- try {
- return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
- } catch(e) { }
-}
-
-function addVector(self, v) {
- try {
- self[0] += v[0];
- self[1] += v[1];
- } catch(e) { }
-
- self[2] += v[2];
- return self;
-}
-
-function subVector(self, v) {
- try {
- self[0] -= v[0];
- self[1] -= v[1];
- } catch(e) {
- }
- self[2] -= v[2];
- return self;
-}
-
-function scaleVector(self, scale) {
- try {
- self[0] *= scale;
- self[1] *= scale;
- } catch(e) { }
- self[2] *= scale;
- return self;
-}
-
-function normaliseVector(self) {
- var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
- try {
- self[0] /= len;
- self[1] /= len;
- } catch(e) { }
- self[2] /= len;
- return self;
-}
-
-function add(v1, v2) {
- try {
- return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
- } catch(e) { }
-}
-
-function sub(v1, v2) {
- try {
- return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
- } catch(e) { }
-}
-
-function scalev(v1, v2) {
- try {
- return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
- } catch(e) { }
-}
-
-function dot(v1, v2) {
- try {
- return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
- } catch(e) { }
-}
-
-function scale(v, scale) {
- try {
- return [v[0] * scale, v[1] * scale, v[2] * scale];
- } catch(e) { }
-}
-
-function cross(v1, v2) {
- try {
- return [v1[1] * v2[2] - v1[2] * v2[1],
- v1[2] * v2[0] - v1[0] * v2[2],
- v1[0] * v2[1] - v1[1] * v2[0]];
- } catch(e) { }
-
-}
-
-function normalise(v) {
- var len = lengthVector(v);
- try {
- } catch(e) { }
- return [v[0] / len, v[1] / len, v[2] / len];
-}
-
-function transformMatrix(self, v) {
- try {
- var vals = self;
- var x = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];
- var y = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];
- } catch(e) { }
- var z = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];
- return [x, y, z];
-}
-
-function invertMatrix(self) {
- try {
- var temp = new Array(16);
- var tx = -self[3];
- var ty = -self[7];
- var tz = -self[11];
- for (h = 0; h < 3; h++)
- for (v = 0; v < 3; v++)
- temp[h + v * 4] = self[v + h * 4];
- } catch(e) { }
- try {
- for (i = 0; i < 11; i++)
- self[i] = temp[i];
- self[3] = tx * self[0] + ty * self[1] + tz * self[2];
- self[7] = tx * self[4] + ty * self[5] + tz * self[6];
- self[11] = tx * self[8] + ty * self[9] + tz * self[10];
- } catch(e) { }
- return self;
-}
-
-
-// Triangle intersection using barycentric coord method
-function Triangle(p1, p2, p3) {
- try {
- var edge1 = sub(p3, p1);
- var edge2 = sub(p2, p1);
- var normal = cross(edge1, edge2);
- if (Math.abs(normal[0]) > Math.abs(normal[1]))
- if (Math.abs(normal[0]) > Math.abs(normal[2]))
- this.axis = 0;
- else
- this.axis = 2;
- else
- if (Math.abs(normal[1]) > Math.abs(normal[2]))
- this.axis = 1;
- else
- this.axis = 2;
- var u = (this.axis + 1) % 3;
- var v = (this.axis + 2) % 3;
- var u1 = edge1[u];
- var v1 = edge1[v];
-
- var u2 = edge2[u];
- var v2 = edge2[v];
- this.normal = normalise(normal);
- this.nu = normal[u] / normal[this.axis];
- this.nv = normal[v] / normal[this.axis];
- this.nd = dot(normal, p1) / normal[this.axis];
- var det = u1 * v2 - v1 * u2;
- this.eu = p1[u];
- this.ev = p1[v];
- this.nu1 = u1 / det;
- this.nv1 = -v1 / det;
- this.nu2 = v2 / det;
- this.nv2 = -u2 / det;
- this.material = [0.7, 0.7, 0.7];
- } catch(e) { }
-}
-
-Triangle.prototype.intersect = function(orig, dir, near, far) {
- try {
- var u = (this.axis + 1) % 3;
- var v = (this.axis + 2) % 3;
- var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];
- var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;
- } catch(e) { }
- if (t < near || t > far)
- return null;
- try {
- var Pu = orig[u] + t * dir[u] - this.eu;
- var Pv = orig[v] + t * dir[v] - this.ev;
- var a2 = Pv * this.nu1 + Pu * this.nv1;
- } catch(e) { }
- if (a2 < 0)
- return null;
- try {
- var a3 = Pu * this.nu2 + Pv * this.nv2;
- } catch(e) { }
- if (a3 < 0)
- return null;
-
- if ((a2 + a3) > 1)
- return null;
- return t;
-}
-
-function Scene(a_triangles) {
- try {
- this.triangles = a_triangles;
- this.lights = [];
- this.ambient = [0,0,0];
- this.background = [0.8,0.8,1];
- } catch(e) { }
-}
-var zero = new Array(0,0,0);
-
-Scene.prototype.intersect = function(origin, dir, near, far) {
- var closest = null;
- for (i = 0; i < this.triangles.length; i++) {
- try {
- var triangle = this.triangles[i];
- var d = triangle.intersect(origin, dir, near, far);
- if (d == null || d > far || d < near)
- continue;
- far = d;
- closest = triangle;
- } catch(e) { }
- }
-
- if (!closest)
- return [this.background[0],this.background[1],this.background[2]];
-
- try {
- var normal = closest.normal;
- var hit = add(origin, scale(dir, far));
- if (dot(dir, normal) > 0)
- normal = [-normal[0], -normal[1], -normal[2]];
-
- var colour = null;
- if (closest.shader) {
- colour = closest.shader(closest, hit, dir);
- } else {
- colour = closest.material;
- }
- } catch(e) { }
-
- // do reflection
- var reflected = null;
- if (colour.reflection > 0.001) {
- try {
- var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);
- reflected = this.intersect(hit, reflection, 0.0001, 1000000);
- } catch(e) { }
- if (colour.reflection >= 0.999999)
- return reflected;
- }
-
- var l = [this.ambient[0], this.ambient[1], this.ambient[2]];
- for (var i = 0; i < this.lights.length; i++) {
- try {
- var light = this.lights[i];
- var toLight = sub(light, hit);
- var distance = lengthVector(toLight);
- scaleVector(toLight, 1.0/distance);
- distance -= 0.0001;
- if (this.blocked(hit, toLight, distance))
- continue;
- var nl = dot(normal, toLight);
- if (nl > 0)
- addVector(l, scale(light.colour, nl));
- } catch(e) { }
- }
- try {
- l = scalev(l, colour);
- if (reflected) {
- l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));
- }
- } catch(e) { }
- return l;
-}
-
-Scene.prototype.blocked = function(O, D, far) {
- var near = 0.0001;
- var closest = null;
- for (i = 0; i < this.triangles.length; i++) {
- try {
- var triangle = this.triangles[i];
- var d = triangle.intersect(O, D, near, far);
- } catch(e) { }
- if (d == null || d > far || d < near)
- continue;
- return true;
- }
-
- return false;
-}
-
-
-// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where
-// that somewhere is
-function Camera(origin, lookat, up) {
- try {
- var zaxis = normaliseVector(subVector(lookat, origin));
- var xaxis = normaliseVector(cross(up, zaxis));
- var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));
- var m = new Array(16);
- m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];
- m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];
- m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];
- invertMatrix(m);
- m[3] = 0; m[7] = 0; m[11] = 0;
- this.origin = origin;
- this.directions = new Array(4);
- this.directions[0] = normalise([-0.7, 0.7, 1]);
- this.directions[1] = normalise([ 0.7, 0.7, 1]);
- this.directions[2] = normalise([ 0.7, -0.7, 1]);
- this.directions[3] = normalise([-0.7, -0.7, 1]);
- this.directions[0] = transformMatrix(m, this.directions[0]);
- this.directions[1] = transformMatrix(m, this.directions[1]);
- this.directions[2] = transformMatrix(m, this.directions[2]);
- this.directions[3] = transformMatrix(m, this.directions[3]);
-
- } catch(e) { }
-}
-
-Camera.prototype.generateRayPair = function(y) {
- try {
- rays = new Array(new Object(), new Object());
- rays[0].origin = this.origin;
- rays[1].origin = this.origin;
- rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));
- rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));
- } catch(e) { }
- return rays;
-}
-
-function renderRows(camera, scene, pixels, width, height, starty, stopy) {
- for (var y = starty; y < stopy; y++) {
- var rays = camera.generateRayPair(y / height);
- for (var x = 0; x < width; x++) {
- try {
- var xp = x / width;
- var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));
- var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));
- var l = scene.intersect(origin, dir);
- pixels[y][x] = l;
- } catch(e) { }
- }
- }
-}
-
-Camera.prototype.render = function(scene, pixels, width, height) {
- try {
- var cam = this;
- var row = 0;
- renderRows(cam, scene, pixels, width, height, 0, height);
- } catch(e) { }
-}
-
-
-
-function raytraceScene()
-{
- try {
- var startDate = new Date().getTime();
- var numTriangles = 2 * 6;
- var triangles = new Array();//numTriangles);
- var tfl = createVector(-10, 10, -10);
- var tfr = createVector( 10, 10, -10);
- var tbl = createVector(-10, 10, 10);
- var tbr = createVector( 10, 10, 10);
- var bfl = createVector(-10, -10, -10);
- var bfr = createVector( 10, -10, -10);
- var bbl = createVector(-10, -10, 10);
- var bbr = createVector( 10, -10, 10);
-
- // cube!!!
- // front
- var i = 0;
-
- triangles[i++] = new Triangle(tfl, tfr, bfr);
- triangles[i++] = new Triangle(tfl, bfr, bfl);
- // back
- triangles[i++] = new Triangle(tbl, tbr, bbr);
- triangles[i++] = new Triangle(tbl, bbr, bbl);
- // triangles[i-1].material = [0.7,0.2,0.2];
- // triangles[i-1].material.reflection = 0.8;
- // left
- triangles[i++] = new Triangle(tbl, tfl, bbl);
- // triangles[i-1].reflection = 0.6;
- triangles[i++] = new Triangle(tfl, bfl, bbl);
- // triangles[i-1].reflection = 0.6;
- // right
- triangles[i++] = new Triangle(tbr, tfr, bbr);
- triangles[i++] = new Triangle(tfr, bfr, bbr);
- // top
- triangles[i++] = new Triangle(tbl, tbr, tfr);
- triangles[i++] = new Triangle(tbl, tfr, tfl);
- // bottom
- triangles[i++] = new Triangle(bbl, bbr, bfr);
- triangles[i++] = new Triangle(bbl, bfr, bfl);
-
- //Floor!!!!
- var green = createVector(0.0, 0.4, 0.0);
- var grey = createVector(0.4, 0.4, 0.4);
- grey.reflection = 1.0;
-
- } catch(e) { }
- var floorShader = function(tri, pos, view) {
- try {
- var x = ((pos[0]/32) % 2 + 2) % 2;
- var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;
- } catch(e) { }
- try {
- if (x < 1 != z < 1) {
- //in the real world we use the fresnel term...
- // var angle = 1-dot(view, tri.normal);
- // angle *= angle;
- // angle *= angle;
- // angle *= angle;
- //grey.reflection = angle;
- return grey;
- } else
- return green;
- } catch(e) { }
- }
- var ffl = createVector(-1000, -30, -1000);
- var ffr = createVector( 1000, -30, -1000);
- var fbl = createVector(-1000, -30, 1000);
- var fbr = createVector( 1000, -30, 1000);
- triangles[i++] = new Triangle(fbl, fbr, ffr);
- triangles[i-1].shader = floorShader;
- triangles[i++] = new Triangle(fbl, ffr, ffl);
- triangles[i-1].shader = floorShader;
-
- var _scene = new Scene(triangles);
- _scene.lights[0] = createVector(20, 38, -22);
- _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);
- _scene.lights[1] = createVector(-23, 40, 17);
- _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);
- _scene.lights[2] = createVector(23, 20, 17);
- _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);
- _scene.ambient = createVector(0.1, 0.1, 0.1);
- // _scene.background = createVector(0.7, 0.7, 1.0);
-
- var size = 30;
- var pixels = new Array();
- for (var y = 0; y < size; y++) {
- try {
- pixels[y] = new Array();
- } catch(e) { }
- for (var x = 0; x < size; x++) {
- try {
- pixels[y][x] = 0;
- } catch(e) { }
- }
- }
-
- try {
- var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));
- _camera.render(_scene, pixels, size, size);
- } catch(e){}
-
- return pixels;
-}
-
-function arrayToCanvasCommands(pixels)
-{
- var s = '<canvas id="renderCanvas" width="30px" height="30px"></canvas><scr' + 'ipt>\nvar pixels = [';
- var size = 30;
- for (var y = 0; y < size; y++) {
- s += "[";
- for (var x = 0; x < size; x++) {
- s += "[" + pixels[y][x] + "],";
- }
- s+= "],";
- }
- s += '];\n var canvas = document.getElementById("renderCanvas").getContext("2d");\n\
-\n\
-\n\
- var size = 30;\n\
- canvas.fillStyle = "red";\n\
- canvas.fillRect(0, 0, size, size);\n\
- canvas.scale(1, -1);\n\
- canvas.translate(0, -size);\n\
-\n\
- if (!canvas.setFillColor)\n\
- canvas.setFillColor = function(r, g, b, a) {\n\
- this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\
- }\n\
-\n\
-for (var y = 0; y < size; y++) {\n\
- for (var x = 0; x < size; x++) {\n\
- var l = pixels[y][x];\n\
- canvas.setFillColor(l[0], l[1], l[2], 1);\n\
- canvas.fillRect(x, y, 1, 1);\n\
- }\n\
-}</scr' + 'ipt>';
-
- return s;
-}
-
-testOutput = arrayToCanvasCommands(raytraceScene());
-
-var expectedLength = 20970;
-
-if (testOutput.length != expectedLength)
- throw "Error: bad result: expected length " + expectedLength + " but got " + testOutput.length;
-
+++ /dev/null
-/*
- * Copyright (C) 2007 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-let __exceptionCounter = 0;
-function randomException() {
- __exceptionCounter++;
- if (__exceptionCounter % 500 === 0) {
- throw new Error("rando");
- }
-}
-noInline(randomException);
-
-
-function createVector(x,y,z) {
- try {
- return new Array(x,y,z);
- } catch(e) { }
-}
-
-function sqrLengthVector(self) {
- try {
- return self[0] * self[0] + self[1] * self[1] + self[2] * self[2];
- } catch(e) { }
-}
-
-function lengthVector(self) {
- try {
- return Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
- } catch(e) { }
-}
-
-function addVector(self, v) {
- try {
- self[0] += v[0];
- self[1] += v[1];
- randomException();
- } catch(e) { }
-
- self[2] += v[2];
- return self;
-}
-
-function subVector(self, v) {
- try {
- self[0] -= v[0];
- self[1] -= v[1];
- randomException();
- } catch(e) {
- }
- self[2] -= v[2];
- return self;
-}
-
-function scaleVector(self, scale) {
- try {
- self[0] *= scale;
- self[1] *= scale;
- randomException();
- } catch(e) { }
- self[2] *= scale;
- return self;
-}
-
-function normaliseVector(self) {
- var len = Math.sqrt(self[0] * self[0] + self[1] * self[1] + self[2] * self[2]);
- try {
- self[0] /= len;
- self[1] /= len;
- randomException();
- } catch(e) { }
- self[2] /= len;
- return self;
-}
-
-function add(v1, v2) {
- try {
- return new Array(v1[0] + v2[0], v1[1] + v2[1], v1[2] + v2[2]);
- } catch(e) { }
-}
-
-function sub(v1, v2) {
- try {
- return new Array(v1[0] - v2[0], v1[1] - v2[1], v1[2] - v2[2]);
- } catch(e) { }
-}
-
-function scalev(v1, v2) {
- try {
- return new Array(v1[0] * v2[0], v1[1] * v2[1], v1[2] * v2[2]);
- } catch(e) { }
-}
-
-function dot(v1, v2) {
- try {
- return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
- } catch(e) { }
-}
-
-function scale(v, scale) {
- try {
- return [v[0] * scale, v[1] * scale, v[2] * scale];
- } catch(e) { }
-}
-
-function cross(v1, v2) {
- try {
- return [v1[1] * v2[2] - v1[2] * v2[1],
- v1[2] * v2[0] - v1[0] * v2[2],
- v1[0] * v2[1] - v1[1] * v2[0]];
- } catch(e) { }
-
-}
-
-function normalise(v) {
- var len = lengthVector(v);
- try {
- randomException();
- } catch(e) { }
- return [v[0] / len, v[1] / len, v[2] / len];
-}
-
-function transformMatrix(self, v) {
- try {
- var vals = self;
- var x = vals[0] * v[0] + vals[1] * v[1] + vals[2] * v[2] + vals[3];
- var y = vals[4] * v[0] + vals[5] * v[1] + vals[6] * v[2] + vals[7];
- randomException();
- } catch(e) { }
- var z = vals[8] * v[0] + vals[9] * v[1] + vals[10] * v[2] + vals[11];
- return [x, y, z];
-}
-
-function invertMatrix(self) {
- try {
- var temp = new Array(16);
- var tx = -self[3];
- var ty = -self[7];
- var tz = -self[11];
- for (h = 0; h < 3; h++)
- for (v = 0; v < 3; v++)
- temp[h + v * 4] = self[v + h * 4];
- randomException();
- } catch(e) { }
- try {
- for (i = 0; i < 11; i++)
- self[i] = temp[i];
- self[3] = tx * self[0] + ty * self[1] + tz * self[2];
- self[7] = tx * self[4] + ty * self[5] + tz * self[6];
- self[11] = tx * self[8] + ty * self[9] + tz * self[10];
- randomException();
- } catch(e) { }
- return self;
-}
-
-
-// Triangle intersection using barycentric coord method
-function Triangle(p1, p2, p3) {
- try {
- var edge1 = sub(p3, p1);
- var edge2 = sub(p2, p1);
- var normal = cross(edge1, edge2);
- if (Math.abs(normal[0]) > Math.abs(normal[1]))
- if (Math.abs(normal[0]) > Math.abs(normal[2]))
- this.axis = 0;
- else
- this.axis = 2;
- else
- if (Math.abs(normal[1]) > Math.abs(normal[2]))
- this.axis = 1;
- else
- this.axis = 2;
- var u = (this.axis + 1) % 3;
- var v = (this.axis + 2) % 3;
- var u1 = edge1[u];
- var v1 = edge1[v];
-
- var u2 = edge2[u];
- var v2 = edge2[v];
- this.normal = normalise(normal);
- this.nu = normal[u] / normal[this.axis];
- this.nv = normal[v] / normal[this.axis];
- this.nd = dot(normal, p1) / normal[this.axis];
- var det = u1 * v2 - v1 * u2;
- this.eu = p1[u];
- this.ev = p1[v];
- this.nu1 = u1 / det;
- this.nv1 = -v1 / det;
- this.nu2 = v2 / det;
- this.nv2 = -u2 / det;
- this.material = [0.7, 0.7, 0.7];
- randomException();
- } catch(e) { }
-}
-
-Triangle.prototype.intersect = function(orig, dir, near, far) {
- try {
- var u = (this.axis + 1) % 3;
- var v = (this.axis + 2) % 3;
- var d = dir[this.axis] + this.nu * dir[u] + this.nv * dir[v];
- var t = (this.nd - orig[this.axis] - this.nu * orig[u] - this.nv * orig[v]) / d;
- randomException();
- } catch(e) { }
- if (t < near || t > far)
- return null;
- try {
- var Pu = orig[u] + t * dir[u] - this.eu;
- var Pv = orig[v] + t * dir[v] - this.ev;
- var a2 = Pv * this.nu1 + Pu * this.nv1;
- randomException();
- } catch(e) { }
- if (a2 < 0)
- return null;
- try {
- var a3 = Pu * this.nu2 + Pv * this.nv2;
- randomException();
- } catch(e) { }
- if (a3 < 0)
- return null;
-
- if ((a2 + a3) > 1)
- return null;
- return t;
-}
-
-function Scene(a_triangles) {
- try {
- this.triangles = a_triangles;
- this.lights = [];
- this.ambient = [0,0,0];
- this.background = [0.8,0.8,1];
- randomException();
- } catch(e) { }
-}
-var zero = new Array(0,0,0);
-
-Scene.prototype.intersect = function(origin, dir, near, far) {
- var closest = null;
- for (i = 0; i < this.triangles.length; i++) {
- try {
- var triangle = this.triangles[i];
- var d = triangle.intersect(origin, dir, near, far);
- if (d == null || d > far || d < near)
- continue;
- far = d;
- closest = triangle;
- randomException();
- } catch(e) { }
- }
-
- if (!closest)
- return [this.background[0],this.background[1],this.background[2]];
-
- try {
- var normal = closest.normal;
- var hit = add(origin, scale(dir, far));
- if (dot(dir, normal) > 0)
- normal = [-normal[0], -normal[1], -normal[2]];
-
- var colour = null;
- if (closest.shader) {
- colour = closest.shader(closest, hit, dir);
- } else {
- colour = closest.material;
- }
- randomException();
- } catch(e) { }
-
- // do reflection
- var reflected = null;
- if (colour.reflection > 0.001) {
- try {
- var reflection = addVector(scale(normal, -2*dot(dir, normal)), dir);
- reflected = this.intersect(hit, reflection, 0.0001, 1000000);
- randomException();
- } catch(e) { }
- if (colour.reflection >= 0.999999)
- return reflected;
- }
-
- var l = [this.ambient[0], this.ambient[1], this.ambient[2]];
- for (var i = 0; i < this.lights.length; i++) {
- try {
- var light = this.lights[i];
- var toLight = sub(light, hit);
- var distance = lengthVector(toLight);
- scaleVector(toLight, 1.0/distance);
- distance -= 0.0001;
- if (this.blocked(hit, toLight, distance))
- continue;
- var nl = dot(normal, toLight);
- if (nl > 0)
- addVector(l, scale(light.colour, nl));
- randomException();
- } catch(e) { }
- }
- try {
- l = scalev(l, colour);
- if (reflected) {
- l = addVector(scaleVector(l, 1 - colour.reflection), scaleVector(reflected, colour.reflection));
- }
- randomException();
- } catch(e) { }
- return l;
-}
-
-Scene.prototype.blocked = function(O, D, far) {
- var near = 0.0001;
- var closest = null;
- for (i = 0; i < this.triangles.length; i++) {
- try {
- var triangle = this.triangles[i];
- var d = triangle.intersect(O, D, near, far);
- randomException();
- } catch(e) { }
- if (d == null || d > far || d < near)
- continue;
- return true;
- }
-
- return false;
-}
-
-
-// this camera code is from notes i made ages ago, it is from *somewhere* -- i cannot remember where
-// that somewhere is
-function Camera(origin, lookat, up) {
- try {
- var zaxis = normaliseVector(subVector(lookat, origin));
- var xaxis = normaliseVector(cross(up, zaxis));
- var yaxis = normaliseVector(cross(xaxis, subVector([0,0,0], zaxis)));
- var m = new Array(16);
- m[0] = xaxis[0]; m[1] = xaxis[1]; m[2] = xaxis[2];
- m[4] = yaxis[0]; m[5] = yaxis[1]; m[6] = yaxis[2];
- m[8] = zaxis[0]; m[9] = zaxis[1]; m[10] = zaxis[2];
- invertMatrix(m);
- m[3] = 0; m[7] = 0; m[11] = 0;
- this.origin = origin;
- this.directions = new Array(4);
- this.directions[0] = normalise([-0.7, 0.7, 1]);
- this.directions[1] = normalise([ 0.7, 0.7, 1]);
- this.directions[2] = normalise([ 0.7, -0.7, 1]);
- this.directions[3] = normalise([-0.7, -0.7, 1]);
- this.directions[0] = transformMatrix(m, this.directions[0]);
- this.directions[1] = transformMatrix(m, this.directions[1]);
- this.directions[2] = transformMatrix(m, this.directions[2]);
- this.directions[3] = transformMatrix(m, this.directions[3]);
-
- randomException();
- } catch(e) { }
-}
-
-Camera.prototype.generateRayPair = function(y) {
- try {
- rays = new Array(new Object(), new Object());
- rays[0].origin = this.origin;
- rays[1].origin = this.origin;
- rays[0].dir = addVector(scale(this.directions[0], y), scale(this.directions[3], 1 - y));
- rays[1].dir = addVector(scale(this.directions[1], y), scale(this.directions[2], 1 - y));
- randomException();
- } catch(e) { }
- return rays;
-}
-
-function renderRows(camera, scene, pixels, width, height, starty, stopy) {
- for (var y = starty; y < stopy; y++) {
- var rays = camera.generateRayPair(y / height);
- for (var x = 0; x < width; x++) {
- try {
- var xp = x / width;
- var origin = addVector(scale(rays[0].origin, xp), scale(rays[1].origin, 1 - xp));
- var dir = normaliseVector(addVector(scale(rays[0].dir, xp), scale(rays[1].dir, 1 - xp)));
- var l = scene.intersect(origin, dir);
- pixels[y][x] = l;
- randomException();
- } catch(e) { }
- }
- }
-}
-
-Camera.prototype.render = function(scene, pixels, width, height) {
- try {
- var cam = this;
- var row = 0;
- renderRows(cam, scene, pixels, width, height, 0, height);
- randomException();
- } catch(e) { }
-}
-
-
-
-function raytraceScene()
-{
- try {
- var startDate = new Date().getTime();
- var numTriangles = 2 * 6;
- var triangles = new Array();//numTriangles);
- var tfl = createVector(-10, 10, -10);
- var tfr = createVector( 10, 10, -10);
- var tbl = createVector(-10, 10, 10);
- var tbr = createVector( 10, 10, 10);
- var bfl = createVector(-10, -10, -10);
- var bfr = createVector( 10, -10, -10);
- var bbl = createVector(-10, -10, 10);
- var bbr = createVector( 10, -10, 10);
-
- // cube!!!
- // front
- var i = 0;
-
- triangles[i++] = new Triangle(tfl, tfr, bfr);
- triangles[i++] = new Triangle(tfl, bfr, bfl);
- // back
- triangles[i++] = new Triangle(tbl, tbr, bbr);
- triangles[i++] = new Triangle(tbl, bbr, bbl);
- // triangles[i-1].material = [0.7,0.2,0.2];
- // triangles[i-1].material.reflection = 0.8;
- // left
- triangles[i++] = new Triangle(tbl, tfl, bbl);
- // triangles[i-1].reflection = 0.6;
- triangles[i++] = new Triangle(tfl, bfl, bbl);
- // triangles[i-1].reflection = 0.6;
- // right
- triangles[i++] = new Triangle(tbr, tfr, bbr);
- triangles[i++] = new Triangle(tfr, bfr, bbr);
- // top
- triangles[i++] = new Triangle(tbl, tbr, tfr);
- triangles[i++] = new Triangle(tbl, tfr, tfl);
- // bottom
- triangles[i++] = new Triangle(bbl, bbr, bfr);
- triangles[i++] = new Triangle(bbl, bfr, bfl);
-
- //Floor!!!!
- var green = createVector(0.0, 0.4, 0.0);
- var grey = createVector(0.4, 0.4, 0.4);
- grey.reflection = 1.0;
-
- randomException();
- } catch(e) { }
- var floorShader = function(tri, pos, view) {
- try {
- var x = ((pos[0]/32) % 2 + 2) % 2;
- var z = ((pos[2]/32 + 0.3) % 2 + 2) % 2;
- randomException();
- } catch(e) { }
- try {
- if (x < 1 != z < 1) {
- //in the real world we use the fresnel term...
- // var angle = 1-dot(view, tri.normal);
- // angle *= angle;
- // angle *= angle;
- // angle *= angle;
- //grey.reflection = angle;
- return grey;
- } else
- return green;
- } catch(e) { }
- }
- var ffl = createVector(-1000, -30, -1000);
- var ffr = createVector( 1000, -30, -1000);
- var fbl = createVector(-1000, -30, 1000);
- var fbr = createVector( 1000, -30, 1000);
- triangles[i++] = new Triangle(fbl, fbr, ffr);
- triangles[i-1].shader = floorShader;
- triangles[i++] = new Triangle(fbl, ffr, ffl);
- triangles[i-1].shader = floorShader;
-
- var _scene = new Scene(triangles);
- _scene.lights[0] = createVector(20, 38, -22);
- _scene.lights[0].colour = createVector(0.7, 0.3, 0.3);
- _scene.lights[1] = createVector(-23, 40, 17);
- _scene.lights[1].colour = createVector(0.7, 0.3, 0.3);
- _scene.lights[2] = createVector(23, 20, 17);
- _scene.lights[2].colour = createVector(0.7, 0.7, 0.7);
- _scene.ambient = createVector(0.1, 0.1, 0.1);
- // _scene.background = createVector(0.7, 0.7, 1.0);
-
- var size = 30;
- var pixels = new Array();
- for (var y = 0; y < size; y++) {
- try {
- pixels[y] = new Array();
- randomException();
- } catch(e) { }
- for (var x = 0; x < size; x++) {
- try {
- pixels[y][x] = 0;
- randomException();
- } catch(e) { }
- }
- }
-
- try {
- var _camera = new Camera(createVector(-40, 40, 40), createVector(0, 0, 0), createVector(0, 1, 0));
- _camera.render(_scene, pixels, size, size);
- randomException();
- } catch(e){}
-
- return pixels;
-}
-
-function arrayToCanvasCommands(pixels)
-{
- var s = '<canvas id="renderCanvas" width="30px" height="30px"></canvas><scr' + 'ipt>\nvar pixels = [';
- var size = 30;
- for (var y = 0; y < size; y++) {
- s += "[";
- for (var x = 0; x < size; x++) {
- s += "[" + pixels[y][x] + "],";
- }
- s+= "],";
- }
- s += '];\n var canvas = document.getElementById("renderCanvas").getContext("2d");\n\
-\n\
-\n\
- var size = 30;\n\
- canvas.fillStyle = "red";\n\
- canvas.fillRect(0, 0, size, size);\n\
- canvas.scale(1, -1);\n\
- canvas.translate(0, -size);\n\
-\n\
- if (!canvas.setFillColor)\n\
- canvas.setFillColor = function(r, g, b, a) {\n\
- this.fillStyle = "rgb("+[Math.floor(r * 255), Math.floor(g * 255), Math.floor(b * 255)]+")";\n\
- }\n\
-\n\
-for (var y = 0; y < size; y++) {\n\
- for (var x = 0; x < size; x++) {\n\
- var l = pixels[y][x];\n\
- canvas.setFillColor(l[0], l[1], l[2], 1);\n\
- canvas.fillRect(x, y, 1, 1);\n\
- }\n\
-}</scr' + 'ipt>';
-
- return s;
-}
-
-testOutput = arrayToCanvasCommands(raytraceScene());
-
-var expectedLength = 20970;
-
-if (testOutput.length != expectedLength)
- throw "Error: bad result: expected length " + expectedLength + " but got " + testOutput.length;
-
+++ /dev/null
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// This is a JavaScript implementation of the Richards
-// benchmark from:
-//
-// http://www.cl.cam.ac.uk/~mr10/Bench.html
-//
-// The benchmark was originally implemented in BCPL by
-// Martin Richards.
-
-
-/**
- * The Richards benchmark simulates the task dispatcher of an
- * operating system.
- **/
-function runRichards() {
- try {
- var scheduler = new Scheduler();
- scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
-
- var queue = new Packet(null, ID_WORKER, KIND_WORK);
- queue = new Packet(queue, ID_WORKER, KIND_WORK);
- scheduler.addWorkerTask(ID_WORKER, 1000, queue);
-
- queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
-
- queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
-
- scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
-
- scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
-
- scheduler.schedule();
-
- if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
- scheduler.holdCount != EXPECTED_HOLD_COUNT) {
- var msg =
- "Error during execution: queueCount = " + scheduler.queueCount +
- ", holdCount = " + scheduler.holdCount + ".";
- throw new Error(msg);
- }
- } catch(e) { }
-}
-
-var COUNT = 1000;
-
-/**
- * These two constants specify how many times a packet is queued and
- * how many times a task is put on hold in a correct run of richards.
- * They don't have any meaning a such but are characteristic of a
- * correct run so if the actual queue or hold count is different from
- * the expected there must be a bug in the implementation.
- **/
-var EXPECTED_QUEUE_COUNT = 2322;
-var EXPECTED_HOLD_COUNT = 928;
-
-
-/**
- * A scheduler can be used to schedule a set of tasks based on their relative
- * priorities. Scheduling is done by maintaining a list of task control blocks
- * which holds tasks and the data queue they are processing.
- * @constructor
- */
-function Scheduler() {
- try {
- this.queueCount = 0;
- this.holdCount = 0;
- this.blocks = new Array(NUMBER_OF_IDS);
- this.list = null;
- this.currentTcb = null;
- this.currentId = null;
-
- } catch(e) { }
-}
-
-var ID_IDLE = 0;
-var ID_WORKER = 1;
-var ID_HANDLER_A = 2;
-var ID_HANDLER_B = 3;
-var ID_DEVICE_A = 4;
-var ID_DEVICE_B = 5;
-var NUMBER_OF_IDS = 6;
-
-var KIND_DEVICE = 0;
-var KIND_WORK = 1;
-
-/**
- * Add an idle task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {int} count the number of times to schedule the task
- */
-Scheduler.prototype.addIdleTask = function (id, priority, queue, count) {
- try {
- this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count));
- } catch(e) { }
-};
-
-/**
- * Add a work task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addWorkerTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));
- } catch(e) { }
-};
-
-/**
- * Add a handler task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addHandlerTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new HandlerTask(this));
- } catch(e) { }
-};
-
-/**
- * Add a handler task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addDeviceTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new DeviceTask(this))
- } catch(e) { }
-};
-
-/**
- * Add the specified task and mark it as running.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {Task} task the task to add
- */
-Scheduler.prototype.addRunningTask = function (id, priority, queue, task) {
- try {
- this.addTask(id, priority, queue, task);
- this.currentTcb.setRunning();
- } catch(e) { }
-};
-
-/**
- * Add the specified task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {Task} task the task to add
- */
-Scheduler.prototype.addTask = function (id, priority, queue, task) {
- try {
- this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task);
- this.list = this.currentTcb;
- this.blocks[id] = this.currentTcb;
- } catch(e) { }
-};
-
-/**
- * Execute the tasks managed by this scheduler.
- */
-Scheduler.prototype.schedule = function () {
- this.currentTcb = this.list;
- while (this.currentTcb != null) {
- try {
- if (this.currentTcb.isHeldOrSuspended()) {
- this.currentTcb = this.currentTcb.link;
- } else {
- this.currentId = this.currentTcb.id;
- this.currentTcb = this.currentTcb.run();
- }
- } catch(e) { }
- }
-};
-
-/**
- * Release a task that is currently blocked and return the next block to run.
- * @param {int} id the id of the task to suspend
- */
-Scheduler.prototype.release = function (id) {
- try {
- var tcb = this.blocks[id];
- if (tcb == null) return tcb;
- tcb.markAsNotHeld();
- } catch(e) { }
- try {
- if (tcb.priority > this.currentTcb.priority) {
- return tcb;
- } else {
- return this.currentTcb;
- }
- } catch(e) { }
-};
-
-/**
- * Block the currently executing task and return the next task control block
- * to run. The blocked task will not be made runnable until it is explicitly
- * released, even if new work is added to it.
- */
-Scheduler.prototype.holdCurrent = function () {
- try {
- this.holdCount++;
- this.currentTcb.markAsHeld();
- } catch(e) { }
- return this.currentTcb.link;
-};
-
-/**
- * Suspend the currently executing task and return the next task control block
- * to run. If new work is added to the suspended task it will be made runnable.
- */
-Scheduler.prototype.suspendCurrent = function () {
- try {
- this.currentTcb.markAsSuspended();
- } catch(e) { }
- try {
- return this.currentTcb;
- } catch(e) { }
-};
-
-/**
- * Add the specified packet to the end of the worklist used by the task
- * associated with the packet and make the task runnable if it is currently
- * suspended.
- * @param {Packet} packet the packet to add
- */
-Scheduler.prototype.queue = function (packet) {
- try {
- var t = this.blocks[packet.id];
- if (t == null) return t;
- this.queueCount++;
- packet.link = null;
- } catch(e) { }
- packet.id = this.currentId;
- return t.checkPriorityAdd(this.currentTcb, packet);
-};
-
-/**
- * A task control block manages a task and the queue of work packages associated
- * with it.
- * @param {TaskControlBlock} link the preceding block in the linked block list
- * @param {int} id the id of this block
- * @param {int} priority the priority of this block
- * @param {Packet} queue the queue of packages to be processed by the task
- * @param {Task} task the task
- * @constructor
- */
-function TaskControlBlock(link, id, priority, queue, task) {
- try {
- this.link = link;
- this.id = id;
- this.priority = priority;
- this.queue = queue;
- this.task = task;
- } catch(e) { }
- try {
- if (queue == null) {
- this.state = STATE_SUSPENDED;
- } else {
- this.state = STATE_SUSPENDED_RUNNABLE;
- }
- } catch(e) { }
-}
-
-/**
- * The task is running and is currently scheduled.
- */
-var STATE_RUNNING = 0;
-
-/**
- * The task has packets left to process.
- */
-var STATE_RUNNABLE = 1;
-
-/**
- * The task is not currently running. The task is not blocked as such and may
- * be started by the scheduler.
- */
-var STATE_SUSPENDED = 2;
-
-/**
- * The task is blocked and cannot be run until it is explicitly released.
- */
-var STATE_HELD = 4;
-
-var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
-var STATE_NOT_HELD = ~STATE_HELD;
-
-TaskControlBlock.prototype.setRunning = function () {
- try {
- this.state = STATE_RUNNING;
- } catch(e){}
-};
-
-TaskControlBlock.prototype.markAsNotHeld = function () {
- try {
- this.state = this.state & STATE_NOT_HELD;
- } catch(e) { }
-};
-
-TaskControlBlock.prototype.markAsHeld = function () {
- try {
- this.state = this.state | STATE_HELD;
- } catch(e) { }
-};
-
-TaskControlBlock.prototype.isHeldOrSuspended = function () {
- try {
- return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
- } catch(e) {
- return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
- }
-};
-
-TaskControlBlock.prototype.markAsSuspended = function () {
- try {
- this.state = this.state | STATE_SUSPENDED;
- } catch(e) {
- this.state = this.state | STATE_SUSPENDED;
- }
-};
-
-TaskControlBlock.prototype.markAsRunnable = function () {
- try {
- this.state = this.state | STATE_RUNNABLE;
- } catch(e) {
- this.state = this.state | STATE_RUNNABLE;
- }
-};
-
-/**
- * Runs this task, if it is ready to be run, and returns the next task to run.
- */
-TaskControlBlock.prototype.run = function () {
- var packet;
- try {
- if (this.state == STATE_SUSPENDED_RUNNABLE) {
- packet = this.queue;
- this.queue = packet.link;
- if (this.queue == null) {
- this.state = STATE_RUNNING;
- } else {
- this.state = STATE_RUNNABLE;
- }
- } else {
- packet = null;
- }
- } catch(e) { }
- return this.task.run(packet);
-};
-
-/**
- * Adds a packet to the worklist of this block's task, marks this as runnable if
- * necessary, and returns the next runnable object to run (the one
- * with the highest priority).
- */
-TaskControlBlock.prototype.checkPriorityAdd = function (task, packet) {
- try {
- if (this.queue == null) {
- this.queue = packet;
- this.markAsRunnable();
- if (this.priority > task.priority) return this;
- } else {
- this.queue = packet.addTo(this.queue);
- }
-
- return task;
- } catch(e) {
- return task;
- }
-};
-
-TaskControlBlock.prototype.toString = function () {
- try {
- return "tcb { " + this.task + "@" + this.state + " }";
- } catch(e) {
- return "tcb { " + this.task + "@" + this.state + " }";
- }
-};
-
-/**
- * An idle task doesn't do any work itself but cycles control between the two
- * device tasks.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @param {int} v1 a seed value that controls how the device tasks are scheduled
- * @param {int} count the number of times this task should be scheduled
- * @constructor
- */
-function IdleTask(scheduler, v1, count) {
- try {
- this.scheduler = scheduler;
- this.v1 = v1;
- this.count = count;
- } catch(e) {
- this.count = count;
- }
-}
-
-IdleTask.prototype.run = function (packet) {
- try {
- this.count--;
- if (this.count == 0) return this.scheduler.holdCurrent();
- } catch(e) { }
-
- try {
- if ((this.v1 & 1) == 0) {
- this.v1 = this.v1 >> 1;
- return this.scheduler.release(ID_DEVICE_A);
- } else {
- this.v1 = (this.v1 >> 1) ^ 0xD008;
- return this.scheduler.release(ID_DEVICE_B);
- }
- } catch(e) { }
-};
-
-IdleTask.prototype.toString = function () {
- try {
- return "IdleTask"
- } catch(e) {
- return "IdleTask"
- }
-};
-
-/**
- * A task that suspends itself after each time it has been run to simulate
- * waiting for data from an external device.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @constructor
- */
-function DeviceTask(scheduler) {
- try {
- this.scheduler = scheduler;
- this.v1 = null;
- } catch(e) { }
-}
-
-DeviceTask.prototype.run = function (packet) {
- if (packet == null) {
- try {
- if (this.v1 == null) return this.scheduler.suspendCurrent();
- var v = this.v1;
- this.v1 = null;
- } catch(e) { }
- return this.scheduler.queue(v);
- } else {
- try {
- this.v1 = packet;
- } catch(e) { }
- return this.scheduler.holdCurrent();
- }
-};
-
-DeviceTask.prototype.toString = function () {
- try {
- return "DeviceTask";
- } catch(e) { }
-};
-
-/**
- * A task that manipulates work packets.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @param {int} v1 a seed used to specify how work packets are manipulated
- * @param {int} v2 another seed used to specify how work packets are manipulated
- * @constructor
- */
-function WorkerTask(scheduler, v1, v2) {
- try {
- this.scheduler = scheduler;
- this.v1 = v1;
- this.v2 = v2;
- } catch(e) { }
-}
-
-WorkerTask.prototype.run = function (packet) {
- if (packet == null) {
- return this.scheduler.suspendCurrent();
- } else {
- try {
- if (this.v1 == ID_HANDLER_A) {
- this.v1 = ID_HANDLER_B;
- } else {
- this.v1 = ID_HANDLER_A;
- }
- packet.id = this.v1;
- packet.a1 = 0;
- } catch(e) { }
- for (var i = 0; i < DATA_SIZE; i++) {
- try {
- this.v2++;
- if (this.v2 > 26) this.v2 = 1;
- packet.a2[i] = this.v2;
- } catch(e) { }
- }
- return this.scheduler.queue(packet);
- }
-};
-
-WorkerTask.prototype.toString = function () {
- try {
- return "WorkerTask";
- } catch(e) { }
-};
-
-/**
- * A task that manipulates work packets and then suspends itself.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @constructor
- */
-function HandlerTask(scheduler) {
- try {
- this.scheduler = scheduler;
- this.v1 = null;
- this.v2 = null;
- } catch(e) { }
-}
-
-HandlerTask.prototype.run = function (packet) {
- try {
- if (packet != null) {
- if (packet.kind == KIND_WORK) {
- this.v1 = packet.addTo(this.v1);
- } else {
- this.v2 = packet.addTo(this.v2);
- }
- }
- } catch(e) { }
-
- try {
- if (this.v1 != null) {
- var count = this.v1.a1;
- var v;
- if (count < DATA_SIZE) {
- if (this.v2 != null) {
- v = this.v2;
- this.v2 = this.v2.link;
- v.a1 = this.v1.a2[count];
- this.v1.a1 = count + 1;
- return this.scheduler.queue(v);
- }
- } else {
- v = this.v1;
- this.v1 = this.v1.link;
- return this.scheduler.queue(v);
- }
- }
- } catch(e) { }
- return this.scheduler.suspendCurrent();
-};
-
-HandlerTask.prototype.toString = function () {
- try {
- return "HandlerTask";
- } catch(e) { }
-};
-
-/* --- *
- * P a c k e t
- * --- */
-
-var DATA_SIZE = 4;
-
-/**
- * A simple package of data that is manipulated by the tasks. The exact layout
- * of the payload data carried by a packet is not importaint, and neither is the
- * nature of the work performed on packets by the tasks.
- *
- * Besides carrying data, packets form linked lists and are hence used both as
- * data and worklists.
- * @param {Packet} link the tail of the linked list of packets
- * @param {int} id an ID for this packet
- * @param {int} kind the type of this packet
- * @constructor
- */
-function Packet(link, id, kind) {
- try {
- this.link = link;
- this.id = id;
- this.kind = kind;
- this.a1 = 0;
- this.a2 = new Array(DATA_SIZE);
- } catch(e) { }
-}
-
-/**
- * Add this packet to the end of a worklist, and return the worklist.
- * @param {Packet} queue the worklist to add this packet to
- */
-Packet.prototype.addTo = function (queue) {
- this.link = null;
- if (queue == null) return this;
- var peek, next = queue;
- while ((peek = next.link) != null) {
- try {
- next = peek;
- } catch(e) { }
- }
- next.link = this;
- return queue;
-};
-
-Packet.prototype.toString = function () {
- try {
- return "Packet";
- } catch(e) { }
-};
-
-for (let i = 0; i < 350; ++i)
- runRichards();
+++ /dev/null
-// Copyright 2006-2008 the V8 project authors. All rights reserved.
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-
-// This is a JavaScript implementation of the Richards
-// benchmark from:
-//
-// http://www.cl.cam.ac.uk/~mr10/Bench.html
-//
-// The benchmark was originally implemented in BCPL by
-// Martin Richards.
-
-
-let __exceptionCounter = 0;
-function randomException() {
- __exceptionCounter++;
- if (__exceptionCounter % 5000 === 0) {
- throw new Error("rando");
- }
-}
-noInline(randomException);
-
-/**
- * The Richards benchmark simulates the task dispatcher of an
- * operating system.
- **/
-function runRichards() {
- try {
- var scheduler = new Scheduler();
- scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
-
- var queue = new Packet(null, ID_WORKER, KIND_WORK);
- queue = new Packet(queue, ID_WORKER, KIND_WORK);
- scheduler.addWorkerTask(ID_WORKER, 1000, queue);
-
- queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
-
- queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
- scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
-
- scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
-
- scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
-
- scheduler.schedule();
-
- if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
- scheduler.holdCount != EXPECTED_HOLD_COUNT) {
- var msg =
- "Error during execution: queueCount = " + scheduler.queueCount +
- ", holdCount = " + scheduler.holdCount + ".";
- throw new Error(msg);
- }
-
- randomException();
- } catch(e) { }
-}
-
-var COUNT = 1000;
-
-/**
- * These two constants specify how many times a packet is queued and
- * how many times a task is put on hold in a correct run of richards.
- * They don't have any meaning a such but are characteristic of a
- * correct run so if the actual queue or hold count is different from
- * the expected there must be a bug in the implementation.
- **/
-var EXPECTED_QUEUE_COUNT = 2322;
-var EXPECTED_HOLD_COUNT = 928;
-
-
-/**
- * A scheduler can be used to schedule a set of tasks based on their relative
- * priorities. Scheduling is done by maintaining a list of task control blocks
- * which holds tasks and the data queue they are processing.
- * @constructor
- */
-function Scheduler() {
- try {
- this.queueCount = 0;
- this.holdCount = 0;
- this.blocks = new Array(NUMBER_OF_IDS);
- this.list = null;
- this.currentTcb = null;
- this.currentId = null;
-
- randomException();
- } catch(e) { }
-}
-
-var ID_IDLE = 0;
-var ID_WORKER = 1;
-var ID_HANDLER_A = 2;
-var ID_HANDLER_B = 3;
-var ID_DEVICE_A = 4;
-var ID_DEVICE_B = 5;
-var NUMBER_OF_IDS = 6;
-
-var KIND_DEVICE = 0;
-var KIND_WORK = 1;
-
-/**
- * Add an idle task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {int} count the number of times to schedule the task
- */
-Scheduler.prototype.addIdleTask = function (id, priority, queue, count) {
- try {
- this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count));
- randomException();
- } catch(e) { }
-};
-
-/**
- * Add a work task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addWorkerTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));
- randomException();
- } catch(e) { }
-};
-
-/**
- * Add a handler task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addHandlerTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new HandlerTask(this));
- randomException();
- } catch(e) { }
-};
-
-/**
- * Add a handler task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- */
-Scheduler.prototype.addDeviceTask = function (id, priority, queue) {
- try {
- this.addTask(id, priority, queue, new DeviceTask(this))
- randomException();
- } catch(e) { }
-};
-
-/**
- * Add the specified task and mark it as running.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {Task} task the task to add
- */
-Scheduler.prototype.addRunningTask = function (id, priority, queue, task) {
- try {
- this.addTask(id, priority, queue, task);
- this.currentTcb.setRunning();
- randomException();
- } catch(e) { }
-};
-
-/**
- * Add the specified task to this scheduler.
- * @param {int} id the identity of the task
- * @param {int} priority the task's priority
- * @param {Packet} queue the queue of work to be processed by the task
- * @param {Task} task the task to add
- */
-Scheduler.prototype.addTask = function (id, priority, queue, task) {
- try {
- this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task);
- this.list = this.currentTcb;
- this.blocks[id] = this.currentTcb;
- randomException();
- } catch(e) { }
-};
-
-/**
- * Execute the tasks managed by this scheduler.
- */
-Scheduler.prototype.schedule = function () {
- this.currentTcb = this.list;
- while (this.currentTcb != null) {
- try {
- if (this.currentTcb.isHeldOrSuspended()) {
- this.currentTcb = this.currentTcb.link;
- } else {
- this.currentId = this.currentTcb.id;
- this.currentTcb = this.currentTcb.run();
- }
- randomException();
- } catch(e) { }
- }
-};
-
-/**
- * Release a task that is currently blocked and return the next block to run.
- * @param {int} id the id of the task to suspend
- */
-Scheduler.prototype.release = function (id) {
- try {
- var tcb = this.blocks[id];
- if (tcb == null) return tcb;
- tcb.markAsNotHeld();
- randomException();
- } catch(e) { }
- try {
- if (tcb.priority > this.currentTcb.priority) {
- return tcb;
- } else {
- return this.currentTcb;
- }
- } catch(e) { }
-};
-
-/**
- * Block the currently executing task and return the next task control block
- * to run. The blocked task will not be made runnable until it is explicitly
- * released, even if new work is added to it.
- */
-Scheduler.prototype.holdCurrent = function () {
- try {
- this.holdCount++;
- this.currentTcb.markAsHeld();
- randomException();
- } catch(e) { }
- return this.currentTcb.link;
-};
-
-/**
- * Suspend the currently executing task and return the next task control block
- * to run. If new work is added to the suspended task it will be made runnable.
- */
-Scheduler.prototype.suspendCurrent = function () {
- try {
- this.currentTcb.markAsSuspended();
- randomException();
- } catch(e) { }
- try {
- return this.currentTcb;
- } catch(e) { }
-};
-
-/**
- * Add the specified packet to the end of the worklist used by the task
- * associated with the packet and make the task runnable if it is currently
- * suspended.
- * @param {Packet} packet the packet to add
- */
-Scheduler.prototype.queue = function (packet) {
- try {
- var t = this.blocks[packet.id];
- if (t == null) return t;
- this.queueCount++;
- packet.link = null;
- randomException();
- } catch(e) { }
- packet.id = this.currentId;
- return t.checkPriorityAdd(this.currentTcb, packet);
-};
-
-/**
- * A task control block manages a task and the queue of work packages associated
- * with it.
- * @param {TaskControlBlock} link the preceding block in the linked block list
- * @param {int} id the id of this block
- * @param {int} priority the priority of this block
- * @param {Packet} queue the queue of packages to be processed by the task
- * @param {Task} task the task
- * @constructor
- */
-function TaskControlBlock(link, id, priority, queue, task) {
- try {
- this.link = link;
- this.id = id;
- this.priority = priority;
- this.queue = queue;
- this.task = task;
- randomException();
- } catch(e) { }
- try {
- if (queue == null) {
- this.state = STATE_SUSPENDED;
- } else {
- this.state = STATE_SUSPENDED_RUNNABLE;
- }
- randomException();
- } catch(e) { }
-}
-
-/**
- * The task is running and is currently scheduled.
- */
-var STATE_RUNNING = 0;
-
-/**
- * The task has packets left to process.
- */
-var STATE_RUNNABLE = 1;
-
-/**
- * The task is not currently running. The task is not blocked as such and may
- * be started by the scheduler.
- */
-var STATE_SUSPENDED = 2;
-
-/**
- * The task is blocked and cannot be run until it is explicitly released.
- */
-var STATE_HELD = 4;
-
-var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
-var STATE_NOT_HELD = ~STATE_HELD;
-
-TaskControlBlock.prototype.setRunning = function () {
- try {
- this.state = STATE_RUNNING;
- randomException();
- } catch(e){}
-};
-
-TaskControlBlock.prototype.markAsNotHeld = function () {
- try {
- this.state = this.state & STATE_NOT_HELD;
- randomException();
- } catch(e) { }
-};
-
-TaskControlBlock.prototype.markAsHeld = function () {
- try {
- this.state = this.state | STATE_HELD;
- randomException();
- } catch(e) { }
-};
-
-TaskControlBlock.prototype.isHeldOrSuspended = function () {
- try {
- randomException();
- return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
- } catch(e) {
- return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
- }
-};
-
-TaskControlBlock.prototype.markAsSuspended = function () {
- try {
- randomException();
- this.state = this.state | STATE_SUSPENDED;
- } catch(e) {
- this.state = this.state | STATE_SUSPENDED;
- }
-};
-
-TaskControlBlock.prototype.markAsRunnable = function () {
- try {
- randomException();
- this.state = this.state | STATE_RUNNABLE;
- } catch(e) {
- this.state = this.state | STATE_RUNNABLE;
- }
-};
-
-/**
- * Runs this task, if it is ready to be run, and returns the next task to run.
- */
-TaskControlBlock.prototype.run = function () {
- var packet;
- try {
- if (this.state == STATE_SUSPENDED_RUNNABLE) {
- packet = this.queue;
- this.queue = packet.link;
- if (this.queue == null) {
- this.state = STATE_RUNNING;
- } else {
- this.state = STATE_RUNNABLE;
- }
- } else {
- packet = null;
- }
- randomException();
- } catch(e) { }
- return this.task.run(packet);
-};
-
-/**
- * Adds a packet to the worklist of this block's task, marks this as runnable if
- * necessary, and returns the next runnable object to run (the one
- * with the highest priority).
- */
-TaskControlBlock.prototype.checkPriorityAdd = function (task, packet) {
- try {
- if (this.queue == null) {
- this.queue = packet;
- this.markAsRunnable();
- if (this.priority > task.priority) return this;
- } else {
- this.queue = packet.addTo(this.queue);
- }
-
- randomException();
- return task;
- } catch(e) {
- return task;
- }
-};
-
-TaskControlBlock.prototype.toString = function () {
- try {
- randomException();
- return "tcb { " + this.task + "@" + this.state + " }";
- } catch(e) {
- return "tcb { " + this.task + "@" + this.state + " }";
- }
-};
-
-/**
- * An idle task doesn't do any work itself but cycles control between the two
- * device tasks.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @param {int} v1 a seed value that controls how the device tasks are scheduled
- * @param {int} count the number of times this task should be scheduled
- * @constructor
- */
-function IdleTask(scheduler, v1, count) {
- try {
- this.scheduler = scheduler;
- this.v1 = v1;
- randomException();
- this.count = count;
- } catch(e) {
- this.count = count;
- }
-}
-
-IdleTask.prototype.run = function (packet) {
- try {
- this.count--;
- if (this.count == 0) return this.scheduler.holdCurrent();
- randomException();
- } catch(e) { }
-
- try {
- if ((this.v1 & 1) == 0) {
- this.v1 = this.v1 >> 1;
- return this.scheduler.release(ID_DEVICE_A);
- } else {
- this.v1 = (this.v1 >> 1) ^ 0xD008;
- return this.scheduler.release(ID_DEVICE_B);
- }
- } catch(e) { }
-};
-
-IdleTask.prototype.toString = function () {
- try {
- randomException();
- return "IdleTask"
- } catch(e) {
- return "IdleTask"
- }
-};
-
-/**
- * A task that suspends itself after each time it has been run to simulate
- * waiting for data from an external device.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @constructor
- */
-function DeviceTask(scheduler) {
- try {
- this.scheduler = scheduler;
- this.v1 = null;
- randomException();
- } catch(e) { }
-}
-
-DeviceTask.prototype.run = function (packet) {
- if (packet == null) {
- try {
- if (this.v1 == null) return this.scheduler.suspendCurrent();
- var v = this.v1;
- this.v1 = null;
- randomException();
- } catch(e) { }
- return this.scheduler.queue(v);
- } else {
- try {
- this.v1 = packet;
- randomException();
- } catch(e) { }
- return this.scheduler.holdCurrent();
- }
-};
-
-DeviceTask.prototype.toString = function () {
- try {
- randomException();
- return "DeviceTask";
- } catch(e) { }
-};
-
-/**
- * A task that manipulates work packets.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @param {int} v1 a seed used to specify how work packets are manipulated
- * @param {int} v2 another seed used to specify how work packets are manipulated
- * @constructor
- */
-function WorkerTask(scheduler, v1, v2) {
- try {
- this.scheduler = scheduler;
- this.v1 = v1;
- this.v2 = v2;
- randomException();
- } catch(e) { }
-}
-
-WorkerTask.prototype.run = function (packet) {
- if (packet == null) {
- return this.scheduler.suspendCurrent();
- } else {
- try {
- if (this.v1 == ID_HANDLER_A) {
- this.v1 = ID_HANDLER_B;
- } else {
- this.v1 = ID_HANDLER_A;
- }
- packet.id = this.v1;
- packet.a1 = 0;
- randomException();
- } catch(e) { }
- for (var i = 0; i < DATA_SIZE; i++) {
- try {
- this.v2++;
- if (this.v2 > 26) this.v2 = 1;
- packet.a2[i] = this.v2;
- randomException();
- } catch(e) { }
- }
- return this.scheduler.queue(packet);
- }
-};
-
-WorkerTask.prototype.toString = function () {
- try {
- return "WorkerTask";
- } catch(e) { }
-};
-
-/**
- * A task that manipulates work packets and then suspends itself.
- * @param {Scheduler} scheduler the scheduler that manages this task
- * @constructor
- */
-function HandlerTask(scheduler) {
- try {
- this.scheduler = scheduler;
- this.v1 = null;
- this.v2 = null;
- randomException();
- } catch(e) { }
-}
-
-HandlerTask.prototype.run = function (packet) {
- try {
- if (packet != null) {
- if (packet.kind == KIND_WORK) {
- this.v1 = packet.addTo(this.v1);
- } else {
- this.v2 = packet.addTo(this.v2);
- }
- }
- randomException();
- } catch(e) { }
-
- try {
- if (this.v1 != null) {
- var count = this.v1.a1;
- var v;
- if (count < DATA_SIZE) {
- if (this.v2 != null) {
- v = this.v2;
- this.v2 = this.v2.link;
- v.a1 = this.v1.a2[count];
- this.v1.a1 = count + 1;
- return this.scheduler.queue(v);
- }
- } else {
- v = this.v1;
- this.v1 = this.v1.link;
- return this.scheduler.queue(v);
- }
- }
- randomException();
- } catch(e) { }
- return this.scheduler.suspendCurrent();
-};
-
-HandlerTask.prototype.toString = function () {
- try {
- return "HandlerTask";
- } catch(e) { }
-};
-
-/* --- *
- * P a c k e t
- * --- */
-
-var DATA_SIZE = 4;
-
-/**
- * A simple package of data that is manipulated by the tasks. The exact layout
- * of the payload data carried by a packet is not importaint, and neither is the
- * nature of the work performed on packets by the tasks.
- *
- * Besides carrying data, packets form linked lists and are hence used both as
- * data and worklists.
- * @param {Packet} link the tail of the linked list of packets
- * @param {int} id an ID for this packet
- * @param {int} kind the type of this packet
- * @constructor
- */
-function Packet(link, id, kind) {
- try {
- this.link = link;
- this.id = id;
- this.kind = kind;
- this.a1 = 0;
- this.a2 = new Array(DATA_SIZE);
- randomException();
- } catch(e) { }
-}
-
-/**
- * Add this packet to the end of a worklist, and return the worklist.
- * @param {Packet} queue the worklist to add this packet to
- */
-Packet.prototype.addTo = function (queue) {
- this.link = null;
- if (queue == null) return this;
- var peek, next = queue;
- while ((peek = next.link) != null) {
- try {
- next = peek;
- randomException();
- } catch(e) { }
- }
- next.link = this;
- return queue;
-};
-
-Packet.prototype.toString = function () {
- try {
- return "Packet";
- } catch(e) { }
-};
-
-for (let i = 0; i < 350; ++i)
- runRichards();
+++ /dev/null
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.nz.co/raytracer/
-//
-// It has been modified slightly by Google to work as a standalone
-// benchmark, but the all the computational code remains
-// untouched. This file also contains a copy of parts of the Prototype
-// JavaScript framework which is used by the ray tracer.
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-var checkNumber;
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The following is a copy of parts of the Prototype JavaScript library:
-
-// Prototype JavaScript framework, version 1.5.0
-// (c) 2005-2007 Sam Stephenson
-//
-// Prototype is freely distributable under the terms of an MIT-style license.
-// For details, see the Prototype web site: http://prototype.conio.net/
-
-var Class = {
- create: function() {
- return function() {
- try {
- this.initialize.apply(this, arguments);
- } catch(e) { }
- }
- }
-};
-
-
-Object.extend = function(destination, source) {
- for (var property in source) {
- try {
- destination[property] = source[property];
- } catch(e) { }
- }
- return destination;
-};
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The rest of this file is the actual ray tracer written by Adam
-// Burmister. It's a concatenation of the following files:
-//
-// flog/color.js
-// flog/light.js
-// flog/vector.js
-// flog/ray.js
-// flog/scene.js
-// flog/material/basematerial.js
-// flog/material/solid.js
-// flog/material/chessboard.js
-// flog/shape/baseshape.js
-// flog/shape/sphere.js
-// flog/shape/plane.js
-// flog/intersectioninfo.js
-// flog/camera.js
-// flog/background.js
-// flog/engine.js
-
-
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Color = Class.create();
-
-Flog.RayTracer.Color.prototype = {
- red : 0.0,
- green : 0.0,
- blue : 0.0,
-
- initialize : function(r, g, b) {
- try {
- if(!r) r = 0.0;
- if(!g) g = 0.0;
- if(!b) b = 0.0;
-
- this.red = r;
- this.green = g;
- this.blue = b;
- } catch(e) { }
- },
-
- add : function(c1, c2){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red + c2.red;
- result.green = c1.green + c2.green;
- result.blue = c1.blue + c2.blue;
-
- } catch(e) { }
-
- return result;
- },
-
- addScalar: function(c1, s){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red + s;
- result.green = c1.green + s;
- result.blue = c1.blue + s;
-
- result.limit();
-
- } catch(e) { }
-
- return result;
- },
-
- subtract: function(c1, c2){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red - c2.red;
- result.green = c1.green - c2.green;
- result.blue = c1.blue - c2.blue;
-
- } catch(e) { }
-
- return result;
- },
-
- multiply : function(c1, c2) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red * c2.red;
- result.green = c1.green * c2.green;
- result.blue = c1.blue * c2.blue;
-
- } catch(e) { }
-
- return result;
- },
-
- multiplyScalar : function(c1, f) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red * f;
- result.green = c1.green * f;
- result.blue = c1.blue * f;
-
- } catch(e) { }
-
- return result;
- },
-
- divideFactor : function(c1, f) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red / f;
- result.green = c1.green / f;
- result.blue = c1.blue / f;
-
- } catch(e) { }
-
- return result;
- },
-
- limit: function(){
- try {
- this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
- this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
- this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
-
- } catch(e) { }
- },
-
- distance : function(color) {
- try {
- var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
- } catch(e) { }
- return d;
- },
-
- blend: function(c1, c2, w){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
- result = Flog.RayTracer.Color.prototype.add(
- Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
- Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
- );
- } catch(e) { }
- return result;
- },
-
- brightness : function() {
- try {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- } catch(e) { }
- return (r * 77 + g * 150 + b * 29) >> 8;
- },
-
- toString : function () {
- try {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- } catch(e) { }
-
- return "rgb("+ r +","+ g +","+ b +")";
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Light = Class.create();
-
-Flog.RayTracer.Light.prototype = {
- position: null,
- color: null,
- intensity: 10.0,
-
- initialize : function(pos, color, intensity) {
- try {
- this.position = pos;
- this.color = color;
- this.intensity = (intensity ? intensity : 10.0);
-
- } catch(e) { }
- },
-
- toString : function () {
- try {
- var result = 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
- } catch(e) { }
- return result;
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Vector = Class.create();
-
-Flog.RayTracer.Vector.prototype = {
- x : 0.0,
- y : 0.0,
- z : 0.0,
-
- initialize : function(x, y, z) {
- try {
- this.x = (x ? x : 0);
- this.y = (y ? y : 0);
- this.z = (z ? z : 0);
- } catch(e) { }
- },
-
- copy: function(vector){
- try {
- this.x = vector.x;
- this.y = vector.y;
- this.z = vector.z;
- } catch(e) { }
- },
-
- normalize : function() {
- try {
- var m = this.magnitude();
- var result = new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
- } catch(e) { }
- return result;
- },
-
- magnitude : function() {
- try {
- return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
- } catch(e) { }
- },
-
- cross : function(w) {
- try {
- return new Flog.RayTracer.Vector(
- -this.z * w.y + this.y * w.z,
- this.z * w.x - this.x * w.z,
- -this.y * w.x + this.x * w.y);
- } catch(e) { }
- },
-
- dot : function(w) {
- try {
- return this.x * w.x + this.y * w.y + this.z * w.z;
- } catch(e) { }
- },
-
- add : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
- } catch(e) { }
- },
-
- subtract : function(v, w) {
- try {
- if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
- return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
- } catch(e) { }
- },
-
- multiplyVector : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
- } catch(e) { }
- },
-
- multiplyScalar : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Ray = Class.create();
-
-Flog.RayTracer.Ray.prototype = {
- position : null,
- direction : null,
- initialize : function(pos, dir) {
- try {
- this.position = pos;
- this.direction = dir;
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Ray [' + this.position + ',' + this.direction + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Scene = Class.create();
-
-Flog.RayTracer.Scene.prototype = {
- camera : null,
- shapes : [],
- lights : [],
- background : null,
-
- initialize : function() {
- try {
- this.camera = new Flog.RayTracer.Camera(
- new Flog.RayTracer.Vector(0,0,-5),
- new Flog.RayTracer.Vector(0,0,1),
- new Flog.RayTracer.Vector(0,1,0)
- );
- this.shapes = new Array();
- this.lights = new Array();
- this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
-
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
-
-Flog.RayTracer.Material.BaseMaterial = Class.create();
-
-Flog.RayTracer.Material.BaseMaterial.prototype = {
-
- gloss: 2.0, // [0...infinity] 0 = matt
- transparency: 0.0, // 0=opaque
- reflection: 0.0, // [0...infinity] 0 = no reflection
- refraction: 0.50,
- hasTexture: false,
-
- initialize : function() {
-
- },
-
- getColor: function(u, v){
-
- },
-
- wrapUp: function(t){
- try {
- t = t % 2.0;
- if(t < -1) t += 2.0;
- if(t >= 1) t -= 2.0;
- } catch(e) { }
- return t;
- },
-
- toString : function () {
- try {
- return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Material.Solid = Class.create();
-
-Flog.RayTracer.Material.Solid.prototype = Object.extend(
- new Flog.RayTracer.Material.BaseMaterial(), {
- initialize : function(color, reflection, refraction, transparency, gloss) {
- try {
- this.color = color;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.hasTexture = false;
- } catch(e) { }
- },
-
- getColor: function(u, v){
- try {
- return this.color;
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
- }
- );
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Material.Chessboard = Class.create();
-
-Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
- new Flog.RayTracer.Material.BaseMaterial(), {
- colorEven: null,
- colorOdd: null,
- density: 0.5,
-
- initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
- try {
- this.colorEven = colorEven;
- this.colorOdd = colorOdd;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.density = density;
- this.hasTexture = true;
- } catch(e) { }
- },
-
- getColor: function(u, v){
- try {
- var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
- } catch(e) { }
-
- if(t < 0.0)
- return this.colorEven;
- else
- return this.colorOdd;
- },
-
- toString : function () {
- try {
- return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
- }
-);
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
-
-Flog.RayTracer.Shape.Sphere = Class.create();
-
-Flog.RayTracer.Shape.Sphere.prototype = {
- initialize : function(pos, radius, material) {
- try {
- this.radius = radius;
- this.position = pos;
- this.material = material;
-
- } catch(e) { }
- },
-
- intersect: function(ray){
- try {
- var info = new Flog.RayTracer.IntersectionInfo();
- info.shape = this;
-
- var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
-
- var B = dst.dot(ray.direction);
- var C = dst.dot(dst) - (this.radius * this.radius);
- var D = (B * B) - C;
-
- if(D > 0){ // intersection!
- info.isHit = true;
- info.distance = (-B) - Math.sqrt(D);
- info.position = Flog.RayTracer.Vector.prototype.add(
- ray.position,
- Flog.RayTracer.Vector.prototype.multiplyScalar(
- ray.direction,
- info.distance
- )
- );
- info.normal = Flog.RayTracer.Vector.prototype.subtract(
- info.position,
- this.position
- ).normalize();
-
- info.color = this.material.getColor(0,0);
- } else {
- info.isHit = false;
- }
-
- } catch(e) { }
- return info;
- },
-
- toString : function () {
- try {
- return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
-
-Flog.RayTracer.Shape.Plane = Class.create();
-
-Flog.RayTracer.Shape.Plane.prototype = {
- d: 0.0,
-
- initialize : function(pos, d, material) {
- try {
- this.position = pos;
- this.d = d;
- this.material = material;
- } catch(e) { }
- },
-
- intersect: function(ray){
- try {
- var info = new Flog.RayTracer.IntersectionInfo();
-
- var Vd = this.position.dot(ray.direction);
- if(Vd == 0) return info; // no intersection
-
- var t = -(this.position.dot(ray.position) + this.d) / Vd;
- if(t <= 0) return info;
-
- info.shape = this;
- info.isHit = true;
- info.position = Flog.RayTracer.Vector.prototype.add(
- ray.position,
- Flog.RayTracer.Vector.prototype.multiplyScalar(
- ray.direction,
- t
- )
- );
- info.normal = this.position;
- info.distance = t;
-
- if(this.material.hasTexture){
- var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
- var vV = vU.cross(this.position);
- var u = info.position.dot(vU);
- var v = info.position.dot(vV);
- info.color = this.material.getColor(u,v);
- } else {
- info.color = this.material.getColor(0,0);
- }
-
- } catch(e) { }
- return info;
- },
-
- toString : function () {
- try {
- return 'Plane [' + this.position + ', d=' + this.d + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.IntersectionInfo = Class.create();
-
-Flog.RayTracer.IntersectionInfo.prototype = {
- isHit: false,
- hitCount: 0,
- shape: null,
- position: null,
- normal: null,
- color: null,
- distance: null,
-
- initialize : function() {
- try {
- this.color = new Flog.RayTracer.Color(0,0,0);
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Intersection [' + this.position + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Camera = Class.create();
-
-Flog.RayTracer.Camera.prototype = {
- position: null,
- lookAt: null,
- equator: null,
- up: null,
- screen: null,
-
- initialize : function(pos, lookAt, up) {
- try {
- this.position = pos;
- this.lookAt = lookAt;
- this.up = up;
- this.equator = lookAt.normalize().cross(this.up);
- this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
- } catch(e) { }
- },
-
- getRay: function(vx, vy){
- try {
- var pos = Flog.RayTracer.Vector.prototype.subtract(
- this.screen,
- Flog.RayTracer.Vector.prototype.subtract(
- Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
- Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
- )
- );
- pos.y = pos.y * -1;
- var dir = Flog.RayTracer.Vector.prototype.subtract(
- pos,
- this.position
- );
-
- var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
-
- } catch(e) { }
- return ray;
- },
-
- toString : function () {
- try {
- return 'Ray []';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Background = Class.create();
-
-Flog.RayTracer.Background.prototype = {
- color : null,
- ambience : 0.0,
-
- initialize : function(color, ambience) {
- try {
- this.color = color;
- this.ambience = ambience;
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Engine = Class.create();
-
-Flog.RayTracer.Engine.prototype = {
- canvas: null, /* 2d context we can render to */
-
- initialize: function(options){
- try {
- this.options = Object.extend({
- canvasHeight: 100,
- canvasWidth: 100,
- pixelWidth: 2,
- pixelHeight: 2,
- renderDiffuse: false,
- renderShadows: false,
- renderHighlights: false,
- renderReflections: false,
- rayDepth: 2
- }, options || {});
-
- this.options.canvasHeight /= this.options.pixelHeight;
- this.options.canvasWidth /= this.options.pixelWidth;
-
- } catch(e) { }
-
- /* TODO: dynamically include other scripts */
- },
-
- setPixel: function(x, y, color){
- try {
- var pxW, pxH;
- pxW = this.options.pixelWidth;
- pxH = this.options.pixelHeight;
-
- if (this.canvas) {
- this.canvas.fillStyle = color.toString();
- this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
- } else {
- if (x === y) {
- checkNumber += color.brightness();
- }
- // print(x * pxW, y * pxH, pxW, pxH);
- }
-
- } catch(e) { }
- },
-
- renderScene: function(scene, canvas){
- try {
- checkNumber = 0;
- /* Get canvas */
- if (canvas) {
- this.canvas = canvas.getContext("2d");
- } else {
- this.canvas = null;
- }
-
- var canvasHeight = this.options.canvasHeight;
- var canvasWidth = this.options.canvasWidth;
-
- for(var y=0; y < canvasHeight; y++){
- for(var x=0; x < canvasWidth; x++){
- try {
- var yp = y * 1.0 / canvasHeight * 2 - 1;
- var xp = x * 1.0 / canvasWidth * 2 - 1;
-
- var ray = scene.camera.getRay(xp, yp);
-
- var color = this.getPixelColor(ray, scene);
-
- this.setPixel(x, y, color);
-
- } catch(e) { }
- }
- }
- } catch(e) { }
- if (checkNumber !== 2321) {
- throw new Error("Scene rendered incorrectly");
- }
- },
-
- getPixelColor: function(ray, scene){
- try {
- var info = this.testIntersection(ray, scene, null);
- if(info.isHit){
- var color = this.rayTrace(info, ray, scene, 0);
- return color;
- }
- return scene.background.color;
- } catch(e) { }
- },
-
- testIntersection: function(ray, scene, exclude){
- try {
- var hits = 0;
- var best = new Flog.RayTracer.IntersectionInfo();
- best.distance = 2000;
-
- for(var i=0; i<scene.shapes.length; i++){
- try {
- var shape = scene.shapes[i];
-
- if(shape != exclude){
- var info = shape.intersect(ray);
- if(info.isHit && info.distance >= 0 && info.distance < best.distance){
- best = info;
- hits++;
- }
- }
-
- } catch(e) { }
- }
- best.hitCount = hits;
-
- } catch(e) { }
- return best;
- },
-
- getReflectionRay: function(P,N,V){
- try {
- var c1 = -N.dot(V);
- var R1 = Flog.RayTracer.Vector.prototype.add(
- Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
- V
- );
-
- } catch(e) { }
- return new Flog.RayTracer.Ray(P, R1);
- },
-
- rayTrace: function(info, ray, scene, depth){
- // Calc ambient
- try {
- var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
- var oldColor = color;
- var shininess = Math.pow(10, info.shape.material.gloss + 1);
-
- for(var i=0; i<scene.lights.length; i++){
- try {
- var light = scene.lights[i];
-
- // Calc diffuse lighting
- var v = Flog.RayTracer.Vector.prototype.subtract(
- light.position,
- info.position
- ).normalize();
-
- if(this.options.renderDiffuse){
- var L = v.dot(info.normal);
- if(L > 0.0){
- color = Flog.RayTracer.Color.prototype.add(
- color,
- Flog.RayTracer.Color.prototype.multiply(
- info.color,
- Flog.RayTracer.Color.prototype.multiplyScalar(
- light.color,
- L
- )
- )
- );
- }
- }
-
- } catch(e) { }
-
- try {
- // The greater the depth the more accurate the colours, but
- // this is exponentially (!) expensive
- if(depth <= this.options.rayDepth){
- // calculate reflection ray
- if(this.options.renderReflections && info.shape.material.reflection > 0)
- {
- var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
- var refl = this.testIntersection(reflectionRay, scene, info.shape);
-
- if (refl.isHit && refl.distance > 0){
- refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
- } else {
- refl.color = scene.background.color;
- }
-
- color = Flog.RayTracer.Color.prototype.blend(
- color,
- refl.color,
- info.shape.material.reflection
- );
- }
-
- // Refraction
- /* TODO */
- }
- } catch(e) { }
-
- /* Render shadows and highlights */
-
- var shadowInfo = new Flog.RayTracer.IntersectionInfo();
-
- if(this.options.renderShadows){
- var shadowRay = new Flog.RayTracer.Ray(info.position, v);
-
- shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
- if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
- var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
- var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
- color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
- }
- }
-
- try {
- // Phong specular highlights
- if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
- var Lv = Flog.RayTracer.Vector.prototype.subtract(
- info.shape.position,
- light.position
- ).normalize();
-
- var E = Flog.RayTracer.Vector.prototype.subtract(
- scene.camera.position,
- info.shape.position
- ).normalize();
-
- var H = Flog.RayTracer.Vector.prototype.subtract(
- E,
- Lv
- ).normalize();
-
- var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
- color = Flog.RayTracer.Color.prototype.add(
- Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
- color
- );
- }
- } catch(e) { }
- }
- color.limit();
-
- } catch(e) { }
- return color;
- }
-};
-
-
-function renderScene(){
- try {
- var scene = new Flog.RayTracer.Scene();
-
- scene.camera = new Flog.RayTracer.Camera(
- new Flog.RayTracer.Vector(0, 0, -15),
- new Flog.RayTracer.Vector(-0.2, 0, 5),
- new Flog.RayTracer.Vector(0, 1, 0)
- );
-
- scene.background = new Flog.RayTracer.Background(
- new Flog.RayTracer.Color(0.5, 0.5, 0.5),
- 0.4
- );
-
- var sphere = new Flog.RayTracer.Shape.Sphere(
- new Flog.RayTracer.Vector(-1.5, 1.5, 2),
- 1.5,
- new Flog.RayTracer.Material.Solid(
- new Flog.RayTracer.Color(0,0.5,0.5),
- 0.3,
- 0.0,
- 0.0,
- 2.0
- )
- );
-
- var sphere1 = new Flog.RayTracer.Shape.Sphere(
- new Flog.RayTracer.Vector(1, 0.25, 1),
- 0.5,
- new Flog.RayTracer.Material.Solid(
- new Flog.RayTracer.Color(0.9,0.9,0.9),
- 0.1,
- 0.0,
- 0.0,
- 1.5
- )
- );
-
- var plane = new Flog.RayTracer.Shape.Plane(
- new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
- 1.2,
- new Flog.RayTracer.Material.Chessboard(
- new Flog.RayTracer.Color(1,1,1),
- new Flog.RayTracer.Color(0,0,0),
- 0.2,
- 0.0,
- 1.0,
- 0.7
- )
- );
-
- scene.shapes.push(plane);
- scene.shapes.push(sphere);
- scene.shapes.push(sphere1);
-
- var light = new Flog.RayTracer.Light(
- new Flog.RayTracer.Vector(5, 10, -1),
- new Flog.RayTracer.Color(0.8, 0.8, 0.8)
- );
-
- var light1 = new Flog.RayTracer.Light(
- new Flog.RayTracer.Vector(-3, 5, -15),
- new Flog.RayTracer.Color(0.8, 0.8, 0.8),
- 100
- );
-
- scene.lights.push(light);
- scene.lights.push(light1);
-
- var imageWidth = 100; // $F('imageWidth');
- var imageHeight = 100; // $F('imageHeight');
- var pixelSize = "5,5".split(','); // $F('pixelSize').split(',');
- var renderDiffuse = true; // $F('renderDiffuse');
- var renderShadows = true; // $F('renderShadows');
- var renderHighlights = true; // $F('renderHighlights');
- var renderReflections = true; // $F('renderReflections');
- var rayDepth = 2;//$F('rayDepth');
-
- var raytracer = new Flog.RayTracer.Engine(
- {
- canvasWidth: imageWidth,
- canvasHeight: imageHeight,
- pixelWidth: pixelSize[0],
- pixelHeight: pixelSize[1],
- "renderDiffuse": renderDiffuse,
- "renderHighlights": renderHighlights,
- "renderShadows": renderShadows,
- "renderReflections": renderReflections,
- "rayDepth": rayDepth
- }
- );
-
- raytracer.renderScene(scene, null, 0);
- } catch(e) { }
-}
-
-for (var i = 0; i < 6; ++i)
- renderScene();
+++ /dev/null
-// The ray tracer code in this file is written by Adam Burmister. It
-// is available in its original form from:
-//
-// http://labs.flog.nz.co/raytracer/
-//
-// It has been modified slightly by Google to work as a standalone
-// benchmark, but the all the computational code remains
-// untouched. This file also contains a copy of parts of the Prototype
-// JavaScript framework which is used by the ray tracer.
-
-// Variable used to hold a number that can be used to verify that
-// the scene was ray traced correctly.
-var checkNumber;
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The following is a copy of parts of the Prototype JavaScript library:
-
-// Prototype JavaScript framework, version 1.5.0
-// (c) 2005-2007 Sam Stephenson
-//
-// Prototype is freely distributable under the terms of an MIT-style license.
-// For details, see the Prototype web site: http://prototype.conio.net/
-
-let __exceptionCounter = 0;
-function randomException() {
- __exceptionCounter++;
- if (__exceptionCounter % 500 === 0) {
- throw new Error("rando");
- }
-}
-noInline(randomException);
-
-var Class = {
- create: function() {
- return function() {
- try {
- this.initialize.apply(this, arguments);
- randomException();
- } catch(e) { }
- }
- }
-};
-
-
-Object.extend = function(destination, source) {
- for (var property in source) {
- try {
- destination[property] = source[property];
- randomException();
- } catch(e) { }
- }
- return destination;
-};
-
-
-// ------------------------------------------------------------------------
-// ------------------------------------------------------------------------
-
-// The rest of this file is the actual ray tracer written by Adam
-// Burmister. It's a concatenation of the following files:
-//
-// flog/color.js
-// flog/light.js
-// flog/vector.js
-// flog/ray.js
-// flog/scene.js
-// flog/material/basematerial.js
-// flog/material/solid.js
-// flog/material/chessboard.js
-// flog/shape/baseshape.js
-// flog/shape/sphere.js
-// flog/shape/plane.js
-// flog/intersectioninfo.js
-// flog/camera.js
-// flog/background.js
-// flog/engine.js
-
-
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Color = Class.create();
-
-Flog.RayTracer.Color.prototype = {
- red : 0.0,
- green : 0.0,
- blue : 0.0,
-
- initialize : function(r, g, b) {
- try {
- if(!r) r = 0.0;
- if(!g) g = 0.0;
- if(!b) b = 0.0;
-
- this.red = r;
- this.green = g;
- this.blue = b;
- randomException();
- } catch(e) { }
- },
-
- add : function(c1, c2){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red + c2.red;
- result.green = c1.green + c2.green;
- result.blue = c1.blue + c2.blue;
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- addScalar: function(c1, s){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red + s;
- result.green = c1.green + s;
- result.blue = c1.blue + s;
-
- result.limit();
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- subtract: function(c1, c2){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red - c2.red;
- result.green = c1.green - c2.green;
- result.blue = c1.blue - c2.blue;
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- multiply : function(c1, c2) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red * c2.red;
- result.green = c1.green * c2.green;
- result.blue = c1.blue * c2.blue;
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- multiplyScalar : function(c1, f) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red * f;
- result.green = c1.green * f;
- result.blue = c1.blue * f;
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- divideFactor : function(c1, f) {
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
-
- result.red = c1.red / f;
- result.green = c1.green / f;
- result.blue = c1.blue / f;
-
- randomException();
- } catch(e) { }
-
- return result;
- },
-
- limit: function(){
- try {
- this.red = (this.red > 0.0) ? ( (this.red > 1.0) ? 1.0 : this.red ) : 0.0;
- this.green = (this.green > 0.0) ? ( (this.green > 1.0) ? 1.0 : this.green ) : 0.0;
- this.blue = (this.blue > 0.0) ? ( (this.blue > 1.0) ? 1.0 : this.blue ) : 0.0;
-
- randomException();
- } catch(e) { }
- },
-
- distance : function(color) {
- try {
- var d = Math.abs(this.red - color.red) + Math.abs(this.green - color.green) + Math.abs(this.blue - color.blue);
- randomException();
- } catch(e) { }
- return d;
- },
-
- blend: function(c1, c2, w){
- try {
- var result = new Flog.RayTracer.Color(0,0,0);
- result = Flog.RayTracer.Color.prototype.add(
- Flog.RayTracer.Color.prototype.multiplyScalar(c1, 1 - w),
- Flog.RayTracer.Color.prototype.multiplyScalar(c2, w)
- );
- randomException();
- } catch(e) { }
- return result;
- },
-
- brightness : function() {
- try {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- randomException();
- } catch(e) { }
- return (r * 77 + g * 150 + b * 29) >> 8;
- },
-
- toString : function () {
- try {
- var r = Math.floor(this.red*255);
- var g = Math.floor(this.green*255);
- var b = Math.floor(this.blue*255);
- randomException();
- } catch(e) { }
-
- return "rgb("+ r +","+ g +","+ b +")";
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Light = Class.create();
-
-Flog.RayTracer.Light.prototype = {
- position: null,
- color: null,
- intensity: 10.0,
-
- initialize : function(pos, color, intensity) {
- try {
- this.position = pos;
- this.color = color;
- this.intensity = (intensity ? intensity : 10.0);
-
- randomException();
- } catch(e) { }
- },
-
- toString : function () {
- try {
- var result = 'Light [' + this.position.x + ',' + this.position.y + ',' + this.position.z + ']';
- randomException();
- } catch(e) { }
- return result;
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Vector = Class.create();
-
-Flog.RayTracer.Vector.prototype = {
- x : 0.0,
- y : 0.0,
- z : 0.0,
-
- initialize : function(x, y, z) {
- try {
- this.x = (x ? x : 0);
- this.y = (y ? y : 0);
- this.z = (z ? z : 0);
- randomException();
- } catch(e) { }
- },
-
- copy: function(vector){
- try {
- this.x = vector.x;
- this.y = vector.y;
- this.z = vector.z;
- randomException();
- } catch(e) { }
- },
-
- normalize : function() {
- try {
- var m = this.magnitude();
- var result = new Flog.RayTracer.Vector(this.x / m, this.y / m, this.z / m);
- randomException();
- } catch(e) { }
- return result;
- },
-
- magnitude : function() {
- try {
- return Math.sqrt((this.x * this.x) + (this.y * this.y) + (this.z * this.z));
- } catch(e) { }
- },
-
- cross : function(w) {
- try {
- return new Flog.RayTracer.Vector(
- -this.z * w.y + this.y * w.z,
- this.z * w.x - this.x * w.z,
- -this.y * w.x + this.x * w.y);
- } catch(e) { }
- },
-
- dot : function(w) {
- try {
- return this.x * w.x + this.y * w.y + this.z * w.z;
- } catch(e) { }
- },
-
- add : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(w.x + v.x, w.y + v.y, w.z + v.z);
- } catch(e) { }
- },
-
- subtract : function(v, w) {
- try {
- if(!w || !v) throw 'Vectors must be defined [' + v + ',' + w + ']';
- return new Flog.RayTracer.Vector(v.x - w.x, v.y - w.y, v.z - w.z);
- } catch(e) { }
- },
-
- multiplyVector : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(v.x * w.x, v.y * w.y, v.z * w.z);
- } catch(e) { }
- },
-
- multiplyScalar : function(v, w) {
- try {
- return new Flog.RayTracer.Vector(v.x * w, v.y * w, v.z * w);
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Vector [' + this.x + ',' + this.y + ',' + this.z + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Ray = Class.create();
-
-Flog.RayTracer.Ray.prototype = {
- position : null,
- direction : null,
- initialize : function(pos, dir) {
- try {
- this.position = pos;
- this.direction = dir;
- randomException();
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Ray [' + this.position + ',' + this.direction + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Scene = Class.create();
-
-Flog.RayTracer.Scene.prototype = {
- camera : null,
- shapes : [],
- lights : [],
- background : null,
-
- initialize : function() {
- try {
- this.camera = new Flog.RayTracer.Camera(
- new Flog.RayTracer.Vector(0,0,-5),
- new Flog.RayTracer.Vector(0,0,1),
- new Flog.RayTracer.Vector(0,1,0)
- );
- this.shapes = new Array();
- this.lights = new Array();
- this.background = new Flog.RayTracer.Background(new Flog.RayTracer.Color(0,0,0.5), 0.2);
-
- randomException();
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Material) == 'undefined') Flog.RayTracer.Material = {};
-
-Flog.RayTracer.Material.BaseMaterial = Class.create();
-
-Flog.RayTracer.Material.BaseMaterial.prototype = {
-
- gloss: 2.0, // [0...infinity] 0 = matt
- transparency: 0.0, // 0=opaque
- reflection: 0.0, // [0...infinity] 0 = no reflection
- refraction: 0.50,
- hasTexture: false,
-
- initialize : function() {
-
- },
-
- getColor: function(u, v){
-
- },
-
- wrapUp: function(t){
- try {
- t = t % 2.0;
- if(t < -1) t += 2.0;
- if(t >= 1) t -= 2.0;
- randomException();
- } catch(e) { }
- return t;
- },
-
- toString : function () {
- try {
- return 'Material [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Material.Solid = Class.create();
-
-Flog.RayTracer.Material.Solid.prototype = Object.extend(
- new Flog.RayTracer.Material.BaseMaterial(), {
- initialize : function(color, reflection, refraction, transparency, gloss) {
- try {
- this.color = color;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.hasTexture = false;
- randomException();
- } catch(e) { }
- },
-
- getColor: function(u, v){
- try {
- return this.color;
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'SolidMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
- }
- );
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Material.Chessboard = Class.create();
-
-Flog.RayTracer.Material.Chessboard.prototype = Object.extend(
- new Flog.RayTracer.Material.BaseMaterial(), {
- colorEven: null,
- colorOdd: null,
- density: 0.5,
-
- initialize : function(colorEven, colorOdd, reflection, transparency, gloss, density) {
- try {
- this.colorEven = colorEven;
- this.colorOdd = colorOdd;
- this.reflection = reflection;
- this.transparency = transparency;
- this.gloss = gloss;
- this.density = density;
- this.hasTexture = true;
- randomException();
- } catch(e) { }
- },
-
- getColor: function(u, v){
- try {
- var t = this.wrapUp(u * this.density) * this.wrapUp(v * this.density);
- randomException();
- } catch(e) { }
-
- if(t < 0.0)
- return this.colorEven;
- else
- return this.colorOdd;
- },
-
- toString : function () {
- try {
- return 'ChessMaterial [gloss=' + this.gloss + ', transparency=' + this.transparency + ', hasTexture=' + this.hasTexture +']';
- } catch(e) { }
- }
- }
-);
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
-
-Flog.RayTracer.Shape.Sphere = Class.create();
-
-Flog.RayTracer.Shape.Sphere.prototype = {
- initialize : function(pos, radius, material) {
- try {
- this.radius = radius;
- this.position = pos;
- this.material = material;
-
- randomException();
- } catch(e) { }
- },
-
- intersect: function(ray){
- try {
- var info = new Flog.RayTracer.IntersectionInfo();
- info.shape = this;
-
- var dst = Flog.RayTracer.Vector.prototype.subtract(ray.position, this.position);
-
- var B = dst.dot(ray.direction);
- var C = dst.dot(dst) - (this.radius * this.radius);
- var D = (B * B) - C;
-
- if(D > 0){ // intersection!
- info.isHit = true;
- info.distance = (-B) - Math.sqrt(D);
- info.position = Flog.RayTracer.Vector.prototype.add(
- ray.position,
- Flog.RayTracer.Vector.prototype.multiplyScalar(
- ray.direction,
- info.distance
- )
- );
- info.normal = Flog.RayTracer.Vector.prototype.subtract(
- info.position,
- this.position
- ).normalize();
-
- info.color = this.material.getColor(0,0);
- } else {
- info.isHit = false;
- }
-
- randomException();
- } catch(e) { }
- return info;
- },
-
- toString : function () {
- try {
- return 'Sphere [position=' + this.position + ', radius=' + this.radius + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-if(typeof(Flog.RayTracer.Shape) == 'undefined') Flog.RayTracer.Shape = {};
-
-Flog.RayTracer.Shape.Plane = Class.create();
-
-Flog.RayTracer.Shape.Plane.prototype = {
- d: 0.0,
-
- initialize : function(pos, d, material) {
- try {
- this.position = pos;
- this.d = d;
- this.material = material;
- randomException();
- } catch(e) { }
- },
-
- intersect: function(ray){
- try {
- var info = new Flog.RayTracer.IntersectionInfo();
-
- var Vd = this.position.dot(ray.direction);
- if(Vd == 0) return info; // no intersection
-
- var t = -(this.position.dot(ray.position) + this.d) / Vd;
- if(t <= 0) return info;
-
- info.shape = this;
- info.isHit = true;
- info.position = Flog.RayTracer.Vector.prototype.add(
- ray.position,
- Flog.RayTracer.Vector.prototype.multiplyScalar(
- ray.direction,
- t
- )
- );
- info.normal = this.position;
- info.distance = t;
-
- if(this.material.hasTexture){
- var vU = new Flog.RayTracer.Vector(this.position.y, this.position.z, -this.position.x);
- var vV = vU.cross(this.position);
- var u = info.position.dot(vU);
- var v = info.position.dot(vV);
- info.color = this.material.getColor(u,v);
- } else {
- info.color = this.material.getColor(0,0);
- }
-
- randomException();
- } catch(e) { }
- return info;
- },
-
- toString : function () {
- try {
- return 'Plane [' + this.position + ', d=' + this.d + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.IntersectionInfo = Class.create();
-
-Flog.RayTracer.IntersectionInfo.prototype = {
- isHit: false,
- hitCount: 0,
- shape: null,
- position: null,
- normal: null,
- color: null,
- distance: null,
-
- initialize : function() {
- try {
- this.color = new Flog.RayTracer.Color(0,0,0);
- randomException();
- } catch(e) { }
- },
-
- toString : function () {
- try {
- return 'Intersection [' + this.position + ']';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Camera = Class.create();
-
-Flog.RayTracer.Camera.prototype = {
- position: null,
- lookAt: null,
- equator: null,
- up: null,
- screen: null,
-
- initialize : function(pos, lookAt, up) {
- try {
- this.position = pos;
- this.lookAt = lookAt;
- this.up = up;
- this.equator = lookAt.normalize().cross(this.up);
- this.screen = Flog.RayTracer.Vector.prototype.add(this.position, this.lookAt);
- randomException();
- } catch(e) { }
- },
-
- getRay: function(vx, vy){
- try {
- var pos = Flog.RayTracer.Vector.prototype.subtract(
- this.screen,
- Flog.RayTracer.Vector.prototype.subtract(
- Flog.RayTracer.Vector.prototype.multiplyScalar(this.equator, vx),
- Flog.RayTracer.Vector.prototype.multiplyScalar(this.up, vy)
- )
- );
- pos.y = pos.y * -1;
- var dir = Flog.RayTracer.Vector.prototype.subtract(
- pos,
- this.position
- );
-
- var ray = new Flog.RayTracer.Ray(pos, dir.normalize());
-
- randomException();
- } catch(e) { }
- return ray;
- },
-
- toString : function () {
- try {
- return 'Ray []';
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Background = Class.create();
-
-Flog.RayTracer.Background.prototype = {
- color : null,
- ambience : 0.0,
-
- initialize : function(color, ambience) {
- try {
- this.color = color;
- this.ambience = ambience;
- randomException();
- } catch(e) { }
- }
-}
-/* Fake a Flog.* namespace */
-if(typeof(Flog) == 'undefined') var Flog = {};
-if(typeof(Flog.RayTracer) == 'undefined') Flog.RayTracer = {};
-
-Flog.RayTracer.Engine = Class.create();
-
-Flog.RayTracer.Engine.prototype = {
- canvas: null, /* 2d context we can render to */
-
- initialize: function(options){
- try {
- this.options = Object.extend({
- canvasHeight: 100,
- canvasWidth: 100,
- pixelWidth: 2,
- pixelHeight: 2,
- renderDiffuse: false,
- renderShadows: false,
- renderHighlights: false,
- renderReflections: false,
- rayDepth: 2
- }, options || {});
-
- this.options.canvasHeight /= this.options.pixelHeight;
- this.options.canvasWidth /= this.options.pixelWidth;
-
- randomException();
- } catch(e) { }
-
- /* TODO: dynamically include other scripts */
- },
-
- setPixel: function(x, y, color){
- try {
- var pxW, pxH;
- pxW = this.options.pixelWidth;
- pxH = this.options.pixelHeight;
-
- if (this.canvas) {
- this.canvas.fillStyle = color.toString();
- this.canvas.fillRect (x * pxW, y * pxH, pxW, pxH);
- } else {
- if (x === y) {
- checkNumber += color.brightness();
- }
- // print(x * pxW, y * pxH, pxW, pxH);
- }
-
- randomException();
- } catch(e) { }
- },
-
- renderScene: function(scene, canvas){
- try {
- checkNumber = 0;
- /* Get canvas */
- if (canvas) {
- this.canvas = canvas.getContext("2d");
- } else {
- this.canvas = null;
- }
-
- var canvasHeight = this.options.canvasHeight;
- var canvasWidth = this.options.canvasWidth;
-
- for(var y=0; y < canvasHeight; y++){
- for(var x=0; x < canvasWidth; x++){
- try {
- var yp = y * 1.0 / canvasHeight * 2 - 1;
- var xp = x * 1.0 / canvasWidth * 2 - 1;
-
- var ray = scene.camera.getRay(xp, yp);
-
- var color = this.getPixelColor(ray, scene);
-
- this.setPixel(x, y, color);
-
- randomException();
- } catch(e) { }
- }
- }
- } catch(e) { }
- if (checkNumber !== 2321) {
- throw new Error("Scene rendered incorrectly");
- }
- },
-
- getPixelColor: function(ray, scene){
- try {
- var info = this.testIntersection(ray, scene, null);
- if(info.isHit){
- var color = this.rayTrace(info, ray, scene, 0);
- return color;
- }
- return scene.background.color;
- } catch(e) { }
- },
-
- testIntersection: function(ray, scene, exclude){
- try {
- var hits = 0;
- var best = new Flog.RayTracer.IntersectionInfo();
- best.distance = 2000;
-
- for(var i=0; i<scene.shapes.length; i++){
- try {
- var shape = scene.shapes[i];
-
- if(shape != exclude){
- var info = shape.intersect(ray);
- if(info.isHit && info.distance >= 0 && info.distance < best.distance){
- best = info;
- hits++;
- }
- }
-
- randomException();
- } catch(e) { }
- }
- best.hitCount = hits;
-
- randomException();
- } catch(e) { }
- return best;
- },
-
- getReflectionRay: function(P,N,V){
- try {
- var c1 = -N.dot(V);
- var R1 = Flog.RayTracer.Vector.prototype.add(
- Flog.RayTracer.Vector.prototype.multiplyScalar(N, 2*c1),
- V
- );
-
- randomException();
- } catch(e) { }
- return new Flog.RayTracer.Ray(P, R1);
- },
-
- rayTrace: function(info, ray, scene, depth){
- // Calc ambient
- try {
- var color = Flog.RayTracer.Color.prototype.multiplyScalar(info.color, scene.background.ambience);
- var oldColor = color;
- var shininess = Math.pow(10, info.shape.material.gloss + 1);
-
- for(var i=0; i<scene.lights.length; i++){
- try {
- var light = scene.lights[i];
-
- // Calc diffuse lighting
- var v = Flog.RayTracer.Vector.prototype.subtract(
- light.position,
- info.position
- ).normalize();
-
- if(this.options.renderDiffuse){
- var L = v.dot(info.normal);
- if(L > 0.0){
- color = Flog.RayTracer.Color.prototype.add(
- color,
- Flog.RayTracer.Color.prototype.multiply(
- info.color,
- Flog.RayTracer.Color.prototype.multiplyScalar(
- light.color,
- L
- )
- )
- );
- }
- }
-
- randomException();
- } catch(e) { }
-
- try {
- // The greater the depth the more accurate the colours, but
- // this is exponentially (!) expensive
- if(depth <= this.options.rayDepth){
- // calculate reflection ray
- if(this.options.renderReflections && info.shape.material.reflection > 0)
- {
- var reflectionRay = this.getReflectionRay(info.position, info.normal, ray.direction);
- var refl = this.testIntersection(reflectionRay, scene, info.shape);
-
- if (refl.isHit && refl.distance > 0){
- refl.color = this.rayTrace(refl, reflectionRay, scene, depth + 1);
- } else {
- refl.color = scene.background.color;
- }
-
- color = Flog.RayTracer.Color.prototype.blend(
- color,
- refl.color,
- info.shape.material.reflection
- );
- }
-
- // Refraction
- /* TODO */
- }
- randomException();
- } catch(e) { }
-
- /* Render shadows and highlights */
-
- var shadowInfo = new Flog.RayTracer.IntersectionInfo();
-
- if(this.options.renderShadows){
- var shadowRay = new Flog.RayTracer.Ray(info.position, v);
-
- shadowInfo = this.testIntersection(shadowRay, scene, info.shape);
- if(shadowInfo.isHit && shadowInfo.shape != info.shape /*&& shadowInfo.shape.type != 'PLANE'*/){
- var vA = Flog.RayTracer.Color.prototype.multiplyScalar(color, 0.5);
- var dB = (0.5 * Math.pow(shadowInfo.shape.material.transparency, 0.5));
- color = Flog.RayTracer.Color.prototype.addScalar(vA,dB);
- }
- }
-
- try {
- // Phong specular highlights
- if(this.options.renderHighlights && !shadowInfo.isHit && info.shape.material.gloss > 0){
- var Lv = Flog.RayTracer.Vector.prototype.subtract(
- info.shape.position,
- light.position
- ).normalize();
-
- var E = Flog.RayTracer.Vector.prototype.subtract(
- scene.camera.position,
- info.shape.position
- ).normalize();
-
- var H = Flog.RayTracer.Vector.prototype.subtract(
- E,
- Lv
- ).normalize();
-
- var glossWeight = Math.pow(Math.max(info.normal.dot(H), 0), shininess);
- color = Flog.RayTracer.Color.prototype.add(
- Flog.RayTracer.Color.prototype.multiplyScalar(light.color, glossWeight),
- color
- );
- }
- randomException();
- } catch(e) { }
- }
- color.limit();
-
- randomException();
- } catch(e) { }
- return color;
- }
-};
-
-
-function renderScene(){
- try {
- var scene = new Flog.RayTracer.Scene();
-
- scene.camera = new Flog.RayTracer.Camera(
- new Flog.RayTracer.Vector(0, 0, -15),
- new Flog.RayTracer.Vector(-0.2, 0, 5),
- new Flog.RayTracer.Vector(0, 1, 0)
- );
-
- scene.background = new Flog.RayTracer.Background(
- new Flog.RayTracer.Color(0.5, 0.5, 0.5),
- 0.4
- );
-
- var sphere = new Flog.RayTracer.Shape.Sphere(
- new Flog.RayTracer.Vector(-1.5, 1.5, 2),
- 1.5,
- new Flog.RayTracer.Material.Solid(
- new Flog.RayTracer.Color(0,0.5,0.5),
- 0.3,
- 0.0,
- 0.0,
- 2.0
- )
- );
-
- var sphere1 = new Flog.RayTracer.Shape.Sphere(
- new Flog.RayTracer.Vector(1, 0.25, 1),
- 0.5,
- new Flog.RayTracer.Material.Solid(
- new Flog.RayTracer.Color(0.9,0.9,0.9),
- 0.1,
- 0.0,
- 0.0,
- 1.5
- )
- );
-
- var plane = new Flog.RayTracer.Shape.Plane(
- new Flog.RayTracer.Vector(0.1, 0.9, -0.5).normalize(),
- 1.2,
- new Flog.RayTracer.Material.Chessboard(
- new Flog.RayTracer.Color(1,1,1),
- new Flog.RayTracer.Color(0,0,0),
- 0.2,
- 0.0,
- 1.0,
- 0.7
- )
- );
-
- scene.shapes.push(plane);
- scene.shapes.push(sphere);
- scene.shapes.push(sphere1);
-
- var light = new Flog.RayTracer.Light(
- new Flog.RayTracer.Vector(5, 10, -1),
- new Flog.RayTracer.Color(0.8, 0.8, 0.8)
- );
-
- var light1 = new Flog.RayTracer.Light(
- new Flog.RayTracer.Vector(-3, 5, -15),
- new Flog.RayTracer.Color(0.8, 0.8, 0.8),
- 100
- );
-
- scene.lights.push(light);
- scene.lights.push(light1);
-
- var imageWidth = 100; // $F('imageWidth');
- var imageHeight = 100; // $F('imageHeight');
- var pixelSize = "5,5".split(','); // $F('pixelSize').split(',');
- var renderDiffuse = true; // $F('renderDiffuse');
- var renderShadows = true; // $F('renderShadows');
- var renderHighlights = true; // $F('renderHighlights');
- var renderReflections = true; // $F('renderReflections');
- var rayDepth = 2;//$F('rayDepth');
-
- var raytracer = new Flog.RayTracer.Engine(
- {
- canvasWidth: imageWidth,
- canvasHeight: imageHeight,
- pixelWidth: pixelSize[0],
- pixelHeight: pixelSize[1],
- "renderDiffuse": renderDiffuse,
- "renderHighlights": renderHighlights,
- "renderShadows": renderShadows,
- "renderReflections": renderReflections,
- "rayDepth": rayDepth
- }
- );
-
- raytracer.renderScene(scene, null, 0);
- randomException();
- } catch(e) { }
-}
-
-for (var i = 0; i < 6; ++i)
- renderScene();
+++ /dev/null
-JSRegress/v8-raytrace-with-empty-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/v8-raytrace-with-empty-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
+++ /dev/null
-JSRegress/v8-raytrace-with-try-catch
-
-On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
-
-
-PASS no exception thrown
-PASS successfullyParsed is true
-
-TEST COMPLETE
-
+++ /dev/null
-<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
-<html>
-<head>
-<script src="../../resources/js-test-pre.js"></script>
-</head>
-<body>
-<script src="../../resources/regress-pre.js"></script>
-<script src="script-tests/v8-raytrace-with-try-catch.js"></script>
-<script src="../../resources/regress-post.js"></script>
-<script src="../../resources/js-test-post.js"></script>
-</body>
-</html>
dfg/DFGFixupPhase.cpp
dfg/DFGFlushFormat.cpp
dfg/DFGFlushedAt.cpp
- dfg/DFGLiveCatchVariablePreservationPhase.cpp
dfg/DFGFrozenValue.cpp
dfg/DFGFunctionWhitelist.cpp
dfg/DFGGraph.cpp
+2015-09-17 Commit Queue <commit-queue@webkit.org>
+
+ Unreviewed, rolling out r189938, r189952, and r189956.
+ https://bugs.webkit.org/show_bug.cgi?id=149329
+
+ Broke Web Workers (Requested by ap on #webkit).
+
+ Reverted changesets:
+
+ "Implement try/catch in the DFG."
+ https://bugs.webkit.org/show_bug.cgi?id=147374
+ http://trac.webkit.org/changeset/189938
+
+ "CLoop build fix after r189938."
+ http://trac.webkit.org/changeset/189952
+
+ "add a regress test for richards with try/catch."
+ https://bugs.webkit.org/show_bug.cgi?id=149301
+ http://trac.webkit.org/changeset/189956
+
2015-09-17 Ryosuke Niwa <rniwa@webkit.org>
CLoop build fix after r189938.
<ClCompile Include="..\dfg\DFGFixupPhase.cpp" />
<ClCompile Include="..\dfg\DFGFlushedAt.cpp" />
<ClCompile Include="..\dfg\DFGFlushFormat.cpp" />
- <ClCompile Include="..\dfg\DFGLiveCatchVariablePreservationPhase.cpp" />
<ClCompile Include="..\dfg\DFGFrozenValue.cpp" />
<ClCompile Include="..\dfg\DFGFunctionWhitelist.cpp" />
<ClCompile Include="..\dfg\DFGGraph.cpp" />
<ClInclude Include="..\dfg\DFGFixupPhase.h" />
<ClInclude Include="..\dfg\DFGFlushedAt.h" />
<ClInclude Include="..\dfg\DFGFlushFormat.h" />
- <ClInclude Include="..\dfg\DFGLiveCatchVariablePreservationPhase.h" />
<ClInclude Include="..\dfg\DFGForAllKills.h" />
<ClInclude Include="..\dfg\DFGFPRInfo.h" />
<ClInclude Include="..\dfg\DFGFrozenValue.h" />
<ClCompile Include="..\dfg\DFGFlushFormat.cpp">
<Filter>dfg</Filter>
</ClCompile>
- <ClCompile Include="..\dfg\DFGLiveCatchVariablePreservationPhase.cpp">
- <Filter>dfg</Filter>
- </ClCompile>
<ClCompile Include="..\dfg\DFGFunctionWhitelist.cpp">
<Filter>dfg</Filter>
</ClCompile>
<ClInclude Include="..\dfg\DFGFlushFormat.h">
<Filter>dfg</Filter>
</ClInclude>
- <ClInclude Include="..\dfg\DFGLiveCatchVariablePreservationPhase.h">
- <Filter>dfg</Filter>
- </ClInclude>
<ClInclude Include="..\dfg\DFGFPRInfo.h">
<Filter>dfg</Filter>
</ClInclude>
7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 796465681B952FF0003059EE /* GetPutInfo.h */; settings = {ATTRIBUTES = (Private, ); }; };
797E07A91B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */; };
797E07AA1B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
- 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */; };
- 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */ = {isa = PBXBuildFile; fileRef = 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */; settings = {ATTRIBUTES = (Private, ); }; };
79EE0BFF1B4AFB85000385C9 /* VariableEnvironment.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */; };
79EE0C001B4AFB85000385C9 /* VariableEnvironment.h in Headers */ = {isa = PBXBuildFile; fileRef = 79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */; settings = {ATTRIBUTES = (Private, ); }; };
79F8FC1E1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */; };
796465681B952FF0003059EE /* GetPutInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = GetPutInfo.h; sourceTree = "<group>"; };
797E07A71B8FCFB9008400BA /* JSGlobalLexicalEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSGlobalLexicalEnvironment.cpp; sourceTree = "<group>"; };
797E07A81B8FCFB9008400BA /* JSGlobalLexicalEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSGlobalLexicalEnvironment.h; sourceTree = "<group>"; };
- 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGLiveCatchVariablePreservationPhase.cpp; path = dfg/DFGLiveCatchVariablePreservationPhase.cpp; sourceTree = "<group>"; };
- 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = DFGLiveCatchVariablePreservationPhase.h; path = dfg/DFGLiveCatchVariablePreservationPhase.h; sourceTree = "<group>"; };
79EE0BFD1B4AFB85000385C9 /* VariableEnvironment.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = VariableEnvironment.cpp; sourceTree = "<group>"; };
79EE0BFE1B4AFB85000385C9 /* VariableEnvironment.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = VariableEnvironment.h; sourceTree = "<group>"; };
79F8FC1C1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DFGMaximalFlushInsertionPhase.cpp; path = dfg/DFGMaximalFlushInsertionPhase.cpp; sourceTree = "<group>"; };
0F9D339517FFC4E60073C2BC /* DFGFlushedAt.h */,
A7D89CE817A0B8CC00773AD8 /* DFGFlushFormat.cpp */,
A7D89CE917A0B8CC00773AD8 /* DFGFlushFormat.h */,
- 79C4B15B1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp */,
- 79C4B15C1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h */,
0F2DD8101AB3D8BE00BBB8E8 /* DFGForAllKills.h */,
0F69CC86193AC60A0045759E /* DFGFrozenValue.cpp */,
0F69CC87193AC60A0045759E /* DFGFrozenValue.h */,
A1A009C11831A26E00CF8711 /* ARM64Assembler.h in Headers */,
0F898F321B27689F0083A33C /* DFGIntegerRangeOptimizationPhase.h in Headers */,
86D3B2C410156BDE002865E7 /* ARMAssembler.h in Headers */,
- 79C4B15E1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.h in Headers */,
79F8FC1F1B9FED0F00CA66AB /* DFGMaximalFlushInsertionPhase.h in Headers */,
99F1A7011B98FBEC00463B26 /* InspectorFrontendRouter.h in Headers */,
7964656A1B952FF0003059EE /* GetPutInfo.h in Headers */,
A1587D711B4DC14100D69849 /* IntlDateTimeFormatPrototype.cpp in Sources */,
0F2B670A17B6B5AB00A7AE3F /* TypedArrayType.cpp in Sources */,
52C952B919A28A1C0069B386 /* TypeProfiler.cpp in Sources */,
- 79C4B15D1BA2158F00FD592E /* DFGLiveCatchVariablePreservationPhase.cpp in Sources */,
0FF4274A158EBE91004CB9FF /* udis86.c in Sources */,
0FF42740158EBE8B004CB9FF /* udis86_decode.c in Sources */,
0FF42743158EBE91004CB9FF /* udis86_input.c in Sources */,
HandlerInfo* CodeBlock::handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler requiredHandler)
{
RELEASE_ASSERT(bytecodeOffset < instructions().size());
- return handlerForIndex(bytecodeOffset, requiredHandler);
-}
-HandlerInfo* CodeBlock::handlerForIndex(unsigned index, RequiredHandler requiredHandler)
-{
if (!m_rareData)
return 0;
// Handlers are ordered innermost first, so the first handler we encounter
// that contains the source address is the correct handler to use.
- // This index used is either the BytecodeOffset or a CallSiteIndex.
- if (handler.start <= index && handler.end > index)
+ if (handler.start <= bytecodeOffset && handler.end > bytecodeOffset)
return &handler;
}
AnyHandler
};
HandlerInfo* handlerForBytecodeOffset(unsigned bytecodeOffset, RequiredHandler = RequiredHandler::AnyHandler);
- HandlerInfo* handlerForIndex(unsigned, RequiredHandler = RequiredHandler::AnyHandler);
unsigned lineNumberForBytecodeOffset(unsigned bytecodeOffset);
unsigned columnNumberForBytecodeOffset(unsigned bytecodeOffset);
void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
EvalCodeCache m_evalCodeCache;
};
- void clearExceptionHandlers()
- {
- if (m_rareData)
- m_rareData->m_exceptionHandlers.clear();
- }
-
- void appendExceptionHandler(const HandlerInfo& handler)
- {
- createRareDataIfNecessary(); // We may be handling the exception of an inlined call frame.
- m_rareData->m_exceptionHandlers.append(handler);
- }
-
protected:
virtual void visitWeakReferences(SlotVisitor&) override;
virtual void finalizeUnconditionally() override;
if (!codeBlock->numberOfJumpTargets())
return;
- for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;) {
+ for (unsigned i = codeBlock->numberOfExceptionHandlers(); i--;)
out.append(codeBlock->exceptionHandler(i).target);
- out.append(codeBlock->exceptionHandler(i).start);
- out.append(codeBlock->exceptionHandler(i).end);
- }
-
+
Interpreter* interpreter = codeBlock->vm()->interpreter;
Instruction* instructionsBegin = codeBlock->instructions().begin();
unsigned instructionCount = codeBlock->instructions().size();
m_currentBlock->variablesAtTail.local(local) = node;
return node;
}
+
Node* setLocal(const CodeOrigin& semanticOrigin, VirtualRegister operand, Node* value, SetMode setMode = NormalSet)
{
CodeOrigin oldSemanticOrigin = m_currentSemanticOrigin;
flushForTerminal();
addToGraph(Unreachable);
LAST_OPCODE(op_throw_static_error);
-
- case op_catch:
- m_graph.m_hasExceptionHandlers = true;
- NEXT_OPCODE(op_catch);
case op_call:
handleCall(currentInstruction, Call, CodeForCall);
case op_new_arrow_func_exp:
case op_create_lexical_environment:
case op_get_parent_scope:
- case op_catch:
return CanCompileAndInline;
case op_put_to_scope: {
return CallSiteIndex(index);
}
-CallSiteIndex CommonData::lastCallSite() const
-{
- ASSERT(codeOrigins.size());
- return CallSiteIndex(codeOrigins.size() - 1);
-}
-
void CommonData::shrinkToFit()
{
codeOrigins.shrinkToFit();
void notifyCompilingStructureTransition(Plan&, CodeBlock*, Node*);
CallSiteIndex addCodeOrigin(CodeOrigin);
- CallSiteIndex lastCallSite() const;
void shrinkToFit();
PlanStage m_planStage { PlanStage::Initial };
RefCountState m_refCountState;
bool m_hasDebuggerEnabled;
- bool m_hasExceptionHandlers { false };
private:
void handleSuccessor(Vector<BasicBlock*, 16>& worklist, BasicBlock*, BasicBlock* successor);
failureJumps.link(this);
else
info.m_replacementDestination = label();
-
- if (exit.m_willArriveAtOSRExitFromGenericUnwind) {
- // We are acting as a defacto op_catch because we arrive here from genericUnwind().
- // So, we must restore our call frame and stack pointer.
- loadPtr(vm()->addressOfCallFrameForCatch(), GPRInfo::callFrameRegister);
- addPtr(TrustedImm32(graph().stackPointerOffset() * sizeof(Register)), GPRInfo::callFrameRegister, stackPointerRegister);
- restoreCalleeSavesFromVMCalleeSavesBuffer();
- } else if (exit.m_isExceptionHandler) {
- ASSERT(!exit.m_willArriveAtOSRExitFromGenericUnwind);
- copyCalleeSavesToVMCalleeSavesBuffer();
- }
-
jitAssertHasValidCallFrame();
store32(TrustedImm32(i), &vm()->osrExitIndex);
exit.setPatchableCodeOffset(patchableJump());
}
} else
ASSERT(!m_exitSiteLabels.size());
-
+
m_jitCode->common.compilation = m_graph.compilation();
- // Link new DFG exception handlers and remove baseline JIT handlers.
- m_codeBlock->clearExceptionHandlers();
- for (unsigned i = 0; i < m_exceptionHandlerOSRExitCallSites.size(); i++) {
- OSRExitCompilationInfo& info = m_exceptionHandlerOSRExitCallSites[i].exitInfo;
- if (info.m_replacementDestination.isSet()) {
- // If this is is *not* set, it means that we already jumped to the OSR exit in pure generated control flow.
- // i.e, we explicitly emitted an exceptionCheck that we know will be caught in this machine frame.
- // If this *is set*, it means we will be landing at this code location from genericUnwind from an
- // exception thrown in a child call frame.
- CodeLocationLabel catchLabel = linkBuffer.locationOf(info.m_replacementDestination);
- HandlerInfo newExceptionHandler = m_exceptionHandlerOSRExitCallSites[i].baselineExceptionHandler;
- CallSiteIndex callSite = m_exceptionHandlerOSRExitCallSites[i].callSiteIndex;
- newExceptionHandler.start = callSite.bits();
- newExceptionHandler.end = callSite.bits() + 1;
- newExceptionHandler.nativeCode = catchLabel;
- m_codeBlock->appendExceptionHandler(newExceptionHandler);
- }
- }
}
void JITCompiler::compile()
link(*linkBuffer);
m_speculative->linkOSREntries(*linkBuffer);
-
+
m_jitCode->shrinkToFit();
codeBlock()->shrinkToFit(CodeBlock::LateShrink);
entry->m_reshufflings.shrinkToFit();
}
-void JITCompiler::appendExceptionHandlingOSRExit(unsigned eventStreamIndex, CodeOrigin opCatchOrigin, HandlerInfo* exceptionHandler, CallSiteIndex callSite, MacroAssembler::JumpList jumpsToFail)
-{
- OSRExit exit(Uncountable, JSValueRegs(), graph().methodOfGettingAValueProfileFor(nullptr), m_speculative.get(), eventStreamIndex);
- exit.m_willArriveAtOSRExitFromGenericUnwind = jumpsToFail.empty(); // If jumps are empty, we're going to jump here from genericUnwind from a child call frame.
- exit.m_isExceptionHandler = true;
- exit.m_codeOrigin = opCatchOrigin;
- OSRExitCompilationInfo& exitInfo = appendExitInfo(jumpsToFail);
- jitCode()->appendOSRExit(exit);
- m_exceptionHandlerOSRExitCallSites.append(ExceptionHandlingOSRExitInfo { exitInfo, *exceptionHandler, callSite });
-}
-
-bool JITCompiler::willCatchExceptionInMachineFrame(CodeOrigin codeOrigin, CodeOrigin& opCatchOriginOut, HandlerInfo*& catchHandlerOut)
-{
- unsigned bytecodeIndexToCheck = codeOrigin.bytecodeIndex;
- while (1) {
- InlineCallFrame* inlineCallFrame = codeOrigin.inlineCallFrame;
- CodeBlock* codeBlock = m_graph.baselineCodeBlockFor(inlineCallFrame);
- if (HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeIndexToCheck)) {
- opCatchOriginOut = CodeOrigin(handler->target, inlineCallFrame);
- catchHandlerOut = handler;
- return true;
- }
-
- if (!inlineCallFrame)
- return false;
-
- bytecodeIndexToCheck = inlineCallFrame->caller.bytecodeIndex;
- codeOrigin = codeOrigin.inlineCallFrame->caller;
- }
-
- RELEASE_ASSERT_NOT_REACHED();
-}
-
-void JITCompiler::exceptionCheck()
-{
- // It's important that we use origin.forExit here. Consider if we hoist string
- // addition outside a loop, and that we exit at the point of that concatenation
- // from an out of memory exception.
- // If the original loop had a try/catch around string concatenation, if we "catch"
- // that exception inside the loop, then the loops induction variable will be undefined
- // in the OSR exit value recovery. It's more defensible for the string concatenation,
- // then, to not be caught by the for loops' try/catch.
- // Here is the program I'm speaking about:
- //
- // >>>> lets presume "c = a + b" gets hoisted here.
- // for (var i = 0; i < length; i++) {
- // try {
- // c = a + b
- // } catch(e) {
- // If we threw an out of memory error, and we cought the exception
- // right here, then "i" would almost certainly be undefined, which
- // would make no sense.
- // ...
- // }
- // }
- CodeOrigin opCatchOrigin;
- HandlerInfo* exceptionHandler;
- bool willCatchException = willCatchExceptionInMachineFrame(m_speculative->m_currentNode->origin.forExit, opCatchOrigin, exceptionHandler);
- if (willCatchException) {
- unsigned streamIndex = m_speculative->m_outOfLineStreamIndex != UINT_MAX ? m_speculative->m_outOfLineStreamIndex : m_speculative->m_stream->size();
- MacroAssembler::Jump hadException = emitNonPatchableExceptionCheck();
- // We assume here that this is called after callOpeartion()/appendCall() is called.
- appendExceptionHandlingOSRExit(streamIndex, opCatchOrigin, exceptionHandler, m_jitCode->common.lastCallSite(), hadException);
- } else
- m_exceptionChecks.append(emitExceptionCheck());
-}
-
-CallSiteIndex JITCompiler::recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(const CodeOrigin& callSiteCodeOrigin, unsigned eventStreamIndex)
-{
- CodeOrigin opCatchOrigin;
- HandlerInfo* exceptionHandler;
- bool willCatchException = willCatchExceptionInMachineFrame(callSiteCodeOrigin, opCatchOrigin, exceptionHandler);
- CallSiteIndex callSite = addCallSite(callSiteCodeOrigin);
- if (willCatchException)
- appendExceptionHandlingOSRExit(eventStreamIndex, opCatchOrigin, exceptionHandler, callSite);
- return callSite;
-}
-
} } // namespace JSC::DFG
#endif // ENABLE(DFG_JIT)
#include "DFGRegisterBank.h"
#include "FPRInfo.h"
#include "GPRInfo.h"
-#include "HandlerInfo.h"
#include "JITCode.h"
#include "JITInlineCacheGenerator.h"
#include "LinkBuffer.h"
void emitStoreCodeOrigin(CodeOrigin codeOrigin)
{
CallSiteIndex callSite = addCallSite(codeOrigin);
- emitStoreCallSiteIndex(callSite);
- }
-
- void emitStoreCallSiteIndex(CallSiteIndex callSite)
- {
store32(TrustedImm32(callSite.bits()), tagFor(static_cast<VirtualRegister>(JSStack::ArgumentCount)));
}
return functionCall;
}
- void exceptionCheck();
+ void exceptionCheck()
+ {
+ m_exceptionChecks.append(emitExceptionCheck());
+ }
void exceptionCheckWithCallFrameRollback()
{
Vector<Label>& blockHeads() { return m_blockHeads; }
- CallSiteIndex recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(const CodeOrigin&, unsigned eventStreamIndex);
-
private:
friend class OSRExitJumpPlaceholder;
void compileExceptionHandlers();
void linkOSRExits();
void disassemble(LinkBuffer&);
-
- bool willCatchExceptionInMachineFrame(CodeOrigin, CodeOrigin& opCatchOriginOut, HandlerInfo*& catchHandlerOut);
- void appendExceptionHandlingOSRExit(unsigned eventStreamIndex, CodeOrigin, HandlerInfo* exceptionHandler, CallSiteIndex, MacroAssembler::JumpList jumpsToFail = MacroAssembler::JumpList());
-
+
// The dataflow graph currently being generated.
Graph& m_graph;
SegmentedVector<OSRExitCompilationInfo, 4> m_exitCompilationInfo;
Vector<Vector<Label>> m_exitSiteLabels;
- struct ExceptionHandlingOSRExitInfo {
- OSRExitCompilationInfo& exitInfo;
- HandlerInfo baselineExceptionHandler;
- CallSiteIndex callSiteIndex;
- };
- Vector<ExceptionHandlingOSRExitInfo> m_exceptionHandlerOSRExitCallSites;
-
Call m_callArityFixup;
Label m_arityCheck;
std::unique_ptr<SpeculativeJIT> m_speculative;
+++ /dev/null
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "config.h"
-#include "DFGLiveCatchVariablePreservationPhase.h"
-
-#if ENABLE(DFG_JIT)
-
-#include "DFGBasicBlockInlines.h"
-#include "DFGGraph.h"
-#include "DFGInsertionSet.h"
-#include "DFGPhase.h"
-#include "FullBytecodeLiveness.h"
-#include "JSCInlines.h"
-
-namespace JSC { namespace DFG {
-
-class FlushLiveCatchVariablesInsertionPhase : public Phase {
-public:
- FlushLiveCatchVariablesInsertionPhase(Graph& graph)
- : Phase(graph, "live catch variable preservation phase")
- {
- }
-
- bool run()
- {
- if (!m_graph.m_hasExceptionHandlers)
- return true;
-
- DFG_ASSERT(m_graph, nullptr, m_graph.m_form == LoadStore);
-
- m_currentBlockLiveness.resize(m_graph.block(0)->variablesAtTail.numberOfLocals());
-
- InsertionSet insertionSet(m_graph);
- for (BasicBlock* block : m_graph.blocksInNaturalOrder()) {
- handleBlock(block, insertionSet);
- insertionSet.execute(block);
- }
-
- return true;
- }
-
- bool willCatchException(CodeOrigin origin)
- {
- unsigned bytecodeIndexToCheck = origin.bytecodeIndex;
- m_currentBlockLiveness.clearAll();
-
- while (1) {
- InlineCallFrame* inlineCallFrame = origin.inlineCallFrame;
- CodeBlock* codeBlock = m_graph.baselineCodeBlockFor(inlineCallFrame);
- if (HandlerInfo* handler = codeBlock->handlerForBytecodeOffset(bytecodeIndexToCheck)) {
- unsigned catchBytecodeIndex = handler->target;
- m_graph.forAllLocalsLiveInBytecode(CodeOrigin(catchBytecodeIndex, inlineCallFrame), [&] (VirtualRegister operand) {
- m_currentBlockLiveness.set(operand.toLocal(), true);
- });
- return true;
- }
-
- if (!inlineCallFrame)
- return false;
-
- bytecodeIndexToCheck = inlineCallFrame->caller.bytecodeIndex;
- origin = inlineCallFrame->caller;
- }
- }
-
- void handleBlock(BasicBlock* block, InsertionSet& insertionSet)
- {
- // Because precise jump targets ensures that the start of a "try" block is its
- // own basic block, we will never have two "try" statements in the same DFG
- // basic block. Therefore, checking the first node in the block is sufficient
- // to checking if we're in a try block.
- if (!willCatchException(block->at(0)->origin.semantic))
- return;
-
- Operands<VariableAccessData*> currentBlockAccessData(block->variablesAtTail.numberOfArguments(), block->variablesAtTail.numberOfLocals(), nullptr);
- HashSet<InlineCallFrame*> seenInlineCallFrames;
-
- {
- for (unsigned i = 0; i < block->size(); i++) {
- Node* node = block->at(i);
- bool isPrimordialSetArgument = node->op() == SetArgument && node->local().isArgument() && node == m_graph.m_arguments[node->local().toArgument()];
- InlineCallFrame* inlineCallFrame = node->origin.semantic.inlineCallFrame;
- if (inlineCallFrame)
- seenInlineCallFrames.add(inlineCallFrame);
-
- if (node->op() == SetLocal || (node->op() == SetArgument && !isPrimordialSetArgument)) {
- VirtualRegister operand = node->local();
-
- int stackOffset = inlineCallFrame ? inlineCallFrame->stackOffset : 0;
- if ((operand.isLocal() && m_currentBlockLiveness.get(operand.toLocal()))
- || (operand.offset() == stackOffset + CallFrame::thisArgumentOffset())) {
-
- VariableAccessData* flushAccessData = currentBlockAccessData.operand(operand);
- if (!flushAccessData)
- flushAccessData = newVariableAccessData(operand);
-
- insertionSet.insertNode(i, SpecNone,
- Flush, node->origin, OpInfo(flushAccessData));
- }
- }
-
- if (node->hasVariableAccessData(m_graph))
- currentBlockAccessData.operand(node->local()) = node->variableAccessData();
- }
- }
-
- // Flush everything at the end of the block.
- // FIXME: I think this will only be necessary if we have any successor
- // blocks who aren't inside this "try" statement. If all our successor's
- // are in this try statement, they will have Flushes for any live "catch"
- // variables.
- {
- NodeOrigin origin = block->at(block->size() - 1)->origin;
- auto insertFlushAtEnd = [&] (VirtualRegister operand, bool alwaysFlush) {
- if ((operand.isLocal() && m_currentBlockLiveness.get(operand.toLocal()))
- || operand.isArgument()
- || alwaysFlush) {
- VariableAccessData* accessData = currentBlockAccessData.operand(operand);
- if (!accessData)
- accessData = newVariableAccessData(operand);
-
- currentBlockAccessData.operand(operand) = accessData;
-
- insertionSet.insertNode(block->size(), SpecNone,
- Flush, origin, OpInfo(accessData));
- }
- };
- for (unsigned local = 0; local < block->variablesAtTail.numberOfLocals(); local++)
- insertFlushAtEnd(virtualRegisterForLocal(local), false);
- for (InlineCallFrame* inlineCallFrame : seenInlineCallFrames)
- insertFlushAtEnd(VirtualRegister(inlineCallFrame->stackOffset + CallFrame::thisArgumentOffset()), true);
- insertFlushAtEnd(VirtualRegister(CallFrame::thisArgumentOffset()), true);
- }
- }
-
- VariableAccessData* newVariableAccessData(VirtualRegister operand)
- {
- ASSERT(!operand.isConstant());
-
- m_graph.m_variableAccessData.append(VariableAccessData(operand));
- return &m_graph.m_variableAccessData.last();
- }
-
- FastBitVector m_currentBlockLiveness;
-};
-
-bool performLiveCatchVariablePreservationPhase(Graph& graph)
-{
- SamplingRegion samplingRegion("DFG Live Catch Variables Preservation Phase");
- return runPhase<FlushLiveCatchVariablesInsertionPhase>(graph);
-}
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
+++ /dev/null
-/*
- * Copyright (C) 2015 Apple Inc. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
- * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
- * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
- * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef DFGLiveCatchVariablePreservationPhase_h
-#define DFGLiveCatchVariablePreservationPhase_h
-
-#if ENABLE(DFG_JIT)
-
-namespace JSC { namespace DFG {
-
-class Graph;
-
-// This phase ensures that we maintain liveness for locals
-// that are live in the "catch" block. Because a "catch"
-// block will not be in the control flow graph, we need to ensure
-// anything live inside the "catch" block in bytecode will maintain
-// liveness inside the "try" block for an OSR exit from the "try"
-// block into the "catch" block in the case of an exception being thrown.
-//
-// The mechanism currently used to demonstrate liveness to OSR exit
-// is ensuring all variables live in a "catch" are flushed to the
-// stack inside the "try" block.
-
-bool performLiveCatchVariablePreservationPhase(Graph&);
-
-} } // namespace JSC::DFG
-
-#endif // ENABLE(DFG_JIT)
-
-#endif // DFGLiveCatchVariablePreservationPhase_h
#include "AssemblyHelpers.h"
#include "DFGGraph.h"
-#include "DFGMayExit.h"
#include "DFGSpeculativeJIT.h"
#include "JSCInlines.h"
, m_patchableCodeOffset(0)
, m_recoveryIndex(recoveryIndex)
, m_streamIndex(streamIndex)
- , m_willArriveAtOSRExitFromGenericUnwind(false)
- , m_isExceptionHandler(false)
{
- bool canExit = jit->m_origin.exitOK;
- if (!canExit && jit->m_currentNode) {
- ExitMode exitMode = mayExit(jit->m_jit.graph(), jit->m_currentNode);
- canExit = exitMode == ExitMode::Exits || exitMode == ExitMode::ExitsForExceptions;
- }
- DFG_ASSERT(jit->m_jit.graph(), jit->m_currentNode, canExit);
+ DFG_ASSERT(jit->m_jit.graph(), jit->m_currentNode, jit->m_origin.exitOK);
}
void OSRExit::setPatchableCodeOffset(MacroAssembler::PatchableJump check)
unsigned m_patchableCodeOffset;
unsigned m_recoveryIndex;
-
+
void setPatchableCodeOffset(MacroAssembler::PatchableJump);
MacroAssembler::Jump getPatchableCodeOffsetAsJump() const;
CodeLocationJump codeLocationForRepatch(CodeBlock*) const;
void correctJump(LinkBuffer&);
unsigned m_streamIndex;
-
- bool m_willArriveAtOSRExitFromGenericUnwind : 1;
- bool m_isExceptionHandler : 1;
void considerAddingAsFrequentExitSite(CodeBlock* profiledCodeBlock)
{
SamplingRegion samplingRegion("DFG OSR Exit Compilation");
CodeBlock* codeBlock = exec->codeBlock();
+
ASSERT(codeBlock);
ASSERT(codeBlock->jitType() == JITCode::DFGJIT);
-
+
VM* vm = &exec->vm();
// It's sort of preferable that we don't GC while in here. Anyways, doing so wouldn't
uint32_t exitIndex = vm->osrExitIndex;
OSRExit& exit = codeBlock->jitCode()->dfg()->osrExit[exitIndex];
- if (vm->callFrameForCatch)
- ASSERT(exit.m_willArriveAtOSRExitFromGenericUnwind);
- if (exit.m_isExceptionHandler)
- ASSERT(!!vm->exception());
-
-
prepareCodeOriginForOSRExit(exec, exit.m_codeOrigin);
// Compute the value recoveries.
exit.m_kind, exit.m_kind == UncountableInvalidation);
jit.add64(CCallHelpers::TrustedImm32(1), CCallHelpers::AbsoluteAddress(profilerExit->counterAddress()));
}
-
+
exitCompiler.compileExit(exit, operands, recovery);
LinkBuffer patchBuffer(*vm, jit, codeBlock);
reifyInlinedCallFrames(m_jit, exit);
// And finish.
- adjustAndJumpToTarget(m_jit, exit, exit.m_isExceptionHandler);
+ adjustAndJumpToTarget(m_jit, exit);
}
} } // namespace JSC::DFG
break;
}
}
-
+
// Need to ensure that the stack pointer accounts for the worst-case stack usage at exit. This
// could toast some stack that the DFG used. We need to do it before storing to stack offsets
// used by baseline.
reifyInlinedCallFrames(m_jit, exit);
// And finish.
- adjustAndJumpToTarget(m_jit, exit, exit.m_isExceptionHandler);
+ adjustAndJumpToTarget(m_jit, exit);
}
} } // namespace JSC::DFG
}
#endif // ENABLE(GGC)
-void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit, bool isExitingToOpCatch)
+void adjustAndJumpToTarget(CCallHelpers& jit, const OSRExitBase& exit)
{
#if ENABLE(GGC)
jit.move(AssemblyHelpers::TrustedImmPtr(jit.codeBlock()->ownerExecutable()), GPRInfo::argumentGPR1);
void* jumpTarget = baselineCodeBlock->jitCode()->executableAddressAtOffset(mapping->m_machineCodeOffset);
jit.addPtr(AssemblyHelpers::TrustedImm32(JIT::stackPointerOffsetFor(baselineCodeBlock) * sizeof(Register)), GPRInfo::callFrameRegister, AssemblyHelpers::stackPointerRegister);
- if (isExitingToOpCatch) {
- // Since we're jumping to op_catch, we need to set callFrameForCatch.
- jit.storePtr(GPRInfo::callFrameRegister, jit.vm()->addressOfCallFrameForCatch());
- }
jit.move(AssemblyHelpers::TrustedImmPtr(jumpTarget), GPRInfo::regT2);
jit.jump(GPRInfo::regT2);
void handleExitCounts(CCallHelpers&, const OSRExitBase&);
void reifyInlinedCallFrames(CCallHelpers&, const OSRExitBase&);
-void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&, bool isExitingToOpCatch);
+void adjustAndJumpToTarget(CCallHelpers&, const OSRExitBase&);
} } // namespace JSC::DFG
#include "DFGInvalidationPointInjectionPhase.h"
#include "DFGJITCompiler.h"
#include "DFGLICMPhase.h"
-#include "DFGLiveCatchVariablePreservationPhase.h"
#include "DFGLivenessAnalysisPhase.h"
#include "DFGLoopPreHeaderCreationPhase.h"
#include "DFGMaximalFlushInsertionPhase.h"
dfg.dump();
}
- performLiveCatchVariablePreservationPhase(dfg);
-
if (Options::enableMaximalFlushInsertionPhase())
performMaximalFlushInsertion(dfg);
public:
SlowPathGenerator(SpeculativeJIT* jit)
: m_currentNode(jit->m_currentNode)
- , m_streamIndex(jit->m_stream->size())
- , m_origin(jit->m_origin)
{
}
virtual ~SlowPathGenerator() { }
{
m_label = jit->m_jit.label();
jit->m_currentNode = m_currentNode;
- jit->m_outOfLineStreamIndex = m_streamIndex;
- jit->m_origin = m_origin;
generateInternal(jit);
- jit->m_outOfLineStreamIndex = UINT_MAX;
if (!ASSERT_DISABLED)
jit->m_jit.abortWithReason(DFGSlowPathGeneratorFellThrough);
}
virtual void generateInternal(SpeculativeJIT*) = 0;
MacroAssembler::Label m_label;
Node* m_currentNode;
- unsigned m_streamIndex;
- NodeOrigin m_origin;
};
template<typename JumpType>
Vector<std::unique_ptr<SlowPathGenerator>, 8> m_slowPathGenerators;
Vector<SilentRegisterSavePlan> m_plans;
- unsigned m_outOfLineStreamIndex { UINT_MAX };
};
basePayloadGPR = resultPayloadGPR;
}
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
JITGetByIdGenerator gen(
- m_jit.codeBlock(), codeOrigin, callSite, usedRegisters(),
+ m_jit.codeBlock(), codeOrigin, m_jit.addCallSite(codeOrigin), usedRegisters(),
JSValueRegs(baseTagGPROrNone, basePayloadGPR),
JSValueRegs(resultTagGPR, resultPayloadGPR), spillMode);
void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg basePayloadGPR, GPRReg valueTagGPR, GPRReg valuePayloadGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
{
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
JITPutByIdGenerator gen(
- m_jit.codeBlock(), codeOrigin, callSite, usedRegisters(),
+ m_jit.codeBlock(), codeOrigin, m_jit.addCallSite(codeOrigin), usedRegisters(),
JSValueRegs::payloadOnly(basePayloadGPR), JSValueRegs(valueTagGPR, valuePayloadGPR),
scratchGPR, spillMode, m_jit.ecmaModeFor(codeOrigin), putKind);
JITCompiler::DataLabelPtr targetToCheck;
JITCompiler::JumpList slowPath;
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(node->origin.semantic, m_stream->size());
- m_jit.emitStoreCallSiteIndex(callSite);
+ m_jit.emitStoreCodeOrigin(node->origin.semantic);
CallLinkInfo* info = m_jit.codeBlock()->addCallLinkInfo();
void SpeculativeJIT::cachedGetById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg resultGPR, unsigned identifierNumber, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
{
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
-
JITGetByIdGenerator gen(
- m_jit.codeBlock(), codeOrigin, callSite, usedRegisters(), JSValueRegs(baseGPR),
+ m_jit.codeBlock(), codeOrigin, m_jit.addCallSite(codeOrigin), usedRegisters(), JSValueRegs(baseGPR),
JSValueRegs(resultGPR), spillMode);
gen.generateFastPath(m_jit);
void SpeculativeJIT::cachedPutById(CodeOrigin codeOrigin, GPRReg baseGPR, GPRReg valueGPR, GPRReg scratchGPR, unsigned identifierNumber, PutKind putKind, JITCompiler::Jump slowPathTarget, SpillRegistersMode spillMode)
{
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(codeOrigin, m_stream->size());
-
JITPutByIdGenerator gen(
- m_jit.codeBlock(), codeOrigin, callSite, usedRegisters(), JSValueRegs(baseGPR),
+ m_jit.codeBlock(), codeOrigin, m_jit.addCallSite(codeOrigin), usedRegisters(), JSValueRegs(baseGPR),
JSValueRegs(valueGPR), scratchGPR, spillMode, m_jit.ecmaModeFor(codeOrigin), putKind);
gen.generateFastPath(m_jit);
JITCompiler::DataLabelPtr targetToCheck;
JITCompiler::Jump slowPath;
- CallSiteIndex callSite = m_jit.recordCallSiteAndGenerateExceptionHandlingOSRExitIfNeeded(node->origin.semantic, m_stream->size());
- m_jit.emitStoreCallSiteIndex(callSite);
+ m_jit.emitStoreCodeOrigin(node->origin.semantic);
CallLinkInfo* callLinkInfo = m_jit.codeBlock()->addCallLinkInfo();
if (m_graph.m_profiledBlock->m_didFailFTLCompilation)
return false;
-
- if (m_graph.m_hasExceptionHandlers)
- return false;
#if ENABLE(FTL_JIT)
FTL::CapabilityLevel level = FTL::canCompile(m_graph);
handleExitCounts(jit, exit);
reifyInlinedCallFrames(jit, exit);
- adjustAndJumpToTarget(jit, exit, false);
+ adjustAndJumpToTarget(jit, exit);
LinkBuffer patchBuffer(*vm, jit, codeBlock);
exit.m_code = FINALIZE_CODE_IF(
StackVisitor::Status operator()(StackVisitor& visitor)
{
- visitor.unwindToMachineCodeBlockFrame();
-
CodeBlock* codeBlock = visitor->codeBlock();
if (!codeBlock)
return StackVisitor::Continue;
- unsigned exceptionHandlerIndex;
- if (codeBlock->jitType() != JITCode::DFGJIT)
- exceptionHandlerIndex = visitor->callFrame()->bytecodeOffset();
- else
- exceptionHandlerIndex = visitor->callFrame()->callSiteIndex().bits();
-
- m_handler = codeBlock->handlerForIndex(exceptionHandlerIndex, CodeBlock::RequiredHandler::CatchHandler);
+ unsigned bytecodeOffset = visitor->bytecodeOffset();
+ m_handler = codeBlock->handlerForBytecodeOffset(bytecodeOffset, CodeBlock::RequiredHandler::CatchHandler);
if (m_handler)
return StackVisitor::Done;
StackVisitor::Status operator()(StackVisitor& visitor)
{
- visitor.unwindToMachineCodeBlockFrame();
VM& vm = m_callFrame->vm();
m_callFrame = visitor->callFrame();
m_codeBlock = visitor->codeBlock();
+ unsigned bytecodeOffset = visitor->bytecodeOffset();
- unsigned exceptionHandlerIndex;
- if (m_codeBlock->jitType() != JITCode::DFGJIT)
- exceptionHandlerIndex = m_callFrame->bytecodeOffset();
- else
- exceptionHandlerIndex = m_callFrame->callSiteIndex().bits();
m_handler = nullptr;
if (!m_isTermination) {
if (m_codeBlock && !isWebAssemblyExecutable(m_codeBlock->ownerExecutable()))
- m_handler = m_codeBlock->handlerForIndex(exceptionHandlerIndex);
+ m_handler = m_codeBlock->handlerForBytecodeOffset(bytecodeOffset);
}
if (m_handler)
readFrame(m_frame.callerFrame());
}
-CodeBlock* StackVisitor::unwindToMachineCodeBlockFrame()
-{
-#if ENABLE(DFG_JIT)
- while (m_frame.isInlinedFrame())
- gotoNextFrame();
-#endif // ENABLE(DFG_JIT)
- CodeBlock* result = m_frame.codeBlock();
- return result;
-}
-
void StackVisitor::readFrame(CallFrame* callFrame)
{
if (!callFrame) {
Frame& operator*() { return m_frame; }
ALWAYS_INLINE Frame* operator->() { return &m_frame; }
- CodeBlock* unwindToMachineCodeBlockFrame();
private:
JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame);
return realJump.m_jump;
}
-AssemblyHelpers::Jump AssemblyHelpers::emitNonPatchableExceptionCheck()
-{
- callExceptionFuzz();
-
- Jump result;
-#if USE(JSVALUE64)
- result = branchTest64(NonZero, AbsoluteAddress(vm()->addressOfException()));
-#elif USE(JSVALUE32_64)
- result = branch32(NotEqual, AbsoluteAddress(vm()->addressOfException()), TrustedImm32(0));
-#endif
-
- return result;
-}
-
void AssemblyHelpers::emitStoreStructureWithTypeInfo(AssemblyHelpers& jit, TrustedImmPtr structure, RegisterID dest)
{
const Structure* structurePtr = static_cast<const Structure*>(structure.m_value);
enum ExceptionJumpWidth { NormalJumpWidth, FarJumpWidth };
Jump emitExceptionCheck(
ExceptionCheckKind = NormalExceptionCheck, ExceptionJumpWidth = NormalJumpWidth);
- Jump emitNonPatchableExceptionCheck();
#if ENABLE(SAMPLING_COUNTERS)
static void emitCount(MacroAssembler& jit, AbstractSamplingCounter& counter, int32_t increment = 1)
void* catchRoutine;
Instruction* catchPCForInterpreter = 0;
if (handler) {
- // handler->target is meaningless for getting a code offset when catching
- // the exception in a DFG frame. This bytecode target offset could be
- // something that's in an inlined frame, which means an array access
- // with this bytecode offset in the machine frame is utterly meaningless
- // and can cause an overflow. OSR exit properly exits to handler->target
- // in the proper frame.
- if (callFrame->codeBlock()->jitType() != JITCode::DFGJIT)
- catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
+ catchPCForInterpreter = &callFrame->codeBlock()->instructions()[handler->target];
#if ENABLE(JIT)
catchRoutine = handler->nativeCode.executableAddress();
#else
move(TrustedImmPtr(m_vm), regT3);
load64(Address(regT3, VM::callFrameForCatchOffset()), callFrameRegister);
- storePtr(TrustedImmPtr(nullptr), Address(regT3, VM::callFrameForCatchOffset()));
addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
move(TrustedImmPtr(m_vm), regT3);
// operationThrow returns the callFrame for the handler.
load32(Address(regT3, VM::callFrameForCatchOffset()), callFrameRegister);
- storePtr(TrustedImmPtr(nullptr), Address(regT3, VM::callFrameForCatchOffset()));
addPtr(TrustedImm32(stackPointerOffsetFor(codeBlock()) * sizeof(Register)), callFrameRegister, stackPointerRegister);
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
loadp VM::callFrameForCatch[t3], cfr
- storep 0, VM::callFrameForCatch[t3]
loadp CallerFrame[cfr], cfr
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
loadp VM::callFrameForCatch[t3], cfr
- storep 0, VM::callFrameForCatch[t3]
restoreStackPointerAfterCall()
loadi VM::targetInterpreterPCForThrow[t3], PC
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
loadp VM::callFrameForCatch[t3], cfr
- storep 0, VM::callFrameForCatch[t3]
loadp CallerFrame[cfr], cfr
vmEntryRecord(cfr, t2)
loadp MarkedBlock::m_weakSet + WeakSet::m_vm[t3], t3
restoreCalleeSavesFromVMCalleeSavesBuffer(t3, t0)
loadp VM::callFrameForCatch[t3], cfr
- storep 0, VM::callFrameForCatch[t3]
restoreStackPointerAfterCall()
loadp CodeBlock[cfr], PB
void clearException() { m_exception = nullptr; }
void clearLastException() { m_lastException = nullptr; }
- ExecState** addressOfCallFrameForCatch() { return &callFrameForCatch; }
-
Exception* exception() const { return m_exception; }
JSCell** addressOfException() { return reinterpret_cast<JSCell**>(&m_exception); }
+++ /dev/null
-function f() {
- return 20;
-}
-noInline(f);
-
-function bar(b) {
- if (b)
- throw new Error("blah!");
-}
-
-function Foo(b) {
- try {
- this.value = bar(b);
- } catch(e) {
- this.value = e.toString();
- }
-
- f(this.value, b);
-}
-noInline(Foo);
-
-
-for (var i = 1; i < 1000; i++) {
- let value = new Foo(i % 3 === 0);
- if (i % 3 === 0 && value.value !== "Error: blah!")
- throw new Error("bad value: " + value.value);
-}
+++ /dev/null
-function assert(cond) {
- if (!cond)
- throw new Error("broke assertion");
-}
-noInline(assert);
-
-function shouldThrowInvalidConstAssignment(f) {
- var threw = false;
- try {
- f();
- } catch(e) {
- //print(e);
- if (e.name.indexOf("TypeError") !== -1 && e.message.indexOf("readonly") !== -1)
- threw = true;
- }
- assert(threw);
-}
-noInline(shouldThrowInvalidConstAssignment);
-
-function baz(){}
-noInline(baz);
-
-function foo() {
- for (const item of [1,2,3]) {
- item = 20;
- }
-}
-for (var i = 0; i < 1000; i++)
- shouldThrowInvalidConstAssignment(foo);
+++ /dev/null
-function assert(b) {
- if (!b)
- throw new Error("Bad assertion");
-}
-noInline(assert);
-var o = {
- valueOf: function() { return {}; },
- toString: function() { return {}; }
-};
-function read() {
- return "read";
-}
-noInline(read);
-
-function bar(a, b) {
- return a == b;
-}
-
-function foo(a, b) {
- var result = null;
- var value = read();
- try {
- result = bar(a, b);
- } catch(e) {
- assert("" + value === "read");
- }
- return value;
-}
-noInline(foo);
-
-for (var i = 0; i < 1000; i++) {
- foo(10, 20);
- foo({}, {});
- foo(10, 10.0);
- foo("hello", "hello");
- foo(null, undefined);
- foo(false, 0);
-}
-foo(o, "hello");
+++ /dev/null
-;(function () {
-function foo(a, b) {
- var result = null;
- try {
- result = a == b;
- } catch(e) {
- }
-}
-noInline(foo);
-
-for (var i = 0; i < 1000; i++) {
- foo(10, 20);
- foo({}, {});
- foo(10, 10.0);
- foo("hello", "hello");
- foo(null, undefined);
- foo(false, 0);
-}
-
-var o = {
- valueOf: function() { return {}; },
- toString: function() { return {}; }
-};
-foo(o, "hello");
-})();
-
-
-function assert(b) {
- if (!b)
- throw new Error("Bad assertion");
-}
-noInline(assert);
-
-
-;(function() {
-
-var _shouldDoSomethingInFinally = false;
-function shouldDoSomethingInFinally() { return _shouldDoSomethingInFinally; }
-noInline(shouldDoSomethingInFinally);
-
-function foo(a, b) {
- var result = null;
- try {
- result = a == b;
- } finally {
- if (shouldDoSomethingInFinally())
- assert(result === null);
- }
- return result;
-}
-noInline(foo);
-
-for (var i = 0; i < 1000; i++) {
- foo(10, 20);
- foo({}, {});
- foo(10, 10.0);
- foo("hello", "hello");
- foo(null, undefined);
- foo(false, 0);
-}
-
-var o = {
- valueOf: function() { return {}; },
- toString: function() { return {}; }
-};
-try {
- _shouldDoSomethingInFinally = true;
- foo(o, "hello");
-} catch(e) {}
-
-})();
+++ /dev/null
-function assert(b) {
- if (!b)
- throw new Error("Bad assertion");
-}
-noInline(assert);
-var o = {
- valueOf: function() { return {}; },
- toString: function() { return {}; }
-};
-function read() {
- return "read";
-}
-noInline(read);
-
-function foo(a, b) {
- var result = null;
- var value = read();
- try {
- result = a == b;
- } catch(e) {
- assert("" + value === "read");
- }
- return value;
-}
-noInline(foo);
-
-for (var i = 0; i < 1000; i++) {
- foo(10, 20);
- foo({}, {});
- foo(10, 10.0);
- foo("hello", "hello");
- foo(null, undefined);
- foo(false, 0);
-}
-foo(o, "hello");
+++ /dev/null
-"use strict";
-function assert(cond, m) {
- if (!cond)
- throw new Error("broke assertion: '" + m + "'");
-}
-noInline(assert);
-
-function baz(b) {
- if (b)
- throw new Error("Baz");
-}
-
-function bar(b) {
- var exception = null;
- try {
- baz(b);
- } catch(e) {
- exception = e;
- baz(b);
- } finally {
- if (b)
- assert(exception);
- }
-}
-
-function foo(b) {
- var exception = null;
- try {
- bar(b);
- } catch(e) {
- exception = e;
- }
- if (b)
- assert(exception);
-}
-
-const NUM_LOOPS = 1000;
-for (var i = 0; i < NUM_LOOPS; i++) {
- foo(i === NUM_LOOPS - 1);
-}