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

Side by Side Diff: src/d8.cc

Issue 10392130: Some clean-up of typed array support in d8. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 8 years, 7 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 | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 316 matching lines...) Expand 10 before | Expand all | Expand 10 after
327 TryCatch try_catch; 327 TryCatch try_catch;
328 bool is_array_buffer_construct = element_size == 0; 328 bool is_array_buffer_construct = element_size == 0;
329 if (is_array_buffer_construct) { 329 if (is_array_buffer_construct) {
330 type = v8::kExternalByteArray; 330 type = v8::kExternalByteArray;
331 element_size = 1; 331 element_size = 1;
332 } 332 }
333 ASSERT(element_size == 1 || element_size == 2 || element_size == 4 || 333 ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
334 element_size == 8); 334 element_size == 8);
335 if (args.Length() == 0) { 335 if (args.Length() == 0) {
336 return ThrowException( 336 return ThrowException(
337 String::New("Array constructor must have at least one " 337 String::New("Array constructor must have at least one parameter."));
338 "parameter."));
339 } 338 }
340 bool first_arg_is_array_buffer = 339 bool first_arg_is_array_buffer =
341 args[0]->IsObject() && 340 args[0]->IsObject() &&
342 args[0]->ToObject()->Get( 341 args[0]->ToObject()->Get(
343 String::New(kArrayBufferMarkerPropName))->IsTrue(); 342 String::New(kArrayBufferMarkerPropName))->IsTrue();
344 // Currently, only the following constructors are supported: 343 // Currently, only the following constructors are supported:
344 // ArrayBuffer(unsigned long length)
345 // TypedArray(unsigned long length) 345 // TypedArray(unsigned long length)
346 // TypedArray(ArrayBuffer buffer, 346 // TypedArray(ArrayBuffer buffer,
347 // optional unsigned long byteOffset, 347 // optional unsigned long byteOffset,
348 // optional unsigned long length) 348 // optional unsigned long length)
349 if (args.Length() > 3) { 349 size_t length;
350 return ThrowException( 350 size_t byteLength;
351 String::New("Array constructor from ArrayBuffer must " 351 size_t byteOffset;
352 "have 1-3 parameters.")); 352 void* data = NULL;
353 } 353 Handle<Object> array = Object::New();
354 if (is_array_buffer_construct) {
355 byteLength = convertToUint(args[0], &try_catch);
356 if (try_catch.HasCaught()) return try_catch.Exception();
357 byteOffset = 0;
358 length = byteLength;
354 359
355 Local<Value> length_value = (args.Length() < 3) 360 array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly);
Yang 2012/05/18 12:10:40 Is the property _is_array_buffer_ something that i
rossberg 2012/05/30 13:37:16 Done. _array_buffer_ref_ actually is redundant. Cl
356 ? (first_arg_is_array_buffer 361 } else if (first_arg_is_array_buffer) {
357 ? args[0]->ToObject()->Get(String::New("byteLength")) 362 Handle<Object> buffer = args[0]->ToObject();
358 : args[0]) 363 data = buffer->GetIndexedPropertiesExternalArrayData();
359 : args[2]; 364 byteLength =
360 size_t byteLength = convertToUint(length_value, &try_catch); 365 convertToUint(buffer->Get(String::New("byteLength")), &try_catch);
361 size_t length = byteLength;
362 if (try_catch.HasCaught()) return try_catch.Exception();
363
364 void* data = NULL;
365 size_t offset = 0;
366
367 Handle<Object> array = Object::New();
368 if (first_arg_is_array_buffer) {
369 Handle<Object> derived_from = args[0]->ToObject();
370 data = derived_from->GetIndexedPropertiesExternalArrayData();
371
372 size_t array_buffer_length = convertToUint(
373 derived_from->Get(String::New("byteLength")),
374 &try_catch);
375 if (try_catch.HasCaught()) return try_catch.Exception(); 366 if (try_catch.HasCaught()) return try_catch.Exception();
376 367 if (data == NULL && byteLength != 0) {
377 if (data == NULL && array_buffer_length != 0) { 368 return ThrowException(String::New("ArrayBuffer does not have data"));
378 return ThrowException(
379 String::New("ArrayBuffer doesn't have data"));
380 } 369 }
381 370
382 if (args.Length() > 1) { 371 if (args.Length() < 2 || args[1]->IsUndefined()) {
383 offset = convertToUint(args[1], &try_catch); 372 byteOffset = 0;
373 } else {
374 byteOffset = convertToUint(args[1], &try_catch);
384 if (try_catch.HasCaught()) return try_catch.Exception(); 375 if (try_catch.HasCaught()) return try_catch.Exception();
385 376 if (byteOffset % element_size != 0) {
386 // The given byteOffset must be a multiple of the element size of the
387 // specific type, otherwise an exception is raised.
388 if (offset % element_size != 0) {
389 return ThrowException( 377 return ThrowException(
390 String::New("offset must be multiple of element_size")); 378 String::New("byteOffset must be multiple of element_size"));
391 } 379 }
392 } 380 }
393 381
394 if (offset > array_buffer_length) { 382 if (args.Length() < 3 || args[2]->IsUndefined()) {
395 return ThrowException( 383 if (byteLength % element_size != 0) {
396 String::New("byteOffset must be less than ArrayBuffer length.")); 384 return ThrowException(
385 String::New("buffer size must be multiple of element_size"));
386 }
387 length = (byteLength - byteOffset) / element_size;
388 } else {
389 length = convertToUint(args[2], &try_catch);
390 if (try_catch.HasCaught()) return try_catch.Exception();
397 } 391 }
398 392
399 if (args.Length() == 2) { 393 if (byteOffset + length * element_size > byteLength) {
400 // If length is not explicitly specified, the length of the ArrayBuffer 394 return ThrowException(
401 // minus the byteOffset must be a multiple of the element size of the 395 String::New("byteOffset or length out of bounds"));
402 // specific type, or an exception is raised.
403 length = array_buffer_length - offset;
404 } 396 }
405 397 byteLength = byteOffset + length * element_size;
406 if (args.Length() != 3) {
407 if (length % element_size != 0) {
408 return ThrowException(
409 String::New("ArrayBuffer length minus the byteOffset must be a "
410 "multiple of the element size"));
411 }
412 length /= element_size;
413 }
414
415 // If a given byteOffset and length references an area beyond the end of
416 // the ArrayBuffer an exception is raised.
417 if (offset + (length * element_size) > array_buffer_length) {
418 return ThrowException(
419 String::New("length references an area beyond the end of the "
420 "ArrayBuffer"));
421 }
422 398
423 // Hold a reference to the ArrayBuffer so its buffer doesn't get collected. 399 // Hold a reference to the ArrayBuffer so its buffer doesn't get collected.
424 array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly); 400 array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
425 } 401 } else {
426 402 length = convertToUint(args[0], &try_catch);
427 if (is_array_buffer_construct) { 403 byteLength = length * element_size;
428 array->Set(String::New(kArrayBufferMarkerPropName), True(), ReadOnly); 404 byteOffset = 0;
429 } 405 }
430 406
431 Persistent<Object> persistent_array = Persistent<Object>::New(array); 407 Persistent<Object> persistent_array = Persistent<Object>::New(array);
432 if (data == NULL && length != 0) { 408 if (data == NULL && byteLength != 0) {
409 ASSERT(byteOffset == 0);
410 // Prepend the size of the allocated chunk to the data itself.
411 int total_size =
412 byteLength + kExternalArrayAllocationHeaderSize * sizeof(size_t);
413 static const int kMaxSize = 0x7fffffff;
433 // Make sure the total size fits into a (signed) int. 414 // Make sure the total size fits into a (signed) int.
434 static const int kMaxSize = 0x7fffffff; 415 if (total_size > kMaxSize) {
435 if (length > (kMaxSize - sizeof(size_t)) / element_size) {
436 return ThrowException(String::New("Array exceeds maximum size (2G)")); 416 return ThrowException(String::New("Array exceeds maximum size (2G)"));
437 } 417 }
438 // Prepend the size of the allocated chunk to the data itself.
439 int total_size = length * element_size +
440 kExternalArrayAllocationHeaderSize * sizeof(size_t);
441 data = malloc(total_size); 418 data = malloc(total_size);
442 if (data == NULL) { 419 if (data == NULL) {
443 return ThrowException(String::New("Memory allocation failed.")); 420 return ThrowException(String::New("Memory allocation failed."));
444 } 421 }
445 *reinterpret_cast<size_t*>(data) = total_size; 422 *reinterpret_cast<size_t*>(data) = total_size;
446 data = reinterpret_cast<size_t*>(data) + kExternalArrayAllocationHeaderSize; 423 data = reinterpret_cast<size_t*>(data) + kExternalArrayAllocationHeaderSize;
447 memset(data, 0, length * element_size); 424 memset(data, 0, byteLength);
448 V8::AdjustAmountOfExternalAllocatedMemory(total_size); 425 V8::AdjustAmountOfExternalAllocatedMemory(total_size);
449 } 426 }
450 persistent_array.MakeWeak(data, ExternalArrayWeakCallback); 427 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
451 persistent_array.MarkIndependent(); 428 persistent_array.MarkIndependent();
452 429
453 array->SetIndexedPropertiesToExternalArrayData( 430 array->SetIndexedPropertiesToExternalArrayData(
454 reinterpret_cast<uint8_t*>(data) + offset, type, 431 reinterpret_cast<uint8_t*>(data) + byteOffset, type,
455 static_cast<int>(length)); 432 static_cast<int>(length));
456 array->Set(String::New("byteLength"), 433 array->Set(String::New("byteLength"),
457 Int32::New(static_cast<int32_t>(byteLength)), ReadOnly); 434 Int32::New(static_cast<int32_t>(byteLength)), ReadOnly);
458 if (!is_array_buffer_construct) { 435 if (!is_array_buffer_construct) {
436 array->Set(String::New("byteOffset"),
437 Int32::New(static_cast<int32_t>(byteOffset)), ReadOnly);
459 array->Set(String::New("length"), 438 array->Set(String::New("length"),
460 Int32::New(static_cast<int32_t>(length)), ReadOnly); 439 Int32::New(static_cast<int32_t>(length)), ReadOnly);
461 array->Set(String::New("byteOffset"),
462 Int32::New(static_cast<int32_t>(offset)), ReadOnly);
463 array->Set(String::New("BYTES_PER_ELEMENT"), 440 array->Set(String::New("BYTES_PER_ELEMENT"),
464 Int32::New(static_cast<int32_t>(element_size))); 441 Int32::New(static_cast<int32_t>(element_size)));
465 // We currently support 'buffer' property only if constructed from a buffer. 442 // We currently support 'buffer' property only if constructed from a buffer.
466 if (first_arg_is_array_buffer) { 443 if (first_arg_is_array_buffer) {
467 array->Set(String::New("buffer"), args[0], ReadOnly); 444 array->Set(String::New("buffer"), args[0], ReadOnly);
468 } 445 }
469 } 446 }
470 return array; 447 return array;
471 } 448 }
472 449
(...skipping 1122 matching lines...) Expand 10 before | Expand all | Expand 10 after
1595 } 1572 }
1596 1573
1597 } // namespace v8 1574 } // namespace v8
1598 1575
1599 1576
1600 #ifndef GOOGLE3 1577 #ifndef GOOGLE3
1601 int main(int argc, char* argv[]) { 1578 int main(int argc, char* argv[]) {
1602 return v8::Shell::Main(argc, argv); 1579 return v8::Shell::Main(argc, argv);
1603 } 1580 }
1604 #endif 1581 #endif
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698