| // Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file | |
| // for details. All rights reserved. Use of this source code is governed by a | |
| // BSD-style license that can be found in the LICENSE file. | |
| #include <stdio.h> | |
| #include <stdlib.h> | |
| #include <string.h> | |
| // TODO(dartbug.com/40579): This requires static linking to either link | |
| // dart.exe or dartaotruntime.exe on Windows. | |
| // The sample currently fails on Windows in AOT mode. | |
| #include "include/dart_api.h" | |
| #define ENSURE(X) \ | |
| if (!(X)) { \ | |
| fprintf(stderr, "%s:%d: %s\n", __FILE__, __LINE__, "Check failed: " #X); \ | |
| exit(1); \ | |
| } | |
| #define ENSURE_VALID(X) ENSURE(!Dart_IsError(X)) | |
| // | |
| // Functions under test. | |
| // | |
| void Function1Uint8(Dart_NativeArguments args) { | |
| int64_t arg = 0; | |
| Dart_GetNativeIntegerArgument(args, /*index=*/0, &arg); | |
| Dart_SetIntegerReturnValue(args, arg + 42); | |
| } | |
| void Function20Int64(Dart_NativeArguments args) { | |
| int64_t arg = 0; | |
| int64_t result = 0; | |
| for (int i = 0; i < 20; i++) { | |
| Dart_GetNativeIntegerArgument(args, /*index=*/i, &arg); | |
| result += arg; | |
| } | |
| Dart_SetIntegerReturnValue(args, result); | |
| } | |
| void Function1Double(Dart_NativeArguments args) { | |
| double arg = 0.0; | |
| Dart_GetNativeDoubleArgument(args, /*index=*/0, &arg); | |
| Dart_SetDoubleReturnValue(args, arg + 42.0); | |
| } | |
| void Function20Double(Dart_NativeArguments args) { | |
| double arg = 0; | |
| double result = 0; | |
| for (int i = 0; i < 20; i++) { | |
| Dart_GetNativeDoubleArgument(args, /*index=*/i, &arg); | |
| result += arg; | |
| } | |
| Dart_SetDoubleReturnValue(args, result); | |
| } | |
| void Function1Handle(Dart_NativeArguments args) { | |
| Dart_Handle arg = Dart_GetNativeArgument(args, /*index=*/0); | |
| Dart_SetReturnValue(args, arg); | |
| } | |
| void Function20Handle(Dart_NativeArguments args) { | |
| Dart_Handle arg = Dart_GetNativeArgument(args, /*index=*/0); | |
| Dart_SetReturnValue(args, arg); | |
| } | |
| // | |
| // Test helpers. | |
| // | |
| DART_EXPORT Dart_Handle GetRootLibraryUrl() { | |
| Dart_Handle root_lib = Dart_RootLibrary(); | |
| Dart_Handle lib_url = Dart_LibraryUrl(root_lib); | |
| ENSURE_VALID(lib_url); | |
| return lib_url; | |
| } | |
| Dart_NativeFunction NativeEntryResolver(Dart_Handle name, | |
| int num_of_arguments, | |
| bool* auto_setup_scope) { | |
| ENSURE(Dart_IsString(name)); | |
| ENSURE(auto_setup_scope != NULL); | |
| *auto_setup_scope = true; | |
| const char* name_str = NULL; | |
| ENSURE_VALID(Dart_StringToCString(name, &name_str)); | |
| if (strcmp(name_str, "Function1Uint8") == 0 && num_of_arguments == 1) { | |
| return &Function1Uint8; | |
| } else if (strcmp(name_str, "Function20Int64") == 0 && | |
| num_of_arguments == 20) { | |
| return &Function20Int64; | |
| } else if (strcmp(name_str, "Function1Double") == 0 && | |
| num_of_arguments == 1) { | |
| return &Function1Double; | |
| } else if (strcmp(name_str, "Function20Double") == 0 && | |
| num_of_arguments == 20) { | |
| return &Function20Double; | |
| } else if (strcmp(name_str, "Function1Handle") == 0 && | |
| num_of_arguments == 1) { | |
| return &Function1Handle; | |
| } else if (strcmp(name_str, "Function20Handle") == 0 && | |
| num_of_arguments == 20) { | |
| return &Function20Handle; | |
| } | |
| // Unreachable in benchmark. | |
| ENSURE(false); | |
| } | |
| DART_EXPORT void SetNativeResolverForTest(Dart_Handle url) { | |
| Dart_Handle library = Dart_LookupLibrary(url); | |
| ENSURE_VALID(library); | |
| Dart_Handle result = | |
| Dart_SetNativeResolver(library, &NativeEntryResolver, NULL); | |
| ENSURE_VALID(result); | |
| } |