Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

get rid of 'reference not set to an instance of an object' error, which appears when context is null #1917

14 changes: 14 additions & 0 deletions Jint.Tests/Runtime/EvaluationContextTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
namespace Jint.Tests.Runtime;

public class EvaluationContextTests
{
[Fact]
public void ShouldThrowJavaScriptException()
{
var mockedEngine = new Engine();

Expression expression = new Identifier(NodeType.MemberExpression.ToString());

Assert.Throws<Jint.Runtime.JavaScriptException>(() => AstExtensions.TryGetComputedPropertyKey(expression, mockedEngine));
}
}
10 changes: 5 additions & 5 deletions Jint/AstExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ internal static JsValue TryGetKey<T>(this T expression, Engine engine, bool reso
return key;
}

private static JsValue TryGetComputedPropertyKey<T>(T expression, Engine engine)
internal static JsValue TryGetComputedPropertyKey<T>(T expression, Engine engine)
where T : Expression
{
if (expression.Type is NodeType.Identifier
Expand All @@ -79,8 +79,8 @@ or NodeType.FunctionExpression
or NodeType.YieldExpression
or NodeType.TemplateLiteral)
{
var context = engine._activeEvaluationContext;
return JintExpression.Build(expression).GetValue(context!);
var context = engine._activeEvaluationContext ?? new EvaluationContext(engine);
return JintExpression.Build(expression).GetValue(context);
}

return JsValue.Undefined;
Expand Down Expand Up @@ -152,7 +152,7 @@ internal static bool IsAnonymousFunctionDefinition<T>(this T node) where T : Nod
internal static bool IsOptional<T>(this T node) where T : Expression
{
return node is IChainElement { Optional: true };
}
}

[MethodImpl(MethodImplOptions.AggressiveInlining)]
internal static string LiteralKeyToString(Literal literal)
Expand Down Expand Up @@ -318,7 +318,7 @@ internal static Record DefineMethod<T>(this T m, ObjectInstance obj, ObjectInsta

var runningExecutionContext = engine.ExecutionContext;
var env = runningExecutionContext.LexicalEnvironment;
var privateEnv= runningExecutionContext.PrivateEnvironment;
var privateEnv = runningExecutionContext.PrivateEnvironment;

var prototype = functionPrototype ?? intrinsics.Function.PrototypeObject;
var function = m.Value as IFunction;
Expand Down
6 changes: 3 additions & 3 deletions Jint/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ public sealed partial class Engine : IDisposable
internal readonly Dictionary<string, Type?> TypeCache = new(StringComparer.Ordinal);

// we use registered type reference as prototype if it's known
internal Dictionary<Type,TypeReference>? _typeReferences;
internal Dictionary<Type, TypeReference>? _typeReferences;

// cache for already wrapped CLR objects to keep object identity
internal ConditionalWeakTable<object, ObjectInstance>? _objectWrapperCache;
Expand Down Expand Up @@ -459,7 +459,7 @@ private Engine ScriptEvaluation(ScriptRecord scriptRecord, ParserOptions parserO
// TODO what about callstack and thrown exceptions?
RunAvailableContinuations();

return this;
return this;
}
finally
{
Expand Down Expand Up @@ -1243,7 +1243,7 @@ internal void EvalDeclarationInstantiation(
{
foreach (var name in pointer.Names)
{
privateIdentifiers??= new HashSet<PrivateIdentifier>(PrivateIdentifierNameComparer._instance);
privateIdentifiers ??= new HashSet<PrivateIdentifier>(PrivateIdentifierNameComparer._instance);
privateIdentifiers.Add(name.Key);
}

Expand Down
5 changes: 4 additions & 1 deletion Jint/Native/Function/EvalFunction.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using Jint.Runtime;
using Jint.Runtime.Descriptors;
using Jint.Runtime.Environments;
using Jint.Runtime.Interpreter;
using Jint.Runtime.Interpreter.Statements;
using Environment = Jint.Runtime.Environments.Environment;

Expand Down Expand Up @@ -178,7 +179,9 @@ internal JsValue PerformEval(JsValue x, Realm callerRealm, bool strictCaller, bo
Engine.EvalDeclarationInstantiation(script, varEnv, lexEnv, privateEnv, strictEval);

var statement = new JintScript(script);
var result = statement.Execute(_engine._activeEvaluationContext!);
var context = _engine._activeEvaluationContext ?? new EvaluationContext(_engine);
var result = statement.Execute(context);

var value = result.GetValueOrDefault();

if (result.Type == CompletionType.Throw)
Expand Down
2 changes: 1 addition & 1 deletion Jint/Runtime/Interpreter/Expressions/JintExpression.cs
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ protected internal static JintExpression Build(Expression expression)
: new JintMemberExpression((MemberExpression) ((ChainExpression) expression).Expression),
NodeType.AwaitExpression => new JintAwaitExpression((AwaitExpression) expression),
NodeType.YieldExpression => new JintYieldExpression((YieldExpression) expression),
_ => null
_ => null
};

if (result is null)
Expand Down