git.delta.rocks / jrsonnet / refs/commits / cfa49ab1b7b8

difftreelog

perf move std.object[Keys]Values[All] to native

Yaroslav Bolyukin2023-08-10parent: #be6e85a.patch.diff
in: master

6 files changed

modifiedcrates/jrsonnet-evaluator/src/arr/spec.rsdiffbeforeafterboth
9 error::ErrorKind::InfiniteRecursionDetected,9 error::ErrorKind::InfiniteRecursionDetected,
10 evaluate,10 evaluate,
11 function::FuncVal,11 function::FuncVal,
12 typed::Typed,
12 val::{StrValue, ThunkValue},13 val::{StrValue, ThunkValue},
13 Context, Error, Result, Thunk, Val,14 Context, Error, ObjValue, Result, Thunk, Val,
14};15};
1516
16pub trait ArrayLike: Any + Trace + Debug {17pub trait ArrayLike: Any + Trace + Debug {
577 }578 }
578}579}
580
581#[derive(Trace, Debug)]
582pub struct PickObjectValues {
583 obj: ObjValue,
584 keys: Vec<IStr>,
585}
586
587impl PickObjectValues {
588 pub fn new(obj: ObjValue, keys: Vec<IStr>) -> Self {
589 Self { obj, keys }
590 }
591}
592
593impl ArrayLike for PickObjectValues {
594 fn len(&self) -> usize {
595 self.keys.len()
596 }
597
598 fn get(&self, index: usize) -> Result<Option<Val>> {
599 let Some(key) = self.keys.get(index) else {
600 return Ok(None);
601 };
602 Ok(Some(self.obj.get_or_bail(key.clone())?))
603 }
604
605 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {
606 let Some(key) = self.keys.get(index) else {
607 return None;
608 };
609 Some(self.obj.get_lazy_or_bail(key.clone()))
610 }
611
612 fn get_cheap(&self, _index: usize) -> Option<Val> {
613 None
614 }
615
616 fn is_cheap(&self) -> bool {
617 false
618 }
619}
620
621#[derive(Trace, Debug)]
622pub struct PickObjectKeyValues {
623 obj: ObjValue,
624 keys: Vec<IStr>,
625}
626
627impl PickObjectKeyValues {
628 pub fn new(obj: ObjValue, keys: Vec<IStr>) -> Self {
629 Self { obj, keys }
630 }
631}
632
633#[derive(Typed)]
634pub struct KeyValue {
635 key: IStr,
636 value: Thunk<Val>,
637}
638
639impl ArrayLike for PickObjectKeyValues {
640 fn len(&self) -> usize {
641 self.keys.len()
642 }
643
644 fn get(&self, index: usize) -> Result<Option<Val>> {
645 let Some(key) = self.keys.get(index) else {
646 return Ok(None);
647 };
648 Ok(Some(
649 KeyValue::into_untyped(KeyValue {
650 key: key.clone(),
651 value: Thunk::evaluated(self.obj.get_or_bail(key.clone())?),
652 })
653 .expect("convertible"),
654 ))
655 }
656
657 fn get_lazy(&self, index: usize) -> Option<Thunk<Val>> {
658 let Some(key) = self.keys.get(index) else {
659 return None;
660 };
661 // Nothing can fail in the key part, yet value is still
662 // lazy-evaluated
663 Some(Thunk::evaluated(
664 KeyValue::into_untyped(KeyValue {
665 key: key.clone(),
666 value: self.obj.get_lazy_or_bail(key.clone()),
667 })
668 .expect("convertible"),
669 ))
670 }
671
672 fn get_cheap(&self, _index: usize) -> Option<Val> {
673 None
674 }
675
676 fn is_cheap(&self) -> bool {
677 false
678 }
679}
579680
modifiedcrates/jrsonnet-evaluator/src/obj.rsdiffbeforeafterboth
12use rustc_hash::FxHashMap;12use rustc_hash::FxHashMap;
1313
14use crate::{14use crate::{
15 arr::{PickObjectKeyValues, PickObjectValues},
15 error::{Error, ErrorKind::*},16 error::{suggest_object_fields, Error, ErrorKind::*},
16 function::CallLocation,17 function::CallLocation,
17 gc::{GcHashMap, GcHashSet, TraceBox},18 gc::{GcHashMap, GcHashSet, TraceBox},
18 operator::evaluate_add_op,19 operator::evaluate_add_op,
19 tb, throw,20 tb, throw,
20 val::ThunkValue,21 val::{ArrValue, ThunkValue},
21 MaybeUnbound, Result, State, Thunk, Unbound, Val,22 MaybeUnbound, Result, State, Thunk, Unbound, Val,
22};23};
2324
398 self.0.get_for(key, this)399 self.0.get_for(key, this)
399 }400 }
401
402 pub fn get_or_bail(&self, key: IStr) -> Result<Val> {
403 let Some(value) = self.get(key.clone())? else {
404 let suggestions = suggest_object_fields(self, key.clone());
405 throw!(NoSuchField(key, suggestions))
406 };
407 Ok(value)
408 }
400409
401 fn get_raw(&self, key: IStr, this: ObjValue) -> Result<Option<Val>> {410 fn get_raw(&self, key: IStr, this: ObjValue) -> Result<Option<Val>> {
402 self.0.get_for_uncached(key, this)411 self.0.get_for_uncached(key, this)
452 key,461 key,
453 }))462 }))
454 }463 }
464 pub fn get_lazy_or_bail(&self, key: IStr) -> Thunk<Val> {
465 #[derive(Trace)]
466 struct ThunkGet {
467 obj: ObjValue,
468 key: IStr,
469 }
470 impl ThunkValue for ThunkGet {
471 type Output = Val;
472
473 fn get(self: Box<Self>) -> Result<Self::Output> {
474 Ok(self.obj.get_or_bail(self.key)?)
475 }
476 }
477
478 Thunk::new(ThunkGet {
479 obj: self.clone(),
480 key,
481 })
482 }
455 pub fn ptr_eq(a: &Self, b: &Self) -> bool {483 pub fn ptr_eq(a: &Self, b: &Self) -> bool {
456 Cc::ptr_eq(&a.0, &b.0)484 Cc::ptr_eq(&a.0, &b.0)
457 }485 }
529 preserve_order,557 preserve_order,
530 )558 )
531 }559 }
560 pub fn values_ex(
561 &self,
562 include_hidden: bool,
563 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,
564 ) -> ArrValue {
565 ArrValue::new(PickObjectValues::new(
566 self.clone(),
567 self.fields_ex(
568 include_hidden,
569 #[cfg(feature = "exp-preserve-order")]
570 preserve_order,
571 ),
572 ))
573 }
574 pub fn values(&self, #[cfg(feature = "exp-preserve-order")] preserve_order: bool) -> ArrValue {
575 self.values_ex(
576 false,
577 #[cfg(feature = "exp-preserve-order")]
578 preserve_order,
579 )
580 }
581 pub fn key_values_ex(
582 &self,
583 include_hidden: bool,
584 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,
585 ) -> ArrValue {
586 ArrValue::new(PickObjectKeyValues::new(
587 self.clone(),
588 self.fields_ex(
589 include_hidden,
590 #[cfg(feature = "exp-preserve-order")]
591 preserve_order,
592 ),
593 ))
594 }
595 pub fn key_values(
596 &self,
597 #[cfg(feature = "exp-preserve-order")] preserve_order: bool,
598 ) -> ArrValue {
599 self.key_values_ex(
600 false,
601 #[cfg(feature = "exp-preserve-order")]
602 preserve_order,
603 )
604 }
532}605}
533606
534impl OopObject {607impl OopObject {
modifiedcrates/jrsonnet-evaluator/src/val.rsdiffbeforeafterboth
1use std::{1use std::{
2 cell::RefCell,2 cell::RefCell,
3 fmt::{self, Debug, Display},3 fmt::{self, Debug, Display},
4 hash::Hasher,
5 mem::replace,4 mem::replace,
6 rc::Rc,5 rc::Rc,
7};6};
87
9use jrsonnet_gcmodule::{Cc, Trace};8use jrsonnet_gcmodule::{Cc, Trace};
10use jrsonnet_interner::IStr;9use jrsonnet_interner::IStr;
11use jrsonnet_types::ValType;10use jrsonnet_types::ValType;
12use rustc_hash::FxHasher;
1311
14pub use crate::arr::{ArrValue, ArrayLike};12pub use crate::arr::{ArrValue, ArrayLike};
15use crate::{13use crate::{
50 pub fn errored(e: Error) -> Self {48 pub fn errored(e: Error) -> Self {
51 Self(Cc::new(RefCell::new(ThunkInner::Errored(e))))49 Self(Cc::new(RefCell::new(ThunkInner::Errored(e))))
52 }50 }
51 pub fn result(res: Result<T, Error>) -> Self {
52 match res {
53 Ok(o) => Self::evaluated(o),
54 Err(e) => Self::errored(e),
55 }
56 }
53}57}
5458
55impl<T> Thunk<T>59impl<T> Thunk<T>
modifiedcrates/jrsonnet-stdlib/src/lib.rsdiffbeforeafterboth
138 ("base64DecodeBytes", builtin_base64_decode_bytes::INST),138 ("base64DecodeBytes", builtin_base64_decode_bytes::INST),
139 // Objects139 // Objects
140 ("objectFieldsEx", builtin_object_fields_ex::INST),140 ("objectFieldsEx", builtin_object_fields_ex::INST),
141 ("objectValues", builtin_object_values::INST),
142 ("objectValuesAll", builtin_object_values_all::INST),
143 ("objectKeysValues", builtin_object_keys_values::INST),
144 ("objectKeysValuesAll", builtin_object_keys_values_all::INST),
141 ("objectHasEx", builtin_object_has_ex::INST),145 ("objectHasEx", builtin_object_has_ex::INST),
142 ("objectRemoveKey", builtin_object_remove_key::INST),146 ("objectRemoveKey", builtin_object_remove_key::INST),
143 // Manifest147 // Manifest
modifiedcrates/jrsonnet-stdlib/src/objects.rsdiffbeforeafterboth
1use jrsonnet_evaluator::{1use jrsonnet_evaluator::{
2 function::builtin,2 function::builtin,
3 val::{StrValue, Val},3 val::{ArrValue, StrValue, Val},
4 IStr, ObjValue, ObjValueBuilder,4 IStr, ObjValue, ObjValueBuilder,
5};5};
66
23 .collect::<Vec<_>>()23 .collect::<Vec<_>>()
24}24}
25
26pub fn builtin_object_values_ex(
27 o: ObjValue,
28 include_hidden: bool,
29 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
30) -> ArrValue {
31 #[cfg(feature = "exp-preserve-order")]
32 let preserve_order = preserve_order.unwrap_or(false);
33 o.values_ex(
34 include_hidden,
35 #[cfg(feature = "exp-preserve-order")]
36 preserve_order,
37 )
38}
39#[builtin]
40pub fn builtin_object_values(
41 o: ObjValue,
42 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
43) -> ArrValue {
44 builtin_object_values_ex(
45 o,
46 false,
47 #[cfg(feature = "exp-preserve-order")]
48 preserve_order,
49 )
50}
51#[builtin]
52pub fn builtin_object_values_all(
53 o: ObjValue,
54 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
55) -> ArrValue {
56 builtin_object_values_ex(
57 o,
58 true,
59 #[cfg(feature = "exp-preserve-order")]
60 preserve_order,
61 )
62}
63
64pub fn builtin_object_keys_values_ex(
65 o: ObjValue,
66 include_hidden: bool,
67 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
68) -> ArrValue {
69 #[cfg(feature = "exp-preserve-order")]
70 let preserve_order = preserve_order.unwrap_or(false);
71 o.key_values_ex(
72 include_hidden,
73 #[cfg(feature = "exp-preserve-order")]
74 preserve_order,
75 )
76}
77#[builtin]
78pub fn builtin_object_keys_values(
79 o: ObjValue,
80 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
81) -> ArrValue {
82 builtin_object_keys_values_ex(
83 o,
84 false,
85 #[cfg(feature = "exp-preserve-order")]
86 preserve_order,
87 )
88}
89#[builtin]
90pub fn builtin_object_keys_values_all(
91 o: ObjValue,
92 #[cfg(feature = "exp-preserve-order")] preserve_order: Option<bool>,
93) -> ArrValue {
94 builtin_object_keys_values_ex(
95 o,
96 true,
97 #[cfg(feature = "exp-preserve-order")]
98 preserve_order,
99 )
100}
25101
26#[builtin]102#[builtin]
27pub fn builtin_object_has_ex(obj: ObjValue, fname: IStr, hidden: bool) -> bool {103pub fn builtin_object_has_ex(obj: ObjValue, fname: IStr, hidden: bool) -> bool {
modifiedcrates/jrsonnet-stdlib/src/std.jsonnetdiffbeforeafterboth
268 objectHasAll(o, f)::268 objectHasAll(o, f)::
269 std.objectHasEx(o, f, true),269 std.objectHasEx(o, f, true),
270270
271 objectValues(o)::
272 [o[k] for k in std.objectFields(o)],
273
274 objectValuesAll(o)::
275 [o[k] for k in std.objectFieldsAll(o)],
276
277 objectKeysValues(o)::
278 [{ key: k, value: o[k] } for k in std.objectFields(o)],
279
280 objectKeysValuesAll(o)::
281 [{ key: k, value: o[k] } for k in std.objectFieldsAll(o)],
282
283 resolvePath(f, r)::271 resolvePath(f, r)::
284 local arr = std.split(f, '/');272 local arr = std.split(f, '/');
285 std.join('/', std.makeArray(std.length(arr) - 1, function(i) arr[i]) + [r]),273 std.join('/', std.makeArray(std.length(arr) - 1, function(i) arr[i]) + [r]),