| 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 | 
| 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | 
| 12  * GNU General Public License for more details. | 12  * GNU General Public License for more details. | 
| 13  * | 13  * | 
| 14  * You should have received a copy of the GNU General Public License | 14  * You should have received a copy of the GNU General Public License | 
| 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 15  * along with Adblock Plus.  If not, see <http://www.gnu.org/licenses/>. | 
| 16  */ | 16  */ | 
| 17 | 17 | 
| 18 "use strict"; | 18 "use strict"; | 
| 19 | 19 | 
| 20 let {fixedPropertyDescriptor, getViewsForType, defineProperties} = require("type
     dObjects/utils"); | 20 let {fixedPropertyDescriptor, getViewsForType, defineProperties, alloc, dealloc}
      = require("typedObjects/utils"); | 
| 21 let {Reference, TypedReference} = require("typedObjects/references"); | 21 let {Reference, TypedReference} = require("typedObjects/references"); | 
| 22 let {uint8, uint32} = require("typedObjects/primitiveTypes"); | 22 let {uint8, uint32} = require("typedObjects/primitiveTypes"); | 
|  | 23 let {createArrayType} = require("typedObjects/arrayTypes"); | 
| 23 | 24 | 
| 24 const STATE_UNINITIALIZED = 0; | 25 const STATE_UNINITIALIZED = exports.STATE_UNINITIALIZED = 0; | 
| 25 const STATE_CREATED = 1; | 26 const STATE_CREATED = exports.STATE_CREATED = 1; | 
| 26 const STATE_RELEASING = 2; | 27 const STATE_RELEASING = exports.STATE_RELEASING = 2; | 
| 27 | 28 | 
| 28 /** | 29 /** | 
| 29  * List of registered types (typeId is the index in that array). | 30  * List of registered types (typeId is the index in that array). | 
| 30  */ | 31  */ | 
| 31 let types = []; | 32 let types = []; | 
| 32 | 33 | 
| 33 function fromReference(reference) | 34 function fromReference(reference) | 
| 34 { | 35 { | 
| 35   let typeInfo = reference.typeInfo; | 36   let typeInfo = reference.typeInfo; | 
| 36   if (typeInfo) | 37   if (typeInfo) | 
| 37   { | 38   { | 
| 38     return Object.create(typeInfo.proto, { | 39     return Object.create(typeInfo.proto, { | 
| 39       typeId: fixedPropertyDescriptor(typeInfo.typeId), | 40       typeId: fixedPropertyDescriptor(typeInfo.typeId), | 
| 40       bufferIndex: fixedPropertyDescriptor(reference.targetBufferIndex), | 41       bufferIndex: fixedPropertyDescriptor(reference.targetBufferIndex), | 
| 41       byteOffset: fixedPropertyDescriptor(reference.targetByteOffset) | 42       byteOffset: fixedPropertyDescriptor(reference.targetByteOffset) | 
| 42     }); | 43     }); | 
| 43   } | 44   } | 
| 44   else | 45   else | 
| 45     return null; | 46     return null; | 
| 46 } | 47 } | 
| 47 | 48 | 
| 48 function create() | 49 function create() | 
| 49 { | 50 { | 
| 50   let {bufferIndex, byteOffset} = this.firstFree; | 51   let [bufferIndex, byteOffset] = alloc(this.firstFree, this.byteLength, | 
| 51   if (bufferIndex >= 0) | 52       this.bufferSize, this.buffers, this.viewTypes, this.views); | 
| 52   { |  | 
| 53     // There is still a free spot, simply move on firstFree reference |  | 
| 54     [this.firstFree.bufferIndex, this.firstFree.byteOffset] = |  | 
| 55         [this.firstFree.targetBufferIndex, this.firstFree.targetByteOffset]; |  | 
| 56   } |  | 
| 57   else |  | 
| 58   { |  | 
| 59     let viewTypes = this.viewTypes; |  | 
| 60     let views = this.views; |  | 
| 61     let byteLength = this.byteLength | 0; |  | 
| 62     let bufferSize = this.bufferSize | 0; |  | 
| 63 |  | 
| 64     // Create new buffer and use the first element of it |  | 
| 65     let buffer = new ArrayBuffer(byteLength * bufferSize); |  | 
| 66     bufferIndex = (this.buffers.push(buffer) | 0) - 1; |  | 
| 67     byteOffset = 0; |  | 
| 68     for (let i = 0, l = viewTypes.length | 0; i < l; i++) |  | 
| 69       views[i].push(new viewTypes[i](buffer)); |  | 
| 70 |  | 
| 71     // Mark last element of the new buffer as the last free spot |  | 
| 72     this.firstFree.bufferIndex = bufferIndex; |  | 
| 73     this.firstFree.byteOffset = (bufferSize - 1) * byteLength; |  | 
| 74     this.firstFree.targetBufferIndex = -1; |  | 
| 75 |  | 
| 76     // Make each remaining element of the new buffer point to the next one |  | 
| 77     for (let i = bufferSize - 2; i >= 1; i--) |  | 
| 78     { |  | 
| 79       let nextByteOffset = this.firstFree.byteOffset; |  | 
| 80       this.firstFree.byteOffset = nextByteOffset - byteLength; |  | 
| 81       this.firstFree.targetBufferIndex = bufferIndex; |  | 
| 82       this.firstFree.targetByteOffset = nextByteOffset; |  | 
| 83     } |  | 
| 84   } |  | 
| 85 | 53 | 
| 86   let result = Object.create(this.proto, { | 54   let result = Object.create(this.proto, { | 
| 87     typeId: fixedPropertyDescriptor(this.typeId), | 55     typeId: fixedPropertyDescriptor(this.typeId), | 
| 88     bufferIndex: fixedPropertyDescriptor(bufferIndex), | 56     bufferIndex: fixedPropertyDescriptor(bufferIndex), | 
| 89     byteOffset: fixedPropertyDescriptor(byteOffset) | 57     byteOffset: fixedPropertyDescriptor(byteOffset) | 
| 90   }); | 58   }); | 
| 91 | 59 | 
| 92   result._state = STATE_UNINITIALIZED; | 60   result._state = STATE_UNINITIALIZED; | 
| 93   for (let [prop, value] of this.cleanupValues) | 61   for (let [prop, value] of this.cleanupValues) | 
| 94     result[prop] = value; | 62     result[prop] = value; | 
| (...skipping 14 matching lines...) Expand all  Loading... | 
| 109       this.destructor.call(obj); | 77       this.destructor.call(obj); | 
| 110       if (obj._refCount | 0) | 78       if (obj._refCount | 0) | 
| 111         throw new Error("Reference count is no longer zero after calling the des
     tructor"); | 79         throw new Error("Reference count is no longer zero after calling the des
     tructor"); | 
| 112     } | 80     } | 
| 113   } | 81   } | 
| 114   finally | 82   finally | 
| 115   { | 83   { | 
| 116     for (let [prop, value] of this.cleanupValues) | 84     for (let [prop, value] of this.cleanupValues) | 
| 117       obj[prop] = value; | 85       obj[prop] = value; | 
| 118 | 86 | 
| 119     // Mark object as first free spot | 87     dealloc(this.firstFree, obj.bufferIndex, obj.byteOffset); | 
| 120     let oldFreeBufferIndex = this.firstFree.bufferIndex; |  | 
| 121     let oldFreeByteOffset = this.firstFree.byteOffset; |  | 
| 122     this.firstFree.bufferIndex = obj.bufferIndex; |  | 
| 123     this.firstFree.byteOffset = obj.byteOffset; |  | 
| 124     this.firstFree.targetBufferIndex = oldFreeBufferIndex; |  | 
| 125     this.firstFree.targetByteOffset = oldFreeByteOffset; |  | 
| 126   } | 88   } | 
| 127 } | 89 } | 
| 128 | 90 | 
| 129 function createGetter(offset) | 91 function createGetter(offset) | 
| 130 { | 92 { | 
| 131   offset = offset | 0; | 93   offset = offset | 0; | 
| 132 | 94 | 
| 133   let views = Array.prototype.slice.call(arguments, 1); | 95   let views = Array.prototype.slice.call(arguments, 1); | 
| 134   let reference = new Reference(types, views); | 96   let reference = new Reference(types, views); | 
| 135   return function() | 97   return function(bufferIndex, byteOffset) | 
| 136   { | 98   { | 
| 137     reference.bufferIndex = this.bufferIndex | 0; | 99     reference.bufferIndex = bufferIndex | 0; | 
| 138     reference.byteOffset = (this.byteOffset | 0) + offset; | 100     reference.byteOffset = (byteOffset | 0) + offset; | 
| 139     return fromReference(reference); | 101     return fromReference(reference); | 
| 140   }; | 102   }; | 
| 141 } | 103 } | 
| 142 | 104 | 
| 143 function createSetter(typeId, offset) | 105 function createSetter(typeId, offset) | 
| 144 { | 106 { | 
| 145   typeId = typeId | 0; | 107   typeId = typeId | 0; | 
| 146   offset = offset | 0; | 108   offset = offset | 0; | 
| 147 | 109 | 
| 148   let views = Array.prototype.slice.call(arguments, 2); | 110   let views = Array.prototype.slice.call(arguments, 2); | 
| 149   let reference = new Reference(types, views); | 111   let reference = new Reference(types, views); | 
| 150   return function(value) | 112   return function(bufferIndex, byteOffset, value) | 
| 151   { | 113   { | 
| 152     if (value && !isInstance(typeId, value)) | 114     if (value && !isInstance(typeId, value)) | 
| 153       throw new Error("Incompatible type"); | 115       throw new Error("Incompatible type"); | 
| 154 | 116 | 
| 155     reference.bufferIndex = this.bufferIndex | 0; | 117     reference.bufferIndex = bufferIndex | 0; | 
| 156     reference.byteOffset = (this.byteOffset | 0) + offset; | 118     reference.byteOffset = (byteOffset | 0) + offset; | 
| 157 | 119 | 
| 158     if ((this._state | 0) > STATE_UNINITIALIZED) | 120     if ((this._state | 0) > STATE_UNINITIALIZED) | 
| 159     { | 121     { | 
| 160       let oldValue = fromReference(reference); | 122       let oldValue = fromReference(reference); | 
| 161       if (oldValue) | 123       if (oldValue) | 
| 162         oldValue.release(); | 124         oldValue.release(); | 
| 163     } | 125     } | 
| 164 | 126 | 
| 165     if (value) | 127     if (value) | 
| 166     { | 128     { | 
| (...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 234         throw new Error("Method " + name + " masks a property with the same name
     "); | 196         throw new Error("Method " + name + " masks a property with the same name
     "); | 
| 235 | 197 | 
| 236       if (name in methods) | 198       if (name in methods) | 
| 237         type = createSubclassMethod(type, methods[name].value); | 199         type = createSubclassMethod(type, methods[name].value); | 
| 238       methods[name] = fixedPropertyDescriptor(type); | 200       methods[name] = fixedPropertyDescriptor(type); | 
| 239     } | 201     } | 
| 240     else | 202     else | 
| 241       throw new Error("Unrecognized type " + type + " given for property " + nam
     e); | 203       throw new Error("Unrecognized type " + type + " given for property " + nam
     e); | 
| 242   } | 204   } | 
| 243 | 205 | 
|  | 206   // Combine inherited watchers with the ones specified for this object | 
|  | 207   let watchers = parentTypeInfo && parentTypeInfo.watchers; | 
|  | 208   if (meta.watch) | 
|  | 209   { | 
|  | 210     watchers = Object.create(watchers); | 
|  | 211     for (let key in meta.watch) | 
|  | 212       watchers[key] = meta.watch[key]; | 
|  | 213   } | 
|  | 214 | 
| 244   let proto = {}; | 215   let proto = {}; | 
| 245   let buffers = []; | 216   let buffers = []; | 
| 246   let viewTypes = []; | 217   let viewTypes = []; | 
| 247   let views = []; | 218   let views = []; | 
| 248   let cleanupValues = []; | 219   let cleanupValues = []; | 
| 249   let byteLength = defineProperties(proto, properties, viewTypes, views, 0, clea
     nupValues); | 220   let byteLength = defineProperties(proto, properties, viewTypes, views, 0, watc
     hers, cleanupValues); | 
| 250   Object.defineProperties(proto, methods); | 221   Object.defineProperties(proto, methods); | 
| 251 | 222 | 
| 252   // Round up to be a multiple of the maximal property size | 223   // Round up to be a multiple of the maximal property size | 
| 253   byteLength = ((byteLength - 1) | (maxReferenceLength - 1)) + 1; | 224   byteLength = ((byteLength - 1) | (maxReferenceLength - 1)) + 1; | 
| 254 | 225 | 
| 255   // We need to be able to store a typed reference in the object's buffer | 226   // We need to be able to store a typed reference in the object's buffer | 
| 256   byteLength = Math.max(byteLength, TypedReference.byteLength) | 0; | 227   byteLength = Math.max(byteLength, TypedReference.byteLength) | 0; | 
| 257   let typedReferenceViews = getViewsForType(TypedReference, viewTypes, views); | 228   let typedReferenceViews = getViewsForType(TypedReference, viewTypes, views); | 
| 258 | 229 | 
| 259   // Take constructor and destructor from meta parameters, allow calling | 230   // Take constructor and destructor from meta parameters, allow calling | 
| (...skipping 17 matching lines...) Expand all  Loading... | 
| 277   } | 248   } | 
| 278 | 249 | 
| 279   let typeId = types.length | 0; | 250   let typeId = types.length | 0; | 
| 280   let typeInfo = { | 251   let typeInfo = { | 
| 281     byteLength: byteLength, | 252     byteLength: byteLength, | 
| 282     bufferSize: "bufferSize" in meta ? Math.max(meta.bufferSize | 0, 2) : 128, | 253     bufferSize: "bufferSize" in meta ? Math.max(meta.bufferSize | 0, 2) : 128, | 
| 283     firstFree: new TypedReference(typeId, typedReferenceViews), | 254     firstFree: new TypedReference(typeId, typedReferenceViews), | 
| 284     proto: proto, | 255     proto: proto, | 
| 285     properties: properties, | 256     properties: properties, | 
| 286     methods: methods, | 257     methods: methods, | 
|  | 258     watchers: watchers, | 
| 287     buffers: buffers, | 259     buffers: buffers, | 
| 288     viewTypes: viewTypes, | 260     viewTypes: viewTypes, | 
| 289     views: views, | 261     views: views, | 
| 290     cleanupValues: cleanupValues, | 262     cleanupValues: cleanupValues, | 
| 291     typeId: typeId, | 263     typeId: typeId, | 
| 292     parentTypeInfo: parentTypeInfo, | 264     parentTypeInfo: parentTypeInfo, | 
| 293     constructor: constructor, | 265     constructor: constructor, | 
| 294     destructor: destructor | 266     destructor: destructor | 
| 295   }; | 267   }; | 
| 296 | 268 | 
| 297   let result = create.bind(typeInfo); | 269   let result = create.bind(typeInfo); | 
| 298   Object.defineProperties(result, { | 270   Object.defineProperties(result, { | 
| 299     byteLength: fixedPropertyDescriptor(byteLength), | 271     byteLength: fixedPropertyDescriptor(byteLength), | 
| 300 | 272 | 
| 301     referenceLength: fixedPropertyDescriptor(Reference.byteLength), | 273     referenceLength: fixedPropertyDescriptor(Reference.byteLength), | 
| 302     viewTypes: fixedPropertyDescriptor(Reference.viewTypes), | 274     viewTypes: fixedPropertyDescriptor(Reference.viewTypes), | 
| 303     cleanupValue: fixedPropertyDescriptor(null), | 275     cleanupValue: fixedPropertyDescriptor(null), | 
| 304 | 276 | 
| 305     typeId: fixedPropertyDescriptor(typeId), | 277     typeId: fixedPropertyDescriptor(typeId), | 
| 306     extend: fixedPropertyDescriptor(extend.bind(null, typeInfo)), | 278     extend: fixedPropertyDescriptor(extend.bind(null, typeInfo)), | 
| 307     isInstance: fixedPropertyDescriptor(isInstance.bind(null, typeId)), | 279     isInstance: fixedPropertyDescriptor(isInstance.bind(null, typeId)), | 
|  | 280     Array: fixedPropertyDescriptor(createArrayType.bind(null, result)), | 
| 308 | 281 | 
| 309     createGetter: fixedPropertyDescriptor(createGetter), | 282     createGetter: fixedPropertyDescriptor(createGetter), | 
| 310     createSetter: fixedPropertyDescriptor(createSetter.bind(null, typeId)) | 283     createSetter: fixedPropertyDescriptor(createSetter.bind(null, typeId)) | 
| 311   }); | 284   }); | 
| 312   types.push(typeInfo); | 285   types.push(typeInfo); | 
| 313   return result; | 286   return result; | 
| 314 } | 287 } | 
| 315 | 288 | 
| 316 function isInstance(typeId, obj) | 289 function isInstance(typeId, obj) | 
| 317 { | 290 { | 
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
| 350     this._refCount--; | 323     this._refCount--; | 
| 351     if (this._refCount == 0 && this._state < STATE_RELEASING) | 324     if (this._refCount == 0 && this._state < STATE_RELEASING) | 
| 352     { | 325     { | 
| 353       this._state = STATE_RELEASING; | 326       this._state = STATE_RELEASING; | 
| 354       free.call(types[this.typeId | 0], this); | 327       free.call(types[this.typeId | 0], this); | 
| 355     } | 328     } | 
| 356   } | 329   } | 
| 357 }, null); | 330 }, null); | 
| 358 | 331 | 
| 359 exports.ObjectType = ObjectBase.extend; | 332 exports.ObjectType = ObjectBase.extend; | 
| OLD | NEW | 
|---|