Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(5)

Side by Side Diff: src/typedarray.js

Issue 17572009: Update typed arrays behavior to match ES6 rev 15. Remove TO_POSITIVE_INTEGER and throw on negative … (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: CR feedback Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/runtime.js ('k') | test/mjsunit/harmony/dataview-accessors.js » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 the V8 project authors. All rights reserved. 1 // Copyright 2013 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 19 matching lines...) Expand all
30 // This file relies on the fact that the following declaration has been made 30 // This file relies on the fact that the following declaration has been made
31 // in runtime.js: 31 // in runtime.js:
32 // var $Array = global.Array; 32 // var $Array = global.Array;
33 33
34 34
35 35
36 // --------------- Typed Arrays --------------------- 36 // --------------- Typed Arrays ---------------------
37 37
38 function CreateTypedArrayConstructor(name, elementSize, arrayId, constructor) { 38 function CreateTypedArrayConstructor(name, elementSize, arrayId, constructor) {
39 function ConstructByArrayBuffer(obj, buffer, byteOffset, length) { 39 function ConstructByArrayBuffer(obj, buffer, byteOffset, length) {
40 var offset = IS_UNDEFINED(byteOffset) ? 0 : TO_POSITIVE_INTEGER(byteOffset); 40 var offset = ToPositiveInteger(byteOffset, "invalid_typed_array_length")
41 41
42 if (offset % elementSize !== 0) { 42 if (offset % elementSize !== 0) {
43 throw MakeRangeError("invalid_typed_array_alignment", 43 throw MakeRangeError("invalid_typed_array_alignment",
44 "start offset", name, elementSize); 44 "start offset", name, elementSize);
45 } 45 }
46 var bufferByteLength = %ArrayBufferGetByteLength(buffer); 46 var bufferByteLength = %ArrayBufferGetByteLength(buffer);
47 if (offset > bufferByteLength) { 47 if (offset > bufferByteLength) {
48 throw MakeRangeError("invalid_typed_array_offset"); 48 throw MakeRangeError("invalid_typed_array_offset");
49 } 49 }
50 50
51 var newByteLength; 51 var newByteLength;
52 var newLength; 52 var newLength;
53 if (IS_UNDEFINED(length)) { 53 if (IS_UNDEFINED(length)) {
54 if (bufferByteLength % elementSize !== 0) { 54 if (bufferByteLength % elementSize !== 0) {
55 throw MakeRangeError("invalid_typed_array_alignment", 55 throw MakeRangeError("invalid_typed_array_alignment",
56 "byte length", name, elementSize); 56 "byte length", name, elementSize);
57 } 57 }
58 newByteLength = bufferByteLength - offset; 58 newByteLength = bufferByteLength - offset;
59 newLength = newByteLength / elementSize; 59 newLength = newByteLength / elementSize;
60 } else { 60 } else {
61 var newLength = TO_POSITIVE_INTEGER(length); 61 var newLength = ToPositiveInteger(length, "invalid_typed_array_length");
62 newByteLength = newLength * elementSize; 62 newByteLength = newLength * elementSize;
63 } 63 }
64 if (offset + newByteLength > bufferByteLength) { 64 if (offset + newByteLength > bufferByteLength) {
65 throw MakeRangeError("invalid_typed_array_length"); 65 throw MakeRangeError("invalid_typed_array_length");
66 } 66 }
67 %TypedArrayInitialize(obj, arrayId, buffer, offset, newByteLength); 67 %TypedArrayInitialize(obj, arrayId, buffer, offset, newByteLength);
68 } 68 }
69 69
70 function ConstructByLength(obj, length) { 70 function ConstructByLength(obj, length) {
71 var l = IS_UNDEFINED(length) ? 0 : TO_POSITIVE_INTEGER(length); 71 var l = ToPositiveInteger(length, "invalid_typed_array_length");
72 var byteLength = l * elementSize; 72 var byteLength = l * elementSize;
73 var buffer = new global.ArrayBuffer(byteLength); 73 var buffer = new global.ArrayBuffer(byteLength);
74 %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength); 74 %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
75 } 75 }
76 76
77 function ConstructByArrayLike(obj, arrayLike) { 77 function ConstructByArrayLike(obj, arrayLike) {
78 var length = arrayLike.length; 78 var length = arrayLike.length;
79 var l = IS_UNDEFINED(length) ? 0 : TO_POSITIVE_INTEGER(length); 79 var l = ToPositiveInteger(length, "invalid_typed_array_length");
80 var byteLength = l * elementSize; 80 var byteLength = l * elementSize;
81 var buffer = new $ArrayBuffer(byteLength); 81 var buffer = new $ArrayBuffer(byteLength);
82 %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength); 82 %TypedArrayInitialize(obj, arrayId, buffer, 0, byteLength);
83 for (var i = 0; i < l; i++) { 83 for (var i = 0; i < l; i++) {
84 obj[i] = arrayLike[i]; 84 obj[i] = arrayLike[i];
85 } 85 }
86 } 86 }
87 87
88 return function (arg1, arg2, arg3) { 88 return function (arg1, arg2, arg3) {
89 if (%_IsConstructCall()) { 89 if (%_IsConstructCall()) {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 } 139 }
140 var newLength = endInt - beginInt; 140 var newLength = endInt - beginInt;
141 var beginByteOffset = 141 var beginByteOffset =
142 %TypedArrayGetByteOffset(this) + beginInt * elementSize; 142 %TypedArrayGetByteOffset(this) + beginInt * elementSize;
143 return new constructor(%TypedArrayGetBuffer(this), 143 return new constructor(%TypedArrayGetBuffer(this),
144 beginByteOffset, newLength); 144 beginByteOffset, newLength);
145 } 145 }
146 } 146 }
147 147
148 function TypedArraySet(obj, offset) { 148 function TypedArraySet(obj, offset) {
149 var intOffset = IS_UNDEFINED(offset) ? 0 : TO_POSITIVE_INTEGER(offset); 149 var intOffset = IS_UNDEFINED(offset) ? 0 : TO_INTEGER(offset);
150 if (intOffset < 0) {
151 throw MakeTypeError("typed_array_set_negative_offset");
152 }
150 if (%TypedArraySetFastCases(this, obj, intOffset)) 153 if (%TypedArraySetFastCases(this, obj, intOffset))
151 return; 154 return;
152 155
153 var l = obj.length; 156 var l = obj.length;
154 if (IS_UNDEFINED(l)) { 157 if (IS_UNDEFINED(l)) {
155 throw MakeTypeError("invalid_argument"); 158 throw MakeTypeError("invalid_argument");
156 } 159 }
157 if (intOffset + l > this.length) { 160 if (intOffset + l > this.length) {
158 throw MakeRangeError("typed_array_set_source_too_large"); 161 throw MakeRangeError("typed_array_set_source_too_large");
159 } 162 }
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
202 // --------------------------- DataView ----------------------------- 205 // --------------------------- DataView -----------------------------
203 206
204 var $DataView = global.DataView; 207 var $DataView = global.DataView;
205 208
206 function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3 209 function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3
207 if (%_IsConstructCall()) { 210 if (%_IsConstructCall()) {
208 if (!IS_ARRAYBUFFER(buffer)) { 211 if (!IS_ARRAYBUFFER(buffer)) {
209 throw MakeTypeError('data_view_not_array_buffer', []); 212 throw MakeTypeError('data_view_not_array_buffer', []);
210 } 213 }
211 var bufferByteLength = %ArrayBufferGetByteLength(buffer); 214 var bufferByteLength = %ArrayBufferGetByteLength(buffer);
212 var offset = IS_UNDEFINED(byteOffset) ? 0 : TO_POSITIVE_INTEGER(byteOffset); 215 var offset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset');
213 if (offset > bufferByteLength) { 216 if (offset > bufferByteLength) {
214 throw MakeRangeError('invalid_data_view_offset', []); 217 throw MakeRangeError('invalid_data_view_offset');
215 } 218 }
216 var length = IS_UNDEFINED(byteLength) ? 219 var length = IS_UNDEFINED(byteLength) ?
217 bufferByteLength - offset : TO_POSITIVE_INTEGER(byteLength); 220 bufferByteLength - offset : TO_INTEGER(byteLength);
218 if (offset + length > bufferByteLength) { 221 if (length < 0 || offset + length > bufferByteLength) {
219 throw new MakeRangeError('invalid_data_view_length'); 222 throw new MakeRangeError('invalid_data_view_length');
220 } 223 }
221 %DataViewInitialize(this, buffer, offset, length); 224 %DataViewInitialize(this, buffer, offset, length);
222 } else { 225 } else {
223 return new $DataView(buffer, byteOffset, byteLength) 226 return new $DataView(buffer, byteOffset, byteLength)
224 } 227 }
225 } 228 }
226 229
227 function DataViewGetBuffer() { 230 function DataViewGetBuffer() {
228 if (!IS_DATAVIEW(this)) { 231 if (!IS_DATAVIEW(this)) {
(...skipping 12 matching lines...) Expand all
241 } 244 }
242 245
243 function DataViewGetByteLength() { 246 function DataViewGetByteLength() {
244 if (!IS_DATAVIEW(this)) { 247 if (!IS_DATAVIEW(this)) {
245 throw MakeTypeError('incompatible_method_reciever', 248 throw MakeTypeError('incompatible_method_reciever',
246 ['DataView.byteLength', this]); 249 ['DataView.byteLength', this]);
247 } 250 }
248 return %DataViewGetByteLength(this); 251 return %DataViewGetByteLength(this);
249 } 252 }
250 253
254 function ToPositiveDataViewOffset(offset) {
255 return ToPositiveInteger(offset, 'invalid_data_view_accessor_offset');
256 }
257
251 function DataViewGetInt8(offset, little_endian) { 258 function DataViewGetInt8(offset, little_endian) {
252 if (!IS_DATAVIEW(this)) { 259 if (!IS_DATAVIEW(this)) {
253 throw MakeTypeError('incompatible_method_reciever', 260 throw MakeTypeError('incompatible_method_reciever',
254 ['DataView.getInt8', this]); 261 ['DataView.getInt8', this]);
255 } 262 }
256 return %DataViewGetInt8(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 263 return %DataViewGetInt8(this,
264 ToPositiveDataViewOffset(offset),
265 !!little_endian);
257 } 266 }
258 267
259 function DataViewSetInt8(offset, value, little_endian) { 268 function DataViewSetInt8(offset, value, little_endian) {
260 if (!IS_DATAVIEW(this)) { 269 if (!IS_DATAVIEW(this)) {
261 throw MakeTypeError('incompatible_method_reciever', 270 throw MakeTypeError('incompatible_method_reciever',
262 ['DataView.setInt8', this]); 271 ['DataView.setInt8', this]);
263 } 272 }
264 %DataViewSetInt8(this, 273 %DataViewSetInt8(this,
265 TO_POSITIVE_INTEGER(offset), 274 ToPositiveDataViewOffset(offset),
266 TO_NUMBER_INLINE(value), 275 TO_NUMBER_INLINE(value),
267 !!little_endian); 276 !!little_endian);
268 } 277 }
269 278
270 function DataViewGetUint8(offset, little_endian) { 279 function DataViewGetUint8(offset, little_endian) {
271 if (!IS_DATAVIEW(this)) { 280 if (!IS_DATAVIEW(this)) {
272 throw MakeTypeError('incompatible_method_reciever', 281 throw MakeTypeError('incompatible_method_reciever',
273 ['DataView.getUint8', this]); 282 ['DataView.getUint8', this]);
274 } 283 }
275 return %DataViewGetUint8(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 284 return %DataViewGetUint8(this,
285 ToPositiveDataViewOffset(offset),
286 !!little_endian);
276 } 287 }
277 288
278 function DataViewSetUint8(offset, value, little_endian) { 289 function DataViewSetUint8(offset, value, little_endian) {
279 if (!IS_DATAVIEW(this)) { 290 if (!IS_DATAVIEW(this)) {
280 throw MakeTypeError('incompatible_method_reciever', 291 throw MakeTypeError('incompatible_method_reciever',
281 ['DataView.setUint8', this]); 292 ['DataView.setUint8', this]);
282 } 293 }
283 %DataViewSetUint8(this, 294 %DataViewSetUint8(this,
284 TO_POSITIVE_INTEGER(offset), 295 ToPositiveDataViewOffset(offset),
285 TO_NUMBER_INLINE(value), 296 TO_NUMBER_INLINE(value),
286 !!little_endian); 297 !!little_endian);
287 } 298 }
288 299
289 function DataViewGetInt16(offset, little_endian) { 300 function DataViewGetInt16(offset, little_endian) {
290 if (!IS_DATAVIEW(this)) { 301 if (!IS_DATAVIEW(this)) {
291 throw MakeTypeError('incompatible_method_reciever', 302 throw MakeTypeError('incompatible_method_reciever',
292 ['DataView.getInt16', this]); 303 ['DataView.getInt16', this]);
293 } 304 }
294 return %DataViewGetInt16(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 305 return %DataViewGetInt16(this,
306 ToPositiveDataViewOffset(offset),
307 !!little_endian);
295 } 308 }
296 309
297 function DataViewSetInt16(offset, value, little_endian) { 310 function DataViewSetInt16(offset, value, little_endian) {
298 if (!IS_DATAVIEW(this)) { 311 if (!IS_DATAVIEW(this)) {
299 throw MakeTypeError('incompatible_method_reciever', 312 throw MakeTypeError('incompatible_method_reciever',
300 ['DataView.setInt16', this]); 313 ['DataView.setInt16', this]);
301 } 314 }
302 %DataViewSetInt16(this, 315 %DataViewSetInt16(this,
303 TO_POSITIVE_INTEGER(offset), 316 ToPositiveDataViewOffset(offset),
304 TO_NUMBER_INLINE(value), 317 TO_NUMBER_INLINE(value),
305 !!little_endian); 318 !!little_endian);
306 } 319 }
307 320
308 function DataViewGetUint16(offset, little_endian) { 321 function DataViewGetUint16(offset, little_endian) {
309 if (!IS_DATAVIEW(this)) { 322 if (!IS_DATAVIEW(this)) {
310 throw MakeTypeError('incompatible_method_reciever', 323 throw MakeTypeError('incompatible_method_reciever',
311 ['DataView.getUint16', this]); 324 ['DataView.getUint16', this]);
312 } 325 }
313 return %DataViewGetUint16(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 326 return %DataViewGetUint16(this,
327 ToPositiveDataViewOffset(offset),
328 !!little_endian);
314 } 329 }
315 330
316 function DataViewSetUint16(offset, value, little_endian) { 331 function DataViewSetUint16(offset, value, little_endian) {
317 if (!IS_DATAVIEW(this)) { 332 if (!IS_DATAVIEW(this)) {
318 throw MakeTypeError('incompatible_method_reciever', 333 throw MakeTypeError('incompatible_method_reciever',
319 ['DataView.setUint16', this]); 334 ['DataView.setUint16', this]);
320 } 335 }
321 %DataViewSetUint16(this, 336 %DataViewSetUint16(this,
322 TO_POSITIVE_INTEGER(offset), 337 ToPositiveDataViewOffset(offset),
323 TO_NUMBER_INLINE(value), 338 TO_NUMBER_INLINE(value),
324 !!little_endian); 339 !!little_endian);
325 } 340 }
326 341
327 function DataViewGetInt32(offset, little_endian) { 342 function DataViewGetInt32(offset, little_endian) {
328 if (!IS_DATAVIEW(this)) { 343 if (!IS_DATAVIEW(this)) {
329 throw MakeTypeError('incompatible_method_reciever', 344 throw MakeTypeError('incompatible_method_reciever',
330 ['DataView.getInt32', this]); 345 ['DataView.getInt32', this]);
331 } 346 }
332 return %DataViewGetInt32(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 347 return %DataViewGetInt32(this,
348 ToPositiveDataViewOffset(offset),
349 !!little_endian);
333 } 350 }
334 351
335 function DataViewSetInt32(offset, value, little_endian) { 352 function DataViewSetInt32(offset, value, little_endian) {
336 if (!IS_DATAVIEW(this)) { 353 if (!IS_DATAVIEW(this)) {
337 throw MakeTypeError('incompatible_method_reciever', 354 throw MakeTypeError('incompatible_method_reciever',
338 ['DataView.setInt32', this]); 355 ['DataView.setInt32', this]);
339 } 356 }
340 %DataViewSetInt32(this, 357 %DataViewSetInt32(this,
341 TO_POSITIVE_INTEGER(offset), 358 ToPositiveDataViewOffset(offset),
342 TO_NUMBER_INLINE(value), 359 TO_NUMBER_INLINE(value),
343 !!little_endian); 360 !!little_endian);
344 } 361 }
345 362
346 function DataViewGetUint32(offset, little_endian) { 363 function DataViewGetUint32(offset, little_endian) {
347 if (!IS_DATAVIEW(this)) { 364 if (!IS_DATAVIEW(this)) {
348 throw MakeTypeError('incompatible_method_reciever', 365 throw MakeTypeError('incompatible_method_reciever',
349 ['DataView.getUint32', this]); 366 ['DataView.getUint32', this]);
350 } 367 }
351 return %DataViewGetUint32(this, TO_POSITIVE_INTEGER(offset), !!little_endian); 368 return %DataViewGetUint32(this,
369 ToPositiveDataViewOffset(offset),
370 !!little_endian);
352 } 371 }
353 372
354 function DataViewSetUint32(offset, value, little_endian) { 373 function DataViewSetUint32(offset, value, little_endian) {
355 if (!IS_DATAVIEW(this)) { 374 if (!IS_DATAVIEW(this)) {
356 throw MakeTypeError('incompatible_method_reciever', 375 throw MakeTypeError('incompatible_method_reciever',
357 ['DataView.setUint32', this]); 376 ['DataView.setUint32', this]);
358 } 377 }
359 %DataViewSetUint32(this, 378 %DataViewSetUint32(this,
360 TO_POSITIVE_INTEGER(offset), 379 ToPositiveDataViewOffset(offset),
361 TO_NUMBER_INLINE(value), 380 TO_NUMBER_INLINE(value),
362 !!little_endian); 381 !!little_endian);
363 } 382 }
364 383
365 function DataViewGetFloat32(offset, little_endian) { 384 function DataViewGetFloat32(offset, little_endian) {
366 if (!IS_DATAVIEW(this)) { 385 if (!IS_DATAVIEW(this)) {
367 throw MakeTypeError('incompatible_method_reciever', 386 throw MakeTypeError('incompatible_method_reciever',
368 ['DataView.getFloat32', this]); 387 ['DataView.getFloat32', this]);
369 } 388 }
370 return %DataViewGetFloat32(this, TO_POSITIVE_INTEGER(offset), !!little_endian) ; 389 return %DataViewGetFloat32(this,
390 ToPositiveDataViewOffset(offset),
391 !!little_endian);
371 } 392 }
372 393
373 function DataViewSetFloat32(offset, value, little_endian) { 394 function DataViewSetFloat32(offset, value, little_endian) {
374 if (!IS_DATAVIEW(this)) { 395 if (!IS_DATAVIEW(this)) {
375 throw MakeTypeError('incompatible_method_reciever', 396 throw MakeTypeError('incompatible_method_reciever',
376 ['DataView.setFloat32', this]); 397 ['DataView.setFloat32', this]);
377 } 398 }
378 %DataViewSetFloat32(this, 399 %DataViewSetFloat32(this,
379 TO_POSITIVE_INTEGER(offset), 400 ToPositiveDataViewOffset(offset),
380 TO_NUMBER_INLINE(value), 401 TO_NUMBER_INLINE(value),
381 !!little_endian); 402 !!little_endian);
382 } 403 }
383 404
384 function DataViewGetFloat64(offset, little_endian) { 405 function DataViewGetFloat64(offset, little_endian) {
385 if (!IS_DATAVIEW(this)) { 406 if (!IS_DATAVIEW(this)) {
386 throw MakeTypeError('incompatible_method_reciever', 407 throw MakeTypeError('incompatible_method_reciever',
387 ['DataView.getFloat64', this]); 408 ['DataView.getFloat64', this]);
388 } 409 }
389 return %DataViewGetFloat64(this, TO_POSITIVE_INTEGER(offset), !!little_endian) ; 410 offset = TO_INTEGER(offset);
411 if (offset < 0) {
412 throw MakeRangeError("invalid_data_view_accessor_offset");
413 }
414 return %DataViewGetFloat64(this,
415 ToPositiveDataViewOffset(offset),
416 !!little_endian);
390 } 417 }
391 418
392 function DataViewSetFloat64(offset, value, little_endian) { 419 function DataViewSetFloat64(offset, value, little_endian) {
393 if (!IS_DATAVIEW(this)) { 420 if (!IS_DATAVIEW(this)) {
394 throw MakeTypeError('incompatible_method_reciever', 421 throw MakeTypeError('incompatible_method_reciever',
395 ['DataView.setFloat64', this]); 422 ['DataView.setFloat64', this]);
396 } 423 }
424 offset = TO_INTEGER(offset);
425 if (offset < 0) {
426 throw MakeRangeError("invalid_data_view_accessor_offset");
427 }
397 %DataViewSetFloat64(this, 428 %DataViewSetFloat64(this,
398 TO_POSITIVE_INTEGER(offset), 429 ToPositiveDataViewOffset(offset),
399 TO_NUMBER_INLINE(value), 430 TO_NUMBER_INLINE(value),
400 !!little_endian); 431 !!little_endian);
401 } 432 }
402 433
403 function SetupDataView() { 434 function SetupDataView() {
404 %CheckIsBootstrapping(); 435 %CheckIsBootstrapping();
405 436
406 // Setup the DataView constructor. 437 // Setup the DataView constructor.
407 %SetCode($DataView, DataViewConstructor); 438 %SetCode($DataView, DataViewConstructor);
408 %FunctionSetPrototype($DataView, new $Object); 439 %FunctionSetPrototype($DataView, new $Object);
(...skipping 26 matching lines...) Expand all
435 466
436 "getFloat32", DataViewGetFloat32, 467 "getFloat32", DataViewGetFloat32,
437 "setFloat32", DataViewSetFloat32, 468 "setFloat32", DataViewSetFloat32,
438 469
439 "getFloat64", DataViewGetFloat64, 470 "getFloat64", DataViewGetFloat64,
440 "setFloat64", DataViewSetFloat64 471 "setFloat64", DataViewSetFloat64
441 )); 472 ));
442 } 473 }
443 474
444 SetupDataView(); 475 SetupDataView();
OLDNEW
« no previous file with comments | « src/runtime.js ('k') | test/mjsunit/harmony/dataview-accessors.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698