LEFT | RIGHT |
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 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
78 { | 78 { |
79 let {STATE_UNINITIALIZED} = require("typedObjects/objectTypes"); | 79 let {STATE_UNINITIALIZED} = require("typedObjects/objectTypes"); |
80 return function lengthWatcher(newLength) | 80 return function lengthWatcher(newLength) |
81 { | 81 { |
82 newLength = newLength | 0; | 82 newLength = newLength | 0; |
83 if (newLength < 0) | 83 if (newLength < 0) |
84 newLength = 0; | 84 newLength = 0; |
85 if (newLength > this.size) | 85 if (newLength > this.size) |
86 this.size = newLength; | 86 this.size = newLength; |
87 | 87 |
88 let cleanupValue = elementType.cleanupValue; | 88 let initialValue = elementType.initialValue; |
89 if (typeof cleanupValue != "undefined") | 89 if (typeof initialValue != "undefined") |
90 { | 90 { |
91 let length = this.length; | 91 let length = this.length; |
92 if (newLength > length) | 92 if (newLength > length) |
93 { | 93 { |
94 // We have to call element setter directly here, this.set() will | 94 // We have to call element setter directly here, this.set() will |
95 // complain because of writing out of bounds (new length isn't set yet). | 95 // complain because of writing out of bounds (new length isn't set yet). |
96 // We also need to change state temporarily in order to avoid an attemt | 96 // We also need to change state temporarily in order to avoid an attemt |
97 // to release "existing" values. | 97 // to release "existing" values. |
98 let origState = this._state; | 98 let origState = this._state; |
99 this._state = STATE_UNINITIALIZED; | 99 this._state = STATE_UNINITIALIZED; |
100 try | 100 try |
101 { | 101 { |
102 let referenceLength = elementType.referenceLength | 0; | 102 let referenceLength = elementType.referenceLength | 0; |
103 let bufferIndex = this.arrayBufferIndex | 0; | 103 let bufferIndex = this.arrayBufferIndex | 0; |
104 for (let i = length, offset = this.arrayByteOffset + length * referenc
eLength; | 104 for (let i = length, offset = this.arrayByteOffset + length * referenc
eLength; |
105 i < newLength; | 105 i < newLength; |
106 i++, offset += referenceLength) | 106 i++, offset += referenceLength) |
107 { | 107 { |
108 elementSetter.call(this, bufferIndex, offset, cleanupValue); | 108 elementSetter.call(this, bufferIndex, offset, initialValue); |
109 } | 109 } |
110 } | 110 } |
111 finally | 111 finally |
112 { | 112 { |
113 this._state = origState; | 113 this._state = origState; |
114 } | 114 } |
115 } | 115 } |
116 else | 116 else |
117 { | 117 { |
118 for (let i = newLength; i < length; i++) | 118 for (let i = newLength; i < length; i++) |
119 this.set(i, cleanupValue); | 119 this.set(i, initialValue); |
120 } | 120 } |
121 } | 121 } |
122 | 122 |
123 return newLength; | 123 return newLength; |
124 } | 124 } |
125 } | 125 } |
126 | 126 |
127 function createSizeWatcher(elementType, minElements, bufferSize, buffers, viewTy
pes, views, firstFree) | 127 function createSizeWatcher(elementType, minElements, bufferSize, buffers, viewTy
pes, views, firstFree) |
128 { | 128 { |
129 let referenceLength = elementType.referenceLength | 0; | 129 let referenceLength = elementType.referenceLength | 0; |
(...skipping 22 matching lines...) Expand all Loading... |
152 if (typeof reference != "undefined") | 152 if (typeof reference != "undefined") |
153 { | 153 { |
154 [bufferIndex, byteOffset] = alloc(reference, | 154 [bufferIndex, byteOffset] = alloc(reference, |
155 referenceLength * newSize, (bufferSize / newSize) | 0, | 155 referenceLength * newSize, (bufferSize / newSize) | 0, |
156 buffers, viewTypes, views); | 156 buffers, viewTypes, views); |
157 } | 157 } |
158 else | 158 else |
159 { | 159 { |
160 // This array is too large, it needs an individual buffer | 160 // This array is too large, it needs an individual buffer |
161 bufferIndex = addBuffer(referenceLength * newSize, buffers, viewTypes,
views); | 161 bufferIndex = addBuffer(referenceLength * newSize, buffers, viewTypes,
views); |
| 162 bufferOffset = 0; |
162 } | 163 } |
163 | 164 |
164 if (size > 0) | 165 if (size > 0) |
165 { | 166 { |
166 let copyBytes = length * referenceLength; | 167 let copyBytes = length * referenceLength; |
167 let src = Uint8Array(buffers[this.arrayBufferIndex], this.arrayByteOff
set, copyBytes); | 168 let src = new Uint8Array(buffers[this.arrayBufferIndex], this.arrayByt
eOffset, copyBytes); |
168 let dst = Uint8Array(buffers[bufferIndex], byteOffset, copyBytes); | 169 let dst = new Uint8Array(buffers[bufferIndex], byteOffset, copyBytes); |
169 dst.set(src); | 170 dst.set(src); |
170 } | 171 } |
171 | 172 |
172 this.arrayBufferIndex = bufferIndex; | 173 this.arrayBufferIndex = bufferIndex; |
173 this.arrayByteOffset = byteOffset; | 174 this.arrayByteOffset = byteOffset; |
174 } | 175 } |
175 else | 176 else |
176 this.arrayBufferIndex = -1; | 177 this.arrayBufferIndex = -1; |
177 | 178 |
178 if (size > 0) | 179 if (size > 0) |
(...skipping 19 matching lines...) Expand all Loading... |
198 // We need to make sure that all buffer chunks are big enough to hold a | 199 // We need to make sure that all buffer chunks are big enough to hold a |
199 // reference in order to manage the free chunks as a linked list. Each array | 200 // reference in order to manage the free chunks as a linked list. Each array |
200 // buffer should be dedicated to arrays of particular size - the number of | 201 // buffer should be dedicated to arrays of particular size - the number of |
201 // possible sizes is limited as the sizes can only be powers of two. | 202 // possible sizes is limited as the sizes can only be powers of two. |
202 let {TypedReference} = require("typedObjects/references"); | 203 let {TypedReference} = require("typedObjects/references"); |
203 let minElements = nextPow2(Math.max(Math.ceil(TypedReference.byteLength / elem
entType.referenceLength) | 0, 1)); | 204 let minElements = nextPow2(Math.max(Math.ceil(TypedReference.byteLength / elem
entType.referenceLength) | 0, 1)); |
204 let bufferSize = ("arrayBufferSize" in meta ? meta.arrayBufferSize | 0 : 1024)
; | 205 let bufferSize = ("arrayBufferSize" in meta ? meta.arrayBufferSize | 0 : 1024)
; |
205 bufferSize = nextPow2(Math.max(bufferSize, minElements * 2)) | 0; | 206 bufferSize = nextPow2(Math.max(bufferSize, minElements * 2)) | 0; |
206 | 207 |
207 let buffers = []; | 208 let buffers = []; |
208 let viewTypes = elementType.viewTypes; | 209 let viewTypes = elementType.viewTypes.slice(); |
209 let views = []; | 210 let views = []; |
210 for (let i = 0, l = viewTypes.length | 0; i < l; i++) | 211 for (let i = 0, l = viewTypes.length | 0; i < l; i++) |
211 views.push([]); | 212 views.push([]); |
212 | 213 |
213 let elementGetter = elementType.createGetter.apply(elementType, [0].concat(vie
ws)); | 214 let elementGetter = elementType.createGetter.apply(elementType, [0].concat(vie
ws)); |
214 let elementSetter = elementType.createSetter.apply(elementType, [0].concat(vie
ws)); | 215 let elementSetter = elementType.createSetter.apply(elementType, [0].concat(vie
ws)); |
215 | 216 |
216 let typedReferenceTypes = TypedReference.viewTypes; | 217 let typedReferenceTypes = TypedReference.viewTypes; |
217 let typedReferenceViews = []; | 218 let typedReferenceViews = []; |
218 for (let i = 0, l = typedReferenceTypes.length | 0; i < l; i++) | 219 for (let i = 0, l = typedReferenceTypes.length | 0; i < l; i++) |
(...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
257 meta.watch = {}; | 258 meta.watch = {}; |
258 | 259 |
259 meta.watch.length = createLengthWatcher(elementType, elementSetter); | 260 meta.watch.length = createLengthWatcher(elementType, elementSetter); |
260 meta.watch.size = createSizeWatcher(elementType, minElements, bufferSize, buff
ers, viewTypes, views, firstFree); | 261 meta.watch.size = createSizeWatcher(elementType, minElements, bufferSize, buff
ers, viewTypes, views, firstFree); |
261 | 262 |
262 let {ObjectBase} = require("typedObjects/objectTypes"); | 263 let {ObjectBase} = require("typedObjects/objectTypes"); |
263 return ObjectBase.extend(typeDescriptor, meta); | 264 return ObjectBase.extend(typeDescriptor, meta); |
264 } | 265 } |
265 | 266 |
266 exports.createArrayType = createArrayType; | 267 exports.createArrayType = createArrayType; |
LEFT | RIGHT |