| OLD | NEW | 
|---|
| 1 /* | 1 /* | 
| 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 2  * This file is part of Adblock Plus <http://adblockplus.org/>, | 
| 3  * Copyright (C) 2006-2014 Eyeo GmbH | 3  * Copyright (C) 2006-2014 Eyeo GmbH | 
| 4  * | 4  * | 
| 5  * Adblock Plus is free software: you can redistribute it and/or modify | 5  * Adblock Plus is free software: you can redistribute it and/or modify | 
| 6  * it under the terms of the GNU General Public License version 3 as | 6  * it under the terms of the GNU General Public License version 3 as | 
| 7  * published by the Free Software Foundation. | 7  * published by the Free Software Foundation. | 
| 8  * | 8  * | 
| 9  * Adblock Plus is distributed in the hope that it will be useful, | 9  * Adblock Plus is distributed in the hope that it will be useful, | 
| 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10  * but WITHOUT ANY WARRANTY; without even the implied warranty of | 
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 80     if (index < 0) | 80     if (index < 0) | 
| 81     { | 81     { | 
| 82       index = (viewTypes.push(viewType) | 0) - 1; | 82       index = (viewTypes.push(viewType) | 0) - 1; | 
| 83       views.push([]); | 83       views.push([]); | 
| 84     } | 84     } | 
| 85     result.push(views[index]); | 85     result.push(views[index]); | 
| 86   } | 86   } | 
| 87   return result; | 87   return result; | 
| 88 }; | 88 }; | 
| 89 | 89 | 
|  | 90  /** | 
|  | 91  * Creates a wrapper function for a setter that will call the watcher function | 
|  | 92  * with the new value of the property before executing the actual setter. | 
|  | 93  */ | 
|  | 94 function watchSetter(/**Function*/ setter, /**Function*/ watcher) /**Function*/ | 
|  | 95 { | 
|  | 96   return function(value) | 
|  | 97   { | 
|  | 98     setter.call(this, watcher.call(this, value)); | 
|  | 99   } | 
|  | 100 } | 
|  | 101 | 
|  | 102 /** | 
|  | 103  * Creates a parameter-less wrapper function around a getter that will get | 
|  | 104  * bufferIndex and byteOffset parameters from object properties. | 
|  | 105  */ | 
|  | 106 function wrapGetter(/**Function*/ getter) /**Function*/ | 
|  | 107 { | 
|  | 108   return function() | 
|  | 109   { | 
|  | 110     return getter.call(this, this.bufferIndex, this.byteOffset); | 
|  | 111   } | 
|  | 112 } | 
|  | 113 | 
|  | 114 /** | 
|  | 115  * Creates a wrapper function around a setter with value as the only parameter, | 
|  | 116  * the bufferIndex and byteOffset parameters will be retrieved from object | 
|  | 117  * properties. | 
|  | 118  */ | 
|  | 119 function wrapSetter(/**Function*/ setter) /**Function*/ | 
|  | 120 { | 
|  | 121   return function(value) | 
|  | 122   { | 
|  | 123     return setter.call(this, this.bufferIndex, this.byteOffset, value); | 
|  | 124   } | 
|  | 125 } | 
|  | 126 | 
| 90 /** | 127 /** | 
| 91  * Defines properties with given name and type on an object. | 128  * Defines properties with given name and type on an object. | 
| 92  * | 129  * | 
| 93  * @param obj object to define properties on | 130  * @param obj object to define properties on | 
| 94  * @param properties object mapping property names to their respective types | 131  * @param properties object mapping property names to their respective types | 
| 95  * @param viewTypes see getViewsForType() | 132  * @param viewTypes see getViewsForType() | 
| 96  * @param views see getViewsForType() | 133  * @param views see getViewsForType() | 
| 97  * @param [offset] byte array offset at which the properties should start | 134  * @param [offset] byte array offset at which the properties should start | 
|  | 135  * @param [watchers] map of watcher functions to be called when a particular pro
     perty is being set | 
| 98  * @param [cleanupValues] array of property/value combinations to be set when th
     e object is created or destroyed | 136  * @param [cleanupValues] array of property/value combinations to be set when th
     e object is created or destroyed | 
| 99  * @return new start offset for additional properties | 137  * @return new start offset for additional properties | 
| 100  */ | 138  */ | 
| 101 exports.defineProperties = function defineProperties(obj, properties, viewTypes,
      views, offset, cleanupValues) | 139 exports.defineProperties = function defineProperties(obj, properties, viewTypes,
      views, offset, watchers, cleanupValues) | 
