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

Unified Diff: runtime/vm/dart_api_impl.cc

Issue 282883002: Add a new API function to extract all the native arguments into an array (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 6 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: runtime/vm/dart_api_impl.cc
===================================================================
--- runtime/vm/dart_api_impl.cc (revision 36461)
+++ runtime/vm/dart_api_impl.cc (working copy)
@@ -81,6 +81,142 @@
}
+static bool GetNativeStringArgument(NativeArguments* arguments,
+ int arg_index,
+ Dart_Handle* str,
+ void** peer) {
+ ASSERT(peer != NULL);
+ if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
+ *str = NULL;
+ return true;
+ }
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ *peer = NULL;
+ REUSABLE_OBJECT_HANDLESCOPE(isolate);
+ Object& obj = isolate->ObjectHandle();
+ obj = arguments->NativeArgAt(arg_index);
+ if (RawObject::IsStringClassId(obj.GetClassId())) {
+ ASSERT(isolate->api_state() &&
+ isolate->api_state()->top_scope() != NULL);
+ *str = Api::NewHandle(isolate, obj.raw());
+ return true;
+ }
+ if (obj.IsNull()) {
+ *str = Api::Null();
+ return true;
+ }
+ return false;
+}
+
+
+static bool GetNativeIntegerArgument(NativeArguments* arguments,
+ int arg_index,
+ int64_t* value) {
+ ASSERT(value != NULL);
+ if (Api::GetNativeIntegerArgument(arguments, arg_index, value)) {
+ return true;
+ }
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ REUSABLE_OBJECT_HANDLESCOPE(isolate);
+ Object& obj = isolate->ObjectHandle();
+ obj = arguments->NativeArgAt(arg_index);
+ intptr_t cid = obj.GetClassId();
+ if (cid == kBigintCid) {
+ const Bigint& bigint = Bigint::Cast(obj);
+ if (BigintOperations::FitsIntoInt64(bigint)) {
+ *value = BigintOperations::ToInt64(bigint);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+static bool GetNativeUnsignedIntegerArgument(NativeArguments* arguments,
+ int arg_index,
+ uint64_t* value) {
+ ASSERT(value != NULL);
+ int64_t arg_value = 0;
+ if (Api::GetNativeIntegerArgument(arguments, arg_index, &arg_value)) {
+ *value = static_cast<uint64_t>(arg_value);
+ return true;
+ }
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ REUSABLE_OBJECT_HANDLESCOPE(isolate);
+ Object& obj = isolate->ObjectHandle();
+ obj = arguments->NativeArgAt(arg_index);
+ intptr_t cid = obj.GetClassId();
+ if (cid == kBigintCid) {
+ const Bigint& bigint = Bigint::Cast(obj);
+ if (BigintOperations::FitsIntoUint64(bigint)) {
+ *value = BigintOperations::ToUint64(bigint);
+ return true;
+ }
+ }
+ return false;
+}
+
+
+static bool GetNativeDoubleArgument(NativeArguments* arguments,
+ int arg_index,
+ double* value) {
+ ASSERT(value != NULL);
+ if (Api::GetNativeDoubleArgument(arguments, arg_index, value)) {
+ return true;
+ }
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ REUSABLE_OBJECT_HANDLESCOPE(isolate);
+ Object& obj = isolate->ObjectHandle();
+ obj = arguments->NativeArgAt(arg_index);
+ intptr_t cid = obj.GetClassId();
+ if (cid == kBigintCid) {
+ *value = Bigint::Cast(obj).AsDoubleValue();
+ return true;
+ }
+ return false;
+}
+
+
+static Dart_Handle GetNativeFieldsOfArgument(NativeArguments* arguments,
+ int arg_index,
+ int num_fields,
+ intptr_t* field_values,
+ const char* current_func) {
+ ASSERT(field_values != NULL);
+ if (Api::GetNativeFieldsOfArgument(arguments,
+ arg_index,
+ num_fields,
+ field_values)) {
+ return Api::Success();
+ }
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ REUSABLE_OBJECT_HANDLESCOPE(isolate);
+ Object& obj = isolate->ObjectHandle();
+ obj = arguments->NativeArgAt(arg_index);
+ if (obj.IsNull()) {
+ memset(field_values, 0, (num_fields * sizeof(field_values[0])));
+ return Api::Success();
+ }
+ // We did not succeed in extracting the native fields report the
+ // appropriate error.
+ if (!obj.IsInstance()) {
+ return Api::NewError("%s expects argument at index '%d' to be of"
+ " type Instance.", current_func, arg_index);
+ }
+ const Instance& instance = Instance::Cast(obj);
+ int field_count = instance.NumNativeFields();
+ ASSERT(num_fields != field_count);
+ return Api::NewError(
+ "%s: expected %d 'num_fields' but was passed in %d.",
+ current_func, field_count, num_fields);
+}
+
+
Heap::Space SpaceForExternal(Isolate* isolate, intptr_t size) {
Heap* heap = isolate->heap();
// If 'size' would be a significant fraction of new space, then use old.
@@ -356,6 +492,74 @@
}
+bool Api::GetNativeIntegerArgument(NativeArguments* arguments,
+ int arg_index,
+ int64_t* value) {
+ NoGCScope no_gc_scope;
+ RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ if (raw_obj->IsHeapObject()) {
+ intptr_t cid = raw_obj->GetClassId();
+ if (cid == kMintCid) {
+ *value = reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_;
+ return true;
+ }
+ return false;
+ }
+ *value = Smi::Value(reinterpret_cast<RawSmi*>(raw_obj));
+ return true;
+}
+
+
+bool Api::GetNativeDoubleArgument(NativeArguments* arguments,
+ int arg_index,
+ double* value) {
+ NoGCScope no_gc_scope;
+ RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ if (raw_obj->IsHeapObject()) {
+ intptr_t cid = raw_obj->GetClassId();
+ if (cid == kDoubleCid) {
+ *value = reinterpret_cast<RawDouble*>(raw_obj)->ptr()->value_;
+ return true;
+ }
+ if (cid == kMintCid) {
+ *value = static_cast<double>(
+ reinterpret_cast<RawMint*>(raw_obj)->ptr()->value_);
+ return true;
+ }
+ return false;
+ }
+ *value = static_cast<double>(Smi::Value(reinterpret_cast<RawSmi*>(raw_obj)));
+ return true;
+}
+
+
+bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
+ int arg_index,
+ int num_fields,
+ intptr_t* field_values) {
+ NoGCScope no_gc_scope;
+ RawObject* raw_obj = arguments->NativeArgAt(arg_index);
+ if (raw_obj->IsHeapObject()) {
+ intptr_t cid = raw_obj->GetClassId();
+ if (cid > kNumPredefinedCids) {
+ RawTypedData* native_fields = *reinterpret_cast<RawTypedData**>(
+ RawObject::ToAddr(raw_obj) + sizeof(RawObject));
+ if (native_fields == TypedData::null()) {
+ memset(field_values, 0, (num_fields * sizeof(field_values[0])));
+ } else if (num_fields == Smi::Value(native_fields->ptr()->length_)) {
+ intptr_t* native_values =
+ bit_cast<intptr_t*, uint8_t*>(native_fields->ptr()->data_);
+ memmove(field_values,
+ native_values,
+ (num_fields * sizeof(field_values[0])));
+ }
+ return true;
+ }
+ }
+ return false;
+}
+
+
void Api::SetWeakHandleReturnValue(NativeArguments* args,
Dart_WeakPersistentHandle retval) {
args->SetReturnUnsafe(FinalizablePersistentHandle::Cast(retval)->raw());
@@ -4014,6 +4218,140 @@
}
+DART_EXPORT Dart_Handle Dart_GetNativeArguments(
+ Dart_NativeArguments args,
+ int num_arguments,
+ const Dart_NativeArgument_Descriptor* argument_descriptors,
+ Dart_NativeArgument_Value* arg_values) {
+ NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
+ ASSERT(arguments->isolate() == Isolate::Current());
+ if (arg_values == NULL) {
+ RETURN_NULL_ERROR(arg_values);
+ }
+ for (int i = 0; i < num_arguments; i++) {
+ Dart_NativeArgument_Descriptor desc = argument_descriptors[i];
+ Dart_NativeArgument_Type arg_type = static_cast<Dart_NativeArgument_Type>(
+ desc.type);
+ int arg_index = desc.index;
+ ASSERT(arg_index >= 0 && arg_index < arguments->NativeArgCount());
+ Dart_NativeArgument_Value* native_value = &(arg_values[i]);
+ switch (arg_type) {
+ case Dart_NativeArgument_kBool:
+ if (!Api::GetNativeBooleanArgument(arguments,
+ arg_index,
+ &(native_value->as_bool))) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Boolean.", CURRENT_FUNC, i);
+ }
+ break;
+
+ case Dart_NativeArgument_kInt32: {
+ int64_t value = 0;
+ if (!GetNativeIntegerArgument(arguments,
+ arg_index,
+ &value)) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Integer.", CURRENT_FUNC, i);
+ }
+ if (value < INT_MIN || value > INT_MAX) {
+ return Api::NewError("%s: argument value at index %d is out of range",
+ CURRENT_FUNC, i);
+ }
+ native_value->as_int32 = static_cast<int32_t>(value);
+ break;
+ }
+
+ case Dart_NativeArgument_kUint32: {
+ int64_t value = 0;
+ if (!GetNativeIntegerArgument(arguments,
+ arg_index,
+ &value)) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Integer.", CURRENT_FUNC, i);
+ }
+ if (value < 0 || value > UINT_MAX) {
+ return Api::NewError("%s: argument value at index %d is out of range",
+ CURRENT_FUNC, i);
+ }
+ native_value->as_uint32 = static_cast<uint32_t>(value);
+ break;
+ }
+
+ case Dart_NativeArgument_kInt64: {
+ int64_t value = 0;
+ if (!GetNativeIntegerArgument(arguments,
+ arg_index,
+ &value)) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Integer.", CURRENT_FUNC, i);
+ }
+ native_value->as_int64 = value;
+ break;
+ }
+
+ case Dart_NativeArgument_kUint64: {
+ uint64_t value = 0;
+ if (!GetNativeUnsignedIntegerArgument(arguments,
+ arg_index,
+ &value)) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Integer.", CURRENT_FUNC, i);
+ }
+ native_value->as_uint64 = value;
+ break;
+ }
+
+ case Dart_NativeArgument_kDouble:
+ if (!GetNativeDoubleArgument(arguments,
+ arg_index,
+ &(native_value->as_double))) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type Double.", CURRENT_FUNC, i);
+ }
+ break;
+
+ case Dart_NativeArgument_kString:
+ if (!GetNativeStringArgument(arguments,
+ arg_index,
+ &(native_value->as_string.dart_str),
+ &(native_value->as_string.peer))) {
+ return Api::NewError("%s: expects argument at index %d to be of"
+ " type String.", CURRENT_FUNC, i);
+ }
+ break;
+
+ case Dart_NativeArgument_kNativeFields: {
+ Dart_Handle result = GetNativeFieldsOfArgument(
+ arguments,
+ arg_index,
+ native_value->as_native_fields.num_fields,
+ native_value->as_native_fields.values,
+ CURRENT_FUNC);
+ if (result != Api::Success()) {
+ return result;
+ }
+ break;
+ }
+
+ case Dart_NativeArgument_kInstance: {
+ Isolate* isolate = arguments->isolate();
+ ASSERT(isolate == Isolate::Current());
+ ASSERT(isolate->api_state() &&
+ isolate->api_state()->top_scope() != NULL);
+ native_value->as_instance =
+ Api::NewHandle(isolate, arguments->NativeArgAt(arg_index));
+ break;
+ }
+
+ default:
+ return Api::NewError("%s: invalid argument type %d.",
+ CURRENT_FUNC, arg_type);
+ }
+ }
+ return Api::Success();
+}
+
+
DART_EXPORT Dart_Handle Dart_GetNativeArgument(Dart_NativeArguments args,
int index) {
TRACE_API_CALL(CURRENT_FUNC);
@@ -4048,30 +4386,11 @@
if (field_values == NULL) {
RETURN_NULL_ERROR(field_values);
}
- Isolate* isolate = arguments->isolate();
- ASSERT(isolate == Isolate::Current());
- REUSABLE_OBJECT_HANDLESCOPE(isolate);
- Object& obj = isolate->ObjectHandle();
- obj = arguments->NativeArgAt(arg_index);
- if (obj.IsNull()) {
- for (intptr_t i = 0; i < num_fields; i++) {
- field_values[i] = 0;
- }
- return Api::Success();
- }
- if (!obj.IsInstance()) {
- return Api::NewError("%s expects argument at index '%d' to be of"
- " type Instance.", CURRENT_FUNC, arg_index);
- }
- const Instance& instance = Instance::Cast(obj);
- uint16_t field_count = instance.NumNativeFields();
- if (num_fields != field_count) {
- return Api::NewError(
- "%s: invalid 'field_values' array specified for returning field values",
- CURRENT_FUNC);
- }
- instance.GetNativeFields(num_fields, field_values);
- return Api::Success();
+ return GetNativeFieldsOfArgument(arguments,
+ arg_index,
+ num_fields,
+ field_values,
+ CURRENT_FUNC);
}
@@ -4094,23 +4413,12 @@
int arg_index,
void** peer) {
NativeArguments* arguments = reinterpret_cast<NativeArguments*>(args);
- Isolate* isolate = arguments->isolate();
- ASSERT(isolate == Isolate::Current());
- if (Api::StringGetPeerHelper(arguments, arg_index, peer)) {
- return Api::Success();
+ Dart_Handle result = Api::Null();
+ if (!GetNativeStringArgument(arguments, arg_index, &result, peer)) {
+ return Api::NewError("%s expects argument at %d to be of"
+ " type String.", CURRENT_FUNC, arg_index);
}
- *peer = NULL;
- REUSABLE_OBJECT_HANDLESCOPE(isolate);
- Object& obj = isolate->ObjectHandle();
- obj = arguments->NativeArgAt(arg_index);
- if (RawObject::IsStringClassId(obj.GetClassId())) {
- return Api::NewHandle(isolate, obj.raw());
- }
- if (obj.IsNull()) {
- return Api::Null();
- }
- return Api::NewError("%s expects argument to be of"
- " type String.", CURRENT_FUNC);
+ return result;
}
@@ -4124,33 +4432,11 @@
"%s: argument 'index' out of range. Expected 0..%d but saw %d.",
CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
}
- Isolate* isolate = arguments->isolate();
- ASSERT(isolate == Isolate::Current());
- REUSABLE_OBJECT_HANDLESCOPE(isolate);
- Object& obj = isolate->ObjectHandle();
- obj = arguments->NativeArgAt(index);
- intptr_t cid = obj.GetClassId();
- if (cid == kSmiCid) {
- *value = Smi::Cast(obj).Value();
- return Api::Success();
+ if (!GetNativeIntegerArgument(arguments, index, value)) {
+ return Api::NewError("%s: expects argument at %d to be of"
+ " type Integer.", CURRENT_FUNC, index);
}
- if (cid == kMintCid) {
- *value = Mint::Cast(obj).value();
- return Api::Success();
- }
- if (cid == kBigintCid) {
- const Bigint& bigint = Bigint::Cast(obj);
- if (BigintOperations::FitsIntoInt64(bigint)) {
- *value = BigintOperations::ToInt64(bigint);
- return Api::Success();
- }
- return Api::NewError(
- "%s: argument %d is a big integer that does not fit in 'value'.",
- CURRENT_FUNC, index);
- }
- return Api::NewError(
- "%s: argument %d is not an Integer argument.",
- CURRENT_FUNC, index);
+ return Api::Success();
}
@@ -4164,11 +4450,11 @@
"%s: argument 'index' out of range. Expected 0..%d but saw %d.",
CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
}
- if (Api::GetNativeBooleanArgument(arguments, index, value)) {
- return Api::Success();
+ if (!Api::GetNativeBooleanArgument(arguments, index, value)) {
+ return Api::NewError("%s: expects argument at %d to be of type Boolean.",
+ CURRENT_FUNC, index);
}
- return Api::NewError("%s: argument %d is not a Boolean argument.",
- CURRENT_FUNC, index);
+ return Api::Success();
}
@@ -4182,31 +4468,11 @@
"%s: argument 'index' out of range. Expected 0..%d but saw %d.",
CURRENT_FUNC, arguments->NativeArgCount() - 1, index);
}
- Isolate* isolate = arguments->isolate();
- ASSERT(isolate == Isolate::Current());
- REUSABLE_OBJECT_HANDLESCOPE(isolate);
- Object& obj = isolate->ObjectHandle();
- obj = arguments->NativeArgAt(index);
- intptr_t cid = obj.GetClassId();
- if (cid == kDoubleCid) {
- *value = Double::Cast(obj).value();
- return Api::Success();
+ if (!GetNativeDoubleArgument(arguments, index, value)) {
+ return Api::NewError("%s: expects argument at %d to be of"
+ " type Double.", CURRENT_FUNC, index);
}
- if (cid == kSmiCid) {
- *value = Smi::Cast(obj).AsDoubleValue();
- return Api::Success();
- }
- if (cid == kMintCid) {
- *value = Mint::Cast(obj).AsDoubleValue();
- return Api::Success();
- }
- if (cid == kBigintCid) {
- *value = Bigint::Cast(obj).AsDoubleValue();
- return Api::Success();
- }
- return Api::NewError(
- "%s: argument %d is not a Double argument.",
- CURRENT_FUNC, index);
+ return Api::Success();
}
« no previous file with comments | « runtime/vm/dart_api_impl.h ('k') | runtime/vm/dart_api_impl_test.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698