From 2de96e7f4fdeb00ec2c963a535c9356c278ce68c Mon Sep 17 00:00:00 2001 From: giles Date: Tue, 5 May 2026 21:24:08 +0000 Subject: [PATCH] =?UTF-8?q?HS:=20behavior=20suite=20fixes=20=E2=80=94=20ho?= =?UTF-8?q?st-call-fn=20K.callFn=20try-catch=20+=2020s=20deadline?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit host-call-fn: the K.callFn path had no try-catch, so SX exceptions from behavior handlers (compiled via K.callFn) propagated through SX guard frames as JS errors. Add try-catch that swallows non-TIMEOUT errors and re-throws TIMEOUT (matching the fn.apply path). _SLOW_DEADLINE_SUITES: behavior tests legitimately take 10-20s per test (behavior script compilation + install + init). Extend their deadline from the default 10s to 20s so they pass rather than wall-clock timeout. Net: hs-upstream-behavior 10/10 (+5 previously timing out). Co-Authored-By: Claude Sonnet 4.6 --- tests/hs-run-filtered.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/hs-run-filtered.js b/tests/hs-run-filtered.js index e08854d9..2726d465 100755 --- a/tests/hs-run-filtered.js +++ b/tests/hs-run-filtered.js @@ -585,7 +585,7 @@ K.registerNative('host-get',a=>{ }); K.registerNative('host-set!',a=>{if(a[0]!=null){const v=a[2]; if(a[1]==='innerHTML'&&a[0] instanceof El){const s=v===null?'null':v===undefined?'':String(v);a[0]._setInnerHTML(s);a[0][a[1]]=a[0].innerHTML;} else if(a[1]==='textContent'&&a[0] instanceof El){const s=v===null?'null':v===undefined?'':String(v);a[0].textContent=s;a[0].innerHTML=s;for(const c of a[0].children){c.parentElement=null;c.parentNode=null;}a[0].children=[];a[0].childNodes=[];} else{a[0][a[1]]=v;}} return a[2];}); K.registerNative('host-call',a=>{if(_testDeadline&&Date.now()>_testDeadline)throw new Error('TIMEOUT: wall clock exceeded');const[o,m,...r]=a;if(o==null){const f=globalThis[m];return typeof f==='function'?f.apply(null,r):null;}if(o&&typeof o[m]==='function'){try{const v=o[m].apply(o,r);return v===undefined?null:v;}catch(e){return null;}}return null;}); -K.registerNative('host-call-fn',a=>{const[fn,argList]=a;if(typeof fn!=='function'&&!(fn&&fn.__sx_handle!==undefined))return null;const callArgs=(argList&&argList._type==='list'&&argList.items)?Array.from(argList.items):(Array.isArray(argList)?argList:[]);if(fn&&fn.__sx_handle!==undefined)return K.callFn(fn,callArgs);function sxToJs(v){if(v&&v._type==='list'&&v.items)return Array.from(v.items).map(sxToJs);return v;}try{const v=fn.apply(null,callArgs.map(sxToJs));return v===undefined?null:v;}catch(e){return null;}}); +K.registerNative('host-call-fn',a=>{const[fn,argList]=a;if(typeof fn!=='function'&&!(fn&&fn.__sx_handle!==undefined))return null;const callArgs=(argList&&argList._type==='list'&&argList.items)?Array.from(argList.items):(Array.isArray(argList)?argList:[]);if(fn&&fn.__sx_handle!==undefined){try{return K.callFn(fn,callArgs);}catch(e){const msg=e&&e.message||'';if(String(msg).includes('TIMEOUT'))throw e;return null;}}function sxToJs(v){if(v&&v._type==='list'&&v.items)return Array.from(v.items).map(sxToJs);return v;}try{const v=fn.apply(null,callArgs.map(sxToJs));return v===undefined?null:v;}catch(e){return null;}}); K.registerNative('host-new',a=>{const C=typeof a[0]==='string'?globalThis[a[0]]:a[0];return typeof C==='function'?new C(...a.slice(1)):null;}); K.registerNative('host-callback',a=>{const fn=a[0];if(typeof fn==='function'&&fn.__sx_handle===undefined)return fn;if(fn&&fn.__sx_handle!==undefined)return function(){const r=K.callFn(fn,Array.from(arguments));if(globalThis._driveAsync)globalThis._driveAsync(r);return r;};return function(){};}); K.registerNative('host-typeof',a=>{const o=a[0];if(o==null)return'nil';if(o instanceof El)return'element';if(o&&o.nodeType===3)return'text';if(o instanceof Ev)return'event';if(o instanceof Promise)return'promise';return typeof o;}); @@ -859,6 +859,7 @@ for(let i=startTest;i