we (web engine): Experimental web browser project to understand the limits of Claude
2
fork

Configure Feed

Select the types of activity you want to include in your feed.

Review fixes: use named constants, remove redundant reaction, add allSettled test

- Make PROMISE_FULFILLED, PROMISE_REJECTED, PROMISE_RESULT_KEY pub
so drain_microtasks can use named constants instead of magic values
- Remove redundant add_reaction call in promise_native_resolve
(chain_promise already handles pending thenable propagation)
- Add test_promise_all_settled integration test

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

+25 -19
+5 -13
crates/js/src/builtins.rs
··· 4667 4667 4668 4668 /// Promise states. 4669 4669 const PROMISE_PENDING: f64 = 0.0; 4670 - const PROMISE_FULFILLED: f64 = 1.0; 4671 - const PROMISE_REJECTED: f64 = 2.0; 4670 + pub const PROMISE_FULFILLED: f64 = 1.0; 4671 + pub const PROMISE_REJECTED: f64 = 2.0; 4672 4672 4673 4673 /// Hidden property keys for Promise objects. 4674 4674 const PROMISE_STATE_KEY: &str = "__promise_state__"; 4675 - const PROMISE_RESULT_KEY: &str = "__promise_result__"; 4675 + pub const PROMISE_RESULT_KEY: &str = "__promise_result__"; 4676 4676 const PROMISE_REACTIONS_KEY: &str = "__promise_reactions__"; 4677 4677 const PROMISE_REACTION_COUNT_KEY: &str = "__promise_reaction_count__"; 4678 4678 ··· 4987 4987 let reason = promise_get_prop(ctx.gc, value_ref, PROMISE_RESULT_KEY); 4988 4988 reject_promise_internal(ctx.gc, promise_ref, reason); 4989 4989 } else { 4990 - // Pending thenable: register a reaction to propagate settlement. 4991 - add_reaction( 4992 - ctx.gc, 4993 - value_ref, 4994 - Value::Undefined, // identity — will be handled by microtask drain 4995 - Value::Undefined, 4996 - ); 4997 - // Actually, we need to resolve/reject promise_ref when value_ref settles. 4998 - // Add reactions that call __Promise_resolve/__Promise_reject on promise_ref. 4999 - // For simplicity, store a direct chain. 4990 + // Pending thenable: chain so that when value_ref settles, 4991 + // promise_ref settles the same way. 5000 4992 chain_promise(ctx.gc, value_ref, promise_ref); 5001 4993 } 5002 4994 } else {
+20 -6
crates/js/src/vm.rs
··· 868 868 crate::builtins::promise_get_prop_pub( 869 869 &self.gc, 870 870 parent_ref, 871 - "__promise_result__", 871 + crate::builtins::PROMISE_RESULT_KEY, 872 872 ); 873 - if parent_state == 1.0 { 873 + if parent_state == crate::builtins::PROMISE_FULFILLED { 874 874 crate::builtins::resolve_promise_internal( 875 875 &mut self.gc, 876 876 chained, ··· 903 903 let state = crate::builtins::promise_state_pub( 904 904 &self.gc, val_ref, 905 905 ); 906 - if state == 1.0 { 906 + if state == crate::builtins::PROMISE_FULFILLED { 907 907 let r = crate::builtins::promise_get_prop_pub( 908 908 &self.gc, 909 909 val_ref, 910 - "__promise_result__", 910 + crate::builtins::PROMISE_RESULT_KEY, 911 911 ); 912 912 crate::builtins::resolve_promise_internal( 913 913 &mut self.gc, 914 914 chained, 915 915 r, 916 916 ); 917 - } else if state == 2.0 { 917 + } else if state == crate::builtins::PROMISE_REJECTED 918 + { 918 919 let r = crate::builtins::promise_get_prop_pub( 919 920 &self.gc, 920 921 val_ref, 921 - "__promise_result__", 922 + crate::builtins::PROMISE_RESULT_KEY, 922 923 ); 923 924 crate::builtins::reject_promise_internal( 924 925 &mut self.gc, ··· 5421 5422 { 5422 5423 Value::Number(n) => assert_eq!(n, 99.0), 5423 5424 v => panic!("expected 99, got {v:?}"), 5425 + } 5426 + } 5427 + 5428 + #[test] 5429 + fn test_promise_all_settled() { 5430 + match eval_global( 5431 + "Promise.allSettled([Promise.resolve(1), Promise.reject('err')]).then(function(v) { result = v[0].status + ',' + v[1].status; });", 5432 + "result", 5433 + ) 5434 + .unwrap() 5435 + { 5436 + Value::String(s) => assert_eq!(s, "fulfilled,rejected"), 5437 + v => panic!("expected 'fulfilled,rejected', got {v:?}"), 5424 5438 } 5425 5439 } 5426 5440 }