// Copyright (c) 2017, 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 "lib/stacktrace.h" #include "platform/assert.h" #include "vm/bootstrap_natives.h" #include "vm/debugger.h" #include "vm/exceptions.h" #include "vm/flags.h" #include "vm/microtask_mirror_queues.h" #include "vm/native_entry.h" #include "vm/object_store.h" #include "vm/runtime_entry.h" namespace dart { // This flag is defined in "runtime/vm/microtask_mirror_queues.cc". DECLARE_FLAG(bool, profile_microtasks); DEFINE_NATIVE_ENTRY(AsyncStarMoveNext_debuggerStepCheck, 0, 1) { #if !defined(PRODUCT) GET_NON_NULL_NATIVE_ARGUMENT(Closure, generator, arguments->NativeArgAt(0)); Debugger* debugger = isolate->debugger(); if (debugger != nullptr && debugger->IsSingleStepping()) { debugger->AsyncStepInto(generator); } #endif return Object::null(); } // Instantiate generic [closure] using the type argument T // corresponding to Future in the given [future] instance // (which may extend or implement Future). DEFINE_NATIVE_ENTRY(SuspendState_instantiateClosureWithFutureTypeArgument, 0, 2) { GET_NON_NULL_NATIVE_ARGUMENT(Closure, closure, arguments->NativeArgAt(0)); GET_NON_NULL_NATIVE_ARGUMENT(Instance, future, arguments->NativeArgAt(1)); IsolateGroup* isolate_group = thread->isolate_group(); const auto& future_class = Class::Handle(zone, isolate_group->object_store()->future_class()); ASSERT(future_class.NumTypeArguments() == 1); const auto& cls = Class::Handle(zone, future.clazz()); auto& type = Type::Handle(zone, cls.GetInstantiationOf(zone, future_class)); ASSERT(!type.IsNull()); if (!type.IsInstantiated()) { const auto& instance_type_args = TypeArguments::Handle(zone, future.GetTypeArguments()); type ^= type.InstantiateFrom(instance_type_args, Object::null_type_arguments(), kNoneFree, Heap::kOld); } auto& type_args = TypeArguments::Handle(zone, type.arguments()); ASSERT(type_args.IsNull() || type_args.Length() == 1); type_args = type_args.Canonicalize(thread); ASSERT(closure.delayed_type_arguments() == Object::empty_type_arguments().ptr()); closure.set_delayed_type_arguments(type_args); return closure.ptr(); } DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onScheduleAsyncCallback, 0, 0) { // There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that // this function can only ever be called when the `--profile-microtasks` CLI // flag is set in non-PRODUCT modes. #if !defined(PRODUCT) ASSERT(FLAG_profile_microtasks); const StackTrace& stack_trace = GetCurrentStackTrace( // We pass a `skip_frames` argument of 1 to skip the // `_MicrotaskMirrorQueue._onScheduleAsyncCallback` frame. 1); MicrotaskMirrorQueues::GetQueue(static_cast(isolate->main_port())) ->OnScheduleAsyncCallback(stack_trace); return Object::null(); #else UNREACHABLE(); #endif // !defined(PRODUCT) } DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onSchedulePriorityAsyncCallback, 0, 0) { // There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that // this function can only ever be called when the `--profile-microtasks` CLI // flag is set in non-PRODUCT modes. #if !defined(PRODUCT) ASSERT(FLAG_profile_microtasks); MicrotaskMirrorQueues::GetQueue(static_cast(isolate->main_port())) ->OnSchedulePriorityAsyncCallback(); return Object::null(); #else UNREACHABLE(); #endif // !defined(PRODUCT) } DEFINE_NATIVE_ENTRY(MicrotaskMirrorQueue_onAsyncCallbackComplete, 0, 2) { // There is logic in `sdk/lib/async/schedule_microtask.dart` that ensures that // this function can only ever be called when the `--profile-microtasks` CLI // flag is set in non-PRODUCT modes. #if !defined(PRODUCT) ASSERT(FLAG_profile_microtasks); GET_NON_NULL_NATIVE_ARGUMENT(Integer, start_time, arguments->NativeArgAt(0)); GET_NON_NULL_NATIVE_ARGUMENT(Integer, end_time, arguments->NativeArgAt(1)); MicrotaskMirrorQueues::GetQueue(static_cast(isolate->main_port())) ->OnAsyncCallbackComplete(start_time.Value(), end_time.Value()); return Object::null(); #else UNREACHABLE(); #endif // !defined(PRODUCT) } } // namespace dart