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

Side by Side Diff: src/d8.cc

Issue 9114050: Add primitive WebGL ArrayBuffer() support to d8 (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: reactivate TypedArray disposal Created 8 years, 11 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/d8.h ('k') | 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 2011 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
11 // with the distribution. 11 // with the distribution.
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after
274 if (source.IsEmpty()) { 274 if (source.IsEmpty()) {
275 return ThrowException(String::New("Error loading file")); 275 return ThrowException(String::New("Error loading file"));
276 } 276 }
277 if (!ExecuteString(source, String::New(*file), false, true)) { 277 if (!ExecuteString(source, String::New(*file), false, true)) {
278 return ThrowException(String::New("Error executing file")); 278 return ThrowException(String::New("Error executing file"));
279 } 279 }
280 } 280 }
281 return Undefined(); 281 return Undefined();
282 } 282 }
283 283
284 static int convertToInt(Local<Value> value_in, TryCatch* try_catch) {
Jakob Kummerow 2012/01/11 10:17:53 Rename to convertToUint?
danno 2012/01/11 13:07:41 Done.
285 if (value_in->IsUint32()) {
286 return value_in->Uint32Value();
287 }
288
289 Local<Value> number = value_in->ToNumber();
290 if (number.IsEmpty()) {
291 ASSERT(try_catch->HasCaught());
292 return 0;
293 }
294
295 ASSERT(number->IsNumber());
296 Local<Int32> int32 = number->ToInt32();
297 if (int32.IsEmpty()) {
298 ASSERT(try_catch->HasCaught());
299 return 0;
300 }
301 int32_t raw_value = int32->Int32Value();
302 if (try_catch->HasCaught()) {
303 return 0;
304 }
305 if (raw_value < 0) {
306 ThrowException(String::New("Array length must not be negative."));
307 return 0;
308 }
309
310 static const int kMaxLength = 0x3fffffff;
311 #ifndef V8_SHARED
312 ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
313 #endif // V8_SHARED
314 if (raw_value > static_cast<int32_t>(kMaxLength)) {
315 ThrowException(
316 String::New("Array length exceeds maximum length."));
317 }
318 return static_cast<size_t>(raw_value);
319 }
320
321
322 const char kArrayBufferReferencePropName[] = "_array_buffer_ref";
323
284 324
285 Handle<Value> Shell::CreateExternalArray(const Arguments& args, 325 Handle<Value> Shell::CreateExternalArray(const Arguments& args,
286 ExternalArrayType type, 326 ExternalArrayType type,
287 size_t element_size) { 327 size_t element_size) {
288 ASSERT(element_size == 1 || element_size == 2 || element_size == 4 || 328 ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
289 element_size == 8); 329 element_size == 8);
290 if (args.Length() != 1) { 330 TryCatch try_catch;
291 return ThrowException( 331 size_t derived_from_element_size = 1;
292 String::New("Array constructor needs one parameter.")); 332 if (args[0]->IsNumber()) {
333 if (args.Length() != 1) {
334 return ThrowException(
335 String::New("Array constructor with length must have "
336 "one parameter."));
337 }
338 } else {
339 if (args.Length() > 3 || args.Length() == 0) {
Jakob Kummerow 2012/01/11 10:17:53 Arguments.operator[] is benign enough to simply re
danno 2012/01/11 13:07:41 Done.
340 return ThrowException(
341 String::New("Array constructor from ArrayBuffer must "
342 "have 1-3 parameters."));
343 }
293 } 344 }
294 static const int kMaxLength = 0x3fffffff; 345
295 #ifndef V8_SHARED 346 Local<Value> length_value = (args.Length() == 1)
296 ASSERT(kMaxLength == i::ExternalArray::kMaxLength); 347 ? (args[0]->IsNumber()
297 #endif // V8_SHARED 348 ? args[0]
298 size_t length = 0; 349 : args[0]->ToObject()->Get(String::New("length")))
299 TryCatch try_catch; 350 : args[2];
Jakob Kummerow 2012/01/11 10:17:53 args[2] is optional and could be undefined. As imp
danno 2012/01/11 13:07:41 Done.
300 if (args[0]->IsUint32()) { 351 int length = convertToInt(length_value, &try_catch);
301 length = args[0]->Uint32Value(); 352 if (try_catch.HasCaught()) return try_catch.Exception();
302 } else { 353
303 Local<Number> number = args[0]->ToNumber(); 354 void* data = NULL;
304 if (number.IsEmpty()) { 355 if (!args[0]->IsNumber()) {
305 ASSERT(try_catch.HasCaught()); 356 Handle<Object> array = args[0]->ToObject();
306 return try_catch.Exception(); 357 data = array->GetIndexedPropertiesExternalArrayData();
358 if (data == NULL) {
359 return ThrowException(
360 String::New("ArrayBuffer doesn't have data"));
307 } 361 }
308 ASSERT(number->IsNumber()); 362 derived_from_element_size =
309 Local<Int32> int32 = number->ToInt32(); 363 array->Get(String::New("BYTES_PER_ELEMENT"))->ToInt32()->Int32Value();
Jakob Kummerow 2012/01/11 10:17:53 My reading of the spec at http://www.khronos.org/r
danno 2012/01/11 13:07:41 Done.
310 if (int32.IsEmpty()) { 364 length *= derived_from_element_size;
311 if (try_catch.HasCaught()) { 365 length /= element_size;
312 return try_catch.Exception(); 366 }
313 } 367
368 size_t offset = 0;
369 if (args.Length() > 1) {
370 offset = convertToInt(args[1], &try_catch);
371 if (try_catch.HasCaught()) return try_catch.Exception();
372
373 if (offset % element_size != 0) {
374 return ThrowException(
375 String::New("offset must be multiple of element_size"));
314 } 376 }
315 int32_t raw_length = int32->Int32Value();
316 if (try_catch.HasCaught()) {
317 return try_catch.Exception();
318 }
319 if (raw_length < 0) {
320 return ThrowException(String::New("Array length must not be negative."));
321 }
322 if (raw_length > static_cast<int32_t>(kMaxLength)) {
323 return ThrowException(
324 String::New("Array length exceeds maximum length."));
325 }
326 length = static_cast<size_t>(raw_length);
327 } 377 }
328 if (length > static_cast<size_t>(kMaxLength)) { 378
329 return ThrowException(String::New("Array length exceeds maximum length."));
330 }
331 void* data = calloc(length, element_size);
332 if (data == NULL) {
333 return ThrowException(String::New("Memory allocation failed."));
334 }
335 Handle<Object> array = Object::New(); 379 Handle<Object> array = Object::New();
336 Persistent<Object> persistent_array = Persistent<Object>::New(array); 380 Persistent<Object> persistent_array = Persistent<Object>::New(array);
337 persistent_array.MakeWeak(data, ExternalArrayWeakCallback); 381 persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
338 persistent_array.MarkIndependent(); 382 persistent_array.MarkIndependent();
339 array->SetIndexedPropertiesToExternalArrayData(data, type, 383 if (data == NULL) {
340 static_cast<int>(length)); 384 data = calloc(length, element_size);
385 if (data == NULL) {
386 return ThrowException(String::New("Memory allocation failed."));
387 }
388 } else {
389 // Hold a reference to the ArrayBuffer so it's buffer doesn't get collected.
Jakob Kummerow 2012/01/11 10:17:53 s/it's/its/
danno 2012/01/11 13:07:41 Done.
390 array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
391 }
392 array->SetIndexedPropertiesToExternalArrayData(
393 reinterpret_cast<uint8_t*>(data) + offset, type,
Jakob Kummerow 2012/01/11 10:17:53 Whoa... please add checks that both |offset| and |
danno 2012/01/11 13:07:41 Done.
394 static_cast<int>(length));
341 array->Set(String::New("length"), 395 array->Set(String::New("length"),
342 Int32::New(static_cast<int32_t>(length)), ReadOnly); 396 Int32::New(static_cast<int32_t>(length)), ReadOnly);
343 array->Set(String::New("BYTES_PER_ELEMENT"), 397 array->Set(String::New("BYTES_PER_ELEMENT"),
344 Int32::New(static_cast<int32_t>(element_size))); 398 Int32::New(static_cast<int32_t>(element_size)));
345 return array; 399 return array;
346 } 400 }
347 401
348 402
349 void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) { 403 void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
350 free(data); 404 Handle<String> prop_name = String::New(kArrayBufferReferencePropName);
351 object.Dispose(); 405 Handle<Object> converted_object = object->ToObject();
406 Local<Value> prop_value = converted_object->Get(prop_name);
407 if (!prop_value->IsObject()) {
408 free(data);
409 object.Dispose();
410 }
352 } 411 }
353 412
354 413
414 Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
415 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
416 }
417
418
355 Handle<Value> Shell::Int8Array(const Arguments& args) { 419 Handle<Value> Shell::Int8Array(const Arguments& args) {
356 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t)); 420 return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
357 } 421 }
358 422
359 423
360 Handle<Value> Shell::Uint8Array(const Arguments& args) { 424 Handle<Value> Shell::Uint8Array(const Arguments& args) {
361 return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t)); 425 return CreateExternalArray(args, kExternalUnsignedByteArray, sizeof(uint8_t));
362 } 426 }
363 427
364 428
(...skipping 321 matching lines...) Expand 10 before | Expand all | Expand 10 after
686 FunctionTemplate::New(ReadLine)); 750 FunctionTemplate::New(ReadLine));
687 global_template->Set(String::New("load"), FunctionTemplate::New(Load)); 751 global_template->Set(String::New("load"), FunctionTemplate::New(Load));
688 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit)); 752 global_template->Set(String::New("quit"), FunctionTemplate::New(Quit));
689 global_template->Set(String::New("version"), FunctionTemplate::New(Version)); 753 global_template->Set(String::New("version"), FunctionTemplate::New(Version));
690 global_template->Set(String::New("enableProfiler"), 754 global_template->Set(String::New("enableProfiler"),
691 FunctionTemplate::New(EnableProfiler)); 755 FunctionTemplate::New(EnableProfiler));
692 global_template->Set(String::New("disableProfiler"), 756 global_template->Set(String::New("disableProfiler"),
693 FunctionTemplate::New(DisableProfiler)); 757 FunctionTemplate::New(DisableProfiler));
694 758
695 // Bind the handlers for external arrays. 759 // Bind the handlers for external arrays.
760 global_template->Set(String::New("ArrayBuffer"),
761 FunctionTemplate::New(ArrayBuffer));
696 global_template->Set(String::New("Int8Array"), 762 global_template->Set(String::New("Int8Array"),
697 FunctionTemplate::New(Int8Array)); 763 FunctionTemplate::New(Int8Array));
698 global_template->Set(String::New("Uint8Array"), 764 global_template->Set(String::New("Uint8Array"),
699 FunctionTemplate::New(Uint8Array)); 765 FunctionTemplate::New(Uint8Array));
700 global_template->Set(String::New("Int16Array"), 766 global_template->Set(String::New("Int16Array"),
701 FunctionTemplate::New(Int16Array)); 767 FunctionTemplate::New(Int16Array));
702 global_template->Set(String::New("Uint16Array"), 768 global_template->Set(String::New("Uint16Array"),
703 FunctionTemplate::New(Uint16Array)); 769 FunctionTemplate::New(Uint16Array));
704 global_template->Set(String::New("Int32Array"), 770 global_template->Set(String::New("Int32Array"),
705 FunctionTemplate::New(Int32Array)); 771 FunctionTemplate::New(Int32Array));
(...skipping 687 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 } 1459 }
1394 1460
1395 } // namespace v8 1461 } // namespace v8
1396 1462
1397 1463
1398 #ifndef GOOGLE3 1464 #ifndef GOOGLE3
1399 int main(int argc, char* argv[]) { 1465 int main(int argc, char* argv[]) {
1400 return v8::Shell::Main(argc, argv); 1466 return v8::Shell::Main(argc, argv);
1401 } 1467 }
1402 #endif 1468 #endif
OLDNEW
« no previous file with comments | « src/d8.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698