Line | Count | Source (jump to first uncovered line) |
1 | | #include "timers.h" |
2 | | #include "env-inl.h" |
3 | | #include "node_external_reference.h" |
4 | | #include "util-inl.h" |
5 | | #include "v8.h" |
6 | | |
7 | | #include <cstdint> |
8 | | |
9 | | namespace node { |
10 | | namespace timers { |
11 | | |
12 | | using v8::Context; |
13 | | using v8::Function; |
14 | | using v8::FunctionCallbackInfo; |
15 | | using v8::Isolate; |
16 | | using v8::Local; |
17 | | using v8::Number; |
18 | | using v8::Object; |
19 | | using v8::ObjectTemplate; |
20 | | using v8::Value; |
21 | | |
22 | 134k | void BindingData::SetupTimers(const FunctionCallbackInfo<Value>& args) { |
23 | 134k | CHECK(args[0]->IsFunction()); |
24 | 134k | CHECK(args[1]->IsFunction()); |
25 | 134k | auto env = Environment::GetCurrent(args); |
26 | | |
27 | 134k | env->set_immediate_callback_function(args[0].As<Function>()); |
28 | 134k | env->set_timers_callback_function(args[1].As<Function>()); |
29 | 134k | } |
30 | | |
31 | 851 | void BindingData::SlowGetLibuvNow(const FunctionCallbackInfo<Value>& args) { |
32 | 851 | double now = GetLibuvNowImpl(Realm::GetBindingData<BindingData>(args)); |
33 | 851 | args.GetReturnValue().Set(Number::New(args.GetIsolate(), now)); |
34 | 851 | } |
35 | | |
36 | 0 | double BindingData::FastGetLibuvNow(Local<Object> receiver) { |
37 | 0 | return GetLibuvNowImpl(FromJSObject<BindingData>(receiver)); |
38 | 0 | } |
39 | | |
40 | 851 | double BindingData::GetLibuvNowImpl(BindingData* data) { |
41 | 851 | return static_cast<double>(data->env()->GetNowUint64()); |
42 | 851 | } |
43 | | |
44 | 850 | void BindingData::SlowScheduleTimer(const FunctionCallbackInfo<Value>& args) { |
45 | 850 | int64_t duration = |
46 | 850 | args[0]->IntegerValue(args.GetIsolate()->GetCurrentContext()).FromJust(); |
47 | 850 | ScheduleTimerImpl(Realm::GetBindingData<BindingData>(args), duration); |
48 | 850 | } |
49 | | |
50 | 0 | void BindingData::FastScheduleTimer(Local<Object> receiver, int64_t duration) { |
51 | 0 | ScheduleTimerImpl(FromJSObject<BindingData>(receiver), duration); |
52 | 0 | } |
53 | | |
54 | 850 | void BindingData::ScheduleTimerImpl(BindingData* data, int64_t duration) { |
55 | 850 | data->env()->ScheduleTimer(duration); |
56 | 850 | } |
57 | | |
58 | | void BindingData::SlowToggleTimerRef( |
59 | 1.69k | const v8::FunctionCallbackInfo<v8::Value>& args) { |
60 | 1.69k | ToggleTimerRefImpl(Realm::GetBindingData<BindingData>(args), |
61 | 1.69k | args[0]->IsTrue()); |
62 | 1.69k | } |
63 | | |
64 | 0 | void BindingData::FastToggleTimerRef(Local<Object> receiver, bool ref) { |
65 | 0 | ToggleTimerRefImpl(FromJSObject<BindingData>(receiver), ref); |
66 | 0 | } |
67 | | |
68 | 1.69k | void BindingData::ToggleTimerRefImpl(BindingData* data, bool ref) { |
69 | 1.69k | data->env()->ToggleTimerRef(ref); |
70 | 1.69k | } |
71 | | |
72 | | void BindingData::SlowToggleImmediateRef( |
73 | 0 | const v8::FunctionCallbackInfo<v8::Value>& args) { |
74 | 0 | ToggleImmediateRefImpl(Realm::GetBindingData<BindingData>(args), |
75 | 0 | args[0]->IsTrue()); |
76 | 0 | } |
77 | | |
78 | 0 | void BindingData::FastToggleImmediateRef(Local<Object> receiver, bool ref) { |
79 | 0 | ToggleImmediateRefImpl(FromJSObject<BindingData>(receiver), ref); |
80 | 0 | } |
81 | | |
82 | 0 | void BindingData::ToggleImmediateRefImpl(BindingData* data, bool ref) { |
83 | 0 | data->env()->ToggleImmediateRef(ref); |
84 | 0 | } |
85 | | |
86 | | BindingData::BindingData(Realm* realm, Local<Object> object) |
87 | 134k | : SnapshotableObject(realm, object, type_int) {} |
88 | | |
89 | | bool BindingData::PrepareForSerialization(Local<Context> context, |
90 | 0 | v8::SnapshotCreator* creator) { |
91 | | // Return true because we need to maintain the reference to the binding from |
92 | | // JS land. |
93 | 0 | return true; |
94 | 0 | } |
95 | | |
96 | 0 | InternalFieldInfoBase* BindingData::Serialize(int index) { |
97 | 0 | DCHECK_IS_SNAPSHOT_SLOT(index); |
98 | 0 | InternalFieldInfo* info = |
99 | 0 | InternalFieldInfoBase::New<InternalFieldInfo>(type()); |
100 | 0 | return info; |
101 | 0 | } |
102 | | |
103 | | void BindingData::Deserialize(Local<Context> context, |
104 | | Local<Object> holder, |
105 | | int index, |
106 | 0 | InternalFieldInfoBase* info) { |
107 | 0 | DCHECK_IS_SNAPSHOT_SLOT(index); |
108 | 0 | v8::HandleScope scope(context->GetIsolate()); |
109 | 0 | Realm* realm = Realm::GetCurrent(context); |
110 | | // Recreate the buffer in the constructor. |
111 | 0 | BindingData* binding = realm->AddBindingData<BindingData>(holder); |
112 | 0 | CHECK_NOT_NULL(binding); |
113 | 0 | } |
114 | | |
115 | | v8::CFunction BindingData::fast_get_libuv_now_( |
116 | | v8::CFunction::Make(FastGetLibuvNow)); |
117 | | v8::CFunction BindingData::fast_schedule_timers_( |
118 | | v8::CFunction::Make(FastScheduleTimer)); |
119 | | v8::CFunction BindingData::fast_toggle_timer_ref_( |
120 | | v8::CFunction::Make(FastToggleTimerRef)); |
121 | | v8::CFunction BindingData::fast_toggle_immediate_ref_( |
122 | | v8::CFunction::Make(FastToggleImmediateRef)); |
123 | | |
124 | | void BindingData::CreatePerIsolateProperties(IsolateData* isolate_data, |
125 | 134k | Local<ObjectTemplate> target) { |
126 | 134k | Isolate* isolate = isolate_data->isolate(); |
127 | | |
128 | 134k | SetMethod(isolate, target, "setupTimers", SetupTimers); |
129 | 134k | SetFastMethod( |
130 | 134k | isolate, target, "getLibuvNow", SlowGetLibuvNow, &fast_get_libuv_now_); |
131 | 134k | SetFastMethod(isolate, |
132 | 134k | target, |
133 | 134k | "scheduleTimer", |
134 | 134k | SlowScheduleTimer, |
135 | 134k | &fast_schedule_timers_); |
136 | 134k | SetFastMethod(isolate, |
137 | 134k | target, |
138 | 134k | "toggleTimerRef", |
139 | 134k | SlowToggleTimerRef, |
140 | 134k | &fast_toggle_timer_ref_); |
141 | 134k | SetFastMethod(isolate, |
142 | 134k | target, |
143 | 134k | "toggleImmediateRef", |
144 | 134k | SlowToggleImmediateRef, |
145 | 134k | &fast_toggle_immediate_ref_); |
146 | 134k | } |
147 | | |
148 | | void BindingData::CreatePerContextProperties(Local<Object> target, |
149 | | Local<Value> unused, |
150 | | Local<Context> context, |
151 | 134k | void* priv) { |
152 | 134k | Realm* realm = Realm::GetCurrent(context); |
153 | 134k | Environment* env = realm->env(); |
154 | 134k | BindingData* const binding_data = realm->AddBindingData<BindingData>(target); |
155 | 134k | if (binding_data == nullptr) return; |
156 | | |
157 | | // TODO(joyeecheung): move these into BindingData. |
158 | 134k | target |
159 | 134k | ->Set(context, |
160 | 134k | FIXED_ONE_BYTE_STRING(realm->isolate(), "immediateInfo"), |
161 | 134k | env->immediate_info()->fields().GetJSArray()) |
162 | 134k | .Check(); |
163 | | |
164 | 134k | target |
165 | 134k | ->Set(context, |
166 | 134k | FIXED_ONE_BYTE_STRING(realm->isolate(), "timeoutInfo"), |
167 | 134k | env->timeout_info().GetJSArray()) |
168 | 134k | .Check(); |
169 | 134k | } |
170 | | |
171 | | void BindingData::RegisterTimerExternalReferences( |
172 | 0 | ExternalReferenceRegistry* registry) { |
173 | 0 | registry->Register(SetupTimers); |
174 | |
|
175 | 0 | registry->Register(SlowGetLibuvNow); |
176 | 0 | registry->Register(FastGetLibuvNow); |
177 | 0 | registry->Register(fast_get_libuv_now_.GetTypeInfo()); |
178 | |
|
179 | 0 | registry->Register(SlowScheduleTimer); |
180 | 0 | registry->Register(FastScheduleTimer); |
181 | 0 | registry->Register(fast_schedule_timers_.GetTypeInfo()); |
182 | |
|
183 | 0 | registry->Register(SlowToggleTimerRef); |
184 | 0 | registry->Register(FastToggleTimerRef); |
185 | 0 | registry->Register(fast_toggle_timer_ref_.GetTypeInfo()); |
186 | |
|
187 | 0 | registry->Register(SlowToggleImmediateRef); |
188 | 0 | registry->Register(FastToggleImmediateRef); |
189 | 0 | registry->Register(fast_toggle_immediate_ref_.GetTypeInfo()); |
190 | 0 | } |
191 | | |
192 | | } // namespace timers |
193 | | |
194 | | } // namespace node |
195 | | |
196 | | NODE_BINDING_CONTEXT_AWARE_INTERNAL( |
197 | | timers, node::timers::BindingData::CreatePerContextProperties) |
198 | | NODE_BINDING_PER_ISOLATE_INIT( |
199 | | timers, node::timers::BindingData::CreatePerIsolateProperties) |
200 | | NODE_BINDING_EXTERNAL_REFERENCE( |
201 | | timers, node::timers::BindingData::RegisterTimerExternalReferences) |