[vm] Fix Dart_GetNativeFieldsOfArgument when passed an object with no native fields.

Bug: https://github.com/flutter/flutter/issues/64598
Change-Id: I90325e5eecc7a7fca2cb76894ce1830c93c05388
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/160185
Reviewed-by: Siva Annamalai <asiva@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2020-08-26 18:03:05 +00:00
committed by commit-bot@chromium.org
parent d5b9dcb00c
commit ae37f48796
5 changed files with 51 additions and 28 deletions
+1 -1
View File
@@ -36,7 +36,7 @@ static Dart_NativeFunction native_resolver(Dart_Handle name,
bool* auto_setup_scope) {
ASSERT(auto_setup_scope);
*auto_setup_scope = false;
return reinterpret_cast<Dart_NativeFunction>(&NativeFunc);
return NativeFunc;
}
TEST_CASE(StackMapGC) {
@@ -33,7 +33,7 @@ static Dart_NativeFunction NoopNativeLookup(Dart_Handle name,
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != nullptr);
*auto_setup_scope = false;
return reinterpret_cast<Dart_NativeFunction>(&NoopNative);
return NoopNative;
}
// Flatten all non-captured LocalVariables from the given scope and its children
+22 -16
View File
@@ -653,23 +653,29 @@ bool Api::GetNativeFieldsOfArgument(NativeArguments* arguments,
intptr_t* field_values) {
NoSafepointScope no_safepoint_scope;
ObjectPtr raw_obj = arguments->NativeArgAt(arg_index);
if (raw_obj->IsHeapObject()) {
intptr_t cid = raw_obj->GetClassId();
if (cid >= kNumPredefinedCids) {
TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
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;
}
intptr_t cid = raw_obj->GetClassIdMayBeSmi();
int class_num_fields = arguments->thread()
->isolate()
->class_table()
->At(cid)
->ptr()
->num_native_fields_;
if (num_fields != class_num_fields) {
// No native fields or mismatched native field count.
return false;
}
return false;
TypedDataPtr native_fields = *reinterpret_cast<TypedDataPtr*>(
ObjectLayout::ToAddr(raw_obj) + sizeof(ObjectLayout));
if (native_fields == TypedData::null()) {
// Native fields not initialized.
memset(field_values, 0, (num_fields * sizeof(field_values[0])));
return true;
}
ASSERT(class_num_fields == Smi::Value(native_fields->ptr()->length_));
intptr_t* native_values =
reinterpret_cast<intptr_t*>(native_fields->ptr()->data());
memmove(field_values, native_values, (num_fields * sizeof(field_values[0])));
return true;
}
void Api::SetWeakHandleReturnValue(NativeArguments* args,
+26 -10
View File
@@ -538,7 +538,7 @@ static Dart_NativeFunction CurrentStackTraceNativeLookup(
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = true;
return reinterpret_cast<Dart_NativeFunction>(&CurrentStackTraceNative);
return CurrentStackTraceNative;
}
TEST_CASE(DartAPI_CurrentStackTraceInfo) {
@@ -687,7 +687,7 @@ static Dart_NativeFunction PropagateError_native_lookup(
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = true;
return reinterpret_cast<Dart_NativeFunction>(&PropagateErrorNative);
return PropagateErrorNative;
}
TEST_CASE(DartAPI_PropagateCompileTimeError) {
@@ -4995,7 +4995,7 @@ static Dart_NativeFunction native_field_lookup(Dart_Handle name,
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = false;
return reinterpret_cast<Dart_NativeFunction>(&NativeFieldLookup);
return NativeFieldLookup;
}
TEST_CASE(DartAPI_InjectNativeFields2) {
@@ -5139,6 +5139,15 @@ void TestNativeFieldsAccess_access(Dart_NativeArguments args) {
EXPECT_EQ(0, field_values[1]);
}
void TestNativeFieldsAccess_invalidAccess(Dart_NativeArguments args) {
intptr_t field_values[kTestNumNativeFields];
Dart_Handle result = Dart_GetNativeFieldsOfArgument(
args, 0, kTestNumNativeFields, field_values);
EXPECT_ERROR(result,
"Dart_GetNativeFieldsOfArgument: "
"expected 0 'num_fields' but was passed in 2");
}
static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name,
int argument_count,
bool* auto_scope) {
@@ -5152,10 +5161,12 @@ static Dart_NativeFunction TestNativeFieldsAccess_lookup(Dart_Handle name,
const char* function_name = obj.ToCString();
ASSERT(function_name != NULL);
if (strcmp(function_name, "TestNativeFieldsAccess_init") == 0) {
return reinterpret_cast<Dart_NativeFunction>(&TestNativeFieldsAccess_init);
return TestNativeFieldsAccess_init;
} else if (strcmp(function_name, "TestNativeFieldsAccess_access") == 0) {
return reinterpret_cast<Dart_NativeFunction>(
&TestNativeFieldsAccess_access);
return TestNativeFieldsAccess_access;
} else if (strcmp(function_name, "TestNativeFieldsAccess_invalidAccess") ==
0) {
return TestNativeFieldsAccess_invalidAccess;
} else {
return NULL;
}
@@ -5178,10 +5189,15 @@ TEST_CASE(DartAPI_TestNativeFieldsAccess) {
" int%s accessNativeFlds(int%s i) native "
"'TestNativeFieldsAccess_access';\n"
"}\n"
"class NoNativeFields {\n"
" int neitherATypedDataNorNull = 0;\n"
" invalidAccess() native 'TestNativeFieldsAccess_invalidAccess';\n"
"}\n"
"NativeFields testMain() {\n"
" NativeFields obj = new NativeFields(10, 20);\n"
" obj.initNativeFlds();\n"
" obj.accessNativeFlds(null);\n"
" new NoNativeFields().invalidAccess();\n"
" return obj;\n"
"}\n",
nullable_tag, nullable_tag, nullable_tag, nullable_tag),
@@ -6394,7 +6410,7 @@ static Dart_NativeFunction native_lookup(Dart_Handle name,
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = true;
return reinterpret_cast<Dart_NativeFunction>(&ExceptionNative);
return ExceptionNative;
}
TEST_CASE(DartAPI_ThrowException) {
@@ -6557,9 +6573,9 @@ static Dart_NativeFunction native_args_lookup(Dart_Handle name,
const char* function_name = obj.ToCString();
ASSERT(function_name != NULL);
if (strcmp(function_name, "NativeArgument_Create") == 0) {
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCreate);
return NativeArgumentCreate;
} else if (strcmp(function_name, "NativeArgument_Access") == 0) {
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentAccess);
return NativeArgumentAccess;
}
return NULL;
}
@@ -6618,7 +6634,7 @@ static Dart_NativeFunction gnac_lookup(Dart_Handle name,
bool* auto_setup_scope) {
ASSERT(auto_setup_scope != NULL);
*auto_setup_scope = true;
return reinterpret_cast<Dart_NativeFunction>(&NativeArgumentCounter);
return NativeArgumentCounter;
}
TEST_CASE(DartAPI_GetNativeArgumentCount) {
+1
View File
@@ -806,6 +806,7 @@ class ClassLayout : public ObjectLayout {
friend class SnapshotReader;
friend class InstanceSerializationCluster;
friend class CidRewriteVisitor;
friend class Api;
};
class PatchClassLayout : public ObjectLayout {