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

Unified 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/d8.h ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/d8.cc
diff --git a/src/d8.cc b/src/d8.cc
index ad850f5ee780334d7cff606d6da2710005969b11..807124b083d48beffce335bd5c90d03f122a390c 100644
--- a/src/d8.cc
+++ b/src/d8.cc
@@ -1,4 +1,4 @@
-// Copyright 2011 the V8 project authors. All rights reserved.
+// Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
@@ -281,63 +281,117 @@ Handle<Value> Shell::Load(const Arguments& args) {
return Undefined();
}
+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.
+ if (value_in->IsUint32()) {
+ return value_in->Uint32Value();
+ }
-Handle<Value> Shell::CreateExternalArray(const Arguments& args,
- ExternalArrayType type,
- size_t element_size) {
- ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
- element_size == 8);
- if (args.Length() != 1) {
- return ThrowException(
- String::New("Array constructor needs one parameter."));
+ Local<Value> number = value_in->ToNumber();
+ if (number.IsEmpty()) {
+ ASSERT(try_catch->HasCaught());
+ return 0;
+ }
+
+ ASSERT(number->IsNumber());
+ Local<Int32> int32 = number->ToInt32();
+ if (int32.IsEmpty()) {
+ ASSERT(try_catch->HasCaught());
+ return 0;
+ }
+ int32_t raw_value = int32->Int32Value();
+ if (try_catch->HasCaught()) {
+ return 0;
+ }
+ if (raw_value < 0) {
+ ThrowException(String::New("Array length must not be negative."));
+ return 0;
}
+
static const int kMaxLength = 0x3fffffff;
#ifndef V8_SHARED
ASSERT(kMaxLength == i::ExternalArray::kMaxLength);
#endif // V8_SHARED
- size_t length = 0;
+ if (raw_value > static_cast<int32_t>(kMaxLength)) {
+ ThrowException(
+ String::New("Array length exceeds maximum length."));
+ }
+ return static_cast<size_t>(raw_value);
+}
+
+
+const char kArrayBufferReferencePropName[] = "_array_buffer_ref";
+
+
+Handle<Value> Shell::CreateExternalArray(const Arguments& args,
+ ExternalArrayType type,
+ size_t element_size) {
+ ASSERT(element_size == 1 || element_size == 2 || element_size == 4 ||
+ element_size == 8);
TryCatch try_catch;
- if (args[0]->IsUint32()) {
- length = args[0]->Uint32Value();
- } else {
- Local<Number> number = args[0]->ToNumber();
- if (number.IsEmpty()) {
- ASSERT(try_catch.HasCaught());
- return try_catch.Exception();
- }
- ASSERT(number->IsNumber());
- Local<Int32> int32 = number->ToInt32();
- if (int32.IsEmpty()) {
- if (try_catch.HasCaught()) {
- return try_catch.Exception();
- }
- }
- int32_t raw_length = int32->Int32Value();
- if (try_catch.HasCaught()) {
- return try_catch.Exception();
- }
- if (raw_length < 0) {
- return ThrowException(String::New("Array length must not be negative."));
+ size_t derived_from_element_size = 1;
+ if (args[0]->IsNumber()) {
+ if (args.Length() != 1) {
+ return ThrowException(
+ String::New("Array constructor with length must have "
+ "one parameter."));
}
- if (raw_length > static_cast<int32_t>(kMaxLength)) {
+ } else {
+ 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.
return ThrowException(
- String::New("Array length exceeds maximum length."));
+ String::New("Array constructor from ArrayBuffer must "
+ "have 1-3 parameters."));
}
- length = static_cast<size_t>(raw_length);
}
- if (length > static_cast<size_t>(kMaxLength)) {
- return ThrowException(String::New("Array length exceeds maximum length."));
+
+ Local<Value> length_value = (args.Length() == 1)
+ ? (args[0]->IsNumber()
+ ? args[0]
+ : args[0]->ToObject()->Get(String::New("length")))
+ : 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.
+ int length = convertToInt(length_value, &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+
+ void* data = NULL;
+ if (!args[0]->IsNumber()) {
+ Handle<Object> array = args[0]->ToObject();
+ data = array->GetIndexedPropertiesExternalArrayData();
+ if (data == NULL) {
+ return ThrowException(
+ String::New("ArrayBuffer doesn't have data"));
+ }
+ derived_from_element_size =
+ 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.
+ length *= derived_from_element_size;
+ length /= element_size;
}
- void* data = calloc(length, element_size);
- if (data == NULL) {
- return ThrowException(String::New("Memory allocation failed."));
+
+ size_t offset = 0;
+ if (args.Length() > 1) {
+ offset = convertToInt(args[1], &try_catch);
+ if (try_catch.HasCaught()) return try_catch.Exception();
+
+ if (offset % element_size != 0) {
+ return ThrowException(
+ String::New("offset must be multiple of element_size"));
+ }
}
+
Handle<Object> array = Object::New();
Persistent<Object> persistent_array = Persistent<Object>::New(array);
persistent_array.MakeWeak(data, ExternalArrayWeakCallback);
persistent_array.MarkIndependent();
- array->SetIndexedPropertiesToExternalArrayData(data, type,
- static_cast<int>(length));
+ if (data == NULL) {
+ data = calloc(length, element_size);
+ if (data == NULL) {
+ return ThrowException(String::New("Memory allocation failed."));
+ }
+ } else {
+ // 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.
+ array->Set(String::New(kArrayBufferReferencePropName), args[0], ReadOnly);
+ }
+ array->SetIndexedPropertiesToExternalArrayData(
+ 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.
+ static_cast<int>(length));
array->Set(String::New("length"),
Int32::New(static_cast<int32_t>(length)), ReadOnly);
array->Set(String::New("BYTES_PER_ELEMENT"),
@@ -347,8 +401,18 @@ Handle<Value> Shell::CreateExternalArray(const Arguments& args,
void Shell::ExternalArrayWeakCallback(Persistent<Value> object, void* data) {
- free(data);
- object.Dispose();
+ Handle<String> prop_name = String::New(kArrayBufferReferencePropName);
+ Handle<Object> converted_object = object->ToObject();
+ Local<Value> prop_value = converted_object->Get(prop_name);
+ if (!prop_value->IsObject()) {
+ free(data);
+ object.Dispose();
+ }
+}
+
+
+Handle<Value> Shell::ArrayBuffer(const Arguments& args) {
+ return CreateExternalArray(args, v8::kExternalByteArray, sizeof(int8_t));
}
@@ -693,6 +757,8 @@ Handle<ObjectTemplate> Shell::CreateGlobalTemplate() {
FunctionTemplate::New(DisableProfiler));
// Bind the handlers for external arrays.
+ global_template->Set(String::New("ArrayBuffer"),
+ FunctionTemplate::New(ArrayBuffer));
global_template->Set(String::New("Int8Array"),
FunctionTemplate::New(Int8Array));
global_template->Set(String::New("Uint8Array"),
« 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