| 102 { | 140 { | 
| 103   offset = offset | 0; | 141   offset = offset | 0; | 
| 104 | 142 | 
| 105   let propList = []; | 143   let propList = []; | 
| 106   for (let name in properties) | 144   for (let name in properties) | 
| 107     propList.push([name, properties[name]]); | 145     propList.push([name, properties[name]]); | 
| 108 | 146 | 
| 109   // Put larger properties first to make sure alignment requirements are met. | 147   // Put larger properties first to make sure alignment requirements are met. | 
| 110   propList.sort(function(a, b) | 148   propList.sort(function(a, b) | 
| 111   { | 149   { | 
| 112     return b[1].referenceLength - a[1].referenceLength; | 150     return b[1].referenceLength - a[1].referenceLength; | 
| 113   }); | 151   }); | 
| 114 | 152 | 
| 115   // Generates getters and setters for each property. | 153   // Generates getters and setters for each property. | 
| 116   let descriptors = {}; | 154   let descriptors = {}; | 
| 117   for (let i = 0, l = propList.length | 0; i < l; i++) | 155   for (let i = 0, l = propList.length | 0; i < l; i++) | 
| 118   { | 156   { | 
| 119     let [name, type] = propList[i]; | 157     let [name, type] = propList[i]; | 
| 120 | 158 | 
| 121     let viewParams = getViewsForType(type, viewTypes, views); | 159     let viewParams = getViewsForType(type, viewTypes, views); | 
| 122     descriptors[name] = { | 160     descriptors[name] = { | 
| 123       get: type.createGetter.apply(type, [offset].concat(viewParams)), | 161       get: wrapGetter(type.createGetter.apply(type, [offset].concat(viewParams))
     ), | 
| 124       set: type.createSetter.apply(type, [offset].concat(viewParams)), | 162       set: wrapSetter(type.createSetter.apply(type, [offset].concat(viewParams))
     ), | 
| 125       configurable: false, | 163       configurable: false, | 
| 126       enumerable: true | 164       enumerable: true | 
| 127     }; | 165     }; | 
|  | 166 | 
|  | 167     if (watchers && typeof watchers[name] == "function") | 
|  | 168       descriptors[name].set = watchSetter(descriptors[name].set, watchers[name])
     ; | 
|  | 169 | 
| 128     offset += type.referenceLength; | 170     offset += type.referenceLength; | 
| 129     if (cleanupValues && typeof type.cleanupValue != "undefined") | 171     if (cleanupValues && typeof type.cleanupValue != "undefined") | 
| 130       cleanupValues.push([name, type.cleanupValue]); | 172       cleanupValues.push([name, type.cleanupValue]); | 
| 131   } | 173   } | 
| 132 | 174 | 
| 133   // Define properties | 175   // Define properties | 
| 134   Object.defineProperties(obj, descriptors); | 176   Object.defineProperties(obj, descriptors); | 
| 135 | 177 | 
| 136   return offset; | 178   return offset; | 
| 137 }; | 179 }; | 
|  | 180 | 
|  | 181 /** | 
|  | 182  * Creates a new array buffer and adds the necessary views. | 
|  | 183  * | 
|  | 184  * @param {Integer} byteSize  bytes to allocate for the buffer | 
|  | 185  * @param {Array} buffers  existing buffers (will be modified) | 
|  | 186  * @param {Array} viewTypes  view types for the buffers | 
|  | 187  * @param {Array} views  existing buffer views (will be modified) | 
|  | 188  * @result {Integer} index of the buffer created | 
|  | 189  */ | 
|  | 190 let addBuffer = exports.addBuffer = function(byteSize, buffers, viewTypes, views
     ) | 
