Skip to content

Commit

Permalink
Backport fix custom reference resolver argument (#1939)
Browse files Browse the repository at this point in the history
  • Loading branch information
lahma authored Aug 10, 2024
1 parent dc129c7 commit 8ce657f
Show file tree
Hide file tree
Showing 2 changed files with 78 additions and 5 deletions.
62 changes: 62 additions & 0 deletions Jint.Tests.PublicInterface/RavenApiUsageTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,36 @@ public void CanResetCallStack()
var engine = new Engine();
engine.Advanced.ResetCallStack();
}

[Fact]
public void CanUseCustomReferenceResolver()
{
var engine = new Engine(options =>
{
options.ReferenceResolver = new MyReferenceResolver();
});

engine
.Execute("""
function output(doc) {
var rows123 = [{}];
var test = null;
return {
Rows : [{}].map(row=>({row:row, myRows:test.filter(x=>x)
})).map(__rvn4=>({
Custom:__rvn4.myRows[0].Custom,
Custom2:__rvn4.myRows
}))
};
}
""");

var result = engine.Evaluate("output()");

var rows = result.AsObject()["Rows"];
var custom = rows.AsArray()[0].AsObject()["Custom"];
Assert.Equal(JsValue.Null, custom);
}
}

file sealed class CustomString : JsString
Expand Down Expand Up @@ -288,3 +318,35 @@ public override string ToString()
return "null";
}
}

file sealed class MyReferenceResolver : IReferenceResolver
{
public bool TryUnresolvableReference(Engine engine, Reference reference, out JsValue value)
{
JsValue referencedName = reference.ReferencedName;

if (referencedName.IsString())
{
value = reference.IsPropertyReference ? JsValue.Undefined : JsValue.Null;
return true;
}

throw new InvalidOperationException();
}

public bool TryPropertyReference(Engine engine, Reference reference, ref JsValue value)
{
return value.IsNull() || value.IsUndefined();
}

public bool TryGetCallable(Engine engine, object callee, out JsValue value)
{
value = new ClrFunction(engine, "function", static (_, _) => JsValue.Undefined);
return true;
}

public bool CheckCoercible(JsValue value)
{
return true;
}
}
21 changes: 16 additions & 5 deletions Jint/Engine.cs
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,10 @@ public sealed partial class Engine : IDisposable
internal readonly Constraint[] _constraints;
internal readonly bool _isDebugMode;
internal readonly bool _isStrict;

private bool _customResolver;
internal readonly IReferenceResolver _referenceResolver;

internal readonly ReferencePool _referencePool;
internal readonly ArgumentsInstancePool _argumentsInstancePool;
internal readonly JsValueArrayPool _jsValueArrayPool;
Expand Down Expand Up @@ -134,6 +137,7 @@ private Engine(Options? options, Action<Engine, Options>? configure)

_constraints = Options.Constraints.Constraints.ToArray();
_referenceResolver = Options.ReferenceResolver;
_customResolver = !ReferenceEquals(_referenceResolver, DefaultReferenceResolver.Instance);

_referencePool = new ReferencePool();
_argumentsInstancePool = new ArgumentsInstancePool(this);
Expand Down Expand Up @@ -579,18 +583,25 @@ internal JsValue GetValue(Reference reference, bool returnReferenceToPool)

if (baseValue.IsUndefined())
{
if (_referenceResolver.TryUnresolvableReference(this, reference, out var val))
if (_customResolver)
{
return val;
reference.EvaluateAndCachePropertyKey();
if (_referenceResolver.TryUnresolvableReference(this, reference, out var val))
{
return val;
}
}

ExceptionHelper.ThrowReferenceError(Realm, reference);
}

if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == InternalTypes.Empty
&& _referenceResolver.TryPropertyReference(this, reference, ref baseValue))
if ((baseValue._type & InternalTypes.ObjectEnvironmentRecord) == InternalTypes.Empty && _customResolver)
{
return baseValue;
reference.EvaluateAndCachePropertyKey();
if (_referenceResolver.TryPropertyReference(this, reference, ref baseValue))
{
return baseValue;
}
}

if (reference.IsPropertyReference)
Expand Down

0 comments on commit 8ce657f

Please sign in to comment.