diff --git a/NiL.JS/Core/Functions/AsyncFunction.cs b/NiL.JS/Core/Functions/AsyncFunction.cs index 3fa50d8a0..018f20e33 100644 --- a/NiL.JS/Core/Functions/AsyncFunction.cs +++ b/NiL.JS/Core/Functions/AsyncFunction.cs @@ -10,7 +10,7 @@ namespace NiL.JS.Core.Functions [Prototype(typeof(Function), true)] internal sealed class AsyncFunction : Function { - private sealed class Сontinuator + internal sealed class Сontinuator { private readonly AsyncFunction _asyncFunction; private readonly Context _context; diff --git a/NiL.JS/Core/GlobalContext.cs b/NiL.JS/Core/GlobalContext.cs index db265ad20..0b8433d3f 100644 --- a/NiL.JS/Core/GlobalContext.cs +++ b/NiL.JS/Core/GlobalContext.cs @@ -10,6 +10,7 @@ using System.Dynamic; using System.Threading.Tasks; using NiL.JS.Backward; +using System.Runtime.ExceptionServices; namespace NiL.JS.Core { @@ -511,7 +512,18 @@ public JSValue ProxyValue(object value) Task result; if (Tools.IsTaskOfT(value.GetType())) { - result = new Task(() => ProxyValue(value.GetType().GetMethod("get_Result", Type.EmptyTypes).Invoke(value, null))); + result = new Task(() => + { + try + { + return ProxyValue(value.GetType().GetMethod("get_Result", Type.EmptyTypes).Invoke(value, null)); + } + catch (TargetInvocationException e) + { + ExceptionDispatchInfo.Capture(e.InnerException).Throw(); + throw; + } + }); } else { diff --git a/NiL.JS/ExceptionHelper.cs b/NiL.JS/ExceptionHelper.cs index a291ddbf5..013119061 100644 --- a/NiL.JS/ExceptionHelper.cs +++ b/NiL.JS/ExceptionHelper.cs @@ -12,6 +12,7 @@ using NiL.JS.Statements; using System.Collections; using System.Runtime.ExceptionServices; +using NiL.JS.Core.Functions; namespace NiL.JS { @@ -29,6 +30,7 @@ internal static class ExceptionHelper typeof(ExceptionHelper), typeof(ConstructorInfo), typeof(RuntimeMethodHandle), + typeof(AsyncFunction.Сontinuator), }; internal sealed class StackTraceState @@ -58,8 +60,9 @@ public string ToString(JSException jSException) { StackFrame frame = frames[i]; var method = frame.GetMethod(); - if (method != null - && method.GetCustomAttribute(typeof(StackFrameOverrideAttribute)) != null) + if (stack is not null + && method is not null + && method.GetCustomAttribute(typeof(StackFrameOverrideAttribute)) != null) { stackTraceTexts.RemoveRange(stackTraceTexts.Count - recordsToRemove, recordsToRemove); recordsToRemove = 0; diff --git a/NiL.JS/Extensions/JSValueExtensions.cs b/NiL.JS/Extensions/JSValueExtensions.cs index ffa8663e8..a995acf66 100644 --- a/NiL.JS/Extensions/JSValueExtensions.cs +++ b/NiL.JS/Extensions/JSValueExtensions.cs @@ -170,21 +170,22 @@ public static T GetDefinedOr(this JSValue self, T defaultValue) case TypeCode.Object: { - if (self is null || self.Value is null) + var value = self.Value; + if (self is null || value is null) return default(T); - if (self.Value is Function && typeof(Delegate).IsAssignableFrom(typeof(T))) - return ((Function)self.Value).MakeDelegate(); + if (value is Function && typeof(Delegate).IsAssignableFrom(typeof(T))) + return ((Function)value).MakeDelegate(); - if (typeof(T).IsAssignableFrom(self.Value.GetType())) - return (T)self.Value; - - if (typeof(T).IsAssignableFrom(self._oValue.GetType())) + if (self._oValue is not null && typeof(T).IsAssignableFrom(self._oValue.GetType())) return (T)self._oValue; + if (typeof(T).IsAssignableFrom(value.GetType())) + return (T)value; + try { - return (T)(Tools.ConvertJStoObj(self, typeof(T), true) ?? self.Value); + return (T)(Tools.ConvertJStoObj(self, typeof(T), true) ?? value); } catch (InvalidCastException) {