js/src/parjs-benchmarks/rectarray.js

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     1 // -*- mode: js2; indent-tabs-mode: nil; -*-
     3 // A RectArray<X,k> is a subclass of Array with 'width', 'height',
     4 // and 'payload' properties (where payload holds 'k').
     5 // properties, and 'width*height*k' elements (each an X) in the array.
     6 //
     7 // A RectTypedByteArray<k> is a subclass of ArrayBuffer with 'width'
     8 // and 'height' properties, and 'width*height*k' bytes in the buffer.
     9 //
    10 // The 'payload' property is initialized with the value of 'k'.
    11 //
    12 // (Felix would have used Array or ArrayView, but for the following bug: 
    13 //   Bug 695438 - TypedArrays don't support new named properties
    14 //   https://bugzilla.mozilla.org/show_bug.cgi?id=695438
    15 //  and so he is resorting to extending ArrayBuffer instead.)
    16 //
    17 // Both classes add a .get(x,y[,k]) method that eases access to the
    18 // contents, and a set(x,y[,k],value) method that eases modifying
    19 // their entries.
    20 //
    21 // In addition, for those who prefer functional-style,
    22 // RectArray.build,
    23 // and RectByteTypedArray.build
    25 var RectArray, RectByteTypedArray;
    27 // This is a variant of RectArray that supports the same interface,
    28 // but instead of attempting to extend Array (a practice fraught with
    29 // peril), it instead makes a wrapper around another array.
    31 var WrapArray, WrapByteTypedArray;
    33 (function (){
    35    function defineReadOnly(x, name, value) {
    36      Object.defineProperty(x, name, {
    37                              value: value,
    38                              writable: false,
    39                              enumerable: true,
    40                              configurable: true });
    41    }
    43    RectArray = function RectArray(w,h,k) {
    44      if (k === undefined)
    45        k = 1;
    46      this.length = w*h*k;
    47      defineReadOnly(this, "width", w);
    48      defineReadOnly(this, "height", h);
    49      defineReadOnly(this, "payload", k);
    50    };
    52    RectByteTypedArray = function RectByteTypedArray(w,h,k) {
    53      if (k === undefined)
    54        k = 1;
    55      ArrayBuffer.call(this, w*h*k);
    56      defineReadOnly(this, "width", w);
    57      defineReadOnly(this, "height", h);
    58      defineReadOnly(this, "payload", k);
    59    };
    61    WrapArray = function WrapArray(w,h,k) {
    62      if (k === undefined)
    63        k = 1;
    64      this.backingArray = new Array(w*h*k);
    65      defineReadOnly(this, "width", w);
    66      defineReadOnly(this, "height", h);
    67      defineReadOnly(this, "payload", k);
    68    };
    70    WrapByteTypedArray = function WrapByteTypedArray(w,h,k) {
    71      if (k === undefined)
    72        k = 1;
    73      this.backingArray = new Uint8Array(new ArrayBuffer(w*h*k));
    74      defineReadOnly(this, "width", w);
    75      defineReadOnly(this, "height", h);
    76      defineReadOnly(this, "payload", k);
    77    };
    79    WrapArray.prototype.slice = function(a,b) this.backingArray.slice(a,b);
    80    WrapArray.prototype.join  = function(a) this.backingArray.join(a);
    82    RectArray.prototype = new Array();
    83    RectByteTypedArray.prototype = new ArrayBuffer();
    85    RectArray.prototype.get = function get(x,y,j) {
    86      if (j === undefined) j = 0;
    87      return this[(y*this.width+x)*this.payload+j];
    88    };
    90    RectArray.prototype.set = function set(x,y,j,value) {
    91      if (value === undefined) {
    92        value = j;
    93        j = 0;
    94      }
    95      this[(y*this.width+x)*this.payload+j] = value;
    96    };
    98    RectByteTypedArray.prototype.get = function get(x,y,j) {
    99      if (j === undefined) j = 0;
   100      return (new Uint8Array(this))[(y*this.width+x)*this.payload+j];
   101    };
   103    RectByteTypedArray.prototype.set = function set(x,y,j,value) {
   104      if (value === undefined) {
   105        value = j;
   106        j = 0;
   107      }
   108      (new Uint8Array(this))[(y*this.width+x)*this.payload+j] = value;
   109    };
   111    WrapArray.prototype.get = function get(x,y,j) {
   112      if (j === undefined) j = 0;
   113      return this.backingArray[(y*this.width+x)*this.payload+j];
   114    };
   116    WrapArray.prototype.set = function set(x,y,j,value) {
   117      if (value === undefined) {
   118        value = j;
   119        j = 0;
   120      }
   121      this.backingArray[(y*this.width+x)*this.payload+j] = value;
   122    };
   124    WrapByteTypedArray.prototype.get = function get(x,y,j) {
   125      if (j === undefined) j = 0;
   126      return this.backingArray[(y*this.width+x)*this.payload+j];
   127    };
   129    WrapByteTypedArray.prototype.set = function set(x,y,j,value) {
   130      if (value === undefined) {
   131        value = j;
   132        j = 0;
   133      }
   134      this.backingArray[(y*this.width+x)*this.payload+j] = value;
   135    };
   137    function viewToSource(view, width, height, payload) {
   138      var ret = "[";
   139      var i=0;
   140      var matrixNeedsNewline = false;
   141      for (var row=0; row < height; row++) {
   142        if (matrixNeedsNewline)
   143          ret += ",\n ";
   144        ret += "[";
   145        var rowNeedsComma = false;
   146        for (var x=0; x < width; x++) {
   147          if (rowNeedsComma)
   148            ret += ", ";
   149          if (payload == 1) {
   150            if (view[i] !== undefined)
   151              ret += view[i];
   152            i++;
   153          } else {
   154            var entryNeedsComma = false;
   155            ret += "(";
   156            for (var k=0; k < payload; k++) {
   157              // Might be inefficient (does JavaScript have
   158              // StringBuffers?, or use them internally, like Tamarin?)
   159              if (entryNeedsComma)
   160                ret += ", ";
   161              if (view[i] !== undefined)
   162                ret += view[i];
   163              entryNeedsComma = true;
   164              i++;
   165            }
   166            ret += ")";
   167          }
   168          rowNeedsComma = true;
   169        }
   170        ret += "]";
   171        matrixNeedsNewline = true;
   172      }
   173      ret += "]";
   174      return ret;
   175    }
   177    RectArray.prototype.toSource = function toSource() {
   178      return viewToSource(this,
   179                          this.width, this.height, this.payload);
   180    };
   182    RectByteTypedArray.prototype.toSource = function toSource() {
   183      return viewToSource(new Uint8Array(this),
   184                          this.width, this.height, this.payload);
   185    };
   187    WrapArray.prototype.toSource = function toSource() {
   188      return viewToSource(this.backingArray,
   189                          this.width, this.height, this.payload);
   190    };
   192    WrapByteTypedArray.prototype.toSource = function toSource() {
   193      return viewToSource(this.backingArray,
   194                          this.width, this.height, this.payload);
   195    };
   197    RectArray.prototype.map = function map(f) {
   198      var ret = Array.map(this, f);
   199      ret.__proto__ = RectArray.prototype;
   200      defineReadOnly(ret, "width", this.width);
   201      defineReadOnly(ret, "height", this.height);
   202      defineReadOnly(ret, "payload", this.payload);
   203      return ret;
   204    };
   206    WrapArray.prototype.map = function map(f) {
   207      var ret = new WrapArray(this.width, this.height, this.payload);
   208      ret.backingArray = this.backingArray.map(f);
   209      return ret;
   210    };
   212    // (Array<X>|ArrayView<X>) Nat Nat Nat (Nat Nat Nat -> X) -> void
   213    function fillArrayView(view, width, height, k, fill) {
   214      var i = 0;
   215      for (var y=0; y < height; y++) {
   216        for (var x=0; x < width; x++) {
   217          for (var j=0; j < k; j++) {
   218            view[i++] = fill(x, y, j);
   219          }
   220        }
   221      }
   222    }
   225    // Nat Nat (Nat Nat [Nat] -> X) -> RectArray<X,1>
   226    RectArray.build =
   227      function buildRectArray1(width, height, fill) {
   228        var a = new RectArray(width, height, 1);
   229        fillArrayView(a, width, height, 1, fill);
   230        return a;
   231      };
   233    RectArray.buildA =
   234      function buildRectArrayA(width, height, fill) {
   235        var a = new Array(width*height);
   236        fillArrayView(a, width, height, 1, fill);
   237        a.width = width;
   238        a.height = height;
   239        a.payload = 1;
   240        function F() { }
   241        F.prototype = RectArray.prototype;
   242        a.__proto__ = new F();
   243        return a;
   244      };
   246    // Nat Nat (Nat Nat Nat -> X) -> RectArray<X,4>
   247    RectArray.build4 =
   248      function buildRectArray4(width, height, fill) {
   249        var a = new RectArray(width, height, 4);
   250        fillArrayView(a, width, height, 4, fill);
   251        return a;
   252      };
   254    // Nat Nat (Nat Nat Nat -> X) -> RectArray<X,1>
   255    RectArray.buildN =
   256      function buildRectArrayN(width, height, n, fill) {
   257        var a = new RectArray(width, height, n);
   258        fillArrayView(a, width, height, n, fill);
   259        return a;
   260      };
   263    // Nat Nat (Nat Nat [Nat] -> Byte) -> RectTypedByteArray<4>
   264    RectByteTypedArray.build =
   265      function buildRectByteTypedArray1(width, height, fill) {
   266        var buf = new RectByteTypedArray(width, height, 1);
   267        fillArrayView(new Uint8Array(buf), width, height, 1, fill);
   268        return buf;
   269      };
   271    // Nat Nat (Nat Nat Nat -> Byte) -> RectTypedByteArray<4>
   272    RectByteTypedArray.build4 =
   273      function buildRectByteTypedArray4(width, height, fill) {
   274        var buf = new RectByteTypedArray(width, height, 4);
   275        fillArrayView(new Uint8Array(buf), width, height, 4, fill);
   276        return buf;
   277      };
   279    // Nat Nat (Nat Nat Nat -> Byte) -> RectTypedByteArray<4>
   280    RectByteTypedArray.buildN =
   281      function buildRectByteTypedArray4(width, height, n, fill) {
   282        var buf = new RectByteTypedArray(width, height, n);
   283        fillArrayView(new Uint8Array(buf), width, height, n, fill);
   284        return buf;
   285      };
   287    WrapArray.build =
   288      function buildWrapArray1(width, height, fill) {
   289        var a = new WrapArray(width, height, 1);
   290        fillArrayView(a, width, height, 1, fill);
   291        return a;
   292      };
   294    WrapArray.build =
   295      function buildWrapArray1(width, height, fill) {
   296        var a = new WrapArray(width, height, 1);
   297        fillArrayView(a.backingArray, width, height, 1, fill);
   298        return a;
   299      };
   301    WrapArray.build4 =
   302      function buildWrapArray1(width, height, fill) {
   303        var a = new WrapArray(width, height, 4);
   304        fillArrayView(a.backingArray, width, height, 4, fill);
   305        return a;
   306      };
   308    WrapArray.buildN =
   309      function buildWrapArray1(width, height, n, fill) {
   310        var a = new WrapArray(width, height, n);
   311        fillArrayView(a.backingArray, width, height, n, fill);
   312        return a;
   313      };
   315  })();

mercurial