|  | 191 { | 
|  | 192   let buffer = new ArrayBuffer(byteSize | 0); | 
|  | 193   buffers.push(buffer); | 
|  | 194   for (let i = 0, l = viewTypes.length | 0; i < l; i++) | 
|  | 195     views[i].push(new viewTypes[i](buffer)); | 
|  | 196   return (buffers.length | 0) - 1; | 
|  | 197 } | 
|  | 198 | 
|  | 199 /** | 
|  | 200  * Releases an array buffer. | 
|  | 201  * | 
|  | 202  * @param {Integer} bufferIndex  index of the buffer to be released. | 
|  | 203  * @param {Array} buffers  existing buffers (will be modified) | 
|  | 204  * @param {Array} views  existing buffer views (will be modified) | 
|  | 205  */ | 
|  | 206 exports.removeBuffer = function(bufferIndex, buffers, views) | 
|  | 207 { | 
|  | 208   delete buffers[bufferIndex]; | 
|  | 209   for (let i = 0, l = views.length | 0; i < l; i++) | 
|  | 210     delete views[i][bufferIndex]; | 
|  | 211 } | 
|  | 212 | 
|  | 213 /** | 
|  | 214  * Allocates a new fixed-size element. It will return the first available free | 
|  | 215  * block or create a new buffer if the existing ones have no space left. | 
|  | 216  * | 
|  | 217  * @param {TypedReference} firstFree  head of the linked list pointing to unallo
     cated elements | 
|  | 218  * @param {Integer} byteLength  size of an element | 
|  | 219  * @param {Integer} bufferSize  number of elements in a buffer | 
|  | 220  * @param {Array} buffers  existing buffers (might be modified in necessary) | 
|  | 221  * @param {Array} viewTypes  view types for the buffers | 
|  | 222  * @param {Array} views  existing buffer views (might be modified if necessary) | 
|  | 223  * @result {Array} [bufferIndex, byteOffset] parameters of the newly allocated b
     lock | 
|  | 224  */ | 
|  | 225 exports.alloc = function(firstFree, byteLength, bufferSize, buffers, viewTypes, 
     views) | 
|  | 226 { | 
|  | 227   let bufferIndex = firstFree.bufferIndex | 0; | 
|  | 228   let byteOffset = firstFree.byteOffset | 0; | 
|  | 229   if (bufferIndex >= 0) | 
|  | 230   { | 
|  | 231     // There is still a free spot, simply move on firstFree reference | 
|  | 232     [firstFree.bufferIndex, firstFree.byteOffset] = | 
|  | 233         [firstFree.targetBufferIndex, firstFree.targetByteOffset]; | 
|  | 234   } | 
|  | 235   else | 
|  | 236   { | 
|  | 237     byteLength = byteLength | 0; | 
|  | 238     bufferSize = bufferSize | 0; | 
|  | 239 | 
|  | 240     // Create new buffer and use the first element of it | 
|  | 241     bufferIndex = addBuffer(byteLength * bufferSize, buffers, viewTypes, views); | 
|  | 242     byteOffset = 0; | 
|  | 243 | 
|  | 244     // Mark last element of the new buffer as the last free spot | 
|  | 245     firstFree.bufferIndex = bufferIndex; | 
|  | 246     firstFree.byteOffset = (bufferSize - 1) * byteLength; | 
|  | 247     firstFree.targetBufferIndex = -1; | 
|  | 248 | 
|  | 249     // Make each remaining element of the new buffer point to the next one | 
|  | 250     for (let i = bufferSize - 2; i >= 1; i--) | 
|  | 251     { | 
|  | 252       let nextByteOffset = firstFree.byteOffset; | 
|  | 253       firstFree.byteOffset = nextByteOffset - byteLength; | 
|  | 254       firstFree.targetBufferIndex = bufferIndex; | 
|  | 255       firstFree.targetByteOffset = nextByteOffset; | 
|  | 256     } | 
|  | 257   } | 
|  | 258   return [bufferIndex, byteOffset]; | 
|  | 259 }; | 
|  | 260 | 
|  | 261 /** | 
|  | 262  * Releases the block at given offset so that it can be allocated again. | 
|  | 263  * | 
|  | 264  * @param {TypedReference} firstFree  head of the linked list pointing to unallo
     cated elements | 
|  | 265  * @param {Integer} bufferIndex  buffer index of the block to be released | 
|  | 266  * @param {Integer} byteOffset  byte offset o fthe block to be released | 
|  | 267  */ | 
|  | 268 exports.dealloc = function(firstFree, bufferIndex, byteOffset) | 
|  | 269 { | 
|  | 270   let oldFreeBufferIndex = firstFree.bufferIndex | 0; | 
|  | 271   let oldFreeByteOffset = firstFree.byteOffset | 0; | 
|  | 272 | 
|  | 273   firstFree.bufferIndex = bufferIndex | 0; | 
|  | 274   firstFree.byteOffset = byteOffset | 0; | 
|  | 275   firstFree.targetBufferIndex = oldFreeBufferIndex; | 
|  | 276   firstFree.targetByteOffset = oldFreeByteOffset; | 
|  | 277 } | 
| OLD | NEW | 
|---|