paulbartrum / jurassic

A .NET library to parse and execute JavaScript code.
MIT License
873 stars 122 forks source link

arrays not work thru SetGlobalValue #108

Closed friuns2 closed 7 years ago

friuns2 commented 7 years ago

engine.SetGlobalValue("ar", new int[0, 1, 2]);

engine.Execute("var a = [1,2];log(ar[0])");

will return null

eaglemc commented 7 years ago

I believe you need to wrap the array in a Jurassic.Library.ArrayInstance I have a generic method

// Helper function to convert a .NET collection into an array
// in the script engine
private ArrayInstance NewArray<T>(IEnumerable<T> data)
{
    return _Engine.Array.New(data.Cast<object>().ToArray());
}

And then for your example I would do

_Engine.SetGlobalValue("ar", NewArray(new int[]{1, 2, 3}));
_Engine.Execute("res = Math.log(ar[0])");
var res = _Engine.GetGlobalValue("res");

And res then has the correct value of zero. (I got rid of the zero in the array since Math.log(0) is -Infinity, which makes it hard to be clear if it's working.)

ArrayInstance represents a Javascript array, which has different properties than what a C# array has and can do some other things (like be a sparse array).

(Caveat: I'm not using the latest build of the library and there may be other ways to accomplish this.)

friuns2 commented 7 years ago

Hi thanks, i did it otherway by extensing ClrInstanceWrapper class, and now it works without wrappers


        public override object GetPropertyValue(uint index)
        {
            var opa = WrappedInstance as IList;
            if (opa != null)
            {
                var result = opa[(int)index];
                if (result is ObjectInstance)
                    return (ObjectInstance)result;
                return new ClrInstanceWrapper(Engine, result);
            }
            return base.GetPropertyValue(index);
        }