Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 (function() { | 5 (function() { |
| 6 | 6 |
| 7 "use strict"; | 7 "use strict"; |
| 8 | 8 |
| 9 %CheckIsBootstrapping(); | 9 %CheckIsBootstrapping(); |
| 10 | 10 |
| 11 var GlobalArray = global.Array; | 11 var GlobalArray = global.Array; |
| 12 var GlobalArrayBuffer = global.ArrayBuffer; | 12 var GlobalSharedArrayBuffer = global.SharedArrayBuffer; |
| 13 | 13 |
| 14 // --------------- Typed Arrays --------------------- | 14 // --------------- Shared Typed Arrays --------------------- |
| 15 macro TYPED_ARRAYS(FUNCTION) | 15 |
| 16 macro SHARED_TYPED_ARRAYS(FUNCTION) | |
| 16 // arrayIds below should be synchronized with Runtime_TypedArrayInitialize. | 17 // arrayIds below should be synchronized with Runtime_TypedArrayInitialize. |
| 17 FUNCTION(1, Uint8Array, 1) | 18 FUNCTION(1, SharedUint8Array, 1) |
| 18 FUNCTION(2, Int8Array, 1) | 19 FUNCTION(2, SharedInt8Array, 1) |
| 19 FUNCTION(3, Uint16Array, 2) | 20 FUNCTION(3, SharedUint16Array, 2) |
| 20 FUNCTION(4, Int16Array, 2) | 21 FUNCTION(4, SharedInt16Array, 2) |
| 21 FUNCTION(5, Uint32Array, 4) | 22 FUNCTION(5, SharedUint32Array, 4) |
| 22 FUNCTION(6, Int32Array, 4) | 23 FUNCTION(6, SharedInt32Array, 4) |
| 23 FUNCTION(7, Float32Array, 4) | 24 FUNCTION(7, SharedFloat32Array, 4) |
| 24 FUNCTION(8, Float64Array, 8) | 25 FUNCTION(8, SharedFloat64Array, 8) |
| 25 FUNCTION(9, Uint8ClampedArray, 1) | 26 FUNCTION(9, SharedUint8ClampedArray, 1) |
| 26 endmacro | 27 endmacro |
| 27 | 28 |
| 28 macro TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE) | 29 macro SHARED_TYPED_ARRAY_CONSTRUCTOR(ARRAY_ID, NAME, ELEMENT_SIZE) |
| 29 function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) { | 30 function NAMEConstructByArrayBuffer(obj, buffer, byteOffset, length) { |
| 30 if (!IS_UNDEFINED(byteOffset)) { | 31 if (!IS_UNDEFINED(byteOffset)) { |
| 31 byteOffset = | 32 byteOffset = |
| 32 ToPositiveInteger(byteOffset, "invalid_typed_array_length"); | 33 ToPositiveInteger(byteOffset, "invalid_typed_array_length"); |
| 33 } | 34 } |
| 34 if (!IS_UNDEFINED(length)) { | 35 if (!IS_UNDEFINED(length)) { |
| 35 length = ToPositiveInteger(length, "invalid_typed_array_length"); | 36 length = ToPositiveInteger(length, "invalid_typed_array_length"); |
| 36 } | 37 } |
| 37 | 38 |
| 38 var bufferByteLength = %_ArrayBufferGetByteLength(buffer); | 39 var bufferByteLength = %_ArrayBufferGetByteLength(buffer); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 72 } | 73 } |
| 73 | 74 |
| 74 function NAMEConstructByLength(obj, length) { | 75 function NAMEConstructByLength(obj, length) { |
| 75 var l = IS_UNDEFINED(length) ? | 76 var l = IS_UNDEFINED(length) ? |
| 76 0 : ToPositiveInteger(length, "invalid_typed_array_length"); | 77 0 : ToPositiveInteger(length, "invalid_typed_array_length"); |
| 77 if (l > %_MaxSmi()) { | 78 if (l > %_MaxSmi()) { |
| 78 throw MakeRangeError("invalid_typed_array_length"); | 79 throw MakeRangeError("invalid_typed_array_length"); |
| 79 } | 80 } |
| 80 var byteLength = l * ELEMENT_SIZE; | 81 var byteLength = l * ELEMENT_SIZE; |
| 81 if (byteLength > %_TypedArrayMaxSizeInHeap()) { | 82 if (byteLength > %_TypedArrayMaxSizeInHeap()) { |
| 82 var buffer = new GlobalArrayBuffer(byteLength); | 83 var buffer = new GlobalSharedArrayBuffer(byteLength); |
| 83 %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength); | 84 %_TypedArrayInitialize(obj, ARRAY_ID, buffer, 0, byteLength); |
| 84 } else { | 85 } else { |
| 85 %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength); | 86 %_TypedArrayInitialize(obj, ARRAY_ID, null, 0, byteLength); |
|
jochen (gone - plz use gerrit)
2015/04/28 18:31:46
what's the point of having an on-heap shared typed
binji
2015/04/29 18:27:22
Done.
| |
| 86 } | 87 } |
| 87 } | 88 } |
| 88 | 89 |
| 89 function NAMEConstructByArrayLike(obj, arrayLike) { | |
| 90 var length = arrayLike.length; | |
| 91 var l = ToPositiveInteger(length, "invalid_typed_array_length"); | |
| 92 | |
| 93 if (l > %_MaxSmi()) { | |
| 94 throw MakeRangeError("invalid_typed_array_length"); | |
| 95 } | |
| 96 if(!%TypedArrayInitializeFromArrayLike(obj, ARRAY_ID, arrayLike, l)) { | |
| 97 for (var i = 0; i < l; i++) { | |
| 98 // It is crucial that we let any execptions from arrayLike[i] | |
| 99 // propagate outside the function. | |
| 100 obj[i] = arrayLike[i]; | |
| 101 } | |
| 102 } | |
| 103 } | |
| 104 | |
| 105 function NAMEConstructor(arg1, arg2, arg3) { | 90 function NAMEConstructor(arg1, arg2, arg3) { |
| 106 if (%_IsConstructCall()) { | 91 if (%_IsConstructCall()) { |
| 107 if (IS_ARRAYBUFFER(arg1)) { | 92 if (IS_SHAREDARRAYBUFFER(arg1)) { |
| 108 NAMEConstructByArrayBuffer(this, arg1, arg2, arg3); | 93 NAMEConstructByArrayBuffer(this, arg1, arg2, arg3); |
| 109 } else if (IS_NUMBER(arg1) || IS_STRING(arg1) || | 94 } else if (IS_NUMBER(arg1) || IS_STRING(arg1) || |
| 110 IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) { | 95 IS_BOOLEAN(arg1) || IS_UNDEFINED(arg1)) { |
| 111 NAMEConstructByLength(this, arg1); | 96 NAMEConstructByLength(this, arg1); |
| 112 } else { | 97 } else { |
| 113 NAMEConstructByArrayLike(this, arg1); | 98 throw MakeTypeError("invalid_argument"); |
| 114 } | 99 } |
| 115 } else { | 100 } else { |
| 116 throw MakeTypeError("constructor_not_function", ["NAME"]) | 101 throw MakeTypeError("constructor_not_function", ["NAME"]) |
| 117 } | 102 } |
| 118 } | 103 } |
| 119 | 104 |
| 120 function NAME_GetBuffer() { | 105 function NAME_GetBuffer() { |
| 121 if (!(%_ClassOf(this) === 'NAME')) { | 106 if (!(%_ClassOf(this) === 'NAME')) { |
| 122 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.buffer", this); | 107 throw MakeTypeError(kIncompatibleMethodReceiver, "NAME.buffer", this); |
| 123 } | 108 } |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 173 endInt = beginInt; | 158 endInt = beginInt; |
| 174 } | 159 } |
| 175 var newLength = endInt - beginInt; | 160 var newLength = endInt - beginInt; |
| 176 var beginByteOffset = | 161 var beginByteOffset = |
| 177 %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE; | 162 %_ArrayBufferViewGetByteOffset(this) + beginInt * ELEMENT_SIZE; |
| 178 return new $NAME(%TypedArrayGetBuffer(this), | 163 return new $NAME(%TypedArrayGetBuffer(this), |
| 179 beginByteOffset, newLength); | 164 beginByteOffset, newLength); |
| 180 } | 165 } |
| 181 endmacro | 166 endmacro |
| 182 | 167 |
| 183 TYPED_ARRAYS(TYPED_ARRAY_CONSTRUCTOR) | 168 SHARED_TYPED_ARRAYS(SHARED_TYPED_ARRAY_CONSTRUCTOR) |
| 184 | |
| 185 | 169 |
| 186 function TypedArraySetFromArrayLike(target, source, sourceLength, offset) { | 170 function TypedArraySetFromArrayLike(target, source, sourceLength, offset) { |
| 187 if (offset > 0) { | 171 if (offset > 0) { |
| 188 for (var i = 0; i < sourceLength; i++) { | 172 for (var i = 0; i < sourceLength; i++) { |
| 189 target[offset + i] = source[i]; | 173 target[offset + i] = source[i]; |
| 190 } | 174 } |
| 191 } | 175 } |
| 192 else { | 176 else { |
| 193 for (var i = 0; i < sourceLength; i++) { | 177 for (var i = 0; i < sourceLength; i++) { |
| 194 target[i] = source[i]; | 178 target[i] = source[i]; |
| (...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 289 | 273 |
| 290 function TypedArrayGetToStringTag() { | 274 function TypedArrayGetToStringTag() { |
| 291 if (!%IsTypedArray(this)) return; | 275 if (!%IsTypedArray(this)) return; |
| 292 var name = %_ClassOf(this); | 276 var name = %_ClassOf(this); |
| 293 if (IS_UNDEFINED(name)) return; | 277 if (IS_UNDEFINED(name)) return; |
| 294 return name; | 278 return name; |
| 295 } | 279 } |
| 296 | 280 |
| 297 // ------------------------------------------------------------------- | 281 // ------------------------------------------------------------------- |
| 298 | 282 |
| 299 macro SETUP_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE) | 283 |
| 284 macro SETUP_SHARED_TYPED_ARRAY(ARRAY_ID, NAME, ELEMENT_SIZE) | |
| 300 %SetCode(global.NAME, NAMEConstructor); | 285 %SetCode(global.NAME, NAMEConstructor); |
| 301 %FunctionSetPrototype(global.NAME, new $Object()); | 286 %FunctionSetPrototype(global.NAME, new $Object()); |
| 302 | 287 |
| 303 %AddNamedProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE, | 288 %AddNamedProperty(global.NAME, "BYTES_PER_ELEMENT", ELEMENT_SIZE, |
| 304 READ_ONLY | DONT_ENUM | DONT_DELETE); | 289 READ_ONLY | DONT_ENUM | DONT_DELETE); |
| 305 %AddNamedProperty(global.NAME.prototype, | 290 %AddNamedProperty(global.NAME.prototype, |
| 306 "constructor", global.NAME, DONT_ENUM); | 291 "constructor", global.NAME, DONT_ENUM); |
| 307 %AddNamedProperty(global.NAME.prototype, | 292 %AddNamedProperty(global.NAME.prototype, |
| 308 "BYTES_PER_ELEMENT", ELEMENT_SIZE, | 293 "BYTES_PER_ELEMENT", ELEMENT_SIZE, |
| 309 READ_ONLY | DONT_ENUM | DONT_DELETE); | 294 READ_ONLY | DONT_ENUM | DONT_DELETE); |
| 310 InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer); | 295 InstallGetter(global.NAME.prototype, "buffer", NAME_GetBuffer); |
| 311 InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset, | 296 InstallGetter(global.NAME.prototype, "byteOffset", NAME_GetByteOffset, |
| 312 DONT_ENUM | DONT_DELETE); | 297 DONT_ENUM | DONT_DELETE); |
| 313 InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength, | 298 InstallGetter(global.NAME.prototype, "byteLength", NAME_GetByteLength, |
| 314 DONT_ENUM | DONT_DELETE); | 299 DONT_ENUM | DONT_DELETE); |
| 315 InstallGetter(global.NAME.prototype, "length", NAME_GetLength, | 300 InstallGetter(global.NAME.prototype, "length", NAME_GetLength, |
| 316 DONT_ENUM | DONT_DELETE); | 301 DONT_ENUM | DONT_DELETE); |
| 317 InstallGetter(global.NAME.prototype, symbolToStringTag, | 302 InstallGetter(global.NAME.prototype, symbolToStringTag, |
| 318 TypedArrayGetToStringTag); | 303 TypedArrayGetToStringTag); |
| 319 InstallFunctions(global.NAME.prototype, DONT_ENUM, [ | 304 InstallFunctions(global.NAME.prototype, DONT_ENUM, [ |
| 320 "subarray", NAMESubArray, | 305 "subarray", NAMESubArray, |
| 321 "set", TypedArraySet | 306 "set", TypedArraySet |
| 322 ]); | 307 ]); |
| 323 endmacro | 308 endmacro |
| 324 | 309 |
| 325 TYPED_ARRAYS(SETUP_TYPED_ARRAY) | 310 SHARED_TYPED_ARRAYS(SETUP_SHARED_TYPED_ARRAY) |
| 326 | |
| 327 // --------------------------- DataView ----------------------------- | |
| 328 | |
| 329 var $DataView = global.DataView; | |
| 330 | |
| 331 function DataViewConstructor(buffer, byteOffset, byteLength) { // length = 3 | |
| 332 if (%_IsConstructCall()) { | |
| 333 if (!IS_ARRAYBUFFER(buffer)) { | |
| 334 throw MakeTypeError('data_view_not_array_buffer', []); | |
| 335 } | |
| 336 if (!IS_UNDEFINED(byteOffset)) { | |
| 337 byteOffset = ToPositiveInteger(byteOffset, 'invalid_data_view_offset'); | |
| 338 } | |
| 339 if (!IS_UNDEFINED(byteLength)) { | |
| 340 byteLength = TO_INTEGER(byteLength); | |
| 341 } | |
| 342 | |
| 343 var bufferByteLength = %_ArrayBufferGetByteLength(buffer); | |
| 344 | |
| 345 var offset = IS_UNDEFINED(byteOffset) ? 0 : byteOffset; | |
| 346 if (offset > bufferByteLength) { | |
| 347 throw MakeRangeError('invalid_data_view_offset'); | |
| 348 } | |
| 349 | |
| 350 var length = IS_UNDEFINED(byteLength) | |
| 351 ? bufferByteLength - offset | |
| 352 : byteLength; | |
| 353 if (length < 0 || offset + length > bufferByteLength) { | |
| 354 throw new MakeRangeError('invalid_data_view_length'); | |
| 355 } | |
| 356 %_DataViewInitialize(this, buffer, offset, length); | |
| 357 } else { | |
| 358 throw MakeTypeError('constructor_not_function', ["DataView"]); | |
| 359 } | |
| 360 } | |
| 361 | |
| 362 function DataViewGetBufferJS() { | |
| 363 if (!IS_DATAVIEW(this)) { | |
| 364 throw MakeTypeError(kIncompatibleMethodReceiver, 'DataView.buffer', this); | |
| 365 } | |
| 366 return %DataViewGetBuffer(this); | |
| 367 } | |
| 368 | |
| 369 function DataViewGetByteOffset() { | |
| 370 if (!IS_DATAVIEW(this)) { | |
| 371 throw MakeTypeError(kIncompatibleMethodReceiver, | |
| 372 'DataView.byteOffset', this); | |
| 373 } | |
| 374 return %_ArrayBufferViewGetByteOffset(this); | |
| 375 } | |
| 376 | |
| 377 function DataViewGetByteLength() { | |
| 378 if (!IS_DATAVIEW(this)) { | |
| 379 throw MakeTypeError(kIncompatibleMethodReceiver, | |
| 380 'DataView.byteLength', this); | |
| 381 } | |
| 382 return %_ArrayBufferViewGetByteLength(this); | |
| 383 } | |
| 384 | |
| 385 macro DATA_VIEW_TYPES(FUNCTION) | |
| 386 FUNCTION(Int8) | |
| 387 FUNCTION(Uint8) | |
| 388 FUNCTION(Int16) | |
| 389 FUNCTION(Uint16) | |
| 390 FUNCTION(Int32) | |
| 391 FUNCTION(Uint32) | |
| 392 FUNCTION(Float32) | |
| 393 FUNCTION(Float64) | |
| 394 endmacro | |
| 395 | |
| 396 function ToPositiveDataViewOffset(offset) { | |
| 397 return ToPositiveInteger(offset, 'invalid_data_view_accessor_offset'); | |
| 398 } | |
| 399 | |
| 400 | |
| 401 macro DATA_VIEW_GETTER_SETTER(TYPENAME) | |
| 402 function DataViewGetTYPENAMEJS(offset, little_endian) { | |
| 403 if (!IS_DATAVIEW(this)) { | |
| 404 throw MakeTypeError(kIncompatibleMethodReceiver, | |
| 405 'DataView.getTYPENAME', this); | |
| 406 } | |
| 407 if (%_ArgumentsLength() < 1) { | |
| 408 throw MakeTypeError('invalid_argument'); | |
| 409 } | |
| 410 return %DataViewGetTYPENAME(this, | |
| 411 ToPositiveDataViewOffset(offset), | |
| 412 !!little_endian); | |
| 413 } | |
| 414 | |
| 415 function DataViewSetTYPENAMEJS(offset, value, little_endian) { | |
| 416 if (!IS_DATAVIEW(this)) { | |
| 417 throw MakeTypeError(kIncompatibleMethodReceiver, | |
| 418 'DataView.setTYPENAME', this); | |
| 419 } | |
| 420 if (%_ArgumentsLength() < 2) { | |
| 421 throw MakeTypeError('invalid_argument'); | |
| 422 } | |
| 423 %DataViewSetTYPENAME(this, | |
| 424 ToPositiveDataViewOffset(offset), | |
| 425 TO_NUMBER_INLINE(value), | |
| 426 !!little_endian); | |
| 427 } | |
| 428 endmacro | |
| 429 | |
| 430 DATA_VIEW_TYPES(DATA_VIEW_GETTER_SETTER) | |
| 431 | |
| 432 // Setup the DataView constructor. | |
| 433 %SetCode($DataView, DataViewConstructor); | |
| 434 %FunctionSetPrototype($DataView, new $Object); | |
| 435 | |
| 436 // Set up constructor property on the DataView prototype. | |
| 437 %AddNamedProperty($DataView.prototype, "constructor", $DataView, DONT_ENUM); | |
| 438 %AddNamedProperty( | |
| 439 $DataView.prototype, symbolToStringTag, "DataView", READ_ONLY|DONT_ENUM); | |
| 440 | |
| 441 InstallGetter($DataView.prototype, "buffer", DataViewGetBufferJS); | |
| 442 InstallGetter($DataView.prototype, "byteOffset", DataViewGetByteOffset); | |
| 443 InstallGetter($DataView.prototype, "byteLength", DataViewGetByteLength); | |
| 444 | |
| 445 InstallFunctions($DataView.prototype, DONT_ENUM, [ | |
| 446 "getInt8", DataViewGetInt8JS, | |
| 447 "setInt8", DataViewSetInt8JS, | |
| 448 | |
| 449 "getUint8", DataViewGetUint8JS, | |
| 450 "setUint8", DataViewSetUint8JS, | |
| 451 | |
| 452 "getInt16", DataViewGetInt16JS, | |
| 453 "setInt16", DataViewSetInt16JS, | |
| 454 | |
| 455 "getUint16", DataViewGetUint16JS, | |
| 456 "setUint16", DataViewSetUint16JS, | |
| 457 | |
| 458 "getInt32", DataViewGetInt32JS, | |
| 459 "setInt32", DataViewSetInt32JS, | |
| 460 | |
| 461 "getUint32", DataViewGetUint32JS, | |
| 462 "setUint32", DataViewSetUint32JS, | |
| 463 | |
| 464 "getFloat32", DataViewGetFloat32JS, | |
| 465 "setFloat32", DataViewSetFloat32JS, | |
| 466 | |
| 467 "getFloat64", DataViewGetFloat64JS, | |
| 468 "setFloat64", DataViewSetFloat64JS | |
| 469 ]); | |
| 470 | 311 |
| 471 })(); | 312 })(); |
| OLD | NEW |