leptris 1.9.255.1-arm-linux → 1.9.255.2-arm-linux

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: 7b4e0a9650a8476f55d7168393310d84a0f0bc5c4bc68afbcb8da52eb4461b88
4
- data.tar.gz: faeaa46310e9c4034055c61971d3129a0beb92e0aed1dfb3fdb316e40c5a9b83
3
+ metadata.gz: 80168d041717c899053a8f5dabedfd22b34619778a01cce151b4916e96c2fa6b
4
+ data.tar.gz: 897e220a48abfb5bd3043e9e0d58b6851e68f2a708749db9653010b26c8a2728
5
5
  SHA512:
6
- metadata.gz: 6b96a662e7a06ecb95d7a5545a7c69d91c071738362837a061017ccccf1fd11e56b05594e2a42b15fb1fe6e1c9e10bc5fc34cc3d668dc35c1d580d2694c0bdca
7
- data.tar.gz: f8ff48b9d740b085b7945cf5a0a9a2a2ccd9582589a8331e86b7f56d9a4226ce014a642bdb4b1141770b51fa00e92036496dd19d19230b7573e84478778265c0
6
+ metadata.gz: 5d232da85a0a0b1d0f77a6560264e284fb389d0e699830b50bbaf504cbeec55b2b78cd78e15d15a3606e81ddb1a4a0ab3789a253a5c0a499d21b7392813af0dd
7
+ data.tar.gz: 6c94f81436627e8f16986b448df4d0a997efbf2fb200261a46f6eb5e01e9770c0110a750c12fb7603e383d1aa45c56dda2d754bb2e3d5a24dbe56bf66dd9a2cc
@@ -627,6 +627,60 @@ static void *doc_ptr_of(VALUE document)
627
627
  /* Per-document identity caches. Both are lazily allocated on the
628
628
  * Ruby side (@x ||= {}), so replicate that here: ivar read, create
629
629
  * and store when unset. */
630
+ /* #340: per-document wrapper-klass registration. The ivar holds an
631
+ * Array of classes/nil indexed by node kind (the same shape
632
+ * install_child_klasses uses at the klass level). When an entry is
633
+ * set, the walk cache AND the create faces mint that klass
634
+ * (NativeNode subclass, TypedData path) instead of the binding
635
+ * wrapper classes — consumers receive their own contract-carrying
636
+ * nodes straight from C, and their re-wrap drops out. */
637
+ static ID id_iv_doc_klass_map;
638
+
639
+ static VALUE doc_klass_for_kind(VALUE document, int kind)
640
+ {
641
+ VALUE map = rb_ivar_get(document, id_iv_doc_klass_map);
642
+ VALUE k;
643
+ if (NIL_P(map)) return Qnil;
644
+ k = rb_ary_entry(map, (long)kind);
645
+ return RB_TYPE_P(k, T_CLASS) ? k : Qnil;
646
+ }
647
+
648
+ static VALUE mint_consumer_node(VALUE klass, VALUE document, void *ptr)
649
+ {
650
+ struct native_node *n;
651
+ VALUE node =
652
+ TypedData_Make_Struct(klass, struct native_node, &nn_type, n);
653
+ n->ptr = ptr;
654
+ n->document = document;
655
+ rb_hash_aset(native_cache_of(document),
656
+ ULL2NUM((uint64_t)(uintptr_t)ptr), node);
657
+ return node;
658
+ }
659
+
660
+ static VALUE nf_register_doc_klasses(VALUE self, VALUE document, VALUE map)
661
+ {
662
+ long i, len;
663
+ (void)self;
664
+ resolve_binding_classes();
665
+ Check_Type(map, T_ARRAY);
666
+ len = RARRAY_LEN(map);
667
+ if (len > 5)
668
+ rb_raise(rb_eArgError,
669
+ "wrapper klasses: Array of classes/nil indexed by "
670
+ "node kind (element, text, comment, cdata, pi)");
671
+ for (i = 0; i < len; i++) {
672
+ VALUE k = rb_ary_entry(map, i);
673
+ if (!NIL_P(k) &&
674
+ !(RB_TYPE_P(k, T_CLASS) &&
675
+ RTEST(rb_class_inherited_p(k, c_native_node))))
676
+ rb_raise(rb_eTypeError,
677
+ "wrapper klasses entries must be nil or a "
678
+ "Leptris::XML::NativeNode subclass");
679
+ }
680
+ rb_ivar_set(document, id_iv_doc_klass_map, map);
681
+ return document;
682
+ }
683
+
630
684
  static VALUE native_cache_of(VALUE document)
