Chromium Code Reviews| 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_error.h" | |
| 21 #include "sky/engine/tonic/dart_isolate_scope.h" | |
| 22 #include "sky/engine/tonic/dart_state.h" | |
| 23 #include "sky/engine/tonic/dart_value.h" | |
| 24 #include "sky/engine/wtf/text/WTFString.h" | |
| 25 | |
| 26 namespace blink { | |
| 27 | |
| 28 #define REGISTER_FUNCTION(name, count) \ | |
| 29 { "" #name, name, count }, | |
| 30 #define DECLARE_FUNCTION(name, count) \ | |
| 31 extern void name(Dart_NativeArguments args); | |
| 32 | |
| 33 // Lists the native functions implementing basic functionality in | |
| 34 // the Mojo embedder dart, such as printing, and file I/O. | |
| 35 #define BUILTIN_NATIVE_LIST(V) \ | |
| 36 V(Logger_PrintString, 1) \ | |
| 37 V(ScheduleMicrotask, 1) \ | |
| 38 V(Timer_create, 3) \ | |
| 39 V(Timer_cancel, 1) | |
| 40 | |
| 41 BUILTIN_NATIVE_LIST(DECLARE_FUNCTION); | |
| 42 | |
| 43 static struct NativeEntries { | |
| 44 const char* name; | |
| 45 Dart_NativeFunction function; | |
| 46 int argument_count; | |
| 47 } BuiltinEntries[] = {BUILTIN_NATIVE_LIST(REGISTER_FUNCTION)}; | |
| 48 | |
| 49 Dart_NativeFunction BuiltinNatives::NativeLookup(Dart_Handle name, | |
| 50 int argument_count, | |
| 51 bool* auto_setup_scope) { | |
| 52 const char* function_name = nullptr; | |
| 53 Dart_Handle result = Dart_StringToCString(name, &function_name); | |
| 54 DART_CHECK_VALID(result); | |
| 55 DCHECK(function_name != nullptr); | |
| 56 DCHECK(auto_setup_scope != nullptr); | |
| 57 *auto_setup_scope = true; | |
| 58 size_t num_entries = arraysize(BuiltinEntries); | |
| 59 for (size_t i = 0; i < num_entries; i++) { | |
|
eseidel
2015/02/12 21:09:37
I wonder if this is wroth having has an array or i
| |
| 60 const struct NativeEntries& entry = BuiltinEntries[i]; | |
| 61 if (!strcmp(function_name, entry.name) && | |
| 62 (entry.argument_count == argument_count)) { | |
| 63 return entry.function; | |
| 64 } | |
| 65 } | |
| 66 return nullptr; | |
| 67 } | |
| 68 | |
| 69 const uint8_t* BuiltinNatives::NativeSymbol(Dart_NativeFunction native_function) { | |
| 70 size_t num_entries = arraysize(BuiltinEntries); | |
| 71 for (size_t i = 0; i < num_entries; i++) { | |
| 72 const struct NativeEntries& entry = BuiltinEntries[i]; | |
| 73 if (entry.function == native_function) { | |
| 74 return reinterpret_cast<const uint8_t*>(entry.name); | |
| 75 } | |
| 76 } | |
| 77 return nullptr; | |
| 78 } | |
| 79 | |
| 80 static Dart_Handle GetClosure(Dart_Handle builtin_library, const char* name) { | |
| 81 Dart_Handle getter_name = Dart_NewStringFromCString(name); | |
| 82 Dart_Handle closure = Dart_Invoke(builtin_library, getter_name, 0, nullptr); | |
| 83 DART_CHECK_VALID(closure); | |
| 84 return closure; | |
| 85 } | |
| 86 | |
| 87 static void InitDartInternal(Dart_Handle builtin_library) { | |
| 88 Dart_Handle print = GetClosure(builtin_library, "_getPrintClosure"); | |
| 89 Dart_Handle timer = GetClosure(builtin_library, "_getCreateTimerClosure"); | |
| 90 | |
| 91 Dart_Handle internal_name = Dart_NewStringFromCString("dart:_internal"); | |
|
eseidel
2015/02/12 21:09:37
We should have a helper. Dart_Handle LookupLibrar
abarth-chromium
2015/02/12 21:17:54
We should just add DartConverter<char*>. Then you
| |
| 92 Dart_Handle internal_library = Dart_LookupLibrary(internal_name); | |
| 93 DART_CHECK_VALID(internal_library); | |
| 94 | |
| 95 DART_CHECK_VALID(Dart_SetField( | |
| 96 internal_library, Dart_NewStringFromCString("_printClosure"), print)); | |
| 97 | |
| 98 Dart_Handle vm_hooks_name = Dart_NewStringFromCString("VMLibraryHooks"); | |
| 99 Dart_Handle vm_hooks = Dart_GetClass(internal_library, vm_hooks_name); | |
| 100 DART_CHECK_VALID(vm_hooks); | |
| 101 Dart_Handle timer_name = Dart_NewStringFromCString("timerFactory"); | |
|
eseidel
2015/02/12 21:09:37
We should consider a dartString(char*) helper. Po
| |
| 102 DART_CHECK_VALID(Dart_SetField(vm_hooks, timer_name, timer)); | |
| 103 } | |
| 104 | |
| 105 static void InitAsync(Dart_Handle builtin_library) { | |
| 106 Dart_Handle schedule_microtask = | |
| 107 GetClosure(builtin_library, "_getScheduleMicrotaskClosure"); | |
| 108 Dart_Handle async_name = Dart_NewStringFromCString("dart:async"); | |
| 109 Dart_Handle async_library = Dart_LookupLibrary(async_name); | |
| 110 DART_CHECK_VALID(async_library); | |
| 111 Dart_Handle set_schedule_microtask = | |
| 112 Dart_NewStringFromCString("_setScheduleImmediateClosure"); | |
| 113 DART_CHECK_VALID(Dart_Invoke(async_library, set_schedule_microtask, 1, | |
| 114 &schedule_microtask)); | |
| 115 } | |
| 116 | |
| 117 void BuiltinNatives::Init() { | |
| 118 Dart_Handle builtin = Builtin::LoadAndCheckLibrary(Builtin::kBuiltinLibrary); | |
| 119 DART_CHECK_VALID(builtin); | |
| 120 InitDartInternal(builtin); | |
| 121 InitAsync(builtin); | |
| 122 } | |
| 123 | |
| 124 // Implementation of native functions which are used for some | |
| 125 // test/debug functionality in standalone dart mode. | |
| 126 void Logger_PrintString(Dart_NativeArguments args) { | |
| 127 intptr_t length = 0; | |
| 128 uint8_t* chars = nullptr; | |
| 129 Dart_Handle str = Dart_GetNativeArgument(args, 0); | |
| 130 Dart_Handle result = Dart_StringToUTF8(str, &chars, &length); | |
| 131 if (Dart_IsError(result)) { | |
| 132 Dart_PropagateError(result); | |
| 133 } else { | |
| 134 | |
| 135 String message(chars, length); | |
| 136 // TODO(dart): Hook up to developer console (if/when that's a thing). | |
|
abarth-chromium
2015/02/12 20:52:31
This comment should be indented two spaces
| |
| 137 #if OS(ANDROID) | |
| 138 LOG(INFO) << "CONSOLE: " << message.utf8().data(); | |
| 139 #else | |
| 140 printf("CONSOLE: %s\n", message.utf8().data()); | |
| 141 #endif | |
| 142 | |
| 143 } | |
| 144 fflush(stdout); | |
|
eseidel
2015/02/12 21:09:37
I think this only makes sense in the printf case,
abarth-chromium
2015/02/12 21:17:54
Yeah, this should be in the printf branch.
| |
| 145 } | |
| 146 | |
| 147 static void ExecuteMicrotask(base::WeakPtr<DartState> dart_state, | |
| 148 RefPtr<DartValue> callback) { | |
| 149 if (!dart_state) | |
| 150 return; | |
| 151 DartIsolateScope scope(dart_state->isolate()); | |
| 152 DartApiScope api_scope; | |
| 153 LogIfError(Dart_InvokeClosure(callback->dart_value(), 0, nullptr)); | |
| 154 } | |
| 155 | |
| 156 void ScheduleMicrotask(Dart_NativeArguments args) { | |
| 157 DartState* dart_state = DartState::Current(); | |
|
eseidel
2015/02/12 21:09:37
Do we need/want to get the state before checking t
abarth-chromium
2015/02/12 21:17:54
No. It should move down.
| |
| 158 Dart_Handle closure = Dart_GetNativeArgument(args, 0); | |
| 159 if (LogIfError(closure) || !Dart_IsClosure(closure)) | |
| 160 return; | |
| 161 Microtask::enqueueMicrotask(base::Bind(&ExecuteMicrotask, | |
| 162 dart_state->GetWeakPtr(), DartValue::Create(dart_state, closure))); | |
| 163 } | |
| 164 | |
| 165 void Timer_create(Dart_NativeArguments args) { | |
| 166 int64_t milliseconds = 0; | |
| 167 DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &milliseconds)); | |
| 168 Dart_Handle closure = Dart_GetNativeArgument(args, 1); | |
| 169 DART_CHECK_VALID(closure); | |
| 170 CHECK(Dart_IsClosure(closure)); | |
| 171 bool repeating = false; | |
| 172 DART_CHECK_VALID(Dart_GetNativeBooleanArgument(args, 2, &repeating)); | |
| 173 | |
| 174 DOMDartState* state = DOMDartState::Current(); | |
| 175 int timer_id = DOMTimer::install(state->document(), | |
| 176 ScheduledAction::Create(state, closure), | |
| 177 milliseconds, | |
| 178 !repeating); | |
| 179 Dart_SetIntegerReturnValue(args, timer_id); | |
| 180 } | |
| 181 | |
| 182 void Timer_cancel(Dart_NativeArguments args) { | |
| 183 int64_t timer_id = 0; | |
| 184 DART_CHECK_VALID(Dart_GetNativeIntegerArgument(args, 0, &timer_id)); | |
| 185 | |
| 186 DOMDartState* state = DOMDartState::Current(); | |
| 187 DOMTimer::removeByID(state->document(), timer_id); | |
| 188 } | |
| 189 | |
| 190 } // namespace blink | |
| OLD | NEW |