Skip to content

Commit ef34019

Browse files
committed
Significantly reduce recursion limit
1 parent 7fabeb5 commit ef34019

File tree

8 files changed

+190
-230
lines changed

8 files changed

+190
-230
lines changed

NiL.JS/Core/Functions/MethodProxy.cs

Lines changed: 25 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -345,25 +345,18 @@ private WrapperDelegate makeFastWrapper(MethodInfo methodInfo)
345345
if (methodInfo.ReturnType == typeof(void))
346346
tree = Expression.Block(tree, Expression.Constant(null));
347347

348-
try
349-
{
350-
return Expression
351-
.Lambda<WrapperDelegate>(
352-
Expression.Convert(tree, typeof(object)),
353-
methodInfo.Name,
354-
new[]
355-
{
356-
target,
357-
context,
358-
arguments,
359-
argumentsObjectPrm
360-
})
361-
.Compile();
362-
}
363-
catch
364-
{
365-
throw;
366-
}
348+
return Expression
349+
.Lambda<WrapperDelegate>(
350+
Expression.Convert(tree, typeof(object)),
351+
methodInfo.Name,
352+
new[]
353+
{
354+
target,
355+
context,
356+
arguments,
357+
argumentsObjectPrm
358+
})
359+
.Compile();
367360
}
368361

369362
private WrapperDelegate makeFastWrapper(ConstructorInfo constructorInfo)
@@ -429,25 +422,18 @@ private WrapperDelegate makeFastWrapper(ConstructorInfo constructorInfo)
429422
}
430423
}
431424

432-
try
433-
{
434-
return Expression
435-
.Lambda<WrapperDelegate>(
436-
Expression.Convert(tree, typeof(object)),
437-
constructorInfo.DeclaringType.Name,
438-
new[]
439-
{
440-
target,
441-
context,
442-
arguments,
443-
argumentsObjectPrm
444-
})
445-
.Compile();
446-
}
447-
catch
448-
{
449-
throw;
450-
}
425+
return Expression
426+
.Lambda<WrapperDelegate>(
427+
Expression.Convert(tree, typeof(object)),
428+
constructorInfo.DeclaringType.Name,
429+
new[]
430+
{
431+
target,
432+
context,
433+
arguments,
434+
argumentsObjectPrm
435+
})
436+
.Compile();
451437
}
452438

453439
private object callRestPrmsConverter(Context initiator, Expressions.Expression[] arguments, Arguments argumentsObject)
@@ -701,9 +687,8 @@ public override Delegate MakeDelegate(Type delegateType)
701687
}
702688
catch
703689
{
690+
return base.MakeDelegate(delegateType);
704691
}
705-
706-
return base.MakeDelegate(delegateType);
707692
}
708693
#endif
709694

NiL.JS/Core/JSException.cs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using System;
2+
using System.Collections.Generic;
23
using NiL.JS.BaseLibrary;
34
using NiL.JS.Core.Interop;
45

@@ -52,7 +53,7 @@ public JSException(Error avatar, Exception innerException)
5253
Error = Context.CurrentGlobalContext.ProxyValue(avatar);
5354
}
5455

55-
public override string StackTrace => _stackTraceOverride ?? base.StackTrace;
56+
public override string StackTrace => (_stackTraceOverride ??= getStackTrace()) ?? base.StackTrace;
5657

5758
public override string Message
5859
{
@@ -80,9 +81,35 @@ public override string Message
8081
}
8182
}
8283

83-
internal void InternalSetStackTrace(string stackTrace)
84+
private string getStackTrace()
8485
{
85-
_stackTraceOverride = stackTrace;
86+
var stackTrace = new List<string>();
87+
88+
var innerEx = this as Exception;
89+
while (innerEx != null)
90+
{
91+
var isOurException = false;
92+
for (var i = innerEx.Data.Count; i-- > 0;)
93+
{
94+
var item = innerEx.Data[new CallStackMarker(i)] as Tuple<Context, CodeCoordinates>;
95+
if (item == null)
96+
continue;
97+
98+
isOurException = true;
99+
stackTrace.Add(" at " + (item.Item1?._owner?.name ?? "<unknown function>") + (item.Item2 != null ? ": line " + item.Item2.Line : string.Empty));
100+
}
101+
102+
if (!isOurException)
103+
stackTrace.Add(innerEx.StackTrace);
104+
105+
innerEx = innerEx.InnerException;
106+
}
107+
108+
if (stackTrace.Count == 0)
109+
return null;
110+
111+
stackTrace.Reverse();
112+
return string.Join(Environment.NewLine, stackTrace);
86113
}
87114
}
88115
}

