Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* |
michael@0 | 2 | Copyright (C) 2009 Apple Computer, Inc. All rights reserved. |
michael@0 | 3 | |
michael@0 | 4 | Redistribution and use in source and binary forms, with or without |
michael@0 | 5 | modification, are permitted provided that the following conditions |
michael@0 | 6 | are met: |
michael@0 | 7 | 1. Redistributions of source code must retain the above copyright |
michael@0 | 8 | notice, this list of conditions and the following disclaimer. |
michael@0 | 9 | 2. Redistributions in binary form must reproduce the above copyright |
michael@0 | 10 | notice, this list of conditions and the following disclaimer in the |
michael@0 | 11 | documentation and/or other materials provided with the distribution. |
michael@0 | 12 | |
michael@0 | 13 | THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY |
michael@0 | 14 | EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
michael@0 | 15 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
michael@0 | 16 | PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
michael@0 | 17 | CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
michael@0 | 18 | EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
michael@0 | 19 | PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
michael@0 | 20 | PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
michael@0 | 21 | OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
michael@0 | 22 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
michael@0 | 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
michael@0 | 24 | */ |
michael@0 | 25 | |
michael@0 | 26 | // WebKit Specfic code. Add your own here. |
michael@0 | 27 | function initNonKhronosFramework(waitUntilDone) { |
michael@0 | 28 | if (window.layoutTestController) { |
michael@0 | 29 | layoutTestController.overridePreference("WebKitWebGLEnabled", "1"); |
michael@0 | 30 | layoutTestController.dumpAsText(); |
michael@0 | 31 | if (waitUntilDone) { |
michael@0 | 32 | layoutTestController.waitUntilDone(); |
michael@0 | 33 | } |
michael@0 | 34 | } |
michael@0 | 35 | } |
michael@0 | 36 | |
michael@0 | 37 | function nonKhronosFrameworkNotifyDone() { |
michael@0 | 38 | if (window.layoutTestController) { |
michael@0 | 39 | layoutTestController.notifyDone(); |
michael@0 | 40 | } |
michael@0 | 41 | } |
michael@0 | 42 | |
michael@0 | 43 | function reportTestResultsToHarness(success, msg) { |
michael@0 | 44 | if (window.parent.webglTestHarness) { |
michael@0 | 45 | window.parent.webglTestHarness.reportResults(success, msg); |
michael@0 | 46 | } |
michael@0 | 47 | } |
michael@0 | 48 | |
michael@0 | 49 | function notifyFinishedToHarness() { |
michael@0 | 50 | if (window.parent.webglTestHarness) { |
michael@0 | 51 | window.parent.webglTestHarness.notifyFinished(); |
michael@0 | 52 | } |
michael@0 | 53 | } |
michael@0 | 54 | |
michael@0 | 55 | function description(msg) |
michael@0 | 56 | { |
michael@0 | 57 | // For MSIE 6 compatibility |
michael@0 | 58 | var span = document.createElement("span"); |
michael@0 | 59 | span.innerHTML = '<p>' + msg + '</p><p>On success, you will see a series of "<span class="pass">PASS</span>" messages, followed by "<span class="pass">TEST COMPLETE</span>".</p>'; |
michael@0 | 60 | var description = document.getElementById("description"); |
michael@0 | 61 | if (description.firstChild) |
michael@0 | 62 | description.replaceChild(span, description.firstChild); |
michael@0 | 63 | else |
michael@0 | 64 | description.appendChild(span); |
michael@0 | 65 | } |
michael@0 | 66 | |
michael@0 | 67 | function debug(msg) |
michael@0 | 68 | { |
michael@0 | 69 | var span = document.createElement("span"); |
michael@0 | 70 | document.getElementById("console").appendChild(span); // insert it first so XHTML knows the namespace |
michael@0 | 71 | span.innerHTML = msg + '<br />'; |
michael@0 | 72 | } |
michael@0 | 73 | |
michael@0 | 74 | function escapeHTML(text) |
michael@0 | 75 | { |
michael@0 | 76 | return text.replace(/&/g, "&").replace(/</g, "<"); |
michael@0 | 77 | } |
michael@0 | 78 | |
michael@0 | 79 | function testPassed(msg) |
michael@0 | 80 | { |
michael@0 | 81 | reportTestResultsToHarness(true, msg); |
michael@0 | 82 | debug('<span><span class="pass">PASS</span> ' + escapeHTML(msg) + '</span>'); |
michael@0 | 83 | } |
michael@0 | 84 | |
michael@0 | 85 | function testFailed(msg) |
michael@0 | 86 | { |
michael@0 | 87 | reportTestResultsToHarness(false, msg); |
michael@0 | 88 | debug('<span><span class="fail">FAIL</span> ' + escapeHTML(msg) + '</span>'); |
michael@0 | 89 | dump('FAIL: ' + msg + '\n'); |
michael@0 | 90 | |
michael@0 | 91 | var stack = (new Error).stack.split('\n'); |
michael@0 | 92 | if (!stack.length) { |
michael@0 | 93 | return; |
michael@0 | 94 | } |
michael@0 | 95 | |
michael@0 | 96 | dump('STACK TRACE: \n'); |
michael@0 | 97 | |
michael@0 | 98 | stack.pop(); |
michael@0 | 99 | var index = 0, frame, messages = new Array(); |
michael@0 | 100 | // Match all .html files and print out the line in them. |
michael@0 | 101 | while (stack.length && index != -1) { |
michael@0 | 102 | frame = stack.pop(); |
michael@0 | 103 | index = frame.indexOf(".html:"); |
michael@0 | 104 | if (index != -1) { |
michael@0 | 105 | messages.unshift(frame); |
michael@0 | 106 | } |
michael@0 | 107 | } |
michael@0 | 108 | |
michael@0 | 109 | // Print out the first stack frame in JS and then stop. |
michael@0 | 110 | if (stack.length) { |
michael@0 | 111 | messages.unshift(stack.pop()); |
michael@0 | 112 | } |
michael@0 | 113 | |
michael@0 | 114 | for (message in messages) { |
michael@0 | 115 | dump(messages[message] + '\n'); |
michael@0 | 116 | } |
michael@0 | 117 | } |
michael@0 | 118 | |
michael@0 | 119 | function testFailedRender(msg, ref, test, width, height) |
michael@0 | 120 | { |
michael@0 | 121 | var refData; |
michael@0 | 122 | if (typeof ref.getImageData == 'function') { |
michael@0 | 123 | refData = ref.canvas.toDataURL(); |
michael@0 | 124 | } else { |
michael@0 | 125 | refData = arrayToURLData(ref, width, height); |
michael@0 | 126 | } |
michael@0 | 127 | |
michael@0 | 128 | var testData; |
michael@0 | 129 | if (typeof test.getImageData == 'function') { |
michael@0 | 130 | testData = test.canvas.toDataURL(); |
michael@0 | 131 | } else { |
michael@0 | 132 | testData = arrayToURLData(test, width, height); |
michael@0 | 133 | } |
michael@0 | 134 | |
michael@0 | 135 | testFailed(msg); |
michael@0 | 136 | |
michael@0 | 137 | var data = 'REFTEST TEST-DEBUG-INFO | ' + msg + ' | image comparison (==)\n' + |
michael@0 | 138 | 'REFTEST IMAGE 1 (TEST): ' + testData + '\n' + |
michael@0 | 139 | 'REFTEST IMAGE 2 (REFERENCE): ' + refData; |
michael@0 | 140 | dump('FAIL: ' + data + '\n'); |
michael@0 | 141 | dump('To view the differences between these image renderings, go to the following link: https://hg.mozilla.org/mozilla-central/raw-file/tip/layout/tools/reftest/reftest-analyzer.xhtml#log=' + |
michael@0 | 142 | encodeURIComponent(encodeURIComponent(data)) + '\n'); |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | function arrayToURLData(buf, width, height) |
michael@0 | 146 | { |
michael@0 | 147 | var cv = document.createElement('canvas'); |
michael@0 | 148 | cv.height = height; |
michael@0 | 149 | cv.width = width; |
michael@0 | 150 | var ctx = cv.getContext('2d'); |
michael@0 | 151 | var imgd = ctx.getImageData(0, 0, width, height); |
michael@0 | 152 | for (i = 0; i < height * width; ++i) { |
michael@0 | 153 | offset = i * 4; |
michael@0 | 154 | for (j = 0; j < 4; j++) { |
michael@0 | 155 | imgd.data[offset + j] = buf[offset + j]; |
michael@0 | 156 | } |
michael@0 | 157 | } |
michael@0 | 158 | ctx.putImageData(imgd, 0, 0); |
michael@0 | 159 | return cv.toDataURL(); |
michael@0 | 160 | } |
michael@0 | 161 | |
michael@0 | 162 | function areArraysEqual(_a, _b) |
michael@0 | 163 | { |
michael@0 | 164 | try { |
michael@0 | 165 | if (_a.length !== _b.length) |
michael@0 | 166 | return false; |
michael@0 | 167 | for (var i = 0; i < _a.length; i++) |
michael@0 | 168 | if (_a[i] !== _b[i]) |
michael@0 | 169 | return false; |
michael@0 | 170 | } catch (ex) { |
michael@0 | 171 | return false; |
michael@0 | 172 | } |
michael@0 | 173 | return true; |
michael@0 | 174 | } |
michael@0 | 175 | |
michael@0 | 176 | function isMinusZero(n) |
michael@0 | 177 | { |
michael@0 | 178 | // the only way to tell 0 from -0 in JS is the fact that 1/-0 is |
michael@0 | 179 | // -Infinity instead of Infinity |
michael@0 | 180 | return n === 0 && 1/n < 0; |
michael@0 | 181 | } |
michael@0 | 182 | |
michael@0 | 183 | function isResultCorrect(_actual, _expected) |
michael@0 | 184 | { |
michael@0 | 185 | if (_expected === 0) |
michael@0 | 186 | return _actual === _expected && (1/_actual) === (1/_expected); |
michael@0 | 187 | if (_actual === _expected) |
michael@0 | 188 | return true; |
michael@0 | 189 | if (typeof(_expected) == "number" && isNaN(_expected)) |
michael@0 | 190 | return typeof(_actual) == "number" && isNaN(_actual); |
michael@0 | 191 | if (Object.prototype.toString.call(_expected) == Object.prototype.toString.call([])) |
michael@0 | 192 | return areArraysEqual(_actual, _expected); |
michael@0 | 193 | return false; |
michael@0 | 194 | } |
michael@0 | 195 | |
michael@0 | 196 | function stringify(v) |
michael@0 | 197 | { |
michael@0 | 198 | if (v === 0 && 1/v < 0) |
michael@0 | 199 | return "-0"; |
michael@0 | 200 | else return "" + v; |
michael@0 | 201 | } |
michael@0 | 202 | |
michael@0 | 203 | function evalAndLog(_a) |
michael@0 | 204 | { |
michael@0 | 205 | if (typeof _a != "string") |
michael@0 | 206 | debug("WARN: tryAndLog() expects a string argument"); |
michael@0 | 207 | |
michael@0 | 208 | // Log first in case things go horribly wrong or this causes a sync event. |
michael@0 | 209 | debug(_a); |
michael@0 | 210 | |
michael@0 | 211 | var _av; |
michael@0 | 212 | try { |
michael@0 | 213 | _av = eval(_a); |
michael@0 | 214 | } catch (e) { |
michael@0 | 215 | testFailed(_a + " threw exception " + e); |
michael@0 | 216 | } |
michael@0 | 217 | return _av; |
michael@0 | 218 | } |
michael@0 | 219 | |
michael@0 | 220 | function shouldBe(_a, _b, quiet) |
michael@0 | 221 | { |
michael@0 | 222 | if (typeof _a != "string" || typeof _b != "string") |
michael@0 | 223 | debug("WARN: shouldBe() expects string arguments"); |
michael@0 | 224 | var exception; |
michael@0 | 225 | var _av; |
michael@0 | 226 | try { |
michael@0 | 227 | _av = eval(_a); |
michael@0 | 228 | } catch (e) { |
michael@0 | 229 | exception = e; |
michael@0 | 230 | } |
michael@0 | 231 | var _bv = eval(_b); |
michael@0 | 232 | |
michael@0 | 233 | if (exception) |
michael@0 | 234 | testFailed(_a + " should be " + _bv + ". Threw exception " + exception); |
michael@0 | 235 | else if (isResultCorrect(_av, _bv)) { |
michael@0 | 236 | if (!quiet) { |
michael@0 | 237 | testPassed(_a + " is " + _b); |
michael@0 | 238 | } |
michael@0 | 239 | } else if (typeof(_av) == typeof(_bv)) |
michael@0 | 240 | testFailed(_a + " should be " + _bv + ". Was " + stringify(_av) + "."); |
michael@0 | 241 | else |
michael@0 | 242 | testFailed(_a + " should be " + _bv + " (of type " + typeof _bv + "). Was " + _av + " (of type " + typeof _av + ")."); |
michael@0 | 243 | } |
michael@0 | 244 | |
michael@0 | 245 | function shouldNotBe(_a, _b, quiet) |
michael@0 | 246 | { |
michael@0 | 247 | if (typeof _a != "string" || typeof _b != "string") |
michael@0 | 248 | debug("WARN: shouldNotBe() expects string arguments"); |
michael@0 | 249 | var exception; |
michael@0 | 250 | var _av; |
michael@0 | 251 | try { |
michael@0 | 252 | _av = eval(_a); |
michael@0 | 253 | } catch (e) { |
michael@0 | 254 | exception = e; |
michael@0 | 255 | } |
michael@0 | 256 | var _bv = eval(_b); |
michael@0 | 257 | |
michael@0 | 258 | if (exception) |
michael@0 | 259 | testFailed(_a + " should not be " + _bv + ". Threw exception " + exception); |
michael@0 | 260 | else if (!isResultCorrect(_av, _bv)) { |
michael@0 | 261 | if (!quiet) { |
michael@0 | 262 | testPassed(_a + " is not " + _b); |
michael@0 | 263 | } |
michael@0 | 264 | } else |
michael@0 | 265 | testFailed(_a + " should not be " + _bv + "."); |
michael@0 | 266 | } |
michael@0 | 267 | |
michael@0 | 268 | function shouldBeTrue(_a) { shouldBe(_a, "true"); } |
michael@0 | 269 | function shouldBeFalse(_a) { shouldBe(_a, "false"); } |
michael@0 | 270 | function shouldBeNaN(_a) { shouldBe(_a, "NaN"); } |
michael@0 | 271 | function shouldBeNull(_a) { shouldBe(_a, "null"); } |
michael@0 | 272 | |
michael@0 | 273 | function shouldBeEqualToString(a, b) |
michael@0 | 274 | { |
michael@0 | 275 | var unevaledString = '"' + b.replace(/"/g, "\"") + '"'; |
michael@0 | 276 | shouldBe(a, unevaledString); |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | function shouldEvaluateTo(actual, expected) { |
michael@0 | 280 | // A general-purpose comparator. 'actual' should be a string to be |
michael@0 | 281 | // evaluated, as for shouldBe(). 'expected' may be any type and will be |
michael@0 | 282 | // used without being eval'ed. |
michael@0 | 283 | if (expected == null) { |
michael@0 | 284 | // Do this before the object test, since null is of type 'object'. |
michael@0 | 285 | shouldBeNull(actual); |
michael@0 | 286 | } else if (typeof expected == "undefined") { |
michael@0 | 287 | shouldBeUndefined(actual); |
michael@0 | 288 | } else if (typeof expected == "function") { |
michael@0 | 289 | // All this fuss is to avoid the string-arg warning from shouldBe(). |
michael@0 | 290 | try { |
michael@0 | 291 | actualValue = eval(actual); |
michael@0 | 292 | } catch (e) { |
michael@0 | 293 | testFailed("Evaluating " + actual + ": Threw exception " + e); |
michael@0 | 294 | return; |
michael@0 | 295 | } |
michael@0 | 296 | shouldBe("'" + actualValue.toString().replace(/\n/g, "") + "'", |
michael@0 | 297 | "'" + expected.toString().replace(/\n/g, "") + "'"); |
michael@0 | 298 | } else if (typeof expected == "object") { |
michael@0 | 299 | shouldBeTrue(actual + " == '" + expected + "'"); |
michael@0 | 300 | } else if (typeof expected == "string") { |
michael@0 | 301 | shouldBe(actual, expected); |
michael@0 | 302 | } else if (typeof expected == "boolean") { |
michael@0 | 303 | shouldBe("typeof " + actual, "'boolean'"); |
michael@0 | 304 | if (expected) |
michael@0 | 305 | shouldBeTrue(actual); |
michael@0 | 306 | else |
michael@0 | 307 | shouldBeFalse(actual); |
michael@0 | 308 | } else if (typeof expected == "number") { |
michael@0 | 309 | shouldBe(actual, stringify(expected)); |
michael@0 | 310 | } else { |
michael@0 | 311 | debug(expected + " is unknown type " + typeof expected); |
michael@0 | 312 | shouldBeTrue(actual, "'" +expected.toString() + "'"); |
michael@0 | 313 | } |
michael@0 | 314 | } |
michael@0 | 315 | |
michael@0 | 316 | function shouldBeNonZero(_a) |
michael@0 | 317 | { |
michael@0 | 318 | var exception; |
michael@0 | 319 | var _av; |
michael@0 | 320 | try { |
michael@0 | 321 | _av = eval(_a); |
michael@0 | 322 | } catch (e) { |
michael@0 | 323 | exception = e; |
michael@0 | 324 | } |
michael@0 | 325 | |
michael@0 | 326 | if (exception) |
michael@0 | 327 | testFailed(_a + " should be non-zero. Threw exception " + exception); |
michael@0 | 328 | else if (_av != 0) |
michael@0 | 329 | testPassed(_a + " is non-zero."); |
michael@0 | 330 | else |
michael@0 | 331 | testFailed(_a + " should be non-zero. Was " + _av); |
michael@0 | 332 | } |
michael@0 | 333 | |
michael@0 | 334 | function shouldBeNonNull(_a) |
michael@0 | 335 | { |
michael@0 | 336 | var exception; |
michael@0 | 337 | var _av; |
michael@0 | 338 | try { |
michael@0 | 339 | _av = eval(_a); |
michael@0 | 340 | } catch (e) { |
michael@0 | 341 | exception = e; |
michael@0 | 342 | } |
michael@0 | 343 | |
michael@0 | 344 | if (exception) |
michael@0 | 345 | testFailed(_a + " should be non-null. Threw exception " + exception); |
michael@0 | 346 | else if (_av != null) |
michael@0 | 347 | testPassed(_a + " is non-null."); |
michael@0 | 348 | else |
michael@0 | 349 | testFailed(_a + " should be non-null. Was " + _av); |
michael@0 | 350 | } |
michael@0 | 351 | |
michael@0 | 352 | function shouldBeUndefined(_a) |
michael@0 | 353 | { |
michael@0 | 354 | var exception; |
michael@0 | 355 | var _av; |
michael@0 | 356 | try { |
michael@0 | 357 | _av = eval(_a); |
michael@0 | 358 | } catch (e) { |
michael@0 | 359 | exception = e; |
michael@0 | 360 | } |
michael@0 | 361 | |
michael@0 | 362 | if (exception) |
michael@0 | 363 | testFailed(_a + " should be undefined. Threw exception " + exception); |
michael@0 | 364 | else if (typeof _av == "undefined") |
michael@0 | 365 | testPassed(_a + " is undefined."); |
michael@0 | 366 | else |
michael@0 | 367 | testFailed(_a + " should be undefined. Was " + _av); |
michael@0 | 368 | } |
michael@0 | 369 | |
michael@0 | 370 | function shouldBeDefined(_a) |
michael@0 | 371 | { |
michael@0 | 372 | var exception; |
michael@0 | 373 | var _av; |
michael@0 | 374 | try { |
michael@0 | 375 | _av = eval(_a); |
michael@0 | 376 | } catch (e) { |
michael@0 | 377 | exception = e; |
michael@0 | 378 | } |
michael@0 | 379 | |
michael@0 | 380 | if (exception) |
michael@0 | 381 | testFailed(_a + " should be defined. Threw exception " + exception); |
michael@0 | 382 | else if (_av !== undefined) |
michael@0 | 383 | testPassed(_a + " is defined."); |
michael@0 | 384 | else |
michael@0 | 385 | testFailed(_a + " should be defined. Was " + _av); |
michael@0 | 386 | } |
michael@0 | 387 | |
michael@0 | 388 | function shouldBeGreaterThanOrEqual(_a, _b) { |
michael@0 | 389 | if (typeof _a != "string" || typeof _b != "string") |
michael@0 | 390 | debug("WARN: shouldBeGreaterThanOrEqual expects string arguments"); |
michael@0 | 391 | |
michael@0 | 392 | var exception; |
michael@0 | 393 | var _av; |
michael@0 | 394 | try { |
michael@0 | 395 | _av = eval(_a); |
michael@0 | 396 | } catch (e) { |
michael@0 | 397 | exception = e; |
michael@0 | 398 | } |
michael@0 | 399 | var _bv = eval(_b); |
michael@0 | 400 | |
michael@0 | 401 | if (exception) |
michael@0 | 402 | testFailed(_a + " should be >= " + _b + ". Threw exception " + exception); |
michael@0 | 403 | else if (typeof _av == "undefined" || _av < _bv) |
michael@0 | 404 | testFailed(_a + " should be >= " + _b + ". Was " + _av + " (of type " + typeof _av + ")."); |
michael@0 | 405 | else |
michael@0 | 406 | testPassed(_a + " is >= " + _b); |
michael@0 | 407 | } |
michael@0 | 408 | |
michael@0 | 409 | function shouldThrow(_a, _e) |
michael@0 | 410 | { |
michael@0 | 411 | var exception; |
michael@0 | 412 | var _av; |
michael@0 | 413 | try { |
michael@0 | 414 | _av = eval(_a); |
michael@0 | 415 | } catch (e) { |
michael@0 | 416 | exception = e; |
michael@0 | 417 | } |
michael@0 | 418 | |
michael@0 | 419 | var _ev; |
michael@0 | 420 | if (_e) |
michael@0 | 421 | _ev = eval(_e); |
michael@0 | 422 | |
michael@0 | 423 | if (exception) { |
michael@0 | 424 | if (typeof _e == "undefined" || exception == _ev) |
michael@0 | 425 | testPassed(_a + " threw exception " + exception + "."); |
michael@0 | 426 | else |
michael@0 | 427 | testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Threw exception " + exception + "."); |
michael@0 | 428 | } else if (typeof _av == "undefined") |
michael@0 | 429 | testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was undefined."); |
michael@0 | 430 | else |
michael@0 | 431 | testFailed(_a + " should throw " + (typeof _e == "undefined" ? "an exception" : _ev) + ". Was " + _av + "."); |
michael@0 | 432 | } |
michael@0 | 433 | |
michael@0 | 434 | function assertMsg(assertion, msg) { |
michael@0 | 435 | if (assertion) { |
michael@0 | 436 | testPassed(msg); |
michael@0 | 437 | } else { |
michael@0 | 438 | testFailed(msg); |
michael@0 | 439 | } |
michael@0 | 440 | } |
michael@0 | 441 | |
michael@0 | 442 | function gc() { |
michael@0 | 443 | if (window.GCController) { |
michael@0 | 444 | window.GCController.collect(); |
michael@0 | 445 | return; |
michael@0 | 446 | } |
michael@0 | 447 | |
michael@0 | 448 | if (window.opera && window.opera.collect) { |
michael@0 | 449 | window.opera.collect(); |
michael@0 | 450 | return; |
michael@0 | 451 | } |
michael@0 | 452 | |
michael@0 | 453 | try { |
michael@0 | 454 | window.QueryInterface(Components.interfaces.nsIInterfaceRequestor) |
michael@0 | 455 | .getInterface(Components.interfaces.nsIDOMWindowUtils) |
michael@0 | 456 | .garbageCollect(); |
michael@0 | 457 | return; |
michael@0 | 458 | } catch(e) {} |
michael@0 | 459 | |
michael@0 | 460 | function gcRec(n) { |
michael@0 | 461 | if (n < 1) |
michael@0 | 462 | return {}; |
michael@0 | 463 | var temp = {i: "ab" + i + (i / 100000)}; |
michael@0 | 464 | temp += "foo"; |
michael@0 | 465 | gcRec(n-1); |
michael@0 | 466 | } |
michael@0 | 467 | for (var i = 0; i < 1000; i++) |
michael@0 | 468 | gcRec(10); |
michael@0 | 469 | } |
michael@0 | 470 | |
michael@0 | 471 | function finishTest() { |
michael@0 | 472 | debug('<br /><span class="pass">TEST COMPLETE</span>'); |
michael@0 | 473 | notifyFinishedToHarness(); |
michael@0 | 474 | } |