@isolated-vm/experimental 0.0.9 → 0.0.11

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.
Files changed (151) hide show
  1. package/addon/CMakeLists.txt +1 -1
  2. package/addon/handle/local_of.cc +149 -0
  3. package/addon/handle/types.cc +8 -137
  4. package/addon/handle/value_of.cc +82 -27
  5. package/addon/support/callback_info.cc +5 -5
  6. package/addon/support/callback_storage.cc +2 -2
  7. package/addon/support/free_function.cc +3 -3
  8. package/addon/support/initialize.cc +5 -5
  9. package/addon/transfer/accept.cc +104 -72
  10. package/addon/transfer/visit.cc +97 -54
  11. package/addon/value/array.cc +6 -6
  12. package/addon/value/array_buffer.cc +27 -18
  13. package/addon/value/function.cc +5 -5
  14. package/addon/value/function.h.cc +5 -5
  15. package/addon/value/object.cc +3 -3
  16. package/addon/value/primitive.cc +36 -36
  17. package/addon/value/prototype.cc +7 -7
  18. package/addon/value/record.cc +20 -20
  19. package/addon/value/value.cc +1 -1
  20. package/addon/value/vector.cc +9 -9
  21. package/backend/backend.d.cts +9 -9
  22. package/dist/frontend/agent.d.ts +1 -0
  23. package/dist/frontend/agent.d.ts.map +1 -1
  24. package/dist/frontend/agent.js.map +1 -1
  25. package/dist/frontend/module.d.ts +1 -1
  26. package/dist/frontend/module.d.ts.map +1 -1
  27. package/dist/frontend/module.js.map +1 -1
  28. package/dist/frontend/realm.d.ts +1 -1
  29. package/dist/frontend/realm.d.ts.map +1 -1
  30. package/dist/frontend/reference.d.ts +3 -3
  31. package/dist/frontend/reference.d.ts.map +1 -1
  32. package/dist/test/00.agent/00.prerequisites.d.ts +2 -0
  33. package/dist/test/00.agent/00.prerequisites.d.ts.map +1 -0
  34. package/dist/test/00.agent/00.prerequisites.js +25 -0
  35. package/dist/test/00.agent/00.prerequisites.js.map +1 -0
  36. package/dist/test/00.agent/10.clock.d.ts +2 -0
  37. package/dist/test/00.agent/10.clock.d.ts.map +1 -0
  38. package/dist/test/{00.datetime.js → 00.agent/10.clock.js} +8 -8
  39. package/dist/test/00.agent/10.clock.js.map +1 -0
  40. package/dist/test/00.agent/10.random.d.ts +2 -0
  41. package/dist/test/00.agent/10.random.d.ts.map +1 -0
  42. package/dist/test/{00.random.js → 00.agent/10.random.js} +4 -4
  43. package/dist/test/00.agent/10.random.js.map +1 -0
  44. package/dist/test/10.transfer/00.primitives.d.ts +2 -0
  45. package/dist/test/10.transfer/00.primitives.d.ts.map +1 -0
  46. package/dist/test/10.transfer/00.primitives.js +54 -0
  47. package/dist/test/10.transfer/00.primitives.js.map +1 -0
  48. package/dist/test/10.transfer/10.array_buffer.d.ts +2 -0
  49. package/dist/test/10.transfer/10.array_buffer.d.ts.map +1 -0
  50. package/dist/test/{20.array_buffer.js → 10.transfer/10.array_buffer.js} +69 -64
  51. package/dist/test/10.transfer/10.array_buffer.js.map +1 -0
  52. package/dist/test/10.transfer/90.regressions.d.ts +2 -0
  53. package/dist/test/10.transfer/90.regressions.d.ts.map +1 -0
  54. package/dist/test/10.transfer/90.regressions.js +72 -0
  55. package/dist/test/10.transfer/90.regressions.js.map +1 -0
  56. package/dist/test/20.intrinsics/00.script.d.ts +2 -0
  57. package/dist/test/20.intrinsics/00.script.d.ts.map +1 -0
  58. package/dist/test/{10.script.js → 20.intrinsics/00.script.js} +32 -7
  59. package/dist/test/20.intrinsics/00.script.js.map +1 -0
  60. package/dist/test/20.intrinsics/05.global.d.ts.map +1 -0
  61. package/dist/test/{05.global.js → 20.intrinsics/05.global.js} +5 -5
  62. package/dist/test/20.intrinsics/05.global.js.map +1 -0
  63. package/dist/test/20.intrinsics/10.reference.d.ts.map +1 -0
  64. package/dist/test/{10.reference.js → 20.intrinsics/10.reference.js} +73 -27
  65. package/dist/test/20.intrinsics/10.reference.js.map +1 -0
  66. package/dist/test/20.intrinsics/20.module.d.ts +2 -0
  67. package/dist/test/20.intrinsics/20.module.d.ts.map +1 -0
  68. package/dist/test/{10.module.js → 20.intrinsics/20.module.js} +70 -39
  69. package/dist/test/20.intrinsics/20.module.js.map +1 -0
  70. package/dist/test/50.features/50.timers.d.ts.map +1 -0
  71. package/dist/test/{50.timers.js → 50.features/50.timers.js} +8 -8
  72. package/dist/test/50.features/50.timers.js.map +1 -0
  73. package/dist/test/50.features/90.i18n.d.ts +2 -0
  74. package/dist/test/50.features/90.i18n.d.ts.map +1 -0
  75. package/dist/test/{99.i18n.js → 50.features/90.i18n.js} +6 -6
  76. package/dist/test/50.features/90.i18n.js.map +1 -0
  77. package/dist/test/90.isolation/00.dispose.d.ts +1 -1
  78. package/dist/test/90.isolation/00.dispose.d.ts.map +1 -1
  79. package/dist/test/90.isolation/00.dispose.js +23 -5
  80. package/dist/test/90.isolation/00.dispose.js.map +1 -1
  81. package/dist/test/90.isolation/10.memory.d.ts +2 -0
  82. package/dist/test/90.isolation/10.memory.d.ts.map +1 -0
  83. package/dist/test/90.isolation/10.memory.js +51 -0
  84. package/dist/test/90.isolation/10.memory.js.map +1 -0
  85. package/dist/test/fixtures.js +2 -2
  86. package/dist/test/fixtures.js.map +1 -1
  87. package/dist/test/glob.d.ts +2 -0
  88. package/dist/test/glob.d.ts.map +1 -0
  89. package/dist/test/glob.js +11 -0
  90. package/dist/test/glob.js.map +1 -0
  91. package/dist/tsconfig.tsbuildinfo +1 -1
  92. package/dist/utility/completion.d.ts +2 -1
  93. package/dist/utility/completion.d.ts.map +1 -1
  94. package/dist/utility/completion.js +4 -0
  95. package/dist/utility/completion.js.map +1 -1
  96. package/frontend/agent.ts +1 -0
  97. package/frontend/module.ts +1 -1
  98. package/frontend/realm.ts +4 -1
  99. package/frontend/reference.ts +3 -3
  100. package/package.json +13 -13
  101. package/test/00.agent/00.prerequisites.ts +12 -0
  102. package/test/{00.datetime.ts → 00.agent/10.clock.ts} +7 -7
  103. package/test/{00.random.ts → 00.agent/10.random.ts} +3 -3
  104. package/test/10.transfer/00.primitives.ts +47 -0
  105. package/test/{20.array_buffer.ts → 10.transfer/10.array_buffer.ts} +40 -35
  106. package/test/10.transfer/90.regressions.ts +38 -0
  107. package/test/{10.script.ts → 20.intrinsics/00.script.ts} +21 -6
  108. package/test/{05.global.ts → 20.intrinsics/05.global.ts} +5 -5
  109. package/test/20.intrinsics/10.reference.ts +111 -0
  110. package/test/{10.module.ts → 20.intrinsics/20.module.ts} +39 -17
  111. package/test/{50.timers.ts → 50.features/50.timers.ts} +8 -8
  112. package/test/{99.i18n.ts → 50.features/90.i18n.ts} +5 -5
  113. package/test/90.isolation/00.dispose.ts +12 -5
  114. package/test/90.isolation/10.memory.ts +28 -0
  115. package/test/fixtures.ts +4 -4
  116. package/test/glob.ts +11 -0
  117. package/utility/completion.ts +6 -1
  118. package/addon/handle/bound_value.cc +0 -45
  119. package/dist/test/00.datetime.d.ts +0 -2
  120. package/dist/test/00.datetime.d.ts.map +0 -1
  121. package/dist/test/00.datetime.js.map +0 -1
  122. package/dist/test/00.random.d.ts +0 -2
  123. package/dist/test/00.random.d.ts.map +0 -1
  124. package/dist/test/00.random.js.map +0 -1
  125. package/dist/test/00.transfer.d.ts +0 -2
  126. package/dist/test/00.transfer.d.ts.map +0 -1
  127. package/dist/test/00.transfer.js +0 -168
  128. package/dist/test/00.transfer.js.map +0 -1
  129. package/dist/test/05.global.d.ts.map +0 -1
  130. package/dist/test/05.global.js.map +0 -1
  131. package/dist/test/10.module.d.ts +0 -2
  132. package/dist/test/10.module.d.ts.map +0 -1
  133. package/dist/test/10.module.js.map +0 -1
  134. package/dist/test/10.reference.d.ts.map +0 -1
  135. package/dist/test/10.reference.js.map +0 -1
  136. package/dist/test/10.script.d.ts +0 -2
  137. package/dist/test/10.script.d.ts.map +0 -1
  138. package/dist/test/10.script.js.map +0 -1
  139. package/dist/test/20.array_buffer.d.ts +0 -2
  140. package/dist/test/20.array_buffer.d.ts.map +0 -1
  141. package/dist/test/20.array_buffer.js.map +0 -1
  142. package/dist/test/50.timers.d.ts.map +0 -1
  143. package/dist/test/50.timers.js.map +0 -1
  144. package/dist/test/99.i18n.d.ts +0 -2
  145. package/dist/test/99.i18n.d.ts.map +0 -1
  146. package/dist/test/99.i18n.js.map +0 -1
  147. package/test/00.transfer.ts +0 -134
  148. package/test/10.reference.ts +0 -82
  149. /package/dist/test/{05.global.d.ts → 20.intrinsics/05.global.d.ts} +0 -0
  150. /package/dist/test/{10.reference.d.ts → 20.intrinsics/10.reference.d.ts} +0 -0
  151. /package/dist/test/{50.timers.d.ts → 50.features/50.timers.d.ts} +0 -0
