js/src/v8/richards.js

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 // Copyright 2006-2008 the V8 project authors. All rights reserved.
michael@0 2 // Redistribution and use in source and binary forms, with or without
michael@0 3 // modification, are permitted provided that the following conditions are
michael@0 4 // met:
michael@0 5 //
michael@0 6 // * Redistributions of source code must retain the above copyright
michael@0 7 // notice, this list of conditions and the following disclaimer.
michael@0 8 // * Redistributions in binary form must reproduce the above
michael@0 9 // copyright notice, this list of conditions and the following
michael@0 10 // disclaimer in the documentation and/or other materials provided
michael@0 11 // with the distribution.
michael@0 12 // * Neither the name of Google Inc. nor the names of its
michael@0 13 // contributors may be used to endorse or promote products derived
michael@0 14 // from this software without specific prior written permission.
michael@0 15 //
michael@0 16 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
michael@0 17 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
michael@0 18 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
michael@0 19 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
michael@0 20 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
michael@0 21 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
michael@0 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
michael@0 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
michael@0 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
michael@0 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
michael@0 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
michael@0 27
michael@0 28
michael@0 29 // This is a JavaScript implementation of the Richards
michael@0 30 // benchmark from:
michael@0 31 //
michael@0 32 // http://www.cl.cam.ac.uk/~mr10/Bench.html
michael@0 33 //
michael@0 34 // The benchmark was originally implemented in BCPL by
michael@0 35 // Martin Richards.
michael@0 36
michael@0 37
michael@0 38 var Richards = new BenchmarkSuite('Richards', 35302, [
michael@0 39 new Benchmark("Richards", runRichards)
michael@0 40 ]);
michael@0 41
michael@0 42
michael@0 43 /**
michael@0 44 * The Richards benchmark simulates the task dispatcher of an
michael@0 45 * operating system.
michael@0 46 **/
michael@0 47 function runRichards() {
michael@0 48 var scheduler = new Scheduler();
michael@0 49 scheduler.addIdleTask(ID_IDLE, 0, null, COUNT);
michael@0 50
michael@0 51 var queue = new Packet(null, ID_WORKER, KIND_WORK);
michael@0 52 queue = new Packet(queue, ID_WORKER, KIND_WORK);
michael@0 53 scheduler.addWorkerTask(ID_WORKER, 1000, queue);
michael@0 54
michael@0 55 queue = new Packet(null, ID_DEVICE_A, KIND_DEVICE);
michael@0 56 queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
michael@0 57 queue = new Packet(queue, ID_DEVICE_A, KIND_DEVICE);
michael@0 58 scheduler.addHandlerTask(ID_HANDLER_A, 2000, queue);
michael@0 59
michael@0 60 queue = new Packet(null, ID_DEVICE_B, KIND_DEVICE);
michael@0 61 queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
michael@0 62 queue = new Packet(queue, ID_DEVICE_B, KIND_DEVICE);
michael@0 63 scheduler.addHandlerTask(ID_HANDLER_B, 3000, queue);
michael@0 64
michael@0 65 scheduler.addDeviceTask(ID_DEVICE_A, 4000, null);
michael@0 66
michael@0 67 scheduler.addDeviceTask(ID_DEVICE_B, 5000, null);
michael@0 68
michael@0 69 scheduler.schedule();
michael@0 70
michael@0 71 if (scheduler.queueCount != EXPECTED_QUEUE_COUNT ||
michael@0 72 scheduler.holdCount != EXPECTED_HOLD_COUNT) {
michael@0 73 var msg =
michael@0 74 "Error during execution: queueCount = " + scheduler.queueCount +
michael@0 75 ", holdCount = " + scheduler.holdCount + ".";
michael@0 76 throw new Error(msg);
michael@0 77 }
michael@0 78 }
michael@0 79
michael@0 80 var COUNT = 1000;
michael@0 81
michael@0 82 /**
michael@0 83 * These two constants specify how many times a packet is queued and
michael@0 84 * how many times a task is put on hold in a correct run of richards.
michael@0 85 * They don't have any meaning a such but are characteristic of a
michael@0 86 * correct run so if the actual queue or hold count is different from
michael@0 87 * the expected there must be a bug in the implementation.
michael@0 88 **/
michael@0 89 var EXPECTED_QUEUE_COUNT = 2322;
michael@0 90 var EXPECTED_HOLD_COUNT = 928;
michael@0 91
michael@0 92
michael@0 93 /**
michael@0 94 * A scheduler can be used to schedule a set of tasks based on their relative
michael@0 95 * priorities. Scheduling is done by maintaining a list of task control blocks
michael@0 96 * which holds tasks and the data queue they are processing.
michael@0 97 * @constructor
michael@0 98 */
michael@0 99 function Scheduler() {
michael@0 100 this.queueCount = 0;
michael@0 101 this.holdCount = 0;
michael@0 102 this.blocks = new Array(NUMBER_OF_IDS);
michael@0 103 this.list = null;
michael@0 104 this.currentTcb = null;
michael@0 105 this.currentId = null;
michael@0 106 }
michael@0 107
michael@0 108 var ID_IDLE = 0;
michael@0 109 var ID_WORKER = 1;
michael@0 110 var ID_HANDLER_A = 2;
michael@0 111 var ID_HANDLER_B = 3;
michael@0 112 var ID_DEVICE_A = 4;
michael@0 113 var ID_DEVICE_B = 5;
michael@0 114 var NUMBER_OF_IDS = 6;
michael@0 115
michael@0 116 var KIND_DEVICE = 0;
michael@0 117 var KIND_WORK = 1;
michael@0 118
michael@0 119 /**
michael@0 120 * Add an idle task to this scheduler.
michael@0 121 * @param {int} id the identity of the task
michael@0 122 * @param {int} priority the task's priority
michael@0 123 * @param {Packet} queue the queue of work to be processed by the task
michael@0 124 * @param {int} count the number of times to schedule the task
michael@0 125 */
michael@0 126 Scheduler.prototype.addIdleTask = function (id, priority, queue, count) {
michael@0 127 this.addRunningTask(id, priority, queue, new IdleTask(this, 1, count));
michael@0 128 };
michael@0 129
michael@0 130 /**
michael@0 131 * Add a work task to this scheduler.
michael@0 132 * @param {int} id the identity of the task
michael@0 133 * @param {int} priority the task's priority
michael@0 134 * @param {Packet} queue the queue of work to be processed by the task
michael@0 135 */
michael@0 136 Scheduler.prototype.addWorkerTask = function (id, priority, queue) {
michael@0 137 this.addTask(id, priority, queue, new WorkerTask(this, ID_HANDLER_A, 0));
michael@0 138 };
michael@0 139
michael@0 140 /**
michael@0 141 * Add a handler task to this scheduler.
michael@0 142 * @param {int} id the identity of the task
michael@0 143 * @param {int} priority the task's priority
michael@0 144 * @param {Packet} queue the queue of work to be processed by the task
michael@0 145 */
michael@0 146 Scheduler.prototype.addHandlerTask = function (id, priority, queue) {
michael@0 147 this.addTask(id, priority, queue, new HandlerTask(this));
michael@0 148 };
michael@0 149
michael@0 150 /**
michael@0 151 * Add a handler task to this scheduler.
michael@0 152 * @param {int} id the identity of the task
michael@0 153 * @param {int} priority the task's priority
michael@0 154 * @param {Packet} queue the queue of work to be processed by the task
michael@0 155 */
michael@0 156 Scheduler.prototype.addDeviceTask = function (id, priority, queue) {
michael@0 157 this.addTask(id, priority, queue, new DeviceTask(this))
michael@0 158 };
michael@0 159
michael@0 160 /**
michael@0 161 * Add the specified task and mark it as running.
michael@0 162 * @param {int} id the identity of the task
michael@0 163 * @param {int} priority the task's priority
michael@0 164 * @param {Packet} queue the queue of work to be processed by the task
michael@0 165 * @param {Task} task the task to add
michael@0 166 */
michael@0 167 Scheduler.prototype.addRunningTask = function (id, priority, queue, task) {
michael@0 168 this.addTask(id, priority, queue, task);
michael@0 169 this.currentTcb.setRunning();
michael@0 170 };
michael@0 171
michael@0 172 /**
michael@0 173 * Add the specified task to this scheduler.
michael@0 174 * @param {int} id the identity of the task
michael@0 175 * @param {int} priority the task's priority
michael@0 176 * @param {Packet} queue the queue of work to be processed by the task
michael@0 177 * @param {Task} task the task to add
michael@0 178 */
michael@0 179 Scheduler.prototype.addTask = function (id, priority, queue, task) {
michael@0 180 this.currentTcb = new TaskControlBlock(this.list, id, priority, queue, task);
michael@0 181 this.list = this.currentTcb;
michael@0 182 this.blocks[id] = this.currentTcb;
michael@0 183 };
michael@0 184
michael@0 185 /**
michael@0 186 * Execute the tasks managed by this scheduler.
michael@0 187 */
michael@0 188 Scheduler.prototype.schedule = function () {
michael@0 189 this.currentTcb = this.list;
michael@0 190 while (this.currentTcb != null) {
michael@0 191 if (this.currentTcb.isHeldOrSuspended()) {
michael@0 192 this.currentTcb = this.currentTcb.link;
michael@0 193 } else {
michael@0 194 this.currentId = this.currentTcb.id;
michael@0 195 this.currentTcb = this.currentTcb.run();
michael@0 196 }
michael@0 197 }
michael@0 198 };
michael@0 199
michael@0 200 /**
michael@0 201 * Release a task that is currently blocked and return the next block to run.
michael@0 202 * @param {int} id the id of the task to suspend
michael@0 203 */
michael@0 204 Scheduler.prototype.release = function (id) {
michael@0 205 var tcb = this.blocks[id];
michael@0 206 if (tcb == null) return tcb;
michael@0 207 tcb.markAsNotHeld();
michael@0 208 if (tcb.priority > this.currentTcb.priority) {
michael@0 209 return tcb;
michael@0 210 } else {
michael@0 211 return this.currentTcb;
michael@0 212 }
michael@0 213 };
michael@0 214
michael@0 215 /**
michael@0 216 * Block the currently executing task and return the next task control block
michael@0 217 * to run. The blocked task will not be made runnable until it is explicitly
michael@0 218 * released, even if new work is added to it.
michael@0 219 */
michael@0 220 Scheduler.prototype.holdCurrent = function () {
michael@0 221 this.holdCount++;
michael@0 222 this.currentTcb.markAsHeld();
michael@0 223 return this.currentTcb.link;
michael@0 224 };
michael@0 225
michael@0 226 /**
michael@0 227 * Suspend the currently executing task and return the next task control block
michael@0 228 * to run. If new work is added to the suspended task it will be made runnable.
michael@0 229 */
michael@0 230 Scheduler.prototype.suspendCurrent = function () {
michael@0 231 this.currentTcb.markAsSuspended();
michael@0 232 return this.currentTcb;
michael@0 233 };
michael@0 234
michael@0 235 /**
michael@0 236 * Add the specified packet to the end of the worklist used by the task
michael@0 237 * associated with the packet and make the task runnable if it is currently
michael@0 238 * suspended.
michael@0 239 * @param {Packet} packet the packet to add
michael@0 240 */
michael@0 241 Scheduler.prototype.queue = function (packet) {
michael@0 242 var t = this.blocks[packet.id];
michael@0 243 if (t == null) return t;
michael@0 244 this.queueCount++;
michael@0 245 packet.link = null;
michael@0 246 packet.id = this.currentId;
michael@0 247 return t.checkPriorityAdd(this.currentTcb, packet);
michael@0 248 };
michael@0 249
michael@0 250 /**
michael@0 251 * A task control block manages a task and the queue of work packages associated
michael@0 252 * with it.
michael@0 253 * @param {TaskControlBlock} link the preceding block in the linked block list
michael@0 254 * @param {int} id the id of this block
michael@0 255 * @param {int} priority the priority of this block
michael@0 256 * @param {Packet} queue the queue of packages to be processed by the task
michael@0 257 * @param {Task} task the task
michael@0 258 * @constructor
michael@0 259 */
michael@0 260 function TaskControlBlock(link, id, priority, queue, task) {
michael@0 261 this.link = link;
michael@0 262 this.id = id;
michael@0 263 this.priority = priority;
michael@0 264 this.queue = queue;
michael@0 265 this.task = task;
michael@0 266 if (queue == null) {
michael@0 267 this.state = STATE_SUSPENDED;
michael@0 268 } else {
michael@0 269 this.state = STATE_SUSPENDED_RUNNABLE;
michael@0 270 }
michael@0 271 }
michael@0 272
michael@0 273 /**
michael@0 274 * The task is running and is currently scheduled.
michael@0 275 */
michael@0 276 var STATE_RUNNING = 0;
michael@0 277
michael@0 278 /**
michael@0 279 * The task has packets left to process.
michael@0 280 */
michael@0 281 var STATE_RUNNABLE = 1;
michael@0 282
michael@0 283 /**
michael@0 284 * The task is not currently running. The task is not blocked as such and may
michael@0 285 * be started by the scheduler.
michael@0 286 */
michael@0 287 var STATE_SUSPENDED = 2;
michael@0 288
michael@0 289 /**
michael@0 290 * The task is blocked and cannot be run until it is explicitly released.
michael@0 291 */
michael@0 292 var STATE_HELD = 4;
michael@0 293
michael@0 294 var STATE_SUSPENDED_RUNNABLE = STATE_SUSPENDED | STATE_RUNNABLE;
michael@0 295 var STATE_NOT_HELD = ~STATE_HELD;
michael@0 296
michael@0 297 TaskControlBlock.prototype.setRunning = function () {
michael@0 298 this.state = STATE_RUNNING;
michael@0 299 };
michael@0 300
michael@0 301 TaskControlBlock.prototype.markAsNotHeld = function () {
michael@0 302 this.state = this.state & STATE_NOT_HELD;
michael@0 303 };
michael@0 304
michael@0 305 TaskControlBlock.prototype.markAsHeld = function () {
michael@0 306 this.state = this.state | STATE_HELD;
michael@0 307 };
michael@0 308
michael@0 309 TaskControlBlock.prototype.isHeldOrSuspended = function () {
michael@0 310 return (this.state & STATE_HELD) != 0 || (this.state == STATE_SUSPENDED);
michael@0 311 };
michael@0 312
michael@0 313 TaskControlBlock.prototype.markAsSuspended = function () {
michael@0 314 this.state = this.state | STATE_SUSPENDED;
michael@0 315 };
michael@0 316
michael@0 317 TaskControlBlock.prototype.markAsRunnable = function () {
michael@0 318 this.state = this.state | STATE_RUNNABLE;
michael@0 319 };
michael@0 320
michael@0 321 /**
michael@0 322 * Runs this task, if it is ready to be run, and returns the next task to run.
michael@0 323 */
michael@0 324 TaskControlBlock.prototype.run = function () {
michael@0 325 var packet;
michael@0 326 if (this.state == STATE_SUSPENDED_RUNNABLE) {
michael@0 327 packet = this.queue;
michael@0 328 this.queue = packet.link;
michael@0 329 if (this.queue == null) {
michael@0 330 this.state = STATE_RUNNING;
michael@0 331 } else {
michael@0 332 this.state = STATE_RUNNABLE;
michael@0 333 }
michael@0 334 } else {
michael@0 335 packet = null;
michael@0 336 }
michael@0 337 return this.task.run(packet);
michael@0 338 };
michael@0 339
michael@0 340 /**
michael@0 341 * Adds a packet to the worklist of this block's task, marks this as runnable if
michael@0 342 * necessary, and returns the next runnable object to run (the one
michael@0 343 * with the highest priority).
michael@0 344 */
michael@0 345 TaskControlBlock.prototype.checkPriorityAdd = function (task, packet) {
michael@0 346 if (this.queue == null) {
michael@0 347 this.queue = packet;
michael@0 348 this.markAsRunnable();
michael@0 349 if (this.priority > task.priority) return this;
michael@0 350 } else {
michael@0 351 this.queue = packet.addTo(this.queue);
michael@0 352 }
michael@0 353 return task;
michael@0 354 };
michael@0 355
michael@0 356 TaskControlBlock.prototype.toString = function () {
michael@0 357 return "tcb { " + this.task + "@" + this.state + " }";
michael@0 358 };
michael@0 359
michael@0 360 /**
michael@0 361 * An idle task doesn't do any work itself but cycles control between the two
michael@0 362 * device tasks.
michael@0 363 * @param {Scheduler} scheduler the scheduler that manages this task
michael@0 364 * @param {int} v1 a seed value that controls how the device tasks are scheduled
michael@0 365 * @param {int} count the number of times this task should be scheduled
michael@0 366 * @constructor
michael@0 367 */
michael@0 368 function IdleTask(scheduler, v1, count) {
michael@0 369 this.scheduler = scheduler;
michael@0 370 this.v1 = v1;
michael@0 371 this.count = count;
michael@0 372 }
michael@0 373
michael@0 374 IdleTask.prototype.run = function (packet) {
michael@0 375 this.count--;
michael@0 376 if (this.count == 0) return this.scheduler.holdCurrent();
michael@0 377 if ((this.v1 & 1) == 0) {
michael@0 378 this.v1 = this.v1 >> 1;
michael@0 379 return this.scheduler.release(ID_DEVICE_A);
michael@0 380 } else {
michael@0 381 this.v1 = (this.v1 >> 1) ^ 0xD008;
michael@0 382 return this.scheduler.release(ID_DEVICE_B);
michael@0 383 }
michael@0 384 };
michael@0 385
michael@0 386 IdleTask.prototype.toString = function () {
michael@0 387 return "IdleTask"
michael@0 388 };
michael@0 389
michael@0 390 /**
michael@0 391 * A task that suspends itself after each time it has been run to simulate
michael@0 392 * waiting for data from an external device.
michael@0 393 * @param {Scheduler} scheduler the scheduler that manages this task
michael@0 394 * @constructor
michael@0 395 */
michael@0 396 function DeviceTask(scheduler) {
michael@0 397 this.scheduler = scheduler;
michael@0 398 this.v1 = null;
michael@0 399 }
michael@0 400
michael@0 401 DeviceTask.prototype.run = function (packet) {
michael@0 402 if (packet == null) {
michael@0 403 if (this.v1 == null) return this.scheduler.suspendCurrent();
michael@0 404 var v = this.v1;
michael@0 405 this.v1 = null;
michael@0 406 return this.scheduler.queue(v);
michael@0 407 } else {
michael@0 408 this.v1 = packet;
michael@0 409 return this.scheduler.holdCurrent();
michael@0 410 }
michael@0 411 };
michael@0 412
michael@0 413 DeviceTask.prototype.toString = function () {
michael@0 414 return "DeviceTask";
michael@0 415 };
michael@0 416
michael@0 417 /**
michael@0 418 * A task that manipulates work packets.
michael@0 419 * @param {Scheduler} scheduler the scheduler that manages this task
michael@0 420 * @param {int} v1 a seed used to specify how work packets are manipulated
michael@0 421 * @param {int} v2 another seed used to specify how work packets are manipulated
michael@0 422 * @constructor
michael@0 423 */
michael@0 424 function WorkerTask(scheduler, v1, v2) {
michael@0 425 this.scheduler = scheduler;
michael@0 426 this.v1 = v1;
michael@0 427 this.v2 = v2;
michael@0 428 }
michael@0 429
michael@0 430 WorkerTask.prototype.run = function (packet) {
michael@0 431 if (packet == null) {
michael@0 432 return this.scheduler.suspendCurrent();
michael@0 433 } else {
michael@0 434 if (this.v1 == ID_HANDLER_A) {
michael@0 435 this.v1 = ID_HANDLER_B;
michael@0 436 } else {
michael@0 437 this.v1 = ID_HANDLER_A;
michael@0 438 }
michael@0 439 packet.id = this.v1;
michael@0 440 packet.a1 = 0;
michael@0 441 for (var i = 0; i < DATA_SIZE; i++) {
michael@0 442 this.v2++;
michael@0 443 if (this.v2 > 26) this.v2 = 1;
michael@0 444 packet.a2[i] = this.v2;
michael@0 445 }
michael@0 446 return this.scheduler.queue(packet);
michael@0 447 }
michael@0 448 };
michael@0 449
michael@0 450 WorkerTask.prototype.toString = function () {
michael@0 451 return "WorkerTask";
michael@0 452 };
michael@0 453
michael@0 454 /**
michael@0 455 * A task that manipulates work packets and then suspends itself.
michael@0 456 * @param {Scheduler} scheduler the scheduler that manages this task
michael@0 457 * @constructor
michael@0 458 */
michael@0 459 function HandlerTask(scheduler) {
michael@0 460 this.scheduler = scheduler;
michael@0 461 this.v1 = null;
michael@0 462 this.v2 = null;
michael@0 463 }
michael@0 464
michael@0 465 HandlerTask.prototype.run = function (packet) {
michael@0 466 if (packet != null) {
michael@0 467 if (packet.kind == KIND_WORK) {
michael@0 468 this.v1 = packet.addTo(this.v1);
michael@0 469 } else {
michael@0 470 this.v2 = packet.addTo(this.v2);
michael@0 471 }
michael@0 472 }
michael@0 473 if (this.v1 != null) {
michael@0 474 var count = this.v1.a1;
michael@0 475 var v;
michael@0 476 if (count < DATA_SIZE) {
michael@0 477 if (this.v2 != null) {
michael@0 478 v = this.v2;
michael@0 479 this.v2 = this.v2.link;
michael@0 480 v.a1 = this.v1.a2[count];
michael@0 481 this.v1.a1 = count + 1;
michael@0 482 return this.scheduler.queue(v);
michael@0 483 }
michael@0 484 } else {
michael@0 485 v = this.v1;
michael@0 486 this.v1 = this.v1.link;
michael@0 487 return this.scheduler.queue(v);
michael@0 488 }
michael@0 489 }
michael@0 490 return this.scheduler.suspendCurrent();
michael@0 491 };
michael@0 492
michael@0 493 HandlerTask.prototype.toString = function () {
michael@0 494 return "HandlerTask";
michael@0 495 };
michael@0 496
michael@0 497 /* --- *
michael@0 498 * P a c k e t
michael@0 499 * --- */
michael@0 500
michael@0 501 var DATA_SIZE = 4;
michael@0 502
michael@0 503 /**
michael@0 504 * A simple package of data that is manipulated by the tasks. The exact layout
michael@0 505 * of the payload data carried by a packet is not importaint, and neither is the
michael@0 506 * nature of the work performed on packets by the tasks.
michael@0 507 *
michael@0 508 * Besides carrying data, packets form linked lists and are hence used both as
michael@0 509 * data and worklists.
michael@0 510 * @param {Packet} link the tail of the linked list of packets
michael@0 511 * @param {int} id an ID for this packet
michael@0 512 * @param {int} kind the type of this packet
michael@0 513 * @constructor
michael@0 514 */
michael@0 515 function Packet(link, id, kind) {
michael@0 516 this.link = link;
michael@0 517 this.id = id;
michael@0 518 this.kind = kind;
michael@0 519 this.a1 = 0;
michael@0 520 this.a2 = new Array(DATA_SIZE);
michael@0 521 }
michael@0 522
michael@0 523 /**
michael@0 524 * Add this packet to the end of a worklist, and return the worklist.
michael@0 525 * @param {Packet} queue the worklist to add this packet to
michael@0 526 */
michael@0 527 Packet.prototype.addTo = function (queue) {
michael@0 528 this.link = null;
michael@0 529 if (queue == null) return this;
michael@0 530 var peek, next = queue;
michael@0 531 while ((peek = next.link) != null)
michael@0 532 next = peek;
michael@0 533 next.link = this;
michael@0 534 return queue;
michael@0 535 };
michael@0 536
michael@0 537 Packet.prototype.toString = function () {
michael@0 538 return "Packet";
michael@0 539 };

mercurial