@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
@@ -7,7 +7,7 @@ import util;
7
7
  namespace isolated_vm {
8
8
  using namespace js;
9
9
 
10
- constexpr auto primitive_typeofs = std::array{
10
+ constexpr auto primitive_typeofs = util::constexpr_array{
11
11
  value_typeof::undefined,
12
12
  value_typeof::null,
13
13
  value_typeof::boolean,
@@ -20,12 +20,12 @@ constexpr auto primitive_typeofs = std::array{
20
20
  value_typeof::bigint_i64,
21
21
  };
22
22
 
23
- constexpr auto data_block_typeofs = std::array{
23
+ constexpr auto data_block_typeofs = util::constexpr_array{
24
24
  value_typeof::array_buffer,
25
25
  value_typeof::shared_array_buffer,
26
26
  };
27
27
 
28
- constexpr auto array_buffer_view_typeofs = std::array{
28
+ constexpr auto array_buffer_view_typeofs = util::constexpr_array{
29
29
  value_typeof::bigint64_array,
30
30
  value_typeof::biguint64_array,
31
31
  value_typeof::data_view,
@@ -47,18 +47,18 @@ struct visit_vm_property_key {
47
47
  explicit visit_vm_property_key(Visit& visit) : visit_{visit} {}
48
48
 
49
49
  template <class Accept>
50
- auto operator()(value_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
50
+ auto operator()(local_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
51
51
  auto accept_as = [ & ]<class Tag>(Tag tag) -> auto {
52
- auto value = bound_value{lock(), value_of<Tag>::from(subject)};
52
+ auto value = value_of{lock(), local_of<Tag>::from(subject)};
53
53
  return accept(tag, *this, value);
54
54
  };
55
- if (subject.is_string()) {
56
- if (value_of<string_tag>::from(subject).is_latin1()) {
55
+ if (subject->is_string()) {
56
+ if (local_of<string_tag>::from(subject)->is_latin1()) {
57
57
  return accept_as(string_tag_of<char>{});
58
58
  } else {
59
59
  return accept_as(string_tag_of<char16_t>{});
60
60
  }
61
- } else if (subject.is_number()) {
61
+ } else if (subject->is_number()) {
62
62
  return accept_as(number_tag_of<std::int32_t>{});
63
63
  } else {
64
64
  return accept_as(symbol_tag{});
@@ -75,16 +75,16 @@ template <auto Key>
75
75
  struct visit_vm_key_literal {
76
76
  explicit constexpr visit_vm_key_literal(auto* /*transfer*/) {}
77
77
 
78
- auto operator()(const auto& /*anything*/, const auto& accept_or_visit) -> value_of<name_tag> {
78
+ auto operator()(const auto& /*anything*/, const auto& accept_or_visit) -> local_of<name_tag> {
79
79
  if (!local_key_) {
80
80
  constexpr auto key = util::make_consteval_string_view(Key);
81
- local_key_ = transfer_in<value_of<name_tag>>(key, accept_or_visit.lock());
81
+ local_key_ = transfer_in<local_of<name_tag>>(key, accept_or_visit.lock());
82
82
  }
83
83
  return local_key_;
84
84
  }
85
85
 
86
86
  private:
87
- value_of<name_tag> local_key_;
87
+ local_of<name_tag> local_key_;
88
88
  };
89
89
 
90
90
  struct visit_vm_value {
@@ -92,51 +92,51 @@ struct visit_vm_value {
92
92
  explicit visit_vm_value(const runtime_lock& lock) : lock_{lock} {}
93
93
 
94
94
  template <class Accept>
95
- auto operator()(value_of<> subject, const Accept& accept) -> accept_target_t<Accept> {
95
+ auto operator()(local_of<> subject, const Accept& accept) -> accept_target_t<Accept> {
96
96
  // TODO: reference map
97
97
  return util::template_traverse(
98
98
  accept_tags_of_v<Accept>,
99
99
  util::overloaded{
100
100
  // Fast paths
101
101
  [ & ](undefined_tag /*tag*/, auto next) -> accept_target_t<Accept> {
102
- return subject.is_undefined() ? accept_as(undefined_tag{}, subject, accept) : next();
102
+ return subject->is_undefined() ? accept_as(undefined_tag{}, subject, accept) : next();
103
103
  },
104
104
  [ & ](null_tag /*tag*/, auto next) -> accept_target_t<Accept> {
105
- return subject.is_null() ? accept_as(null_tag{}, subject, accept) : next();
105
+ return subject->is_null() ? accept_as(null_tag{}, subject, accept) : next();
106
106
  },
107
107
  [ & ](boolean_tag /*tag*/, auto next) -> accept_target_t<Accept> {
108
- return subject.is_boolean() ? accept_as(boolean_tag{}, subject, accept) : next();
108
+ return subject->is_boolean() ? accept_as(boolean_tag{}, subject, accept) : next();
109
109
  },
110
110
  [ & ](number_tag /*tag*/, auto next) -> accept_target_t<Accept> {
111
- return subject.is_number() ? accept_as(number_tag{}, subject, accept) : next();
111
+ return subject->is_number() ? accept_as(number_tag{}, subject, accept) : next();
112
112
  },
113
113
  [ & ](string_tag /*tag*/, auto next) -> accept_target_t<Accept> {
114
- return subject.is_string() ? accept_as(string_tag{}, subject, accept) : next();
114
+ return subject->is_string() ? accept_as(string_tag{}, subject, accept) : next();
115
115
  },
116
116
  [ & ](bigint_tag /*tag*/, auto next) -> accept_target_t<Accept> {
117
- return subject.is_bigint() ? accept_as(bigint_tag{}, subject, accept) : next();
117
+ return subject->is_bigint() ? accept_as(bigint_tag{}, subject, accept) : next();
118
118
  },
119
119
  [ & ](date_tag /*tag*/, auto next) -> accept_target_t<Accept> {
120
- return subject.is_date() ? accept_as(date_tag{}, subject, accept) : next();
120
+ return subject->is_date() ? accept_as(date_tag{}, subject, accept) : next();
121
121
  },
122
122
  [ & ](list_tag /*tag*/, auto next) -> accept_target_t<Accept> {
123
- return subject.is_array() ? accept_as(list_tag{}, subject, accept) : next();
123
+ return subject->is_array() ? accept_as(list_tag{}, subject, accept) : next();
124
124
  },
125
125
  [ & ](function_tag /*tag*/, auto next) -> accept_target_t<Accept> {
126
- return subject.is_function() ? accept_as(function_tag{}, subject, accept) : next();
126
+ return subject->is_function() ? accept_as(function_tag{}, subject, accept) : next();
127
127
  },
128
128
 
129
129
  // Unknown tag
130
130
  [](auto /*tag*/, auto next) -> accept_target_t<Accept> { return next(); },
131
131
 
132
132
  // Slow path
133
- [ & ]() -> accept_target_t<Accept> {
134
- auto type = subject.inspect();
135
- const auto [... primitive_types ] = primitive_typeofs;
133
+ [ & ] -> accept_target_t<Accept> {
134
+ auto type = subject->inspect();
135
+ constexpr auto [... primitive_types ] = primitive_typeofs;
136
136
  if ((... || (type == primitive_types))) {
137
- return inspected(type, value_of<primitive_tag>::from(subject), accept);
137
+ return inspected(type, local_of<primitive_tag>::from(subject), accept);
138
138
  } else {
139
- return inspected(type, value_of<object_tag>::from(subject), accept);
139
+ return inspected(type, local_of<object_tag>::from(subject), accept);
140
140
  }
141
141
  },
142
142
  }
@@ -144,13 +144,13 @@ struct visit_vm_value {
144
144
  }
145
145
 
146
146
  template <class Accept>
147
- auto operator()(value_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
148
- return inspected(subject.inspect(), subject, accept);
147
+ auto operator()(local_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
148
+ return inspected(subject->inspect(), subject, accept);
149
149
  }
150
150
 
151
151
  template <class Accept>
152
- auto operator()(value_of<number_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
153
- switch (subject.inspect()) {
152
+ auto operator()(local_of<number_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
153
+ switch (subject->inspect()) {
154
154
  case value_typeof::number: return accept_as(number_tag{}, subject, accept);
155
155
  case value_typeof::number_i32: return accept_as(number_tag_of<std::int32_t>{}, subject, accept);
156
156
  default: std::unreachable();
@@ -158,8 +158,8 @@ struct visit_vm_value {
158
158
  }
159
159
 
160
160
  template <class Accept>
161
- auto operator()(value_of<string_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
162
- switch (subject.inspect()) {
161
+ auto operator()(local_of<string_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
162
+ switch (subject->inspect()) {
163
163
  case value_typeof::string: return accept_as(string_tag_of<char16_t>{}, subject, accept);
164
164
  case value_typeof::string_latin1: return accept_as(string_tag_of<char>{}, subject, accept);
165
165
  default: std::unreachable();
@@ -167,8 +167,8 @@ struct visit_vm_value {
167
167
  }
168
168
 
169
169
  template <class Accept>
170
- auto operator()(value_of<bigint_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
171
- switch (subject.inspect()) {
170
+ auto operator()(local_of<bigint_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
171
+ switch (subject->inspect()) {
172
172
  case value_typeof::bigint: return accept_as(bigint_tag{}, subject, accept);
173
173
  case value_typeof::bigint_i64: return accept_as(bigint_tag_of<std::int64_t>{}, subject, accept);
174
174
  default: std::unreachable();
@@ -176,18 +176,18 @@ struct visit_vm_value {
176
176
  }
177
177
 
178
178
  template <class Accept>
179
- auto operator()(value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
180
- return inspected(subject.inspect(), subject, accept);
179
+ auto operator()(local_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
180
+ return inspected(subject->inspect(), subject, accept);
181
181
  }
182
182
 
183
183
  template <class Accept>
184
- auto operator()(value_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
185
- return inspected(subject.inspect(), subject, accept);
184
+ auto operator()(local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
185
+ return inspected(subject->inspect(), subject, accept);
186
186
  }
187
187
 
188
188
  template <class Accept>
189
- auto operator()(value_of<array_buffer_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
190
- return inspected(subject.inspect(), subject, accept);
189
+ auto operator()(local_of<array_buffer_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
190
+ return inspected(subject->inspect(), subject, accept);
191
191
  }
192
192
 
193
193
  [[nodiscard]] auto lock() const -> const runtime_lock& { return lock_.get(); }
@@ -195,7 +195,7 @@ struct visit_vm_value {
195
195
 
196
196
  private:
197
197
  template <class Accept>
198
- constexpr auto inspected(value_typeof type_of, value_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
198
+ constexpr auto inspected(value_typeof type_of, local_of<primitive_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
199
199
  switch (type_of) {
200
200
  case value_typeof::undefined: return accept_as(undefined_tag{}, subject, accept);
201
201
  case value_typeof::null: return accept_as(null_tag{}, subject, accept);
@@ -212,13 +212,13 @@ struct visit_vm_value {
212
212
  }
213
213
 
214
214
  template <class Accept>
215
- constexpr auto inspected(value_typeof type_of, value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
216
- const auto [... data_block_types ] = data_block_typeofs;
217
- const auto [... array_buffer_view_types ] = array_buffer_view_typeofs;
215
+ constexpr auto inspected(value_typeof type_of, local_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
216
+ constexpr auto [... data_block_types ] = data_block_typeofs;
217
+ constexpr auto [... array_buffer_view_types ] = array_buffer_view_typeofs;
218
218
  if ((... || (type_of == data_block_types))) {
219
- return inspected(type_of, value_of<data_block_tag>::from(subject), accept);
219
+ return inspected(type_of, local_of<data_block_tag>::from(subject), accept);
220
220
  } else if ((... || (type_of == array_buffer_view_types))) {
221
- return inspected(type_of, value_of<array_buffer_view_tag>::from(subject), accept);
221
+ return inspected(type_of, local_of<array_buffer_view_tag>::from(subject), accept);
222
222
  } else {
223
223
  switch (type_of) {
224
224
  case value_typeof::external: return accept_as(external_tag{}, subject, accept);
@@ -228,12 +228,12 @@ struct visit_vm_value {
228
228
  case value_typeof::array:
229
229
  {
230
230
  auto visit_entry = visit_entry_pair<visit_vm_property_key<visit_vm_value>, visit_vm_value&>{*this};
231
- return accept(list_tag{}, visit_entry, bound_value{lock_, value_of<record_tag>::from(subject)});
231
+ return accept(list_tag{}, visit_entry, value_of{lock_, local_of<record_tag>::from(subject)});
232
232
  }
233
233
  case value_typeof::dictionary:
234
234
  {
235
235
  auto visit_entry = visit_entry_pair<visit_vm_property_key<visit_vm_value>, visit_vm_value&>{*this};
236
- return accept(dictionary_tag{}, visit_entry, bound_value{lock_, value_of<record_tag>::from(subject)});
236
+ return accept(dictionary_tag{}, visit_entry, value_of{lock_, local_of<record_tag>::from(subject)});
237
237
  }
238
238
  default: std::unreachable();
239
239
  }
@@ -241,7 +241,7 @@ struct visit_vm_value {
241
241
  }
242
242
 
243
243
  template <class Accept>
244
- constexpr auto inspected(value_typeof type_of, value_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
244
+ constexpr auto inspected(value_typeof type_of, local_of<data_block_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
245
245
  switch (type_of) {
246
246
  case value_typeof::array_buffer: return accept_as(array_buffer_tag{}, subject, accept);
247
247
  case value_typeof::shared_array_buffer: return accept_as(shared_array_buffer_tag{}, subject, accept);
@@ -250,7 +250,7 @@ struct visit_vm_value {
250
250
  }
251
251
 
252
252
  template <class Accept>
253
- constexpr auto inspected(value_typeof type_of, value_of<array_buffer_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
253
+ constexpr auto inspected(value_typeof type_of, local_of<array_buffer_view_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
254
254
  switch (type_of) {
255
255
  case value_typeof::bigint64_array: return accept_as(typed_array_tag_of<std::int64_t>{}, subject, accept);
256
256
  case value_typeof::biguint64_array: return accept_as(typed_array_tag_of<std::uint64_t>{}, subject, accept);
@@ -270,25 +270,68 @@ struct visit_vm_value {
270
270
  }
271
271
 
272
272
  template <class Accept, class Tag>
273
- auto accept_as(Tag tag, value_of<> subject, const Accept& accept) -> accept_target_t<Accept> {
274
- return accept(tag, *this, bound_value{lock_, value_of<Tag>::from(subject)});
273
+ auto accept_as(Tag tag, local_of<> subject, const Accept& accept) -> accept_target_t<Accept> {
274
+ return accept(tag, *this, value_of{lock_, local_of<Tag>::from(subject)});
275
275
  }
276
276
 
277
277
  std::reference_wrapper<const runtime_lock> lock_;
278
278
  };
279
279
 
280
+ // Forward `value_of<T>` back to acceptor
281
+ template <class Tag>
282
+ struct visit_vm_value_of {
283
+ private:
284
+ using visit_type = visit_vm_value;
285
+
286
+ public:
287
+ constexpr explicit visit_vm_value_of(const runtime_lock& lock) : visit_{lock} {}
288
+
289
+ template <class Accept>
290
+ constexpr auto operator()(value_of<Tag> subject, const Accept& accept) -> accept_target_t<Accept> {
291
+ return accept(Tag{}, visit_, subject);
292
+ }
293
+
294
+ template <class Accept>
295
+ requires std::is_same_v<Tag, object_tag>
296
+ constexpr auto operator()(value_of<object_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
297
+ auto visit_entry = visit_entry_pair<visit_vm_property_key<visit_type>, visit_type&>{visit_};
298
+ return accept(object_tag{}, visit_entry, subject);
299
+ }
300
+
301
+ template <class Accept>
302
+ requires std::is_same_v<Tag, list_tag>
303
+ constexpr auto operator()(value_of<list_tag> subject, const Accept& accept) -> accept_target_t<Accept> {
304
+ auto visit_entry = visit_entry_pair<visit_vm_property_key<visit_type>, visit_type&>{visit_};
305
+ return accept(list_tag{}, visit_entry, subject);
306
+ }
307
+
308
+ consteval static auto types(auto /*recursive*/) { return util::type_pack{}; }
309
+
310
+ private:
311
+ visit_type visit_;
312
+ };
313
+
280
314
  } // namespace isolated_vm
281
315
 
282
316
  namespace js {
283
317
  using namespace isolated_vm;
284
318
 
285
319
  template <class Tag>
286
- struct visit<void, value_of<Tag>> : visit_vm_value {
320
+ struct visit<void, local_of<Tag>> : visit_vm_value {
287
321
  using visit_vm_value::visit_vm_value;
288
322
  };
289
323
 
324
+ // Pass through `value_of<Tag>`
325
+ template <class Tag>
326
+ struct visit<void, isolated_vm::value_of<Tag>> : isolated_vm::visit_vm_value_of<Tag> {
327
+ using isolated_vm::visit_vm_value_of<Tag>::visit_vm_value_of;
328
+ };
329
+
330
+ template <class Tag>
331
+ struct visit_subject_for<isolated_vm::value_of<Tag>> : std::type_identity<isolated_vm::local_of<Tag>> {};
332
+
290
333
  template <auto Key>
291
- struct visit_key_literal<Key, value_of<record_tag>> : visit_vm_key_literal<Key> {
334
+ struct visit_key_literal<Key, local_of<record_tag>> : visit_vm_key_literal<Key> {
292
335
  using visit_vm_key_literal<Key>::visit_vm_key_literal;
293
336
  };
294
337
 
@@ -1,19 +1,19 @@
1
1
  module;
2
2
  #include "auto_js/export_tag.h"
3
3
  export module isolated_vm:value.array;
4
- import :handle.value_of;
4
+ import :handle.local_of;
5
5
  import :value.record;
6
6
  import auto_js;
7
7
 
8
8
  namespace isolated_vm {
9
9
  using namespace js;
10
10
 
11
- // value_of<list_tag>
12
- class EXPORT value_for_array : public value_next<list_tag> {
11
+ // local_of<list_tag>
12
+ class EXPORT local_for_array : public local_next<list_tag> {
13
13
  public:
14
- using value_next<list_tag>::value_next;
15
- auto set(const runtime_lock& lock, int key, value_of<> value) const -> void;
16
- static auto make(const runtime_lock& lock, int capacity = 0) -> value_of<list_tag>;
14
+ using local_next<list_tag>::local_next;
15
+ auto set(const runtime_lock& lock, int key, local_of<> value) const -> void;
16
+ static auto make(const runtime_lock& lock, int capacity = 0) -> local_of<list_tag>;
17
17
  };
18
18
 
19
19
  } // namespace isolated_vm
@@ -1,7 +1,7 @@
1
1
  module;
2
2
  #include "auto_js/export_tag.h"
3
3
  export module isolated_vm:value.array_buffer;
4
- import :handle.bound_value;
4
+ import :handle.local_of;
5
5
  import :handle.value_of;
6
6
  import :value.object;
7
7
  import auto_js;
@@ -10,43 +10,52 @@ import std;
10
10
  namespace isolated_vm {
11
11
  using namespace js;
12
12
 
13
- // value_of<data_block_tag>
14
- class EXPORT value_for_data_block : public value_next<data_block_tag> {
13
+ // local_of<data_block_tag>
14
+ class EXPORT local_for_data_block : public local_next<data_block_tag> {
15
15
  public:
16
- using value_next<data_block_tag>::value_next;
16
+ using local_next<data_block_tag>::local_next;
17
17
  [[nodiscard]] auto inspect() const -> value_typeof;
18
18
  };
19
19
 
20
- // bound_value<data_block_tag>
21
- class EXPORT bound_value_for_data_block : public bound_value_next<data_block_tag> {
20
+ // value_of<data_block_tag>
21
+ class EXPORT value_for_data_block : public value_next<data_block_tag> {
22
22
  public:
23
- using bound_value_next<data_block_tag>::bound_value_next;
23
+ using value_next<data_block_tag>::value_next;
24
24
  [[nodiscard]] auto byte_length() const -> std::size_t;
25
25
  [[nodiscard]] auto data() const -> std::byte*;
26
26
  explicit operator js::array_buffer() const;
27
27
  explicit operator std::span<std::byte>() const;
28
28
  };
29
29
 
30
- // value_of<array_buffer_tag>
31
- class EXPORT value_for_array_buffer : public value_next<array_buffer_tag> {
30
+ // local_of<array_buffer_tag>
31
+ class EXPORT local_for_array_buffer : public local_next<array_buffer_tag> {
32
32
  public:
33
- using value_next<array_buffer_tag>::value_next;
34
- static auto make(const runtime_lock& lock, js::array_buffer buffer) -> value_of<array_buffer_tag>;
33
+ using local_next<array_buffer_tag>::local_next;
34
+ static auto make(const runtime_lock& lock, js::array_buffer buffer) -> local_of<array_buffer_tag>;
35
35
  };
36
36
 
37
- // value_of<array_buffer_view_tag>
38
- class EXPORT value_for_array_buffer_view : public value_next<array_buffer_view_tag> {
37
+ // local_of<array_buffer_view_tag>
38
+ class EXPORT local_for_array_buffer_view : public local_next<array_buffer_view_tag> {
39
39
  public:
40
- using value_next<array_buffer_view_tag>::value_next;
40
+ using local_next<array_buffer_view_tag>::local_next;
41
41
  [[nodiscard]] auto inspect() const -> value_typeof;
42
42
  };
43
43
 
44
- // bound_value<typed_array_tag_of<Type>>
44
+ // value_of<typed_array_tag_of<Type>>
45
45
  template <class Type>
46
- class EXPORT bound_value_for_typed_array_of : public bound_value_next<typed_array_tag_of<Type>> {
46
+ class EXPORT value_for_typed_array_of : public value_next<typed_array_tag_of<Type>> {
47
+ public:
48
+ using value_next<typed_array_tag_of<Type>>::value_next;
49
+ [[nodiscard]] auto buffer() const -> local_of<data_block_tag>;
50
+ [[nodiscard]] auto byte_offset() const -> std::size_t;
51
+ [[nodiscard]] auto size() const -> std::size_t;
52
+ };
53
+
54
+ // value_of<data_view_tag>
55
+ class EXPORT value_for_data_view : public value_next<data_view_tag> {
47
56
  public:
48
- using bound_value_next<typed_array_tag_of<Type>>::bound_value_next;
49
- [[nodiscard]] auto buffer() const -> value_of<data_block_tag>;
57
+ using value_next<data_view_tag>::value_next;
58
+ [[nodiscard]] auto buffer() const -> local_of<data_block_tag>;
50
59
  [[nodiscard]] auto byte_offset() const -> std::size_t;
51
60
  [[nodiscard]] auto size() const -> std::size_t;
52
61
  };
@@ -6,17 +6,17 @@ namespace isolated_vm {
6
6
  using namespace js;
7
7
 
8
8
  template <class Result>
9
- auto value_for_function::apply(const runtime_lock& lock, auto&& args) -> Result {
10
- using args_type = std::vector<value_of<>>;
11
- auto undefined = js::transfer_in_strict<value_of<>>(std::monostate{}, lock);
9
+ auto local_for_function::apply(const runtime_lock& lock, auto&& args) -> Result {
10
+ using args_type = std::vector<local_of<>>;
11
+ auto undefined = js::transfer_in_strict<local_of<>>(std::monostate{}, lock);
12
12
  auto argv = js::transfer_in_strict<args_type>(std::forward<decltype(args)>(args), lock);
13
13
  auto result = invoke(lock, undefined, argv);
14
14
  return js::transfer_out<Result>(result, lock);
15
15
  }
16
16
 
17
17
  template <class Result>
18
- auto value_for_function::call(const runtime_lock& lock, auto&&... args) -> Result {
19
- using args_type = std::array<value_of<>, sizeof...(args) + 1>;
18
+ auto local_for_function::call(const runtime_lock& lock, auto&&... args) -> Result {
19
+ using args_type = std::array<local_of<>, sizeof...(args) + 1>;
20
20
  auto argv = js::transfer_in_strict<args_type>(
21
21
  std::tuple_cat(
22
22
  std::tuple{std::monostate{}},
@@ -1,17 +1,17 @@
1
1
  module;
2
2
  #include "auto_js/export_tag.h"
3
3
  export module isolated_vm:value.function;
4
- import :handle.value_of;
4
+ import :handle.local_of;
5
5
  import :support.lock_fwd;
6
6
  import :value.primitive;
7
7
 
8
8
  namespace isolated_vm {
9
9
  using namespace js;
10
10
 
11
- // value_of<function_tag>
12
- class EXPORT value_for_function : public value_next<function_tag> {
11
+ // local_of<function_tag>
12
+ class EXPORT local_for_function : public local_next<function_tag> {
13
13
  public:
14
- using value_next<function_tag>::value_next;
14
+ using local_next<function_tag>::local_next;
15
15
 
16
16
  template <class Result = std::monostate>
17
17
  auto apply(const runtime_lock& lock, auto&& args) -> Result;
@@ -20,7 +20,7 @@ class EXPORT value_for_function : public value_next<function_tag> {
20
20
  auto call(const runtime_lock& lock, auto&&... args) -> Result;
21
21
 
22
22
  private:
23
- auto invoke(const runtime_lock& lock, value_of<> that, std::span<value_of<>> argv) -> value_of<>;
23
+ auto invoke(const runtime_lock& lock, local_of<> that, std::span<local_of<>> argv) -> local_of<>;
24
24
  };
25
25
 
26
26
  } // namespace isolated_vm
@@ -6,10 +6,10 @@ import :value.primitive;
6
6
  namespace isolated_vm {
7
7
  using namespace js;
8
8
 
9
- // value_of<object_tag>
10
- class EXPORT value_for_object : public value_next<object_tag> {
9
+ // local_of<object_tag>
10
+ class EXPORT local_for_object : public local_next<object_tag> {
11
11
  public:
12
- using value_next<object_tag>::value_next;
12
+ using local_next<object_tag>::local_next;
13
13
  [[nodiscard]] auto inspect() const -> value_typeof;
14
14
  };
15
15
 
@@ -1,7 +1,7 @@
1
1
  module;
2
2
  #include "auto_js/export_tag.h"
3
3
  export module isolated_vm:value.primitive;
4
- import :handle.bound_value;
4
+ import :handle.local_of;
5
5
  import :handle.value_of;
6
6
  import auto_js;
7
7
  import std;
@@ -50,9 +50,9 @@ export enum class value_typeof : std::uint8_t {
50
50
  };
51
51
 
52
52
  // value & primitive
53
- class EXPORT value_for_value : public value_next<value_tag> {
53
+ class EXPORT local_for_value : public local_next<value_tag> {
54
54
  public:
55
- using value_next<value_tag>::value_next;
55
+ using local_next<value_tag>::local_next;
56
56
  [[nodiscard]] auto is_array() const -> bool;
57
57
  [[nodiscard]] auto is_bigint() const -> bool;
58
58
  [[nodiscard]] auto is_boolean() const -> bool;
@@ -65,90 +65,90 @@ class EXPORT value_for_value : public value_next<value_tag> {
65
65
  [[nodiscard]] auto inspect() const -> value_typeof;
66
66
  };
67
67
 
68
- class EXPORT value_for_primitive : public value_next<primitive_tag> {
68
+ class EXPORT local_for_primitive : public local_next<primitive_tag> {
69
69
  public:
70
- using value_next<primitive_tag>::value_next;
70
+ using local_next<primitive_tag>::local_next;
71
71
  [[nodiscard]] auto inspect() const -> value_typeof;
72
72
  };
73
73
 
74
74
  // null & undefined
75
- class EXPORT value_for_undefined : public value_next<undefined_tag> {
75
+ class EXPORT local_for_undefined : public local_next<undefined_tag> {
76
76
  public:
77
- using value_next<undefined_tag>::value_next;
78
- static auto make(const basic_lock& lock) -> value_of<undefined_tag>;
77
+ using local_next<undefined_tag>::local_next;
78
+ static auto make(const basic_lock& lock) -> local_of<undefined_tag>;
79
79
  };
80
80
 
81
- class EXPORT value_for_null : public value_next<null_tag> {
81
+ class EXPORT local_for_null : public local_next<null_tag> {
82
82
  public:
83
- using value_next<null_tag>::value_next;
84
- static auto make(const basic_lock& lock) -> value_of<null_tag>;
83
+ using local_next<null_tag>::local_next;
84
+ static auto make(const basic_lock& lock) -> local_of<null_tag>;
85
85
  };
86
86
 
87
87
  // boolean
88
- class EXPORT value_for_boolean : public value_next<boolean_tag> {
88
+ class EXPORT local_for_boolean : public local_next<boolean_tag> {
89
89
  public:
90
- using value_next<boolean_tag>::value_next;
91
- static auto make(const basic_lock& lock, bool value) -> value_of<boolean_tag>;
90
+ using local_next<boolean_tag>::local_next;
91
+ static auto make(const basic_lock& lock, bool value) -> local_of<boolean_tag>;
92
92
  };
93
93
 
94
- class EXPORT bound_value_for_boolean : public bound_value_next<boolean_tag> {
94
+ class EXPORT value_for_boolean : public value_next<boolean_tag> {
95
95
  public:
96
- using bound_value_next<boolean_tag>::bound_value_next;
96
+ using value_next<boolean_tag>::value_next;
97
97
  [[nodiscard]] explicit operator bool() const;
98
98
  };
99
99
 
100
100
  // number
101
- class EXPORT value_for_number : public value_next<number_tag> {
101
+ class EXPORT local_for_number : public local_next<number_tag> {
102
102
  public:
103
- using value_next<number_tag>::value_next;
103
+ using local_next<number_tag>::local_next;
104
104
  [[nodiscard]] auto inspect() const -> value_typeof;
105
- static auto make(const basic_lock& lock, double value) -> value_of<number_tag_of<double>>;
106
- static auto make(const basic_lock& lock, std::int32_t value) -> value_of<number_tag_of<std::int32_t>>;
105
+ static auto make(const basic_lock& lock, double value) -> local_of<number_tag_of<double>>;
106
+ static auto make(const basic_lock& lock, std::int32_t value) -> local_of<number_tag_of<std::int32_t>>;
107
107
  };
108
108
 
109
- class EXPORT bound_value_for_number : public bound_value_next<number_tag> {
109
+ class EXPORT value_for_number : public value_next<number_tag> {
110
110
  public:
111
- using bound_value_next<number_tag>::bound_value_next;
111
+ using value_next<number_tag>::value_next;
112
112
  [[nodiscard]] explicit operator double() const;
113
113
  [[nodiscard]] explicit operator std::int32_t() const;
114
114
  };
115
115
 
116
116
  // name
117
- class EXPORT value_for_name : public value_next<name_tag> {
117
+ class EXPORT local_for_name : public local_next<name_tag> {
118
118
  public:
119
- using value_next<name_tag>::value_next;
119
+ using local_next<name_tag>::local_next;
120
120
  [[nodiscard]] auto inspect() const -> value_typeof;
121
121
  };
122
122
 
123
123
  // string
124
- class EXPORT value_for_string : public value_next<string_tag> {
124
+ class EXPORT local_for_string : public local_next<string_tag> {
125
125
  public:
126
- using value_next<string_tag>::value_next;
126
+ using local_next<string_tag>::local_next;
127
127
  [[nodiscard]] auto inspect() const -> value_typeof;
128
128
  [[nodiscard]] auto is_latin1() const -> bool;
129
- static auto make(const basic_lock& lock, std::u16string_view value) -> value_of<string_tag_of<char16_t>>;
130
- static auto make(const basic_lock& lock, std::string_view value) -> value_of<string_tag_of<char>>;
129
+ static auto make(const basic_lock& lock, std::u16string_view value) -> local_of<string_tag_of<char16_t>>;
130
+ static auto make(const basic_lock& lock, std::string_view value) -> local_of<string_tag_of<char>>;
131
131
  };
132
132
 
133
- class EXPORT bound_value_for_string : public bound_value_next<string_tag> {
133
+ class EXPORT value_for_string : public value_next<string_tag> {
134
134
  public:
135
- using bound_value_next<string_tag>::bound_value_next;
135
+ using value_next<string_tag>::value_next;
136
136
  [[nodiscard]] explicit operator std::string() const;
137
137
  [[nodiscard]] explicit operator std::u16string() const;
138
138
  };
139
139
 
140
140
  // bigint
141
- class EXPORT value_for_bigint : public value_next<bigint_tag> {
141
+ class EXPORT local_for_bigint : public local_next<bigint_tag> {
142
142
  public:
143
- using value_next<bigint_tag>::value_next;
143
+ using local_next<bigint_tag>::local_next;
144
144
  [[nodiscard]] auto inspect() const -> value_typeof;
145
- static auto make(const runtime_lock& lock, js::bigint value) -> value_of<bigint_tag_of<js::bigint>>;
146
- static auto make(const basic_lock& lock, std::int64_t value) -> value_of<bigint_tag_of<std::int64_t>>;
145
+ static auto make(const runtime_lock& lock, js::bigint value) -> local_of<bigint_tag_of<js::bigint>>;
146
+ static auto make(const basic_lock& lock, std::int64_t value) -> local_of<bigint_tag_of<std::int64_t>>;
147
147
  };
148
148
 
149
- class EXPORT bound_value_for_bigint : public bound_value_next<bigint_tag> {
149
+ class EXPORT value_for_bigint : public value_next<bigint_tag> {
150
150
  public:
151
- using bound_value_next<bigint_tag>::bound_value_next;
151
+ using value_next<bigint_tag>::value_next;
152
152
  [[nodiscard]] explicit operator js::bigint() const;
153
153
  [[nodiscard]] explicit operator std::int64_t() const;
154
154
  };