moxml 0.5.49 → 0.5.50

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 1e7f648665fbf11423b43ed957f111cabe57a732b2037d6e7d6d718beae4e0c3
4
- data.tar.gz: ec4ac686e3c83b794944c02a3f6b92aa964c9e984fb5752b49dbeb08812e0f61
3
+ metadata.gz: '0188508b255f1adb8c622a2965a91352c7ffc63afd79d53796ad48c708d479eb'
4
+ data.tar.gz: 16f4ce7dfbd8a335dfd535bca051288f8a5645a273d7aea9be8fa2d245073482
5
5
  SHA512:
6
- metadata.gz: ad7b15e82e237a726680c1eed20c0942abbcc74aca205a58681c745548e5a5c9c5048034079b88b1c8f91eddeb742d0eebbd5cc45daca057f852d25da48eb331
7
- data.tar.gz: 834577776b64caa59e9b363a8a936db9684a20ed7793a6698adbfe0d6633a0770e17f5d24b063352c3931bea1289ac53ceb0bd8c9f7b71ad3fe2f2007ef59a5f
6
+ metadata.gz: 13d1a513fecc2d4e23ee833929b05b2c93d77b4567623246f22f4ddb8f3461a2661f69a1cc73b091b08ab6474b40f929ecf4272ba54112f313ba936598761b81
7
+ data.tar.gz: 76ef5828a376dd566c1945a8655e71fe5d8a68f7a8a007a1260855a05ebcec442034712370e3e9decc5d07490ea2f9ce534b49c5c036df41e6b291868698927f
@@ -159,21 +159,96 @@ module Moxml
159
159
  # 3-4 Ruby frames collapse to the module call over the C
160
160
  # method. @native is self; every adapter method that accepts
161
161
  # a native already handles NativeNode receivers.
162
- # Extend-in-place mint (#230 stage 2): disabled by
163
- # measurement. Extending TypedData natives with the
164
- # contract modules works correctly (full battery + lm
165
- # 5422/0 under identity mode) but each extend allocates a
166
- # singleton plus per-module iclasses the consumer
167
- # pipeline regressed 4017us -> 16350us with 6x the
168
- # allocations on a 900-node walk. The per-read frame
169
- # savings (~50ns) cannot repay that mint cost. Revisit
170
- # when the binding grows klass-injection
171
- # (NativeNode.from(doc, ptr, klass:) minting the
172
- # contract-carrying subclass in C) — asked upstream in the
173
- # #230 thread. Wrappers mint through the Wrappers:: shells
174
- # meanwhile.
175
- def wrap_native(_node, _type, _context)
176
- nil
162
+ # Identity mode v2 (#230): wrapper classes SUBCLASS the
163
+ # TypedData native and include the contract modules, and
164
+ # NativeNode.from honors its receiver (klass-injection,
165
+ # 1.9.174.4+): the C wrap mints our class directly — no
166
+ # Ruby-level extend (the v1 extend mint regressed the
167
+ # pipeline 4x; this is the same TypedData wrap the base
168
+ # mint pays). @native is self; the adapter's C-surface
169
+ # bind_calls accept these receivers (they are NativeNode
170
+ # instances). The hot bare reads super into the C methods
171
+ # (exact-name = the bare-name contract).
172
+ module Identity
173
+ ELEMENT = Class.new(::Leptris::XML::NativeNode) do
174
+ include ::Moxml::Node
175
+ include ::Moxml::Element
176
+ end
177
+ TEXT = Class.new(::Leptris::XML::NativeNode) do
178
+ include ::Moxml::Node
179
+ include ::Moxml::Text
180
+ end
181
+ CDATA = Class.new(::Leptris::XML::NativeNode) do
182
+ include ::Moxml::Node
183
+ include ::Moxml::Cdata
184
+ end
185
+ COMMENT = Class.new(::Leptris::XML::NativeNode) do
186
+ include ::Moxml::Node
187
+ include ::Moxml::Comment
188
+ end
189
+ PROCESSING_INSTRUCTION = Class.new(::Leptris::XML::NativeNode) do
190
+ include ::Moxml::Node
191
+ include ::Moxml::ProcessingInstruction
192
+ end
193
+
194
+ TYPES = {
195
+ element: ELEMENT,
196
+ text: TEXT,
197
+ cdata: CDATA,
198
+ comment: COMMENT,
199
+ processing_instruction: PROCESSING_INSTRUCTION,
200
+ }.freeze
201
+
202
+ module Reads
203
+ # The C methods sit BELOW the contract modules in the
204
+ # ancestry (NativeNode is the superclass), so super
205
+ # from here would run the contract implementation and
206
+ # ADD frames. bind_call reaches the C surface
207
+ # directly; prefixed names take the contract path.
208
+ ELEMENT_CONTRACT_READ =
209
+ ::Moxml::ElementBehavior.instance_method(:[])
210
+
211
+ def [](key)
212
+ if key.is_a?(String) && !key.include?(":")
213
+ value = NN_ATTRIBUTE.bind_call(self, key)
214
+ return value unless value.is_a?(String) && entity_bearing?
215
+
216
+ return ::Moxml::Adapter::Leptris.restore_entities(value)
217
+ end
218
+
219
+ ELEMENT_CONTRACT_READ.bind_call(self, key)
220
+ end
221
+
222
+ def text
223
+ value = NN_CONTENT.bind_call(self)
224
+ value.is_a?(String) && entity_bearing? ? ::Moxml::Adapter::Leptris.restore_entities(value) : value
225
+ end
226
+ end
227
+ ELEMENT.include(Reads)
228
+ TEXT.include(Reads)
229
+ end
230
+
231
+ NATIVE_IDENTITY =
232
+ NATIVE_MUTATIONS_COHERENT &&
233
+ Gem::Version.new(::Leptris::VERSION) >= Gem::Version.new("1.9.174.4")
234
+
235
+ def wrap_native(node, type, _context)
236
+ return nil unless NATIVE_IDENTITY &&
237
+ node.is_a?(::Leptris::XML::NativeNode)
238
+
239
+ # from() registers in the shared address-keyed native
240
+ # cache, so later canonical/bulk mints hand OUR instance
241
+ # back — a native already carrying the contract IS the
242
+ # wrapper; minting again would loop per access.
243
+ return node if node.is_a?(::Moxml::Node)
244
+
245
+ klass = Identity::TYPES[type]
246
+ return nil unless klass
247
+
248
+ doc = doc_for(node)
249
+ return nil unless doc
250
+
251
+ klass.from(doc, node)
177
252
  end
178
253
 
179
254
  NATIVE_C_WALK =
data/lib/moxml/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Moxml
4
- VERSION = "0.5.49"
4
+ VERSION = "0.5.50"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: moxml
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.49
4
+ version: 0.5.50
5
5
  platform: ruby
6
6
  authors:
7
7
  - Ribose Inc.