631
685
  {
632
686
  VALUE cache = rb_ivar_get(document, id_iv_native_cache);
@@ -877,7 +931,20 @@ static VALUE trav_wrapper_for(struct trav_state *st, void *node_ptr,
877
931
  int kind)
878
932
  {
879
933
  VALUE key = ULL2NUM((uint64_t)(uintptr_t)node_ptr);
880
- VALUE node = rb_hash_aref(st->cache, key);
934
+ VALUE node;
935
+ VALUE ck = doc_klass_for_kind(st->document, kind);
936
+
937
+ /* #340 klass-parameterized walk cache: registered consumer
938
+ * klasses mint (and identity-cache) through the TypedData
939
+ * path — nodes arrive already being the consumer's wrapper. */
940
+ if (!NIL_P(ck)) {
941
+ VALUE ncache = native_cache_of(st->document);
942
+ node = rb_hash_aref(ncache, key);
943
+ if (!NIL_P(node)) return node;
944
+ return mint_consumer_node(ck, st->document, node_ptr);
945
+ }
946
+
947
+ node = rb_hash_aref(st->cache, key);
881
948
  if (!NIL_P(node)) return node;
882
949
 
883
950
  node = rb_obj_alloc(binding_klass_for(kind));
@@ -2290,20 +2357,15 @@ static VALUE nf_plan_structs_typed_p(VALUE self)
2290
2357
  * C->C dlsym dispatches (create_child = create+attach in one
2291
2358
  * engine call; set_attr per attribute). Returns the new node's
2292
2359
  * address for wrapper minting. */
2293
- static VALUE nf_create_element_with_attrs(VALUE self, VALUE document,
2294
- VALUE parent_addr, VALUE name,
2295
- VALUE attrs)
2296
- {
2297
- void *doc_ptr = NIL_P(document)
2298
- ? NULL
2299
- : (void *)(uintptr_t)NUM2ULL(document);
2300
- void *parent = NIL_P(parent_addr)
2301
- ? NULL
2302
- : (void *)(uintptr_t)NUM2ULL(parent_addr);
2303
- const char *cname = StringValueCStr(name);
2304
-
2305
- if (f_elem_new_with_attrs && doc_ptr && parent && RARRAY_LEN(attrs) > 0 &&
2306
- RARRAY_LEN(attrs) % 2 == 0) {
2360
+ /* Creation core shared by the raw-address face and the #340
2361
+ * wrapper-returning variant: single-crossing arena create +
2362
+ * attributes when the engine has #1344, else create + per-pair
2363
+ * sets. Returns the raw element pointer (NULL on failure). */
2364
+ static void *create_elem_core(void *doc_ptr, void *parent,
2365
+ const char *cname, VALUE attrs)
2366
+ {
2367
+ if (f_elem_new_with_attrs && doc_ptr && parent &&
2368
+ RARRAY_LEN(attrs) > 0 && RARRAY_LEN(attrs) % 2 == 0) {
2307
2369
  /* Engine single-crossing construction (1.9.236+): arena
2308
2370
  * create + all attributes with no per-attr calls at all. */
2309
2371
  long n = RARRAY_LEN(attrs) / 2;
@@ -2319,15 +2381,15 @@ static VALUE nf_create_element_with_attrs(VALUE self, VALUE document,
2319
2381
  }
2320
2382
  void *elem = f_elem_new_with_attrs(doc_ptr, cname, names,
2321
2383
  values, n);
2322
- if (!elem) return Qnil;
2384
+ if (!elem) return NULL;
2323
2385
  /* The face creates a floating element owned by the
2324
2386
  * document — append under the parent afterwards. */
2325
- if (parent) f_append_child(parent, elem);
2326
- return ULL2NUM((uintptr_t)elem);
2387
+ f_append_child(parent, elem);
2388
+ return elem;
2327
2389
  }
2328
2390
 
2329
2391
  void *elem = parent ? f_create_child(parent, cname) : NULL;
2330
- if (!elem) return Qnil;
2392
+ if (!elem) return NULL;
2331
2393
 
2332
2394
  long i, n = RARRAY_LEN(attrs);
2333
2395
  for (i = 0; i + 1 < n; i += 2) {
@@ -2335,7 +2397,65 @@ static VALUE nf_create_element_with_attrs(VALUE self, VALUE document,
2335
2397
  VALUE av = RARRAY_AREF(attrs, i + 1);
2336
2398
  f_set_attr(elem, StringValueCStr(an), StringValueCStr(av));
2337
2399
  }
2338
- return ULL2NUM((uintptr_t)elem);
2400
+ return elem;
2401
+ }
2402
+
2403
+ static VALUE nf_create_element_with_attrs(VALUE self, VALUE document,
2404
+ VALUE parent_addr, VALUE name,
2405
+ VALUE attrs)
2406
+ {
2407
+ void *doc_ptr = NIL_P(document)
2408
+ ? NULL
2409
+ : (void *)(uintptr_t)NUM2ULL(document);
2410
+ void *parent = NIL_P(parent_addr)
2411
+ ? NULL
2412
+ : (void *)(uintptr_t)NUM2ULL(parent_addr);
2413
+ void *elem = create_elem_core(doc_ptr, parent,
2414
+ StringValueCStr(name), attrs);
2415
+ return elem ? ULL2NUM((uintptr_t)elem) : Qnil;
2416
+ }
2417
+
2418
+ /* #340 construction registration: create + attach + attributes in
2419
+ * one crossing AND mint the wrapper C-side — the registered
2420
+ * consumer klass when one is installed for elements (TypedData
2421
+ * path + native-cache identity), else the binding Element minted
2422
+ * exactly like nf_create_binding_element. The caller receives a
2423
+ * contract-carrying node straight from the crossing; no separate
2424
+ * Node.wrap, no consumer re-wrap. */
2425
+ static VALUE nf_create_element_with_attrs_wrapped(
2426
+ VALUE self, VALUE document, VALUE parent_addr, VALUE name,
2427
+ VALUE attrs)
2428
+ {
2429
+ void *doc_ptr = doc_ptr_of(document);
2430
+ void *parent = NIL_P(parent_addr)
2431
+ ? NULL
2432
+ : (void *)(uintptr_t)NUM2ULL(parent_addr);
2433
+ void *elem = create_elem_core(doc_ptr, parent,
2434
+ StringValueCStr(name), attrs);
2435
+ VALUE ck, key, node, cache;
2436
+
2437
+ (void)self;
2438
+ if (!elem) return Qnil;
2439
+ resolve_binding_classes();
2440
+ ck = doc_klass_for_kind(document, 0 /* element */);
2441
+ if (!NIL_P(ck))
2442
+ return mint_consumer_node(ck, document, elem);
2443
+
2444
+ key = ULL2NUM((uint64_t)(uintptr_t)elem);
2445
+ cache = binding_cache_of(document);
2446
+ node = rb_hash_aref(cache, key);
2447
+ if (!NIL_P(node)) return node;
2448
+ node = rb_obj_alloc(c_b_element);
2449
+ rb_iv_set(node, "@c_address", key);
2450
+ rb_iv_set(node, "@document", document);
2451
+ rb_iv_set(node, "@parent", Qnil);
2452
+ rb_iv_set(node, "@structure_memoizable", Qtrue);
2453
+ rb_iv_set(node, "@native_fast", Qtrue);
2454
+ rb_iv_set(node, "@pub_document", document);
2455
+ rb_iv_set(node, "@addr_reads_fast", Qtrue);
2456
+ rb_iv_set(node, "@node_type", INT2FIX(0));
2457
+ rb_hash_aset(cache, key, node);
2458
+ return node;
2339
2459
  }
2340
2460
 
2341
2461
  static VALUE nf_attribute_rows(VALUE self, VALUE document, VALUE addr)
@@ -2844,6 +2964,7 @@ LEPTRIS_INIT_EXPORT void Init_native(void)
2844
2964
  id_iv_nn_attrs = rb_intern("@nn_attrs");
2845
2965
  id_iv_nn_attrs_ver = rb_intern("@nn_attrs_ver");
2846
2966
  id_child_klasses = rb_intern("@nn_child_klasses");
2967
+ id_iv_doc_klass_map = rb_intern("@doc_klass_map");
2847
2968
  id_iv_doc_handle = rb_intern("@doc_handle");
2848
2969
  id_freed_new = rb_intern("new");
2849
2970
  id_alive = rb_intern("alive");
@@ -2954,6 +3075,11 @@ LEPTRIS_INIT_EXPORT void Init_native(void)
2954
3075
  nf_attribute_rows, 2);
2955
3076
  rb_define_module_function(m_native, "create_element_with_attrs",
2956
3077
  nf_create_element_with_attrs, 4);
3078
+ rb_define_module_function(m_native, "register_doc_klasses",
3079
+ nf_register_doc_klasses, 2);
3080
+ rb_define_module_function(m_native,
3081
+ "create_element_with_attrs_wrapped",
3082
+ nf_create_element_with_attrs_wrapped, 4);
2957
3083
  rb_define_module_function(m_native, "plan_structs_typed?",
2958
3084
  nf_plan_structs_typed_p, 0);
2959
3085
  rb_define_module_function(m_native, "doc_handle_attach",
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Leptris
4
- VERSION = "1.9.255.1"
4
+ VERSION = "1.9.255.2"
5
5
  end
Binary file
@@ -75,6 +75,18 @@ class Leptris::XML::Document
75
75
  Leptris::XML::NativeNode.from(self, r.c_ptr)
76
76
  end
77
77
 
78
+ # #340: per-kind wrapper-klass registration for THIS document.
79
+ # map is an Array of classes/nil indexed by node kind (element,
80
+ # text, comment, cdata, pi) — the same shape
81
+ # NativeNode.install_child_klasses uses. Once registered, the C
82
+ # walk cache (trav/visit) and the create faces mint those
83
+ # klasses directly (TypedData path, native-cache identity), so
84
+ # consumers receive their own contract-carrying nodes straight
85
+ # from the crossing with no re-wrap.
86
+ def register_wrapper_klasses(map)
87
+ Leptris::XML::Native.register_doc_klasses(self, map)
88
+ end
89
+
78
90
  # Builder factories that return NativeNodes (#149): one C call
79
91
  # and a TypedData wrap — no FFI::Pointer, no wrap_fresh path.
80
92
  def native_create_element(name)
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: leptris
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.9.255.1
4
+ version: 1.9.255.2
5
5
  platform: arm-linux
6
6
  authors:
7
7
  - Ribose Inc.