// Copyright (c) 2012, 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 #include #include #include "include/bin/dart_io_api.h" #include "include/dart_api.h" #include "include/dart_tools_api.h" #include "platform/assert.h" #include "bin/builtin.h" #include "bin/dartutils.h" #include "bin/file.h" #include "bin/io_natives.h" #include "bin/platform.h" namespace dart { namespace bin { // Lists the native functions implementing basic functionality in // standalone dart, such as printing, file I/O, and platform information. // Advanced I/O classes like sockets and process management are implemented // using functions listed in io_natives.cc. #define BUILTIN_NATIVE_LIST(V) V(Builtin_PrintString, 1) BUILTIN_NATIVE_LIST(DECLARE_FUNCTION); static struct NativeEntries { const char* name_; Dart_NativeFunction function_; int argument_count_; } BuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)}; void Builtin_DummyNative(Dart_NativeArguments args) { UNREACHABLE(); } /** * Looks up native functions in both libdart_builtin and libdart_io. */ Dart_NativeFunction Builtin::NativeLookup(Dart_Handle name, int argument_count, bool* auto_setup_scope) { const char* function_name = nullptr; Dart_Handle err = Dart_StringToCString(name, &function_name); if (Dart_IsError(err)) { Dart_PropagateError(err); } ASSERT(function_name != nullptr); ASSERT(auto_setup_scope != nullptr); *auto_setup_scope = true; int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries); for (int i = 0; i < num_entries; i++) { struct NativeEntries* entry = &(BuiltinEntries[i]); if ((strcmp(function_name, entry->name_) == 0) && (entry->argument_count_ == argument_count)) { return reinterpret_cast(entry->function_); } } Dart_NativeFunction result = IONativeLookup(name, argument_count, auto_setup_scope); if (result == nullptr) { result = Builtin_DummyNative; } return result; } void* Builtin::FfiNativeLookup(const char* name, uintptr_t argument_count) { return IOFfiNativeLookup(name, argument_count); } const uint8_t* Builtin::NativeSymbol(Dart_NativeFunction nf) { int num_entries = sizeof(BuiltinEntries) / sizeof(struct NativeEntries); for (int i = 0; i < num_entries; i++) { struct NativeEntries* entry = &(BuiltinEntries[i]); if (reinterpret_cast(entry->function_) == nf) { return reinterpret_cast(entry->name_); } } return IONativeSymbol(nf); } // Implementation of native functions which are used for some // test/debug functionality in standalone dart mode. void FUNCTION_NAME(Builtin_PrintString)(Dart_NativeArguments args) { intptr_t length = 0; Dart_Handle str = Dart_GetNativeArgument(args, 0); Dart_Handle result = Dart_StringUTF8Length(str, &length); if (Dart_IsError(result)) { Dart_PropagateError(result); } intptr_t new_length = length + 1; uint8_t* chars = Dart_ScopeAllocate(new_length); ASSERT(chars != nullptr); result = Dart_CopyUTF8EncodingOfString(str, chars, length); if (Dart_IsError(result)) { Dart_PropagateError(result); } chars[length] = '\n'; // Uses fwrite to support printing NUL bytes. const uint8_t* cursor = chars; intptr_t remaining = new_length; while (remaining > 0) { intptr_t written = fwrite(cursor, 1, remaining, stdout); if (written == 0) break; // EOF or error: ignore cursor += written; remaining -= written; } fflush(stdout); if (ShouldCaptureStdout()) { // For now we report print output on the Stdout stream. const char* res = Dart_ServiceSendDataEvent("Stdout", "WriteEvent", chars, new_length); ASSERT(res == nullptr); } } } // namespace bin } // namespace dart