NiL.JS/ExceptionHelper.cs

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,5 +204,23 @@ internal static void Throw(Exception exception)
204204
{
205205
throw exception;
206206
}
207+
208+
internal static void SetCallStackData(Exception e, Context context, CodeNode codeNode)
209+
{
210+
foreach (var item in e.Data.Values)
211+
{
212+
if ((item as Tuple<Context, CodeCoordinates>).Item1 == context)
213+
return;
214+
}
215+
216+
e.Data.Add(
217+
new CallStackMarker(e.Data.Count),
218+
Tuple.Create(
219+
context,
220+
CodeCoordinates.FromTextPosition(
221+
ExceptionHelper.GetCode(context),
222+
codeNode.Position,
223+
codeNode.Length)));
224+
}
207225
}
208226
}

NiL.JS/Expressions/Call.cs

Lines changed: 52 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -82,72 +82,20 @@ public Call(Expression first, Expression[] arguments, bool optionalChaining)
8282

8383
public override JSValue Evaluate(Context context)
8484
{
85-
#if DEBUG
86-
if (context._callDepth >= 800)
87-
#else
88-
if (context._callDepth >= 1000)
89-
#endif
85+
if (context._callDepth >= 60)
9086
ExceptionHelper.Throw(new RangeError("Stack overflow."), this, context);
9187

9288
var function = _left.Evaluate(context);
9389

9490
JSValue targetObject = context._objectSource;
9591

96-
ICallable callable = null;
9792
Function func = null;
98-
9993
if (function._valueType == JSValueType.Function)
100-
{
10194
func = function._oValue as Function;
102-
callable = func;
103-
}
10495

10596
if (func == null)
10697
{
107-
callable = function._oValue as ICallable;
108-
if (callable == null)
109-
callable = function.Value as ICallable;
110-
111-
if (callable == null)
112-
{
113-
var typeProxy = function.Value as Proxy;
114-
if (typeProxy != null)
115-
callable = typeProxy.PrototypeInstance as ICallable;
116-
}
117-
118-
if (callable == null)
119-
{
120-
if (OptionalChaining)
121-
return JSValue.undefined;
122-
123-
for (int i = 0; i < _arguments.Length; i++)
124-
{
125-
context._objectSource = null;
126-
_arguments[i].Evaluate(context);
127-
}
128-
129-
context._objectSource = null;
130-
131-
// Аргументы должны быть вычислены даже если функция не существует.
132-
ExceptionHelper.ThrowTypeError(_left.ToString() + " is not a function", this, context);
133-
134-
return null;
135-
}
136-
}
137-
138-
if (func == null)
139-
{
140-
switch (_callMode)
141-
{
142-
case CallMode.Construct:
143-
return callable.Construct(Tools.CreateArguments(_arguments, context));
144-
145-
case CallMode.Super:
146-
return callable.Construct(targetObject, Tools.CreateArguments(_arguments, context));
147-
148-
default:
149-
return callable.Call(targetObject, Tools.CreateArguments(_arguments, context));
150-
}
98+
return callCallable(context, targetObject, function);
15199
}
152100

153101
if (_allowTCO
@@ -177,22 +125,58 @@ public override JSValue Evaluate(Context context)
177125
}
178126
catch (Exception e)
179127
{
180-
foreach(var item in e.Data.Values)
181-
{
182-
if ((item as Tuple<Context, CodeCoordinates>).Item1 == context)
183-
throw;
184-
}
128+
ExceptionHelper.SetCallStackData(e, context, this);
129+
throw;
130+
}
131+
}
185132

186-
e.Data.Add(
187-
new CallStackMarker(e.Data.Count),
188-
Tuple.Create(
189-
context,
190-
CodeCoordinates.FromTextPosition(
191-
ExceptionHelper.GetCode(context),
192-
Position,
193-
Length)));
133+
private void throwNaF(Context context)
134+
{
135+
for (int i = 0; i < _arguments.Length; i++)
136+
{
137+
context._objectSource = null;
138+
_arguments[i].Evaluate(context);
139+
}
194140

195-
throw;
141+
context._objectSource = null;
142+
143+
// Аргументы должны быть вычислены даже если функция не существует.
144+
ExceptionHelper.ThrowTypeError(_left.ToString() + " is not a function", this, context);
145+
}
146+
147+
private JSValue callCallable(Context context, JSValue targetObject, JSValue function)
148+
{
149+
var callable = function._oValue as ICallable;
150+
if (callable == null)
151+
callable = function.Value as ICallable;
152+
153+
if (callable == null)
154+
{
155+
var typeProxy = function.Value as Proxy;
156+
if (typeProxy != null)
157+
callable = typeProxy.PrototypeInstance as ICallable;
158+
}
159+
160+
if (callable == null)
161+
{
162+
if (OptionalChaining)
163+
return JSValue.undefined;
164+
165+
throwNaF(context);
166+
167+
return null;
168+
}
169+
170+
switch (_callMode)
171+
{
172+
case CallMode.Construct:
173+
return callable.Construct(Tools.CreateArguments(_arguments, context));
174+
175+
case CallMode.Super:
176+
return callable.Construct(targetObject, Tools.CreateArguments(_arguments, context));
177+
178+
default:
179+
return callable.Call(targetObject, Tools.CreateArguments(_arguments, context));
196180
}
197181
}
198182

0 commit comments

Comments
 (0)