| OLD | NEW |
| (Empty) |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "sky/engine/config.h" | |
| 6 #include "sky/engine/bindings2/builtin_natives.h" | |
| 7 | |
| 8 #include <stdio.h> | |
| 9 #include <stdlib.h> | |
| 10 #include <string.h> | |
| 11 | |
| 12 #include "base/bind.h" | |
| 13 #include "base/logging.h" | |
| 14 #include "base/macros.h" | |
| 15 #include "dart/runtime/include/dart_api.h" | |
| 16 #include "sky/engine/bindings2/builtin.h" | |
| 17 #include "sky/engine/core/dom/Microtask.h" | |
| 18 #include "sky/engine/core/script/dom_dart_state.h" | |
| 19 #include "sky/engine/tonic/dart_api_scope.h" | |
| 20 #include "sky/engine/tonic/dart_builtin.h" | |
| 21 #include "sky/engine/tonic/dart_error.h" | |
| 22 #include "sky/engine/tonic/dart_isolate_scope.h" | |
| 23 #include "sky/engine/tonic/dart_state.h" | |
| 24 #include "sky/engine/tonic/dart_value.h" | |
| 25 #include "sky/engine/wtf/text/WTFString.h" | |
| 26 | |
| 27 namespace blink { | |
| 28 | |
| 29 #define REGISTER_FUNCTION(name, count) \ | |
| 30 { "" #name, name, count }, | |
| 31 #define DECLARE_FUNCTION(name, count) \ | |
| 32 extern void name(Dart_NativeArguments args); | |
| 33 | |
| 34 // Lists the native functions implementing basic functionality in | |
| 35 // the Mojo embedder dart, such as printing, and file I/O. | |
| 36 #define BUILTIN_NATIVE_LIST(V) \ | |
| 37 V(Logger_PrintString, 1) \ | |
| 38 V(ScheduleMicrotask, 1) \ | |
| 39 V(Timer_create, 3) \ | |
| 40 V(Timer_cancel, 1) | |
| 41 | |
| 42 BUILTIN_NATIVE_LIST(DECLARE_FUNCTION); | |
| 43 | |
| 44 static struct NativeEntries { | |
| 45 const char* name; | |
| 46 Dart_NativeFunction function; | |
| 47 int argument_count; | |
| 48 } BuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)}; | |
| 49 | |
| 50 Dart_NativeFunction BuiltinNatives::NativeLookup(Dart_Handle name, | |
| 51 int argument_count, | |
| 52 bool* auto_setup_scope) { | |
| 53 const char* function_name = nullptr; | |
| 54 Dart_Handle result = Dart_StringToCString(name, &function_name); | |
| 55 DART_CHECK_VALID(result); | |
| 56 DCHECK(function_name != nullptr); | |
| 57 DCHECK(auto_setup_scope != nullptr); | |
| 58 *auto_setup_scope = true; | |
| 59 size_t num_entries = arraysize(BuiltinEntries); | |
| 60 for (size_t i = 0; i < num_entries; i++) { | |
| 61 const struct NativeEntries& entry = BuiltinEntries[i]; | |
| 62 if (!strcmp(function_name, entry.name) && | |
| 63 (entry.argument_count == argument_count)) { | |
| 64 return entry.function; | |
| 65 } | |
| 66 } | |
| 67 return nullptr; | |
| 68 } | |
| 69 | |
| 70 const uint8_t* BuiltinNatives::NativeSymbol(Dart_NativeFunction native_function)
{ | |
| 71 size_t num_entries = arraysize(BuiltinEntries); | |
| 72 for (size_t i = 0; i < num_entries; i++) { | |
| 73 const struct NativeEntries& entry = BuiltinEntries[i]; | |
| 74 if (entry.function == native_function) { | |
| 75 return reinterpret_cast<const uint8_t*>(entry.name); | |
| 76 } | |
| 77 } | |
| 78 return nullptr; | |
| 79 } | |
| 80 | |
| 81 static Dart_Handle GetClosure(Dart_Handle builtin_library, const char* name) { | |
| 82 Dart_Handle getter_name = ToDart(name); | |
| 83 Dart_Handle closure = Dart_Invoke(builtin_library, getter_name, 0, nullptr); | |
| 84 DART_CHECK_VALID(closure); | |
| 85 return closure; | |
| 86 } | |
| 87 | |
| 88 static void InitDartInternal(Dart_Handle builtin_library) { | |
| 89 Dart_Handle print = GetClosure(builtin_library, "_getPrintClosure"); | |
| 90 Dart_Handle timer = GetClosure(builtin_library, "_getCreateTimerClosure"); | |
| 91 | |
| 92 Dart_Handle internal_library = DartBuiltin::LookupLibrary("dart:_internal"); | |
| 93 | |
| 94 DART_CHECK_VALID(Dart_SetField( | |
| 95 internal_library, ToDart("_printClosure"), print)); | |
| 96 | |
| 97 Dart_Handle vm_hooks_name = ToDart("VMLibraryHooks"); | |
| 98 Dart_Handle vm_hooks = Dart_GetClass(internal_library, vm_hooks_name); | |
| 99 DART_CHECK_VALID(vm_hooks); | |
| 100 Dart_Handle timer_name = ToDart("timerFactory"); | |
| 101 DART_CHECK_VALID(Dart_SetField(vm_hooks, timer_name, timer)); | |
| 102 } | |
| 103 | |
| 104 static void InitAsync(Dart_Handle builtin_library) { | |
| 105 Dart_Handle schedule_microtask = | |
| 106 GetClosure(builtin_library, "_getScheduleMicrotaskClosure"); | |
| 107 Dart_Handle async_library = DartBuiltin::LookupLibrary("dart:async"); | |
| 108 Dart_Handle set_schedule_microtask = ToDart("_setScheduleImmediateClosure"); | |
| 109 DART_CHECK_VALID(Dart_Invoke(async_library, set_schedule_microtask, 1, | |
| 110 &schedule_microtask)); | |
| 111 } | |
| 112 | |
| 113 void BuiltinNatives::Init() { | |
| 114 Dart_Handle builtin = Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); | |
| 115 DART_CHECK_VALID(builtin); | |
| 116 InitDartInternal(builtin); | |
| 117 InitAsync(builtin); | |
| 118 } | |
| 119 | |
| 120 // Implementation of native functions which are used for some | |
| 121 // test/debug functionality in standalone dart mode. | |
| 122 void Logger_PrintString(Dart_NativeArguments args) { | |
| 123 intptr_t length = 0; | |
| 124 uint8_t* chars = nullptr; | |
| 125 Dart_Handle str = Dart_GetNativeArgument(args, 0); | |
| 126 Dart_Handle result = Dart_StringToUTF8(str, &chars, &length); | |
| 127 if (Dart_IsError(result)) { | |
| 128 Dart_PropagateError(result); | |
| 129 } else { | |
| 130 | |
| 131 String message(chars, length); | |
| 132 // TODO(dart): Hook up to developer console (if/when that's a thing). | |
| 133 #if OS(ANDROID) | |
| 134 LOG(INFO) << "CONSOLE: " << message.utf8().data(); | |
| 135 #else | |
| 136 printf("CONSOLE: %s\n", message.utf8().data()); | |
| 137 fflush(stdout); | |
| 138 #endif | |
| 139 } | |
| 140 } | |
| 141 | |
| 142 static void ExecuteMicrotask(base::WeakPtr<DartState> dart_state, | |
| 143 RefPtr<DartValue> callback) { | |
| 144 if (!dart_state) | |
| 145 return; | |
| 146 DartIsolateScope scope(dart_state->isolate()); | |
| 147 DartApiScope api_scope; | |
| 148 LogIfError(Dart_InvokeClosure(callback->dart_value(), 0, nullptr)); | |
| 149 } | |
| 150 | |
| 151 void ScheduleMicrotask(Dart_NativeArguments args) { | |
| 152 Dart_Handle closure = Dart_GetNativeArgument(args, 0); | |
| 153 if (LogIfError(closure) || !Dart_IsClosure(closure)) | |
| 154 return; | |
| 155 DartState* dart_state = DartState::Current(); | |
| 156 Microtask::enqueueMicrotask(base::Bind(&ExecuteMicrotask, | |
| 157 dart_state->GetWeakPtr(), DartValue::Create(dart_state, closure))); | |
| 158 } | |
| 159 | |
| 160 void Timer_create(Dart_NativeArguments args) { | |
| 161 int64_t milliseconds = 0; | |
| 162 DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &milliseconds)); | |
| 163 Dart_Handle closure = Dart_GetNativeArgument(args, 1); | |
| 164 DART_CHECK_VALID(closure); | |
| 165 CHECK(Dart_IsClosure(closure)); | |
| 166 bool repeating = false; | |
| 167 DART_CHECK_VALID(Dart_GetNativeBooleanArgument(args, 2, &repeating)); | |
| 168 | |
| 169 DOMDartState* state = DOMDartState::Current(); | |
| 170 int timer_id = DOMTimer::install(state->document(), | |
| 171 ScheduledAction::Create(state, closure), | |
| 172 milliseconds, | |
| 173 !repeating); | |
| 174 Dart_SetIntegerReturnValue(args, timer_id); | |
| 175 } | |
| 176 | |
| 177 void Timer_cancel(Dart_NativeArguments args) { | |
| 178 int64_t timer_id = 0; | |
| 179 DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &timer_id)); | |
| 180 | |
| 181 DOMDartState* state = DOMDartState::Current(); | |
| 182 DOMTimer::removeByID(state->document(), timer_id); | |
| 183 } | |
| 184 | |
| 185 } // namespace blink | |
| OLD | NEW |