@auto_js/v8 0.0.4 → 0.0.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CMakeLists.txt +3 -0
- package/_module.cc +2 -5
- package/package.json +3 -3
- package/support/callback.cc +1 -1
- package/support/callback_storage.cc +3 -6
- package/support/lock.cc +0 -4
- package/support/lock.h.cc +4 -1
- package/transfer/accept.cc +4 -4
- package/transfer/accept.h.cc +10 -11
- package/transfer/visit.cc +85 -57
- package/value/array_buffer.cc +0 -13
- package/value/array_buffer.h.cc +15 -5
- package/value/function.cc +41 -0
- package/value/function.h.cc +16 -0
- package/value/object.cc +4 -7
- package/value/object.h.cc +3 -4
- package/value/primitive.cc +0 -21
- package/value/primitive.h.cc +0 -3
- package/value/tag.cc +25 -6
- package/value/value.cc +8 -0
package/CMakeLists.txt
CHANGED
|
@@ -49,10 +49,13 @@ target_sources("${TARGET_NAME}"
|
|
|
49
49
|
value/array.h.cc
|
|
50
50
|
value/callback_info.cc
|
|
51
51
|
value/fixed_array.h.cc
|
|
52
|
+
value/function.cc
|
|
53
|
+
value/function.h.cc
|
|
52
54
|
value/handle.cc
|
|
53
55
|
value/object.h.cc
|
|
54
56
|
value/primitive.h.cc
|
|
55
57
|
value/tag.cc
|
|
58
|
+
value/value.cc
|
|
56
59
|
)
|
|
57
60
|
|
|
58
61
|
if(TARGET_NAME STREQUAL "embedded_v8_js")
|
package/_module.cc
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
export module v8_js;
|
|
2
2
|
export import :accept;
|
|
3
|
-
export import :array_buffer;
|
|
4
|
-
export import :array;
|
|
5
3
|
export import :boost;
|
|
6
4
|
export import :callback_info;
|
|
7
5
|
export import :callback;
|
|
8
6
|
export import :collected_handle;
|
|
9
7
|
export import :error;
|
|
10
|
-
export import :
|
|
8
|
+
export import :function_definitions;
|
|
11
9
|
export import :handle;
|
|
12
10
|
export import :handle.value;
|
|
13
11
|
export import :hash;
|
|
14
12
|
export import :lock;
|
|
15
|
-
export import :object;
|
|
16
|
-
export import :primitive;
|
|
17
13
|
export import :remote;
|
|
18
14
|
export import :unmaybe;
|
|
15
|
+
export import :value;
|
|
19
16
|
export import :value.tag;
|
|
20
17
|
export import :visit;
|
|
21
18
|
export import :weak_map;
|
package/package.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@auto_js/v8",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.5",
|
|
4
4
|
"author": "https://github.com/laverdet/",
|
|
5
5
|
"homepage": "https://github.com/laverdet/isolated-vm/tree/experimental/packages/auto_js/v8",
|
|
6
6
|
"license": "ISC",
|
|
7
7
|
"dependencies": {
|
|
8
|
-
"@auto_js/js": "^0.0.
|
|
9
|
-
"@auto_js/v8_exports": "^0.0.
|
|
8
|
+
"@auto_js/js": "^0.0.5",
|
|
9
|
+
"@auto_js/v8_exports": "^0.0.3"
|
|
10
10
|
},
|
|
11
11
|
"repository": {
|
|
12
12
|
"type": "git",
|
package/support/callback.cc
CHANGED
|
@@ -35,7 +35,7 @@ constexpr auto make_free_function_with_try_catch =
|
|
|
35
35
|
callback,
|
|
36
36
|
std::tuple_cat(
|
|
37
37
|
std::forward_as_tuple(lock),
|
|
38
|
-
js::transfer_out<std::tuple<Args
|
|
38
|
+
js::transfer_out<std::tuple<js::functional::parameter_transfer_as_t<Args>...>>(info, lock)
|
|
39
39
|
)
|
|
40
40
|
);
|
|
41
41
|
}};
|
|
@@ -15,9 +15,7 @@ constexpr auto make_plain_callback =
|
|
|
15
15
|
) -> auto {
|
|
16
16
|
return util::bind{
|
|
17
17
|
[](auto& function, const v8::FunctionCallbackInfo<v8::Value>& info) -> void {
|
|
18
|
-
|
|
19
|
-
auto context_witness = context_lock_witness::from_isolate(isolate_witness);
|
|
20
|
-
function(context_witness, info);
|
|
18
|
+
function(context_lock_witness{info}, info);
|
|
21
19
|
},
|
|
22
20
|
std::move(function),
|
|
23
21
|
};
|
|
@@ -32,9 +30,8 @@ constexpr auto make_decorated_callback =
|
|
|
32
30
|
) -> auto {
|
|
33
31
|
return util::bind{
|
|
34
32
|
[](auto& agent, auto& function, const v8::FunctionCallbackInfo<v8::Value>& info) -> void {
|
|
35
|
-
auto
|
|
36
|
-
auto
|
|
37
|
-
auto decorated_witness = context_lock_witness_of<Agent, Implements...>{context_witness, agent};
|
|
33
|
+
auto witness = context_lock_witness{info};
|
|
34
|
+
auto decorated_witness = context_lock_witness_of<Agent, Implements...>{witness, agent};
|
|
38
35
|
function(decorated_witness, info);
|
|
39
36
|
},
|
|
40
37
|
std::ref(*lock),
|
package/support/lock.cc
CHANGED
|
@@ -36,10 +36,6 @@ isolate_unlock::isolate_unlock(isolate_lock_witness lock) :
|
|
|
36
36
|
unlocker_{lock.isolate()} {}
|
|
37
37
|
|
|
38
38
|
// `context_lock_witness`
|
|
39
|
-
auto context_lock_witness::from_isolate(isolate_lock_witness lock) -> context_lock_witness {
|
|
40
|
-
return context_lock_witness{lock, lock.isolate()->GetCurrentContext()};
|
|
41
|
-
}
|
|
42
|
-
|
|
43
39
|
auto context_lock_witness::make_witness(isolate_lock_witness lock, v8::Local<v8::Context> context) -> context_lock_witness {
|
|
44
40
|
return context_lock_witness{lock, context};
|
|
45
41
|
}
|
package/support/lock.h.cc
CHANGED
|
@@ -105,8 +105,11 @@ export class context_lock_witness : public isolate_lock_witness {
|
|
|
105
105
|
context_{context} {}
|
|
106
106
|
|
|
107
107
|
public:
|
|
108
|
+
explicit context_lock_witness(const v8::FunctionCallbackInfo<v8::Value>& info) :
|
|
109
|
+
isolate_lock_witness{isolate_lock_witness::make_witness(info.GetIsolate())},
|
|
110
|
+
context_{isolate()->GetCurrentContext()} {}
|
|
111
|
+
|
|
108
112
|
[[nodiscard]] auto context() const -> v8::Local<v8::Context> { return context_; }
|
|
109
|
-
[[nodiscard]] static auto from_isolate(isolate_lock_witness lock) -> context_lock_witness;
|
|
110
113
|
[[nodiscard]] static auto make_witness(isolate_lock_witness lock, v8::Local<v8::Context> context) -> context_lock_witness;
|
|
111
114
|
|
|
112
115
|
private:
|
package/transfer/accept.cc
CHANGED
|
@@ -108,14 +108,14 @@ auto accept_v8_value::operator()(error_tag /*tag*/, visit_holder /*visit*/, cons
|
|
|
108
108
|
}
|
|
109
109
|
|
|
110
110
|
// function
|
|
111
|
-
auto accept_v8_value::operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, v8::Local<v8::FunctionTemplate> subject) const -> v8::Local<
|
|
112
|
-
return unmaybe(subject->GetFunction(context_));
|
|
111
|
+
auto accept_v8_value::operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, v8::Local<v8::FunctionTemplate> subject) const -> v8::Local<iv8::Function> {
|
|
112
|
+
return unmaybe(subject->GetFunction(context_).As<iv8::Function>());
|
|
113
113
|
}
|
|
114
114
|
|
|
115
115
|
// data blocks
|
|
116
116
|
auto accept_v8_value::operator()(array_buffer_tag /*tag*/, visit_holder /*visit*/, js::array_buffer subject) const
|
|
117
117
|
-> js::referenceable_value<v8::Local<v8::ArrayBuffer>> {
|
|
118
|
-
auto byte_length = subject.
|
|
118
|
+
auto byte_length = subject.byte_length();
|
|
119
119
|
auto backing_store = v8::ArrayBuffer::NewBackingStore(
|
|
120
120
|
std::move(subject).acquire_ownership().release(),
|
|
121
121
|
byte_length,
|
|
@@ -130,7 +130,7 @@ auto accept_v8_value::operator()(array_buffer_tag /*tag*/, visit_holder /*visit*
|
|
|
130
130
|
|
|
131
131
|
auto accept_v8_value::operator()(shared_array_buffer_tag /*tag*/, visit_holder /*visit*/, js::shared_array_buffer&& subject) const
|
|
132
132
|
-> js::referenceable_value<v8::Local<v8::SharedArrayBuffer>> {
|
|
133
|
-
auto byte_length = subject.
|
|
133
|
+
auto byte_length = subject.byte_length();
|
|
134
134
|
auto backing_store = [ & ]() -> auto {
|
|
135
135
|
if (byte_length == 0) {
|
|
136
136
|
// v8 does not call the deleter if `byte_length` is zero. So the heap-allocated shared_ptr
|
package/transfer/accept.h.cc
CHANGED
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
export module v8_js:accept;
|
|
2
|
-
import :array_buffer;
|
|
3
2
|
import :callback_storage;
|
|
4
3
|
import :hash;
|
|
5
|
-
import :
|
|
4
|
+
import :value;
|
|
6
5
|
import auto_js;
|
|
7
6
|
import std;
|
|
8
7
|
import util;
|
|
@@ -156,7 +155,7 @@ struct accept_v8_value : accept_v8_primitive {
|
|
|
156
155
|
}
|
|
157
156
|
|
|
158
157
|
// function
|
|
159
|
-
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, v8::Local<v8::FunctionTemplate> subject) const -> v8::Local<
|
|
158
|
+
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, v8::Local<v8::FunctionTemplate> subject) const -> v8::Local<iv8::Function>;
|
|
160
159
|
|
|
161
160
|
// array
|
|
162
161
|
auto operator()(this const auto& self, list_tag /*tag*/, auto& visit, auto&& subject)
|
|
@@ -188,9 +187,9 @@ struct accept_v8_value : accept_v8_primitive {
|
|
|
188
187
|
[](v8::Local<v8::Array> array, auto& self, auto& visit, auto /*&&*/ subject) -> void {
|
|
189
188
|
std::uint32_t ii = 0;
|
|
190
189
|
auto&& range = util::into_range(std::forward<decltype(subject)>(subject));
|
|
191
|
-
for (auto&&
|
|
192
|
-
auto
|
|
193
|
-
unmaybe(array->Set(self.context_, ii++,
|
|
190
|
+
for (auto&& element : util::forward_range(std::forward<decltype(range)>(range))) {
|
|
191
|
+
auto item = visit(std::forward<decltype(element)>(element), self);
|
|
192
|
+
unmaybe(array->Set(self.context_, ii++, item));
|
|
194
193
|
}
|
|
195
194
|
},
|
|
196
195
|
};
|
|
@@ -304,10 +303,10 @@ struct accept_v8_value_with<context_lock_witness> : accept_v8_value {
|
|
|
304
303
|
using accept_v8_value::witness;
|
|
305
304
|
|
|
306
305
|
// function instantiation
|
|
307
|
-
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> v8::Local<
|
|
306
|
+
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> v8::Local<iv8::Function> {
|
|
308
307
|
auto [ function, length ] = make_free_function<context_lock_witness>(std::move(subject).callback);
|
|
309
308
|
auto [ callback, data ] = make_callback_storage(witness(), std::move(function));
|
|
310
|
-
return unmaybe(v8::Function::New(witness().context(), callback, data, length, v8::ConstructorBehavior::kThrow));
|
|
309
|
+
return unmaybe(v8::Function::New(witness().context(), callback, data, length, v8::ConstructorBehavior::kThrow).template As<iv8::Function>());
|
|
311
310
|
}
|
|
312
311
|
};
|
|
313
312
|
|
|
@@ -321,7 +320,7 @@ struct accept_v8_value_with : accept_v8_value {
|
|
|
321
320
|
using accept_v8_value::operator();
|
|
322
321
|
|
|
323
322
|
// function instantiation
|
|
324
|
-
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> v8::Local<
|
|
323
|
+
auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> v8::Local<iv8::Function> {
|
|
325
324
|
auto [ function, length ] = make_free_function<Lock>(std::move(subject).callback);
|
|
326
325
|
auto [ callback, data ] = make_callback_storage(lock_.get(), std::move(function));
|
|
327
326
|
return v8::Function::New(lock_.get().context(), callback, data, length, v8::ConstructorBehavior::kThrow);
|
|
@@ -465,7 +464,7 @@ struct accept_property_subject<v8::Local<Type>> : std::type_identity<v8::Local<v
|
|
|
465
464
|
|
|
466
465
|
// primitives
|
|
467
466
|
template <class Meta, class Type>
|
|
468
|
-
requires std::
|
|
467
|
+
requires std::is_convertible_v<Type, v8::Primitive>
|
|
469
468
|
struct accept<Meta, v8::Local<Type>> : iv8::accept_v8_primitive {
|
|
470
469
|
using accept_v8_primitive::accept_v8_primitive;
|
|
471
470
|
};
|
|
@@ -478,7 +477,7 @@ struct accept<Meta, v8::Local<Type>> : iv8::accept_v8_value_with<typename Meta::
|
|
|
478
477
|
|
|
479
478
|
// templates
|
|
480
479
|
template <class Meta, class Type>
|
|
481
|
-
requires std::
|
|
480
|
+
requires std::is_convertible_v<Type, v8::Template>
|
|
482
481
|
struct accept<Meta, v8::Local<Type>> : iv8::accept_v8_template<Meta, typename Meta::accept_context_type> {
|
|
483
482
|
using iv8::accept_v8_template<Meta, typename Meta::accept_context_type>::accept_v8_template;
|
|
484
483
|
};
|
package/transfer/visit.cc
CHANGED
|
@@ -3,8 +3,8 @@ import :array_buffer;
|
|
|
3
3
|
import :callback_info;
|
|
4
4
|
import :handle.value;
|
|
5
5
|
import :hash;
|
|
6
|
-
import :object;
|
|
7
6
|
import :unmaybe;
|
|
7
|
+
import :value;
|
|
8
8
|
import auto_js;
|
|
9
9
|
import std;
|
|
10
10
|
import v8;
|
|
@@ -30,14 +30,14 @@ struct visit_property_name {
|
|
|
30
30
|
auto value = value_of{witness(), subject.As<tag_to_v8<Tag>>()};
|
|
31
31
|
return accept(tag, *this, value);
|
|
32
32
|
};
|
|
33
|
-
if (subject->
|
|
34
|
-
return accept_as(number_tag_of<std::int32_t>{});
|
|
35
|
-
} else if (subject->IsString()) {
|
|
33
|
+
if (subject->IsString()) {
|
|
36
34
|
if (subject.As<v8::String>()->IsOneByte()) {
|
|
37
35
|
return accept_as(string_tag_of<char>{});
|
|
38
36
|
} else {
|
|
39
37
|
return accept_as(string_tag_of<char16_t>{});
|
|
40
38
|
}
|
|
39
|
+
} else if (subject->IsNumber()) {
|
|
40
|
+
return accept_as(number_tag_of<std::int32_t>{});
|
|
41
41
|
} else {
|
|
42
42
|
return accept_as(symbol_tag{});
|
|
43
43
|
}
|
|
@@ -57,27 +57,15 @@ struct visit_v8_key_literal {
|
|
|
57
57
|
explicit constexpr visit_v8_key_literal(auto* /*transfer*/) {}
|
|
58
58
|
|
|
59
59
|
auto operator()(const auto& /*anything*/, const auto& accept_or_visit) -> v8::Local<v8::Name> {
|
|
60
|
-
const auto make = util::overloaded{
|
|
61
|
-
[](v8::Isolate* isolate, std::string_view subject) -> v8::Local<v8::String> {
|
|
62
|
-
const auto* data = reinterpret_cast<const std::uint8_t*>(subject.data());
|
|
63
|
-
auto size = static_cast<int>(subject.size());
|
|
64
|
-
return unmaybe(v8::String::NewFromOneByte(isolate, data, v8::NewStringType::kInternalized, size));
|
|
65
|
-
},
|
|
66
|
-
[](v8::Isolate* isolate, std::u16string_view subject) -> v8::Local<v8::String> {
|
|
67
|
-
const auto* data = reinterpret_cast<const std::uint16_t*>(subject.data());
|
|
68
|
-
auto size = static_cast<int>(subject.size());
|
|
69
|
-
return unmaybe(v8::String::NewFromTwoByte(isolate, data, v8::NewStringType::kInternalized, size));
|
|
70
|
-
},
|
|
71
|
-
};
|
|
72
60
|
if (local_key_.IsEmpty()) {
|
|
73
61
|
constexpr auto key = util::make_consteval_string_view(Key);
|
|
74
|
-
local_key_ =
|
|
62
|
+
local_key_ = transfer_in<v8::Local<v8::Name>>(key, accept_or_visit.witness());
|
|
75
63
|
}
|
|
76
64
|
return local_key_;
|
|
77
65
|
}
|
|
78
66
|
|
|
79
67
|
private:
|
|
80
|
-
v8::Local<v8::
|
|
68
|
+
v8::Local<v8::Name> local_key_;
|
|
81
69
|
};
|
|
82
70
|
|
|
83
71
|
// Implements `Visit`'s non-caching `immediate()` function as a caching visit operation.
|
|
@@ -155,14 +143,10 @@ struct visit_flat_value : reference_map_t<Reference, visit_reference_map_type> {
|
|
|
155
143
|
// primitives
|
|
156
144
|
template <class Accept>
|
|
157
145
|
auto immediate(v8::Local<v8::Primitive> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
158
|
-
if (subject->
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
} else {
|
|
163
|
-
undefined_ = subject;
|
|
164
|
-
return accept(undefined_tag{}, *this, subject);
|
|
165
|
-
}
|
|
146
|
+
if (subject->IsUndefined()) {
|
|
147
|
+
return accept(undefined_tag{}, *this, subject);
|
|
148
|
+
} else if (subject->IsNull()) {
|
|
149
|
+
return accept(null_tag{}, *this, subject);
|
|
166
150
|
} else if (subject->IsNumber()) {
|
|
167
151
|
return (*this)(subject.As<v8::Number>(), accept);
|
|
168
152
|
} else if (subject->IsName()) {
|
|
@@ -177,7 +161,7 @@ struct visit_flat_value : reference_map_t<Reference, visit_reference_map_type> {
|
|
|
177
161
|
}
|
|
178
162
|
|
|
179
163
|
template <class Accept, class Type>
|
|
180
|
-
requires std::
|
|
164
|
+
requires std::is_convertible_v<Type, v8::Primitive>
|
|
181
165
|
auto immediate(v8::Local<Type> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
182
166
|
return accept_tagged(subject, accept);
|
|
183
167
|
}
|
|
@@ -230,7 +214,7 @@ struct visit_flat_value : reference_map_t<Reference, visit_reference_map_type> {
|
|
|
230
214
|
}
|
|
231
215
|
|
|
232
216
|
template <class Accept, class Type>
|
|
233
|
-
requires std::
|
|
217
|
+
requires std::is_convertible_v<iv8::v8_to_tag<Type>, data_block_tag>
|
|
234
218
|
auto immediate(v8::Local<Type> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
235
219
|
return accept_tagged(subject, accept);
|
|
236
220
|
}
|
|
@@ -241,15 +225,16 @@ struct visit_flat_value : reference_map_t<Reference, visit_reference_map_type> {
|
|
|
241
225
|
return accept_tagged(subject, accept);
|
|
242
226
|
}
|
|
243
227
|
|
|
244
|
-
// promise (
|
|
228
|
+
// promise (maybe could be forwarded)
|
|
245
229
|
template <class Accept>
|
|
246
230
|
auto immediate(v8::Local<v8::Promise> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
247
231
|
return accept(promise_tag{}, *this, subject);
|
|
248
232
|
}
|
|
249
233
|
|
|
250
|
-
// function (
|
|
251
|
-
template <class Accept>
|
|
252
|
-
|
|
234
|
+
// function (can be forwarded)
|
|
235
|
+
template <class Type, class Accept>
|
|
236
|
+
requires std::is_convertible_v<Type, v8::Function>
|
|
237
|
+
auto immediate(v8::Local<Type> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
253
238
|
return accept(function_tag{}, *this, subject);
|
|
254
239
|
}
|
|
255
240
|
|
|
@@ -259,13 +244,8 @@ struct visit_flat_value : reference_map_t<Reference, visit_reference_map_type> {
|
|
|
259
244
|
return accept(iv8::v8_to_tag<Type>{}, *this, value_of{witness(), subject});
|
|
260
245
|
}
|
|
261
246
|
|
|
262
|
-
[[nodiscard]] auto is_cached_null(v8::Local<v8::Value> value) const { return value == null_; }
|
|
263
|
-
[[nodiscard]] auto is_cached_undefined(v8::Local<v8::Value> value) const { return value == undefined_; }
|
|
264
|
-
|
|
265
247
|
private:
|
|
266
248
|
isolate_lock_witness isolate_lock_;
|
|
267
|
-
v8::Local<v8::Primitive> null_;
|
|
268
|
-
v8::Local<v8::Primitive> undefined_;
|
|
269
249
|
};
|
|
270
250
|
|
|
271
251
|
// Primary visitor w/ `context_lock_witness`
|
|
@@ -280,9 +260,8 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
280
260
|
public:
|
|
281
261
|
friend struct visit_flat_value<Target>;
|
|
282
262
|
using visit_type = visit_flat_value<Target>;
|
|
263
|
+
using visit_type::accept_tagged;
|
|
283
264
|
using visit_type::immediate;
|
|
284
|
-
using visit_type::is_cached_null;
|
|
285
|
-
using visit_type::is_cached_undefined;
|
|
286
265
|
using visit_type::lookup_or_visit;
|
|
287
266
|
using visit_type::witness;
|
|
288
267
|
using visit_type::operator();
|
|
@@ -295,27 +274,74 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
295
274
|
|
|
296
275
|
template <class Accept>
|
|
297
276
|
auto operator()(v8::Local<v8::Value> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
298
|
-
// Check known address values before the map lookup
|
|
299
|
-
if (is_cached_null(subject)) {
|
|
300
|
-
return accept(null_tag{}, *this, subject);
|
|
301
|
-
} else if (is_cached_undefined(subject)) {
|
|
302
|
-
return accept(undefined_tag{}, *this, subject);
|
|
303
|
-
}
|
|
304
277
|
|
|
305
278
|
// Check the reference map, and check type
|
|
306
279
|
return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
280
|
+
return util::template_traverse(
|
|
281
|
+
accept_tags_of_v<Accept>,
|
|
282
|
+
util::overloaded{
|
|
283
|
+
// Fast paths
|
|
284
|
+
[ & ](undefined_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
285
|
+
return subject->IsUndefined() ? accept(undefined_tag{}, *this, subject.As<iv8::Undefined>()) : next();
|
|
286
|
+
},
|
|
287
|
+
[ & ](null_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
288
|
+
return subject->IsNull() ? accept(null_tag{}, *this, subject.As<iv8::Null>()) : next();
|
|
289
|
+
},
|
|
290
|
+
[ & ](boolean_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
291
|
+
return subject->IsBoolean() ? (*this)(subject.As<v8::Boolean>(), accept) : next();
|
|
292
|
+
},
|
|
293
|
+
[ & ](number_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
294
|
+
return subject->IsNumber() ? (*this)(subject.As<v8::Number>(), accept) : next();
|
|
295
|
+
},
|
|
296
|
+
[ & ](string_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
297
|
+
return subject->IsString() ? immediate(subject.As<v8::String>(), accept) : next();
|
|
298
|
+
},
|
|
299
|
+
[ & ](bigint_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
300
|
+
return subject->IsBigInt() ? immediate(subject.As<v8::BigInt>(), accept) : next();
|
|
301
|
+
},
|
|
302
|
+
[ & ](date_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
303
|
+
return subject->IsDate() ? immediate(subject.As<v8::Date>(), accept) : next();
|
|
304
|
+
},
|
|
305
|
+
[ & ](list_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
306
|
+
return subject->IsArray() ? immediate(subject.As<v8::Array>(), accept) : next();
|
|
307
|
+
},
|
|
308
|
+
[ & ](function_tag /*tag*/, auto next) -> accept_target_t<Accept> {
|
|
309
|
+
return subject->IsFunction() ? immediate(subject.As<iv8::Function>(), accept) : next();
|
|
310
|
+
},
|
|
311
|
+
|
|
312
|
+
// Unknown tag
|
|
313
|
+
[](auto /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
314
|
+
|
|
315
|
+
// Slow path
|
|
316
|
+
[ & ]() -> accept_target_t<Accept> {
|
|
317
|
+
if (subject->IsObject()) {
|
|
318
|
+
return immediate(subject.As<v8::Object>(), accept);
|
|
319
|
+
} else {
|
|
320
|
+
return immediate(subject.As<v8::Primitive>(), accept);
|
|
321
|
+
}
|
|
322
|
+
},
|
|
323
|
+
}
|
|
324
|
+
);
|
|
312
325
|
});
|
|
313
326
|
}
|
|
314
327
|
|
|
315
328
|
template <class Accept>
|
|
316
329
|
auto operator()(v8::Local<iv8::DataBlock> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
317
330
|
return lookup_or_visit(subject, [ & ]() -> accept_target_t<Accept> {
|
|
318
|
-
return
|
|
331
|
+
return util::template_traverse(
|
|
332
|
+
accept_tags_of_v<Accept>,
|
|
333
|
+
util::overloaded{
|
|
334
|
+
// Fast paths
|
|
335
|
+
[ & ](data_block_tag /*tag*/, auto /*next*/) -> accept_target_t<Accept> { return accept_tagged(subject, accept); },
|
|
336
|
+
[ & ](array_buffer_tag /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
337
|
+
[ & ](shared_array_buffer_tag /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
|
|
338
|
+
|
|
339
|
+
// Slow path
|
|
340
|
+
[ & ]() -> accept_target_t<Accept> {
|
|
341
|
+
return immediate(subject, accept);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
);
|
|
319
345
|
});
|
|
320
346
|
}
|
|
321
347
|
|
|
@@ -343,7 +369,7 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
343
369
|
} else if (subject->IsPromise()) {
|
|
344
370
|
return immediate(subject.As<v8::Promise>(), accept);
|
|
345
371
|
} else if (subject->IsFunction()) {
|
|
346
|
-
return immediate(subject.As<
|
|
372
|
+
return immediate(subject.As<iv8::Function>(), accept);
|
|
347
373
|
} else {
|
|
348
374
|
auto visit_entry = visit_entry_pair<visit_property_name<visit_value>, visit_value&>{*this};
|
|
349
375
|
return accept(dictionary_tag{}, visit_entry, value_of{witness(), subject.As<v8::Object>()});
|
|
@@ -370,6 +396,8 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
370
396
|
return immediate(subject.As<v8::Uint8Array>(), accept);
|
|
371
397
|
} else if (subject->IsDataView()) {
|
|
372
398
|
return immediate(subject.As<v8::DataView>(), accept);
|
|
399
|
+
} else if (subject->IsUint8ClampedArray()) {
|
|
400
|
+
return immediate(subject.As<v8::Uint8ClampedArray>(), accept);
|
|
373
401
|
} else if (subject->IsInt8Array()) {
|
|
374
402
|
return immediate(subject.As<v8::Int8Array>(), accept);
|
|
375
403
|
} else if (subject->IsUint16Array()) {
|
|
@@ -380,6 +408,8 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
380
408
|
return immediate(subject.As<v8::Uint32Array>(), accept);
|
|
381
409
|
} else if (subject->IsInt32Array()) {
|
|
382
410
|
return immediate(subject.As<v8::Int32Array>(), accept);
|
|
411
|
+
} else if (subject->IsFloat16Array()) {
|
|
412
|
+
return immediate(subject.As<v8::Float16Array>(), accept);
|
|
383
413
|
} else if (subject->IsFloat32Array()) {
|
|
384
414
|
return immediate(subject.As<v8::Float32Array>(), accept);
|
|
385
415
|
} else if (subject->IsFloat64Array()) {
|
|
@@ -388,15 +418,13 @@ struct visit_value : visit_flat_value<Target> {
|
|
|
388
418
|
return immediate(subject.As<v8::BigInt64Array>(), accept);
|
|
389
419
|
} else if (subject->IsBigUint64Array()) {
|
|
390
420
|
return immediate(subject.As<v8::BigUint64Array>(), accept);
|
|
391
|
-
} else if (subject->IsUint8ClampedArray()) {
|
|
392
|
-
return immediate(subject.As<v8::Uint8ClampedArray>(), accept);
|
|
393
421
|
} else {
|
|
394
422
|
throw js::type_error{u"Received exotic v8 'ArrayBufferView'"};
|
|
395
423
|
}
|
|
396
424
|
}
|
|
397
425
|
|
|
398
426
|
template <class Accept, class Type>
|
|
399
|
-
requires std::
|
|
427
|
+
requires std::is_convertible_v<Type, v8::ArrayBufferView>
|
|
400
428
|
auto immediate(v8::Local<Type> subject, const Accept& accept) -> accept_target_t<Accept> {
|
|
401
429
|
return accept(v8_to_tag<Type>{}, *this, value_of{witness(), subject});
|
|
402
430
|
}
|
|
@@ -428,7 +456,7 @@ namespace js {
|
|
|
428
456
|
|
|
429
457
|
// Name visitor (string + symbol)
|
|
430
458
|
template <class Meta, class Type>
|
|
431
|
-
requires std::
|
|
459
|
+
requires std::is_convertible_v<Type, v8::Primitive>
|
|
432
460
|
struct visit<Meta, v8::Local<Type>> : iv8::visit_uncached_flat_value_with<Meta> {
|
|
433
461
|
using iv8::visit_uncached_flat_value_with<Meta>::visit_uncached_flat_value_with;
|
|
434
462
|
};
|
|
@@ -441,7 +469,7 @@ struct visit<Meta, v8::Local<Type>> : iv8::visit_value_with<Meta> {
|
|
|
441
469
|
|
|
442
470
|
// Template visitor
|
|
443
471
|
template <class Meta, class Type>
|
|
444
|
-
requires std::
|
|
472
|
+
requires std::is_convertible_v<Type, v8::Template>
|
|
445
473
|
struct visit<Meta, v8::Local<Type>> : iv8::visit_template {
|
|
446
474
|
using iv8::visit_template::visit_template;
|
|
447
475
|
};
|
package/value/array_buffer.cc
CHANGED
|
@@ -4,15 +4,6 @@ import std;
|
|
|
4
4
|
|
|
5
5
|
namespace js::iv8 {
|
|
6
6
|
|
|
7
|
-
// `value_for_array_buffer`
|
|
8
|
-
value_for_array_buffer::operator js::array_buffer() const {
|
|
9
|
-
return js::array_buffer{std::span<std::byte>{*this}};
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
value_for_array_buffer::operator std::span<std::byte>() const {
|
|
13
|
-
return std::span<std::byte>{reinterpret_cast<std::byte*>((*this)->Data()), (*this)->ByteLength()};
|
|
14
|
-
}
|
|
15
|
-
|
|
16
7
|
// `value_for_shared_array_buffer`
|
|
17
8
|
value_for_shared_array_buffer::operator js::shared_array_buffer() const {
|
|
18
9
|
auto backing_store = (*this)->GetBackingStore();
|
|
@@ -21,8 +12,4 @@ value_for_shared_array_buffer::operator js::shared_array_buffer() const {
|
|
|
21
12
|
return js::shared_array_buffer{(*this)->ByteLength(), std::move(data_shared_ptr)};
|
|
22
13
|
}
|
|
23
14
|
|
|
24
|
-
value_for_shared_array_buffer::operator std::span<std::byte>() const {
|
|
25
|
-
return std::span<std::byte>{reinterpret_cast<std::byte*>((*this)->Data()), (*this)->ByteLength()};
|
|
26
|
-
}
|
|
27
|
-
|
|
28
15
|
} // namespace js::iv8
|
package/value/array_buffer.h.cc
CHANGED
|
@@ -7,22 +7,32 @@ import v8;
|
|
|
7
7
|
|
|
8
8
|
namespace js::iv8 {
|
|
9
9
|
|
|
10
|
+
// nb: This handles `v8::ArrayBuffer` and also `v8::SharedArrayBuffer`. They aren't related by
|
|
11
|
+
// inheritance but v8 seem to allow it, and even encourage it.
|
|
12
|
+
class value_for_data_block : public handle_without_lock<v8::ArrayBuffer> {
|
|
13
|
+
public:
|
|
14
|
+
using handle_without_lock<v8::ArrayBuffer>::handle_without_lock;
|
|
15
|
+
[[nodiscard]] auto byte_length() const -> std::size_t { return (*this)->ByteLength(); }
|
|
16
|
+
[[nodiscard]] auto data() const -> std::byte* { return static_cast<std::byte*>((*this)->Data()); }
|
|
17
|
+
explicit operator std::span<std::byte>() const { return {data(), byte_length()}; }
|
|
18
|
+
};
|
|
19
|
+
|
|
10
20
|
class value_for_array_buffer : public handle_without_lock<v8::ArrayBuffer> {
|
|
11
21
|
public:
|
|
12
22
|
using handle_without_lock<v8::ArrayBuffer>::handle_without_lock;
|
|
23
|
+
[[nodiscard]] auto byte_length() const -> std::size_t { return (*this)->ByteLength(); }
|
|
13
24
|
[[nodiscard]] auto data() const -> std::byte* { return static_cast<std::byte*>((*this)->Data()); }
|
|
14
|
-
|
|
15
|
-
explicit operator
|
|
16
|
-
explicit operator std::span<std::byte>() const;
|
|
25
|
+
explicit operator js::array_buffer() const { return js::array_buffer{std::span<std::byte>{*this}}; }
|
|
26
|
+
explicit operator std::span<std::byte>() const { return {data(), byte_length()}; }
|
|
17
27
|
};
|
|
18
28
|
|
|
19
29
|
class value_for_shared_array_buffer : public handle_without_lock<v8::SharedArrayBuffer> {
|
|
20
30
|
public:
|
|
21
31
|
using handle_without_lock<v8::SharedArrayBuffer>::handle_without_lock;
|
|
32
|
+
[[nodiscard]] auto byte_length() const -> std::size_t { return (*this)->ByteLength(); }
|
|
22
33
|
[[nodiscard]] auto data() const -> std::byte* { return static_cast<std::byte*>((*this)->Data()); }
|
|
23
|
-
[[nodiscard]] auto size() const -> std::size_t { return (*this)->ByteLength(); }
|
|
24
34
|
explicit operator js::shared_array_buffer() const;
|
|
25
|
-
explicit operator std::span<std::byte>() const;
|
|
35
|
+
explicit operator std::span<std::byte>() const { return {data(), byte_length()}; }
|
|
26
36
|
};
|
|
27
37
|
|
|
28
38
|
template <class Type>
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
export module v8_js:function_definitions;
|
|
2
|
+
import :accept;
|
|
3
|
+
import :function;
|
|
4
|
+
import :unmaybe;
|
|
5
|
+
import auto_js;
|
|
6
|
+
import std;
|
|
7
|
+
import v8;
|
|
8
|
+
|
|
9
|
+
namespace js::iv8 {
|
|
10
|
+
|
|
11
|
+
template <class Result = std::monostate>
|
|
12
|
+
auto Function::apply(context_lock_witness lock, auto&& args) -> Result {
|
|
13
|
+
auto result = [ & ]() {
|
|
14
|
+
using args_type = std::vector<v8::Local<v8::Value>>;
|
|
15
|
+
auto handle_scope = v8::EscapableHandleScope{lock.isolate()};
|
|
16
|
+
auto undefined = js::transfer_in_strict<v8::Local<v8::Value>>(std::monostate{}, lock);
|
|
17
|
+
auto argv = js::transfer_in_strict<args_type>(std::forward<decltype(args)>(args), lock);
|
|
18
|
+
auto result = unmaybe(v8::Function::Call(lock.context(), undefined, argv.size(), argv.data()));
|
|
19
|
+
return handle_scope.Escape(result);
|
|
20
|
+
}();
|
|
21
|
+
return js::transfer_out<Result>(result, lock);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
template <class Result = std::monostate>
|
|
25
|
+
auto Function::call(context_lock_witness lock, auto&&... args) -> Result {
|
|
26
|
+
auto result = [ & ]() {
|
|
27
|
+
using args_type = std::array<v8::Local<v8::Value>, sizeof...(args) + 1>;
|
|
28
|
+
auto handle_scope = v8::EscapableHandleScope{lock.isolate()};
|
|
29
|
+
auto argv = js::transfer_in_strict<args_type>(
|
|
30
|
+
std::tuple_cat(
|
|
31
|
+
std::tuple{std::monostate{}},
|
|
32
|
+
std::forward_as_tuple(std::forward<decltype(args)>(args)...)
|
|
33
|
+
),
|
|
34
|
+
lock
|
|
35
|
+
);
|
|
36
|
+
return handle_scope.Escape(unmaybe(v8::Function::Call(lock.context(), argv[ 0 ], argv.size() - 1, argv.data() + 1)));
|
|
37
|
+
}();
|
|
38
|
+
return js::transfer_out<Result>(result, lock);
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
} // namespace js::iv8
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
export module v8_js:function;
|
|
2
|
+
import :lock;
|
|
3
|
+
import v8;
|
|
4
|
+
|
|
5
|
+
namespace js::iv8 {
|
|
6
|
+
|
|
7
|
+
class Function : public v8::Function {
|
|
8
|
+
public:
|
|
9
|
+
template <class Result = std::monostate>
|
|
10
|
+
auto apply(context_lock_witness lock, auto&& args) -> Result;
|
|
11
|
+
|
|
12
|
+
template <class Result = std::monostate>
|
|
13
|
+
auto call(context_lock_witness lock, auto&&... args) -> Result;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
} // namespace js::iv8
|
package/value/object.cc
CHANGED
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
module v8_js;
|
|
2
|
-
import :
|
|
3
|
-
import :handle;
|
|
4
|
-
import :lock;
|
|
5
|
-
import :primitive;
|
|
2
|
+
import :object;
|
|
6
3
|
import std;
|
|
7
4
|
import v8;
|
|
8
5
|
|
|
@@ -72,15 +69,15 @@ auto value_for_object::has(v8::Local<v8::Primitive> key) const -> bool {
|
|
|
72
69
|
return has_property(context(), util::slice(*this), key);
|
|
73
70
|
}
|
|
74
71
|
|
|
75
|
-
auto value_for_object::get(v8::Local<v8::Name> key) const ->
|
|
72
|
+
auto value_for_object::get(v8::Local<v8::Name> key) const -> mapped_type {
|
|
76
73
|
return get_property(context(), util::slice(*this), key);
|
|
77
74
|
}
|
|
78
75
|
|
|
79
|
-
auto value_for_object::get(v8::Local<v8::Number> key) const ->
|
|
76
|
+
auto value_for_object::get(v8::Local<v8::Number> key) const -> mapped_type {
|
|
80
77
|
return get_property(context(), util::slice(*this), key);
|
|
81
78
|
}
|
|
82
79
|
|
|
83
|
-
auto value_for_object::get(v8::Local<v8::Primitive> key) const ->
|
|
80
|
+
auto value_for_object::get(v8::Local<v8::Primitive> key) const -> mapped_type {
|
|
84
81
|
return get_property(context(), util::slice(*this), key);
|
|
85
82
|
}
|
|
86
83
|
|
package/value/object.h.cc
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
export module v8_js:object;
|
|
2
2
|
import :array;
|
|
3
|
-
import :primitive;
|
|
4
3
|
import auto_js;
|
|
5
4
|
import std;
|
|
6
5
|
import v8;
|
|
@@ -33,9 +32,9 @@ class value_for_object : public handle_with_context<v8::Object> {
|
|
|
33
32
|
using range_type = std::ranges::transform_view<std::views::all_t<const value_for_array&>, iterator_transform>;
|
|
34
33
|
using iterator = std::ranges::iterator_t<range_type>;
|
|
35
34
|
|
|
36
|
-
[[nodiscard]] auto get(v8::Local<v8::Name> key) const ->
|
|
37
|
-
[[nodiscard]] auto get(v8::Local<v8::Number> key) const ->
|
|
38
|
-
[[nodiscard]] auto get(v8::Local<v8::Primitive> key) const ->
|
|
35
|
+
[[nodiscard]] auto get(v8::Local<v8::Name> key) const -> mapped_type;
|
|
36
|
+
[[nodiscard]] auto get(v8::Local<v8::Number> key) const -> mapped_type;
|
|
37
|
+
[[nodiscard]] auto get(v8::Local<v8::Primitive> key) const -> mapped_type;
|
|
39
38
|
[[nodiscard]] auto has(v8::Local<v8::Name> key) const -> bool;
|
|
40
39
|
[[nodiscard]] auto has(v8::Local<v8::Number> key) const -> bool;
|
|
41
40
|
[[nodiscard]] auto has(v8::Local<v8::Primitive> key) const -> bool;
|
package/value/primitive.cc
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
module v8_js;
|
|
2
|
-
import :handle;
|
|
3
2
|
import :primitive;
|
|
4
3
|
import std;
|
|
5
4
|
import v8;
|
|
@@ -20,14 +19,6 @@ value_for_number::operator std::int32_t() const {
|
|
|
20
19
|
return this->As<v8::Int32>()->Value();
|
|
21
20
|
}
|
|
22
21
|
|
|
23
|
-
value_for_number::operator std::int64_t() const {
|
|
24
|
-
return this->As<v8::Integer>()->Value();
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
value_for_number::operator std::uint32_t() const {
|
|
28
|
-
return this->As<v8::Uint32>()->Value();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
22
|
// `value_for_bigint`
|
|
32
23
|
value_for_bigint::operator js::bigint() const {
|
|
33
24
|
auto bigint = js::bigint{};
|
|
@@ -58,18 +49,6 @@ value_for_string::operator std::string() const {
|
|
|
58
49
|
return string;
|
|
59
50
|
}
|
|
60
51
|
|
|
61
|
-
value_for_string::operator std::u8string() const {
|
|
62
|
-
std::u8string string;
|
|
63
|
-
string.resize_and_overwrite((*this)->Utf8LengthV2(isolate()), [ this ](char8_t* data, std::size_t length) -> std::size_t {
|
|
64
|
-
if (length > 0) {
|
|
65
|
-
auto* data_char = reinterpret_cast<char*>(data);
|
|
66
|
-
(*this)->WriteUtf8V2(isolate(), data_char, length, v8::String::WriteOptions::NO_NULL_TERMINATION);
|
|
67
|
-
}
|
|
68
|
-
return length;
|
|
69
|
-
});
|
|
70
|
-
return string;
|
|
71
|
-
}
|
|
72
|
-
|
|
73
52
|
value_for_string::operator std::u16string() const {
|
|
74
53
|
std::u16string string;
|
|
75
54
|
string.resize_and_overwrite((*this)->Length(), [ this ](char16_t* data, std::size_t length) -> std::size_t {
|
package/value/primitive.h.cc
CHANGED
|
@@ -17,8 +17,6 @@ class value_for_number : public handle_without_lock<v8::Number> {
|
|
|
17
17
|
using handle_without_lock<v8::Number>::handle_without_lock;
|
|
18
18
|
[[nodiscard]] explicit operator double() const;
|
|
19
19
|
[[nodiscard]] explicit operator std::int32_t() const;
|
|
20
|
-
[[nodiscard]] explicit operator std::int64_t() const;
|
|
21
|
-
[[nodiscard]] explicit operator std::uint32_t() const;
|
|
22
20
|
};
|
|
23
21
|
|
|
24
22
|
class value_for_bigint : public handle_without_lock<v8::BigInt> {
|
|
@@ -43,7 +41,6 @@ class value_for_string : public handle_with_isolate<v8::String> {
|
|
|
43
41
|
public:
|
|
44
42
|
using handle_with_isolate<v8::String>::handle_with_isolate;
|
|
45
43
|
[[nodiscard]] explicit operator std::string() const;
|
|
46
|
-
[[nodiscard]] explicit operator std::u8string() const;
|
|
47
44
|
[[nodiscard]] explicit operator std::u16string() const;
|
|
48
45
|
};
|
|
49
46
|
|
package/value/tag.cc
CHANGED
|
@@ -7,6 +7,7 @@ import v8;
|
|
|
7
7
|
namespace js::iv8 {
|
|
8
8
|
|
|
9
9
|
// These helper classes are provided to avoid extra visit inspections on tagged values
|
|
10
|
+
export class Function;
|
|
10
11
|
export class BigInt64 : public v8::BigInt {};
|
|
11
12
|
export class BigIntU64 : public v8::BigInt {};
|
|
12
13
|
export class BigIntWords : public v8::BigInt {};
|
|
@@ -19,7 +20,7 @@ export class Undefined : public v8::Primitive {};
|
|
|
19
20
|
// `v8::Local<v8::ArrayBuffer>{}->Buffer()` returns a `v8::Local<v8::ArrayBuffer>`, even in the case
|
|
20
21
|
// it has a `SharedArrayBuffer`. In this case `buffer->IsArrayBuffer()` will return false. This is a
|
|
21
22
|
// wrapper to denote that there is a data block but we do not know what kind it is.
|
|
22
|
-
class DataBlock : public v8::Object {};
|
|
23
|
+
export class DataBlock : public v8::Object {};
|
|
23
24
|
|
|
24
25
|
constexpr auto tag_to_v8_fn = util::overloaded{
|
|
25
26
|
[](value_tag /*tag*/) -> std::type_identity<v8::Value> { return {}; },
|
|
@@ -42,20 +43,26 @@ constexpr auto tag_to_v8_fn = util::overloaded{
|
|
|
42
43
|
[](symbol_tag /*tag*/) -> std::type_identity<v8::Symbol> { return {}; },
|
|
43
44
|
|
|
44
45
|
// objects
|
|
45
|
-
[](array_buffer_tag /*tag*/) -> std::type_identity<v8::ArrayBuffer> { return {}; },
|
|
46
46
|
[](date_tag /*tag*/) -> std::type_identity<v8::Date> { return {}; },
|
|
47
47
|
[](external_tag /*tag*/) -> std::type_identity<v8::External> { return {}; },
|
|
48
|
-
[](function_tag /*tag*/) -> std::type_identity<
|
|
48
|
+
[](function_tag /*tag*/) -> std::type_identity<iv8::Function> { return {}; },
|
|
49
49
|
[](list_tag /*tag*/) -> std::type_identity<v8::Array> { return {}; },
|
|
50
50
|
[](object_tag /*tag*/) -> std::type_identity<v8::Object> { return {}; },
|
|
51
51
|
[](promise_tag /*tag*/) -> std::type_identity<v8::Promise> { return {}; },
|
|
52
|
+
[](vector_tag /*tag*/) -> std::type_identity<v8::Array> { return {}; },
|
|
53
|
+
|
|
54
|
+
// data blocks
|
|
55
|
+
[](array_buffer_tag /*tag*/) -> std::type_identity<v8::ArrayBuffer> { return {}; },
|
|
56
|
+
[](data_block_tag /*tag*/) -> std::type_identity<iv8::DataBlock> { return {}; },
|
|
52
57
|
[](shared_array_buffer_tag /*tag*/) -> std::type_identity<v8::SharedArrayBuffer> { return {}; },
|
|
53
58
|
|
|
54
59
|
// typed arrays
|
|
60
|
+
[](array_buffer_view_tag /*tag*/) -> std::type_identity<v8::ArrayBufferView> { return {}; },
|
|
55
61
|
[](data_view_tag /*tag*/) -> std::type_identity<v8::DataView> { return {}; },
|
|
56
62
|
[](typed_array_tag_of<double> /*tag*/) -> std::type_identity<v8::Float64Array> { return {}; },
|
|
57
63
|
[](typed_array_tag_of<float> /*tag*/) -> std::type_identity<v8::Float32Array> { return {}; },
|
|
58
|
-
[](typed_array_tag_of<
|
|
64
|
+
[](typed_array_tag_of<js::float16_t> /*tag*/) -> std::type_identity<v8::Float16Array> { return {}; },
|
|
65
|
+
[](typed_array_tag_of<js::uint8_clamped_t> /*tag*/) -> std::type_identity<v8::Uint8ClampedArray> { return {}; },
|
|
59
66
|
[](typed_array_tag_of<std::int16_t> /*tag*/) -> std::type_identity<v8::Int16Array> { return {}; },
|
|
60
67
|
[](typed_array_tag_of<std::int32_t> /*tag*/) -> std::type_identity<v8::Int32Array> { return {}; },
|
|
61
68
|
[](typed_array_tag_of<std::int64_t> /*tag*/) -> std::type_identity<v8::BigInt64Array> { return {}; },
|
|
@@ -94,19 +101,25 @@ constexpr auto v8_to_tag_fn = util::overloaded{
|
|
|
94
101
|
[](std::type_identity<v8::Uint32> /*type*/) -> number_tag_of<std::uint32_t> { return {}; },
|
|
95
102
|
|
|
96
103
|
// objects
|
|
104
|
+
[](std::type_identity<iv8::Function> /*type*/) -> function_tag { return {}; },
|
|
97
105
|
[](std::type_identity<v8::Array> /*type*/) -> list_tag { return {}; },
|
|
98
|
-
[](std::type_identity<v8::ArrayBuffer> /*type*/) -> array_buffer_tag { return {}; },
|
|
99
106
|
[](std::type_identity<v8::Date> /*type*/) -> date_tag { return {}; },
|
|
100
107
|
[](std::type_identity<v8::External> /*type*/) -> external_tag { return {}; },
|
|
101
108
|
[](std::type_identity<v8::Function> /*type*/) -> function_tag { return {}; },
|
|
102
109
|
[](std::type_identity<v8::Object> /*type*/) -> object_tag { return {}; },
|
|
103
110
|
[](std::type_identity<v8::Promise> /*type*/) -> promise_tag { return {}; },
|
|
111
|
+
|
|
112
|
+
// data blocks
|
|
113
|
+
[](std::type_identity<iv8::DataBlock> /*type*/) -> data_block_tag { return {}; },
|
|
114
|
+
[](std::type_identity<v8::ArrayBuffer> /*type*/) -> array_buffer_tag { return {}; },
|
|
104
115
|
[](std::type_identity<v8::SharedArrayBuffer> /*type*/) -> shared_array_buffer_tag { return {}; },
|
|
105
116
|
|
|
106
117
|
// typed arrays
|
|
118
|
+
[](std::type_identity<v8::ArrayBufferView> /*type*/) -> array_buffer_view_tag { return {}; },
|
|
107
119
|
[](std::type_identity<v8::BigInt64Array> /*type*/) -> typed_array_tag_of<std::int64_t> { return {}; },
|
|
108
120
|
[](std::type_identity<v8::BigUint64Array> /*type*/) -> typed_array_tag_of<std::uint64_t> { return {}; },
|
|
109
121
|
[](std::type_identity<v8::DataView> /*type*/) -> data_view_tag { return {}; },
|
|
122
|
+
[](std::type_identity<v8::Float16Array> /*type*/) -> typed_array_tag_of<js::float16_t> { return {}; },
|
|
110
123
|
[](std::type_identity<v8::Float32Array> /*type*/) -> typed_array_tag_of<float> { return {}; },
|
|
111
124
|
[](std::type_identity<v8::Float64Array> /*type*/) -> typed_array_tag_of<double> { return {}; },
|
|
112
125
|
[](std::type_identity<v8::Int16Array> /*type*/) -> typed_array_tag_of<std::int16_t> { return {}; },
|
|
@@ -115,7 +128,7 @@ constexpr auto v8_to_tag_fn = util::overloaded{
|
|
|
115
128
|
[](std::type_identity<v8::Uint16Array> /*type*/) -> typed_array_tag_of<std::uint16_t> { return {}; },
|
|
116
129
|
[](std::type_identity<v8::Uint32Array> /*type*/) -> typed_array_tag_of<std::uint32_t> { return {}; },
|
|
117
130
|
[](std::type_identity<v8::Uint8Array> /*type*/) -> typed_array_tag_of<std::uint8_t> { return {}; },
|
|
118
|
-
[](std::type_identity<v8::Uint8ClampedArray> /*type*/) -> typed_array_tag_of<
|
|
131
|
+
[](std::type_identity<v8::Uint8ClampedArray> /*type*/) -> typed_array_tag_of<js::uint8_clamped_t> { return {}; },
|
|
119
132
|
|
|
120
133
|
// templates
|
|
121
134
|
[](std::type_identity<v8::FunctionTemplate> /*type*/) -> function_prototype_tag { return {}; },
|
|
@@ -130,3 +143,9 @@ export template <class Type>
|
|
|
130
143
|
using v8_to_tag = decltype(v8_to_tag_fn(type<Type>));
|
|
131
144
|
|
|
132
145
|
} // namespace js::iv8
|
|
146
|
+
|
|
147
|
+
// Specialization for `js::forward`.
|
|
148
|
+
namespace js {
|
|
149
|
+
template <class Type>
|
|
150
|
+
struct forward_tag_for<v8::Local<Type>> : std::type_identity<iv8::v8_to_tag<Type>> {};
|
|
151
|
+
} // namespace js
|