@@ -13,79 +13,95 @@ struct accept_vm_primitive {
13
13
  explicit accept_vm_primitive(const basic_lock& lock) : lock_{lock} {}
14
14
 
15
15
  // undefined
16
- auto operator()(undefined_tag /*tag*/, visit_holder /*visit*/, std::monostate /*subject*/) const -> value_of<undefined_tag> {
17
- return value_of<undefined_tag>::make(lock());
16
+ auto operator()(undefined_tag /*tag*/, visit_holder /*visit*/, std::monostate /*subject*/) const -> local_of<undefined_tag> {
17
+ return local_of<undefined_tag>::make(lock());
18
18
  }
19
19
 
20
- auto operator()(undefined_tag tag, visit_holder visit, const auto& /*subject*/) const -> value_of<undefined_tag> {
20
+ auto operator()(undefined_tag tag, visit_holder visit, const auto& /*subject*/) const -> local_of<undefined_tag> {
21
21
  return (*this)(tag, visit, std::monostate{});
22
22
  }
23
23
 
24
24
  // null
25
- auto operator()(null_tag /*tag*/, visit_holder /*visit*/, std::nullptr_t /*subject*/) const -> value_of<null_tag> {
26
- return value_of<null_tag>::make(lock());
25
+ auto operator()(null_tag /*tag*/, visit_holder /*visit*/, std::nullptr_t /*subject*/) const -> local_of<null_tag> {
26
+ return local_of<null_tag>::make(lock());
27
27
  }
28
28
 
29
- auto operator()(null_tag tag, visit_holder visit, const auto& /*subject*/) const -> value_of<null_tag> {
29
+ auto operator()(null_tag tag, visit_holder visit, const auto& /*subject*/) const -> local_of<null_tag> {
30
30
  return (*this)(tag, visit, nullptr);
31
31
  }
32
32
 
33
33
  // boolean
34
- auto operator()(boolean_tag /*tag*/, visit_holder /*visit*/, bool subject) const -> value_of<boolean_tag> {
35
- return value_of<boolean_tag>::make(lock(), subject);
34
+ auto operator()(boolean_tag /*tag*/, visit_holder /*visit*/, bool subject) const -> local_of<boolean_tag> {
35
+ return local_of<boolean_tag>::make(lock(), subject);
36
36
  }
37
37
 
38
38
  // number
39
- auto operator()(number_tag_of<double> /*tag*/, visit_holder /*visit*/, double subject) const -> value_of<number_tag_of<double>> {
40
- return value_of<number_tag>::make(lock(), subject);
39
+ auto operator()(number_tag_of<double> /*tag*/, visit_holder /*visit*/, double subject) const -> local_of<number_tag_of<double>> {
40
+ return local_of<number_tag_of<double>>::make(lock(), subject);
41
41
  }
42
42
 
43
- auto operator()(number_tag_of<std::int32_t> /*tag*/, visit_holder /*visit*/, std::int32_t subject) const -> value_of<number_tag_of<std::int32_t>> {
44
- return value_of<number_tag>::make(lock(), subject);
43
+ auto operator()(number_tag_of<std::int32_t> /*tag*/, visit_holder /*visit*/, std::int32_t subject) const -> local_of<number_tag_of<std::int32_t>> {
44
+ return local_of<number_tag_of<std::int32_t>>::make(lock(), subject);
45
45
  }
46
46
 
47
- auto operator()(number_tag /*tag*/, visit_holder visit, auto&& subject) const -> value_of<number_tag> {
47
+ auto operator()(number_tag_of<std::uint32_t> /*tag*/, visit_holder /*visit*/, std::uint32_t subject) const -> local_of<number_tag_of<std::uint32_t>> {
48
+ if (subject <= std::numeric_limits<std::int32_t>::max()) {
49
+ auto value = local_of<number_tag_of<std::int32_t>>::make(lock(), static_cast<std::int32_t>(subject));
50
+ return local_of<number_tag_of<std::uint32_t>>::from(value);
51
+ } else {
52
+ auto value = local_of<number_tag_of<double>>::make(lock(), static_cast<double>(subject));
53
+ return local_of<number_tag_of<std::uint32_t>>::from(value);
54
+ }
55
+ }
56
+
57
+ auto operator()(number_tag /*tag*/, visit_holder visit, auto&& subject) const -> local_of<number_tag> {
48
58
  return (*this)(number_tag_of<double>{}, visit, double{std::forward<decltype(subject)>(subject)});
49
59
  }
50
60
 
51
61
  template <class Type>
52
- auto operator()(number_tag_of<Type> tag, visit_holder visit, auto&& subject) const -> value_of<number_tag_of<Type>> {
62
+ auto operator()(number_tag_of<Type> tag, visit_holder visit, Type subject) const -> local_of<number_tag_of<Type>> {
63
+ auto value = (*this)(tag, visit, std::int32_t{std::forward<decltype(subject)>(subject)});
64
+ return local_of<number_tag_of<Type>>::from(value);
65
+ }
66
+
67
+ template <class Type>
68
+ auto operator()(number_tag_of<Type> tag, visit_holder visit, auto&& subject) const -> local_of<number_tag_of<Type>> {
53
69
  return (*this)(tag, visit, Type{std::forward<decltype(subject)>(subject)});
54
70
  }
55
71
 
56
72
  // string
57
73
  auto operator()(string_tag_of<char> /*tag*/, visit_holder /*visit*/, std::string_view subject) const
58
- -> js::referenceable_value<value_of<string_tag_of<char>>> {
59
- return js::referenceable_value{value_of<string_tag>::make(lock(), subject)};
74
+ -> js::referenceable_value<local_of<string_tag_of<char>>> {
75
+ return js::referenceable_value{local_of<string_tag_of<char>>::make(lock(), subject)};
60
76
  }
61
77
 
62
78
  auto operator()(string_tag_of<char16_t> /*tag*/, visit_holder /*visit*/, std::u16string_view subject) const
63
- -> js::referenceable_value<value_of<string_tag_of<char16_t>>> {
64
- return js::referenceable_value{value_of<string_tag>::make(lock(), subject)};
79
+ -> js::referenceable_value<local_of<string_tag_of<char16_t>>> {
80
+ return js::referenceable_value{local_of<string_tag_of<char16_t>>::make(lock(), subject)};
65
81
  }
66
82
 
67
83
  auto operator()(string_tag /*tag*/, visit_holder visit, auto&& subject) const
68
- -> js::referenceable_value<value_of<string_tag>> {
84
+ -> js::referenceable_value<local_of<string_tag>> {
69
85
  auto value = (*this)(string_tag_of<char16_t>{}, visit, std::u16string_view{std::forward<decltype(subject)>(subject)});
70
- return js::referenceable_value{value_of<string_tag>{*value}};
86
+ return js::referenceable_value{local_of<string_tag>{*value}};
71
87
  }
72
88
 
73
89
  template <class Char>
74
90
  auto operator()(string_tag_of<Char> tag, visit_holder visit, std::convertible_to<std::basic_string_view<Char>> auto&& subject) const
75
- -> js::referenceable_value<value_of<string_tag_of<Char>>> {
91
+ -> js::referenceable_value<local_of<string_tag_of<Char>>> {
76
92
  return (*this)(tag, visit, std::basic_string_view<Char>{std::forward<decltype(subject)>(subject)});
77
93
  }
78
94
 
79
95
  template <class Char>
80
96
  auto operator()(string_tag_of<Char> tag, visit_holder visit, auto&& subject) const
81
- -> js::referenceable_value<value_of<string_tag_of<Char>>> {
97
+ -> js::referenceable_value<local_of<string_tag_of<Char>>> {
82
98
  return (*this)(tag, visit, std::basic_string<Char>{std::forward<decltype(subject)>(subject)});
83
99
  }
84
100
 
85
101
  // bigint (int64)
86
102
  auto operator()(bigint_tag_of<std::int64_t> /*tag*/, visit_holder /*visit*/, std::int64_t subject) const
87
- -> js::referenceable_value<value_of<bigint_tag_of<std::int64_t>>> {
88
- return js::referenceable_value{value_of<bigint_tag>::make(lock(), subject)};
103
+ -> js::referenceable_value<local_of<bigint_tag_of<std::int64_t>>> {
104
+ return js::referenceable_value{local_of<bigint_tag_of<std::int64_t>>::make(lock(), subject)};
89
105
  }
90
106
 
91
107
  [[nodiscard]] auto lock() const -> const basic_lock& { return lock_; }
@@ -102,22 +118,18 @@ struct accept_vm_prototype : accept_vm_primitive {
102
118
 
103
119
  // cast primitive to prototype
104
120
  template <std::convertible_to<primitive_tag> Tag>
105
- auto operator()(Tag tag, auto& visit, auto&& subject) const -> value_of<prototype_tag> {
121
+ auto operator()(Tag tag, auto& visit, auto&& subject) const -> local_of<prototype_tag> {
106
122
  const accept_vm_primitive& accept = *this;
107
123
  auto result = accept(tag, visit, std::forward<decltype(subject)>(subject));
108
- constexpr auto unwrap = util::overloaded{
109
- [](auto value) { return value; },
110
- []<class Type>(js::referenceable_value<Type> value) { return *std::move(value); },
111
- };
112
- return value_of<prototype_tag>::from(unwrap(result));
124
+ return local_of<prototype_tag>::from(js::dispatch_referenceable(result));
113
125
  }
114
126
 
115
127
  // function
116
- auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> value_of<function_prototype_tag> {
128
+ auto operator()(function_prototype_tag /*tag*/, visit_holder /*visit*/, auto subject) const -> local_of<function_prototype_tag> {
117
129
  using lock_type = const runtime_lock&;
118
130
  auto [ function, length ] = make_free_function<lock_type>(std::move(subject).callback);
119
131
  auto data = make_callback_storage(std::move(function));
120
- return value_of<function_prototype_tag>::make(lock(), std::move(data), length);
132
+ return local_of<function_prototype_tag>::make(lock(), std::move(data), length);
121
133
  }
122
134
  };
123
135
 
@@ -128,39 +140,39 @@ struct accept_vm_value : accept_vm_primitive {
128
140
 
129
141
  // bigint (from words)
130
142
  auto operator()(bigint_tag_of<js::bigint> /*tag*/, visit_holder /*visit*/, const js::bigint& subject) const
131
- -> js::referenceable_value<value_of<bigint_tag_of<js::bigint>>> {
132
- return js::referenceable_value{value_of<bigint_tag>::make(lock(), subject)};
143
+ -> js::referenceable_value<local_of<bigint_tag_of<js::bigint>>> {
144
+ return js::referenceable_value{local_of<bigint_tag_of<js::bigint>>::make(lock(), subject)};
133
145
  }
134
146
 
135
147
  auto operator()(bigint_tag_of<js::bigint> /*tag*/, visit_holder /*visit*/, js::bigint&& subject) const
136
- -> js::referenceable_value<value_of<bigint_tag_of<js::bigint>>> {
137
- return js::referenceable_value{value_of<bigint_tag>::make(lock(), std::move(subject))};
148
+ -> js::referenceable_value<local_of<bigint_tag_of<js::bigint>>> {
149
+ return js::referenceable_value{local_of<bigint_tag_of<js::bigint>>::make(lock(), std::move(subject))};
138
150
  }
139
151
 
140
152
  auto operator()(bigint_tag /*tag*/, visit_holder visit, auto&& subject) const
141
- -> js::referenceable_value<value_of<bigint_tag>> {
153
+ -> js::referenceable_value<local_of<bigint_tag>> {
142
154
  auto value = (*this)(bigint_tag_of<js::bigint>{}, visit, js::bigint{std::forward<decltype(subject)>(subject)});
143
- return js::referenceable_value{value_of<bigint_tag>{*std::move(value)}};
155
+ return js::referenceable_value{local_of<bigint_tag>{*std::move(value)}};
144
156
  }
145
157
 
146
158
  template <class Type>
147
159
  auto operator()(bigint_tag_of<Type> tag, visit_holder visit, auto&& subject) const
148
- -> js::referenceable_value<value_of<bigint_tag_of<Type>>> {
160
+ -> js::referenceable_value<local_of<bigint_tag_of<Type>>> {
149
161
  return (*this)(tag, visit, Type{std::forward<decltype(subject)>(subject)});
150
162
  }
151
163
 
152
164
  // array
153
165
  auto operator()(this const auto& self, list_tag /*tag*/, auto& visit, auto&& subject)
154
- -> js::deferred_receiver<value_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
166
+ -> js::deferred_receiver<local_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
155
167
  return {
156
- value_of<list_tag>::make(self.lock()),
168
+ local_of<list_tag>::make(self.lock()),
157
169
  std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
158
- [](value_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
170
+ [](local_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
159
171
  auto&& range = util::into_range(std::forward<decltype(subject)>(subject));
160
172
  for (auto&& [ key, value ] : util::forward_range(std::forward<decltype(range)>(range))) {
161
173
  auto name = visit.first(std::forward<decltype(key)>(key), self);
162
174
  auto item = visit.first(std::forward<decltype(value)>(value), self);
163
- receiver.set(self.lock(), name, item);
175
+ receiver->set(self.lock(), name, item);
164
176
  }
165
177
  },
166
178
  };
@@ -168,17 +180,17 @@ struct accept_vm_value : accept_vm_primitive {
168
180
 
169
181
  // vectors
170
182
  auto operator()(this const auto& self, vector_tag /*tag*/, auto& visit, auto&& subject)
171
- -> js::deferred_receiver<value_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
183
+ -> js::deferred_receiver<local_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
172
184
  auto [... size ] = util::maybe_range_size(subject);
173
185
  return {
174
- value_of<list_tag>::make(self.lock(), size...),
186
+ local_of<list_tag>::make(self.lock(), size...),
175
187
  std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
176
- [](value_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
188
+ [](local_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
177
189
  int ii = 0;
178
190
  auto&& range = util::into_range(std::forward<decltype(subject)>(subject));
179
191
  for (auto&& element : util::forward_range(std::forward<decltype(range)>(range))) {
180
192
  auto item = visit(std::forward<decltype(element)>(element), self);
181
- receiver.set(self.lock(), ii++, item);
193
+ receiver->set(self.lock(), ii++, item);
182
194
  }
183
195
  },
184
196
  };
@@ -186,15 +198,15 @@ struct accept_vm_value : accept_vm_primitive {
186
198
 
187
199
  template <std::size_t Size>
188
200
  auto operator()(this const auto& self, tuple_tag<Size> /*tag*/, auto& visit, auto&& subject)
189
- -> js::deferred_receiver<value_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
201
+ -> js::deferred_receiver<local_of<list_tag>, decltype(self), decltype(visit), decltype(subject)> {
190
202
  return {
191
- value_of<list_tag>::make(self.lock(), Size),
203
+ local_of<list_tag>::make(self.lock(), Size),
192
204
  std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
193
- [](value_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ tuple) -> void {
194
- const auto [... indices ] = util::sequence<Size>;
195
- (..., [ & ]() -> void {
205
+ [](local_of<list_tag> receiver, auto& self, auto& visit, auto /*&&*/ tuple) -> void {
206
+ constexpr auto [... indices ] = util::sequence<Size>;
207
+ (..., [ & ] -> void {
196
208
  auto element = visit(indices, std::forward<decltype(tuple)>(tuple), self);
197
- unmaybe(receiver.set(self.lock(), indices, element));
209
+ unmaybe(receiver->set(self.lock(), indices, element));
198
210
  }());
199
211
  }
200
212
  };
@@ -202,15 +214,15 @@ struct accept_vm_value : accept_vm_primitive {
202
214
 
203
215
  // dictionary
204
216
  auto operator()(this const auto& self, dictionary_tag /*tag*/, auto& visit, auto&& subject)
205
- -> js::deferred_receiver<value_of<dictionary_tag>, decltype(self), decltype(visit), decltype(subject)> {
217
+ -> js::deferred_receiver<local_of<dictionary_tag>, decltype(self), decltype(visit), decltype(subject)> {
206
218
  return {
207
- value_of<record_tag>::make(self.lock()),
219
+ local_of<record_tag>::make(self.lock()),
208
220
  std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
209
- [](value_of<dictionary_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
221
+ [](local_of<dictionary_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
210
222
  for (auto&& [ key, value ] : util::into_range(subject)) {
211
223
  auto name = visit.first(std::forward<decltype(key)>(key), self);
212
224
  auto item = visit.first(std::forward<decltype(value)>(value), self);
213
- receiver.set(self.lock(), name, item);
225
+ receiver->set(self.lock(), name, item);
214
226
  }
215
227
  },
216
228
  };
@@ -219,30 +231,30 @@ struct accept_vm_value : accept_vm_primitive {
219
231
  // structs
220
232
  template <std::size_t Size>
221
233
  auto operator()(this const auto& self, struct_tag<Size> /*tag*/, auto& visit, auto&& subject)
222
- -> js::deferred_receiver<value_of<record_tag>, decltype(self), decltype(visit), decltype(subject)> {
234
+ -> js::deferred_receiver<local_of<record_tag>, decltype(self), decltype(visit), decltype(subject)> {
223
235
  return {
224
- value_of<record_tag>::make(self.lock()),
236
+ local_of<record_tag>::make(self.lock()),
225
237
  std::forward_as_tuple(self, visit, std::forward<decltype(subject)>(subject)),
226
- [](value_of<record_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
238
+ [](local_of<record_tag> receiver, auto& self, auto& visit, auto /*&&*/ subject) -> void {
227
239
  self.template accept_entry_pair_struct<Size>(visit, receiver, std::forward<decltype(subject)>(subject));
228
240
  }
229
241
  };
230
242
  }
231
243
 
232
244
  template <std::size_t Size>
233
- auto accept_entry_pair_struct(this const auto& self, auto& visit, value_of<record_tag> receiver, auto&& subject) -> void {
234
- const auto [... indices ] = util::sequence<Size>;
235
- (..., [ & ]() -> void {
245
+ auto accept_entry_pair_struct(this const auto& self, auto& visit, local_of<record_tag> receiver, auto&& subject) -> void {
246
+ constexpr auto [... indices ] = util::sequence<Size>;
247
+ (..., [ & ] -> void {
236
248
  auto accept_entry = accept_entry_pair<decltype(self), decltype(self)>{self};
237
249
  auto entry = visit(std::integral_constant<std::size_t, indices>{}, std::forward<decltype(subject)>(subject), accept_entry);
238
- receiver.set(self.lock(), entry.first, entry.second);
250
+ receiver->set(self.lock(), entry.first, entry.second);
239
251
  }());
240
252
  }
241
253
 
242
254
  // array buffer
243
255
  auto operator()(array_buffer_tag /*tag*/, visit_holder /*visit*/, js::array_buffer subject) const
244
- -> js::referenceable_value<value_of<array_buffer_tag>> {
245
- return js::referenceable_value{value_of<array_buffer_tag>::make(lock(), std::move(subject))};
256
+ -> js::referenceable_value<local_of<array_buffer_tag>> {
257
+ return js::referenceable_value{local_of<array_buffer_tag>::make(lock(), std::move(subject))};
246
258
  }
247
259
 
248
260
  [[nodiscard]] auto lock() const -> const runtime_lock& {
@@ -250,6 +262,20 @@ struct accept_vm_value : accept_vm_primitive {
250
262
  }
251
263
  };
252
264
 
265
+ // Forward `value_of<T>`
266
+ template <class Tag>
267
+ struct accept_vm_value_of {
268
+ public:
269
+ explicit accept_vm_value_of(auto* /*transfer*/) {}
270
+
271
+ auto operator()(Tag /*tag*/, visit_holder /*visit*/, value_of<Tag> subject) const -> value_of<Tag> {
272
+ return subject;
273
+ }
274
+
275
+ consteval static auto accept_tags_of() { return std::tuple{Tag{}}; }
276
+ consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
277
+ };
278
+
253
279
  // Object key lookup (struct_template, etc)
254
280
  template <class Meta, auto Key, class Type>
255
281
  struct accept_vm_property_value {
@@ -267,7 +293,7 @@ struct accept_vm_property_value {
267
293
  }
268
294
 
269
295
  private:
270
- mutable visit_key_literal<Key, value_of<record_tag>> first;
296
+ mutable visit_key_literal<Key, local_of<record_tag>> first;
271
297
  accept_value<Meta, Type> second;
272
298
  };
273
299
 
@@ -277,31 +303,37 @@ namespace js {
277
303
  using namespace isolated_vm;
278
304
 
279
305
  template <class Tag>
280
- struct accept_property_subject<value_of<Tag>> : std::type_identity<value_of<record_tag>> {};
306
+ struct accept_property_subject<local_of<Tag>> : std::type_identity<local_of<record_tag>> {};
281
307
 
282
308
  // Primitive acceptor
283
309
  template <std::convertible_to<value_tag> Tag>
284
310
  requires std::is_convertible_v<Tag, primitive_tag>
285
- struct accept<void, value_of<Tag>> : accept_vm_primitive {
311
+ struct accept<void, local_of<Tag>> : accept_vm_primitive {
286
312
  using accept_vm_primitive::accept_vm_primitive;
287
313
  };
288
314
 
289
315
  // Template / prototype acceptor
290
316
  template <class Tag>
291
317
  requires std::is_convertible_v<Tag, prototype_tag>
292
- struct accept<void, value_of<Tag>> : accept_vm_prototype {
318
+ struct accept<void, local_of<Tag>> : accept_vm_prototype {
293
319
  using accept_vm_prototype::accept_vm_prototype;
294
320
  };
295
321
 
296
322
  // Value acceptor
297
323
  template <std::convertible_to<value_tag> Tag>
298
- struct accept<void, value_of<Tag>> : accept_vm_value {
324
+ struct accept<void, local_of<Tag>> : accept_vm_value {
299
325
  using accept_vm_value::accept_vm_value;
300
326
  };
301
327
 
328
+ // Forward `value_of<T>`
329
+ template <class Meta, class Tag>
330
+ struct accept<Meta, isolated_vm::value_of<Tag>> : isolated_vm::accept_vm_value_of<Tag> {
331
+ using isolated_vm::accept_vm_value_of<Tag>::accept_vm_value_of;
332
+ };
333
+
302
334
  // Object key lookup (struct_template, etc)
303
335
  template <class Meta, auto Key, class Type>
304
- struct accept_property_value<Meta, Key, Type, value_of<record_tag>> : accept_vm_property_value<Meta, Key, Type> {
336
+ struct accept_property_value<Meta, Key, Type, local_of<record_tag>> : accept_vm_property_value<Meta, Key, Type> {
305
337
  using accept_vm_property_value<Meta, Key, Type>::accept_vm_property_value;
306
338
  };
307
339