コード例 #1
0
ファイル: DRegExp.cs プロジェクト: vrajeshbhavsar/mcjs
        public mdr.DObject ExecImplementation(string S)
        {
            if (S == null)
            {
                return(Runtime.Instance.DefaultDNull);
            }
            Match match = MatchImplementation(S);

            if (match == null)
            {
                return(Runtime.Instance.DefaultDNull);
            }

            int n = match.Captures.Count;

            mdr.DArray result = new mdr.DArray(n);
            result.SetField("index", match.Index);
            result.SetField("input", S);
            //result.SetField(0, match.Value);
            if (MatchedGroups != null)
            {
                for (int g = 0; g < MatchedGroups.Count; g++)
                {
                    if (MatchedGroups[g].Captures.Count > 0)
                    {
                        result.SetField(g, MatchedGroups[g].Captures[0].Value);
                    }
                }
            }
            return(result);
        }
コード例 #2
0
        private static mdr.DArray CreateArgumentsObject(ref mdr.CallFrame callFrame)
        {
            var argsCount = callFrame.ExpectedArgsCount;

            if (callFrame.PassedArgsCount > callFrame.ExpectedArgsCount)
            {
                argsCount = callFrame.PassedArgsCount;
            }
            var arguments = new mdr.DArray(argsCount);

            switch (callFrame.PassedArgsCount)
            {
            case 0: break;

            case 1: arguments.Elements[0] = callFrame.Arg0; goto case 0;

            case 2: arguments.Elements[1] = callFrame.Arg1; goto case 1;

            case 3: arguments.Elements[2] = callFrame.Arg2; goto case 2;

            case 4: arguments.Elements[3] = callFrame.Arg3; goto case 3;

            default:
                Array.Copy(callFrame.Arguments, 0, arguments.Elements, 4, callFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount);
                goto case 4;
            }
            ///To comply with 10.6 item 6, we add a "length" property to prevent it affecting the actual array,
            ///TODO: in future version os Javscript, this is going change and Arguments is acutally an array
            arguments.DefineOwnProperty("length", callFrame.PassedArgsCount, mdr.PropertyDescriptor.Attributes.Data | mdr.PropertyDescriptor.Attributes.NotEnumerable);

            return(arguments);
        }
コード例 #3
0
ファイル: JSString.cs プロジェクト: vrajeshbhavsar/mcjs
        // ECMA-262 section 15.5.4.10
        void match(ref mdr.CallFrame callFrame)
        {
            Debug.WriteLine("Calling JSString.match()");
            string S = callFrame.This.ToString();

            mdr.DRegExp rx = callFrame.Arg0.AsDObject() as mdr.DRegExp;
            if (rx == null)
            {
                rx = new mdr.DRegExp(callFrame.Arg0.AsString());
            }
            if (!rx.Global)
            {
                callFrame.Return.Set(rx.ExecImplementation(S));
                return;
            }

            mdr.DArray result = new mdr.DArray();
            int        i      = 0;

            foreach (Match match in (rx.Value).Matches(S))
            {
                foreach (Group group in match.Groups)
                {
                    //result.SetField(i++, new mdr.DString(group.Value.ToString()));
                    result.SetField(i++, group.Value);
                }
            }
            callFrame.Return.Set(result);
        }
コード例 #4
0
ファイル: ICMethods.cs プロジェクト: reshadi2/mcjs
 public static void CreateArray(ref mdr.CallFrame callFrame, int resultIndex, int valuesCount)
 {
   var values = callFrame.Values;
   var array = new mdr.DArray(valuesCount);
   for (var i = valuesCount - 1; i >= 0; --i)
     array.Elements[i] = values[resultIndex + i];
   values[resultIndex].Set(array);
 }
コード例 #5
0
        public static void CreateArray(ref mdr.CallFrame callFrame, int resultIndex, int valuesCount)
        {
            var values = callFrame.Values;
            var array  = new mdr.DArray(valuesCount);

            for (var i = valuesCount - 1; i >= 0; --i)
            {
                array.Elements[i] = values[resultIndex + i];
            }
            values[resultIndex].Set(array);
        }
コード例 #6
0
        public static void CreateArray(int itemsCount, ref Stack stack)
        {
            //Debug.WriteLine("calling Exec.CreateArray");
            var sp    = stack.Sp - 1;
            var array = new mdr.DArray(itemsCount);

            for (var i = itemsCount - 1; i >= 0; --i, --sp)
            {
                array.Elements[i] = stack.Items[sp];
            }
            stack.Items[sp + 1].Set(array);
            stack.Sp = sp + 2;
        }
コード例 #7
0
ファイル: JSFunctionArguments.cs プロジェクト: reshadi2/mcjs
    private static mdr.DArray CreateArgumentsObject(ref mdr.CallFrame callFrame)
    {
      var argsCount = callFrame.ExpectedArgsCount;
      if (callFrame.PassedArgsCount > callFrame.ExpectedArgsCount)
        argsCount = callFrame.PassedArgsCount;
      var arguments = new mdr.DArray(argsCount);
      switch (callFrame.PassedArgsCount)
      {
        case 0: break;
        case 1: arguments.Elements[0] = callFrame.Arg0; goto case 0;
        case 2: arguments.Elements[1] = callFrame.Arg1; goto case 1;
        case 3: arguments.Elements[2] = callFrame.Arg2; goto case 2;
        case 4: arguments.Elements[3] = callFrame.Arg3; goto case 3;
        default:
          Array.Copy(callFrame.Arguments, 0, arguments.Elements, 4, callFrame.PassedArgsCount - mdr.CallFrame.InlineArgsCount);
          goto case 4;
      }
      ///To comply with 10.6 item 6, we add a "length" property to prevent it affecting the actual array,
      ///TODO: in future version os Javscript, this is going change and Arguments is acutally an array
      arguments.DefineOwnProperty("length", callFrame.PassedArgsCount, mdr.PropertyDescriptor.Attributes.Data | mdr.PropertyDescriptor.Attributes.NotEnumerable);

      return arguments;
    }
コード例 #8
0
        public static mdr.DArray CreateArgumentsObject(ref mdr.CallFrame callFrame, mdr.DObject context)
        {
            var metadata = (JSFunctionMetadata)callFrame.Function.Metadata;

            Debug.Assert(metadata.Scope.HasArgumentsSymbol, "Invalid situation, created arguments for the wrong scope!");
            mdr.DArray arguments = null;
            if (metadata.Scope.IsEvalFunction)
            {
                //Read from context
                var tmp = new mdr.DValue();
                context.GetField(JSFunctionArguments.Name, ref tmp);
                arguments = tmp.AsDArray();
            }
            else
            {
                arguments = CreateArgumentsObject(ref callFrame);
                var parameters = metadata.FunctionIR.Parameters;
                Debug.Assert(arguments.Length >= parameters.Count, "arguments array is not large enough to hold all arguments.");
                for (var i = parameters.Count - 1; i >= 0; --i)
                {
                    var symbol     = parameters[i].Symbol;
                    var paramIndex = symbol.ParameterIndex;
                    Debug.Assert(paramIndex == i, "Invalid situation!, Parameter indexes don't match!");

                    if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal)
                    {
                        var pd = context.AddOwnPropertyDescriptorByFieldId(symbol.FieldId, mdr.PropertyDescriptor.Attributes.Accessor | mdr.PropertyDescriptor.Attributes.NotConfigurable);
                        context.Fields[pd.Index].Set(new ArgumentAccessor(arguments, paramIndex));
                    }
                }
                if (metadata.Scope.HasEval)
                {
                    context.SetField(JSFunctionArguments.Name, arguments);
                }
            }
            return(arguments);
        }
コード例 #9
0
ファイル: JSString.cs プロジェクト: vrajeshbhavsar/mcjs
        // ECMA-262 section 15.5.4.14
        void split(ref mdr.CallFrame callFrame)
        {
            Debug.WriteLine("Calling JSString.split()");

            var S = Operations.Convert.ToString.Run(callFrame.This);

            mdr.DArray A = new mdr.DArray();

            var limit = (callFrame.PassedArgsCount > 1 && callFrame.Arg1.ValueType != mdr.ValueTypes.Undefined)
        ? Operations.Convert.ToUInt32.Run(ref callFrame.Arg1)
        : UInt32.MaxValue;

            if (limit == 0)
            {
                callFrame.Return.Set(A);
                return;
            }

            if (callFrame.PassedArgsCount == 0 || callFrame.Arg0.ValueType == mdr.ValueTypes.Undefined)
            {
                A.SetField(0, S);
                callFrame.Return.Set(A);
                return;
            }

            if (string.IsNullOrEmpty(S))
            {
                if (callFrame.PassedArgsCount != 0
                    //&& callFrame.Arg0.ValueType != mdr.ValueTypes.Undefined
                    && callFrame.Arg0.ValueType == mdr.ValueTypes.String &&
                    !String.IsNullOrEmpty(callFrame.Arg0.AsString()))
                {
                    //A.SetField(0, new mdr.DString(""));
                    A.SetField(0, "");
                }
                callFrame.Return.Set(A);
                return;
            }

            int s = S.Length;

            string[] result;
            if (callFrame.Arg0.ValueType == mdr.ValueTypes.String)
            {
                string separator = callFrame.Arg0.AsString();
                if (String.IsNullOrEmpty(separator))
                {
                    int i = 0;
                    result = new string[s];
                    foreach (char c in S)
                    {
                        result[i++] = new string(c, 1);
                    }
                }
                else
                {
                    result = S.Split(new string[] { separator }, StringSplitOptions.None);
                }
            }
            else
            {
                Debug.Assert(callFrame.Arg0.ValueType == mdr.ValueTypes.Object, "Does not know what to do with argument type {0} in split", callFrame.Arg0.ValueType);
                mdr.DRegExp regexpSeparator = callFrame.Arg0.AsDObject() as mdr.DRegExp;
                Debug.Assert(regexpSeparator != null, "Does not know what to do with argument type {0} in split", callFrame.Arg0.ValueType);
                //string pattern = regexpSeparator.Value.ToString();
                //result = Regex.Split(S, pattern, RegexOptions.ECMAScript);
                result = regexpSeparator.Value.Split(S);
            }

            for (int i = 0; i < result.Length && i < limit; i++)
            {
                //A.SetField(i, new mdr.DString(result[i]));
                A.SetField(i, result[i]);
            }

            callFrame.Return.Set(A);
        }
コード例 #10
0
ファイル: JSInt8Array.cs プロジェクト: vrajeshbhavsar/mcjs
        public JSInt8Array()
            : base(new mdr.DObject(), "Int8Array", TypeSize)
        {
            JittedCode = (ref mdr.CallFrame callFrame) =>
            {
                DInt8Array int32array = new DInt8Array(TargetPrototype, 0, TypeSize);
                var        argsCount  = callFrame.PassedArgsCount;

                if (argsCount == 1)
                {
                    switch (callFrame.Arg0.ValueType)
                    {
                    case mdr.ValueTypes.Int32:
                        int32array = new DInt8Array(TargetPrototype, callFrame.Arg0.AsInt32() * TypeSize, TypeSize);
                        break;

                    case mdr.ValueTypes.Object:
                        int32array = createArrayFromObject(callFrame.Arg0.AsDObject());
                        break;

                    case mdr.ValueTypes.Array:
                        mdr.DArray array = callFrame.Arg0.AsDArray();
                        int32array = new DInt8Array(TargetPrototype, array.Length * TypeSize, TypeSize);
                        fillArray(int32array, array);
                        break;

                    default:
                        Trace.Fail("invalid Arguments");
                        break;
                    }
                }
                if (argsCount == 2)
                {
                    int byteoffset = callFrame.Arg1.AsInt32();
                    int32array = createArrayFromObject(callFrame.Arg0.AsDObject(), byteoffset);
                }
                if (argsCount == 3)
                {
                    var byteoffset = callFrame.Arg1.AsInt32();
                    var length     = callFrame.Arg2.AsInt32();
                    checkOffsetMemBoundary(byteoffset);
                    int32array = createArrayFromObject(callFrame.Arg0.AsDObject(), byteoffset, length * TypeSize);
                }

                if (IsConstrutor)
                {
                    callFrame.This = (int32array);
                }
                else
                {
                    callFrame.Return.Set(int32array);
                }
            };

            TargetPrototype.DefineOwnProperty("subarray", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                DInt8Array array = (callFrame.This as DInt8Array);
                var argsCount    = callFrame.PassedArgsCount;
                var begin        = (argsCount >= 1) ? callFrame.Arg0.AsInt32() : 0;
                var end          = array.ByteLength / array.TypeSize;
                end            = (argsCount >= 2) ? callFrame.Arg1.AsInt32() : end;
                begin          = begin < 0 ? begin += array.ByteLength / array.TypeSize : begin;
                end            = end < 0 ? end += array.ByteLength / array.TypeSize : end;
                var bytelength = Math.Max(0, (end - begin)) * array.TypeSize;
                end            = Math.Max(array.ByteLength, bytelength);
                var int32array = new DInt8Array(TargetPrototype, bytelength, array.TypeSize);
                int offset     = (begin <= 0) ? 0 : begin * array.TypeSize;
                for (int i = 0; i < int32array.ByteLength; ++i)
                {
                    int32array.Elements_[i] = array.Elements_[i + offset];
                }
                callFrame.Return.Set(int32array);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);
        }
コード例 #11
0
            //mdr.DArray Arguments;
            //int ParamIndex;

            public ArgumentAccessor(mdr.DArray arguments, int paramIndex)
            {
                OnGetDValue = (mdr.DObject This, ref mdr.DValue v) => { v.Set(ref arguments.Elements[paramIndex]); };
                OnSetDValue = (mdr.DObject This, ref mdr.DValue v) => { arguments.Elements[paramIndex].Set(ref v); };
            }
コード例 #12
0
ファイル: ToObject.cs プロジェクト: vrajeshbhavsar/mcjs
 public static mdr.DArray Run(mdr.DArray i0)
 {
     return(i0);
 }
コード例 #13
0
 public static void SetArguments(ref mdr.CallFrame callFrame, mdr.DArray arguments)
 {
     callFrame.Values[1].Set(arguments);
 }
コード例 #14
0
ファイル: Interpreter.cs プロジェクト: reshadi2/mcjs
    private void DeclareParameterSymbols(ref mdr.CallFrame callFrame)
    {
      var parameters = _currFuncMetadata.FunctionIR.Parameters;

      //Extend missing arguments
      callFrame.SetExpectedArgsCount(parameters.Count);

      if (_currScope.HasArgumentsSymbol)
      {
        ///In this case, we already read/write from the arguments.Elements[i] for the symbol. 
        ///however, we should always refer to the arguments variable itself since its .Elements 
        ///may be resized and changed
        ///we cannot rely on the argument symbol's variable for this since the progremmer
        ///may write the arguments symbol and we can lose the value, so we keep our own separately

        Arguments = JSFunctionArguments.CreateArgumentsObject(ref callFrame, Context);
        var symbols = _currScope.Symbols;
        for (var i = parameters.Count; i < symbols.Count; ++i) //Hopefully "arguments" is the symbol almost immediately after the parameters
        {
          var symbol = symbols[i];
          if (symbol.SymbolType == JSSymbol.SymbolTypes.Arguments)
          {
            SymbolValues[symbol.ValueIndex].Set(Arguments);
            break;
          }
        }
      }
      else
      {
        Arguments = null;
        var i = parameters.Count;
        if (i > callFrame.PassedArgsCount)
          i = callFrame.PassedArgsCount;
        for (i = i - 1; i >= 0; --i)
        {
          var symbol = parameters[i].Symbol;
          Debug.Assert(symbol.ParameterIndex == i, "Invalid situation!, symbol {0} should be paramter with parameter index {1} instead of {2}", symbol.Name, i, symbol.ParameterIndex);
          if (symbol.SymbolType == JSSymbol.SymbolTypes.ClosedOnLocal)
          {
            var pd = Context.Map.GetPropertyDescriptorByFieldId(symbol.FieldId);
            Debug.Assert(
              pd != null
              && !pd.HasAttributes(mdr.PropertyDescriptor.Attributes.Undefined | mdr.PropertyDescriptor.Attributes.Inherited | mdr.PropertyDescriptor.Attributes.Accessor)
              , "Invalid situation, symbol {0} is not properly added to context", symbol.Name);
            Context.Fields[pd.Index] = callFrame.Arg(i);
            SymbolValues[symbol.ValueIndex].Set(pd);
          }
        }
      }
    }
コード例 #15
0
 public void Visit(mdr.DArray obj)
 {
     throw new NotImplementedException();
 }
コード例 #16
0
 public static void Run(mdr.DArray i0, ref mdr.DValue result)
 {
     result.Set(i0);
 }
コード例 #17
0
ファイル: Interpreter.cs プロジェクト: reshadi2/mcjs
 public override void Execute(ref mdr.DValue result, ref mdr.CallFrame callFrame, Interpreter interpreter)
 {
   interpreter.PushLocation(this);
   var array = new mdr.DArray(Items.Count);
   for (var i = 0; i < Items.Count; ++i)
     Items[i].Execute(ref array.Elements[i], ref callFrame, interpreter);
   result.Set(array);
   interpreter.PopLocation(this, ref result);
 }
コード例 #18
0
        public JSArray()
            : base(mdr.Runtime.Instance.DArrayPrototype, "Array")
        {
            JittedCode = (ref mdr.CallFrame callFrame) =>
            {
                mdr.DArray array;

                var argsCount = callFrame.PassedArgsCount;

                if (argsCount == 1)
                {
                    var len = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                    array = new mdr.DArray(len);
                }
                else
                {
                    array = new mdr.DArray(argsCount);
                    switch (argsCount)
                    {
                    case 0: break;

                    case 1: break;

                    case 2:
                        array.Elements[1] = callFrame.Arg1;
                        array.Elements[0] = callFrame.Arg0;
                        break;

                    case 3:
                        array.Elements[2] = callFrame.Arg2;
                        goto case 2;

                    case 4:
                        array.Elements[3] = callFrame.Arg3;
                        goto case 3;

                    default:
                        Debug.Assert(argsCount > mdr.CallFrame.InlineArgsCount, "Code gen must be updated to support new CallFrame");
                        Array.Copy(callFrame.Arguments, 0, array.Elements, mdr.CallFrame.InlineArgsCount, argsCount - mdr.CallFrame.InlineArgsCount);
                        goto case 4;
                    }
                }
                if (IsConstrutor)
                {
                    callFrame.This = (array);
                }
                else
                {
                    callFrame.Return.Set(array);
                }
            };

            // ECMA-262 section 15.4.3.1
            this.DefineOwnProperty("isArray", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.isArray");
                if (callFrame.This.ValueType == mdr.ValueTypes.Array)
                {
                    callFrame.Return.Set(true);
                }
                else
                {
                    callFrame.Return.Set(false);
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.2
            TargetPrototype.DefineOwnProperty("toString", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.toString");
                var join = callFrame.This.GetField("join");
                if (join.ValueType == mdr.ValueTypes.Function)// it is callable
                {
                    var joinFun = join.AsDFunction();
                    Debug.Assert(joinFun != null, "Invalid situation!");
                    callFrame.Function = joinFun;
                    //callFrame.This is already set
                    callFrame.Signature       = mdr.DFunctionSignature.EmptySignature;
                    callFrame.PassedArgsCount = 0;
                    callFrame.Arguments       = null;
                    joinFun.Call(ref callFrame);
                    callFrame.Return.Set(callFrame.Return.AsString());
                }
                else
                {
                    callFrame.Return.Set(callFrame.This.ToString());
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.3
            TargetPrototype.DefineOwnProperty("toLocaleString", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                throw new NotImplementedException("Array.toLocaleString is not implemented");
                // TODO: callFrame.This is not an accurate implementation

                /*mdr.DObject array = callFrame.This;
                 * mdr.DFunction join = array.GetField("join").ToDObject() as mdr.DFunction;
                 * if (join != null) // it is callable
                 * {
                 *  callFrame.Function = join;
                 *  callFrame.Signature = mdr.DFunctionSignature.EmptySignature;
                 *  callFrame.Arguments = null;
                 *  join.Call(ref callFrame);
                 *  callFrame.Return.Set(callFrame.Return.ToString());    //TODO: is this the right implementation?
                 * }
                 * else
                 *  callFrame.Return.Set(array.ToString());*/
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.4
            TargetPrototype.DefineOwnProperty("concat", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.concat");
                //The most common case is calling .concat on array object with normal set of arguments
                mdr.DArray newArray;
                var destStartIndex = 0;

                var thisArray = callFrame.This as mdr.DArray;
                if (thisArray != null)
                {
                    newArray = new mdr.DArray(callFrame.PassedArgsCount + thisArray.Length);
                    Array.Copy(thisArray.Elements, 0, newArray.Elements, 0, thisArray.Length);
                    destStartIndex = thisArray.Length;
                }
                else
                {
                    newArray = new mdr.DArray(callFrame.PassedArgsCount + 1);
                    newArray.Elements[0].Set(callFrame.This);
                    destStartIndex = 1;
                }
                for (int i = 0; i < callFrame.PassedArgsCount; ++i)
                {
                    newArray.Elements[destStartIndex] = callFrame.Arg(i); //This is the common case
                    if (newArray.Elements[destStartIndex].ValueType == mdr.ValueTypes.Array)
                    {
                        var array = newArray.Elements[destStartIndex].AsDArray();
                        //We had already accounted 1 cell for this item, so, we add the missing remaining elements
                        newArray.Length += (array.Length - 1); //Extends newArray.Elements
                        Array.Copy(array.Elements, 0, newArray.Elements, destStartIndex, array.Length);
                        destStartIndex += array.Length;
                    }
                    else
                    {
                        ++destStartIndex;
                    }
                }
                //concat(newArray, ref callFrame.Arguments[i]);

                callFrame.Return.Set(newArray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.5
            TargetPrototype.DefineOwnProperty("join", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.join");
                string separator = (callFrame.PassedArgsCount == 0 || callFrame.Arg0.ValueType == mdr.ValueTypes.Undefined)
                    ? ","
                    : callFrame.Arg0.AsString();

                callFrame.Return.Set(join(callFrame.This, separator).ToString());
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.6
            TargetPrototype.DefineOwnProperty("pop", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.pop");
                var This     = callFrame.This;
                var lenField = This.GetField("length");
                int len      = Operations.Convert.ToInt32.Run(ref lenField);
                if (len == 0)
                {
                    This.SetField("length", 0);
                    callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
                }
                else if (len > 0)
                {
                    var index          = len - 1;
                    mdr.DValue element = new mdr.DValue();
                    This.GetField(index, ref element);
                    This.DeletePropertyDescriptor(index.ToString());
                    This.SetField("length", index);
                    callFrame.Return.Set(ref element);
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.7
            TargetPrototype.DefineOwnProperty("push", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.push");
                var This       = callFrame.This;
                var lenField   = This.GetField("length");
                int len        = Operations.Convert.ToInt32.Run(ref lenField);
                mdr.DValue arg = new mdr.DValue();
                for (int i = 0; i < callFrame.PassedArgsCount; ++i)
                {
                    arg = callFrame.Arg(i);
                    This.SetField(len, ref arg);
                    len++;
                }
                This.SetField("length", len);
                callFrame.Return.Set(len);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.8
            TargetPrototype.DefineOwnProperty("reverse", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.reverse");
                var This              = callFrame.This;
                var lenField          = This.GetField("length");
                int len               = Operations.Convert.ToInt32.Run(ref lenField);
                int middle            = len / 2;
                mdr.DValue lowerValue = new mdr.DValue();
                mdr.DValue upperValue = new mdr.DValue();
                bool lowerExists, upperExists;
                for (int lower = 0; lower != middle; lower++)
                {
                    int upper   = len - lower - 1;
                    lowerExists = This.HasProperty(lower);
                    upperExists = This.HasProperty(upper);
                    if (lowerExists && upperExists)
                    {
                        This.GetField(lower, ref lowerValue);
                        This.GetField(upper, ref upperValue);
                        This.SetField(lower, ref upperValue);
                        This.SetField(upper, ref lowerValue);
                    }
                    else if (!lowerExists && upperExists)
                    {
                        This.GetField(upper, ref upperValue);
                        This.SetField(lower, ref upperValue);
                        This.DeletePropertyDescriptor(upper.ToString());
                    }
                    else if (lowerExists && !upperExists)
                    {
                        This.GetField(lower, ref lowerValue);
                        This.SetField(upper, ref lowerValue);
                        This.DeletePropertyDescriptor(lower.ToString());
                    }
                }
                callFrame.Return.Set(This);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.9
            TargetPrototype.DefineOwnProperty("shift", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.shift");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                if (array == null || array.Length == 0)
                {
                    //callFrame.Return.ValueType = mdr.ValueTypes.Undefined;
                    callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
                }
                else
                {
                    callFrame.Return.Set(ref array.Elements[0]);
                    for (int k = 1; k < len; k++)
                    {
                        array.Elements[k - 1].Set(ref array.Elements[k]);
                    }

                    array.Length--;
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.10
            TargetPrototype.DefineOwnProperty("slice", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.slice");

                /*  TODO: This is the implementation for a case that "this" is a DArray. Use this faster implementation after adding PackedArray optimization.
                 * mdr.DArray array = callFrame.This.ToDArray();
                 * int len = array.Length;
                 * int relativeStart = callFrame.Arg0.ToInt32();
                 * int k = (relativeStart < 0) ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                 * int relativeEnd = (callFrame.Arg1.ValueType == mdr.ValueTypes.Undefined) ? len : callFrame.Arg1.ToInt32();
                 * int final = (relativeEnd < 0) ? Math.Max(relativeEnd + len, 0) : Math.Min(relativeEnd, len);
                 * mdr.DArray newArray = new mdr.DArray((final - k > 0) ? (final - k) : 0);
                 * for (int n = 0; k < final; k++, n++)
                 *  newArray.Elements[n].Set(ref array.Elements[k]);
                 * callFrame.Return.Set(newArray);
                 */

                var This          = callFrame.This;
                var lenField      = This.GetField("length");
                int len           = Operations.Convert.ToInt32.Run(ref lenField);
                int relativeStart = 0;
                if (callFrame.PassedArgsCount > 0)
                {
                    relativeStart = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                }
                int k               = (relativeStart < 0) ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                int relativeEnd     = ((callFrame.Arg1.ValueType == mdr.ValueTypes.Undefined) || (callFrame.PassedArgsCount < 2)) ? len : Operations.Convert.ToInt32.Run(ref callFrame.Arg1);
                int final           = (relativeEnd < 0) ? Math.Max(relativeEnd + len, 0) : Math.Min(relativeEnd, len);
                mdr.DArray newArray = new mdr.DArray((final - k > 0) ? (final - k) : 0);
                mdr.DValue item     = new mdr.DValue();
                for (int n = 0; k < final; k++, n++)
                {
                    This.GetField(k, ref item);
                    newArray.Elements[n].Set(ref item);
                }
                callFrame.Return.Set(newArray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.12
            //TODO: splice is generic and can be applied to other objects
            TargetPrototype.DefineOwnProperty("splice", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.splice");
                if (callFrame.PassedArgsCount < 2)
                {
                    callFrame.Return.Set(JSRuntime.Instance.DefaultDUndefined);
                    return;
                }
                var A    = new mdr.DArray();
                var This = callFrame.This as mdr.DArray;
                if (This == null)
                {
                    throw new Exception("Object is not an array, but splice must work with generic objects. Please fix it!");
                }
                int len               = This.Length;
                int relativeStart     = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                int actualStart       = relativeStart < 0 ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                int actualDeleteCount = Math.Min(Math.Max(Operations.Convert.ToInt32.Run(ref callFrame.Arg1), 0), len - actualStart);

                A.Length = actualDeleteCount;
                for (int k = 0; k < actualDeleteCount; k++)
                {
                    int from = relativeStart + k;
                    if (from < len)
                    {
                        A.Elements[k].Set(ref This.Elements[from]);
                    }
                }

                int itemCount = callFrame.PassedArgsCount - 2;
                if (itemCount < actualDeleteCount)
                {
                    for (int k = actualStart; k < len - actualDeleteCount; k++)
                    {
                        int from = k + actualDeleteCount;
                        int to   = k + itemCount;
                        // if (from < len) // This condition will always hold
                        This.Elements[to].Set(ref This.Elements[from]);
                        // from will always be less than less and therefore the element exists in the array
                        //TODO: can we assume any index less than Length exist? When an element is deleted from middle of the Elements, is Length adjusted?

                        /*
                         * else
                         * {
                         *  This.RemoveElements(to, len - actualDeleteCount - k);
                         *  break;
                         * }*/
                    }
                    This.RemoveElements(len - actualDeleteCount + itemCount, actualDeleteCount - itemCount);
                    This.Length = len - actualDeleteCount + itemCount;
                }
                else if (itemCount > actualDeleteCount)
                {
                    This.Length = len - actualDeleteCount + itemCount;
                    for (int k = len - actualDeleteCount; k > actualStart; k--)
                    {
                        int from = k + actualDeleteCount - 1;
                        int to   = k + itemCount - 1;
                        //if (from < len) //This condition will always hold
                        This.Elements[to].Set(ref This.Elements[from]);
                    }
                }

                for (int k = 0; k < itemCount; k++)
                {
                    This.Elements[k + actualStart] = callFrame.Arg(k + 2);
                }


                callFrame.Return.Set(A);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.11
            TargetPrototype.DefineOwnProperty("sort", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.sort");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(array);
                }

                int argsCount       = callFrame.PassedArgsCount;
                mdr.DValue function = callFrame.Arg0;

                for (uint i = 0; i < len - 1; ++i)
                {
                    mdr.DValue iObj   = array.Elements[i];
                    uint themin       = i;
                    mdr.DValue minObj = iObj;
                    for (uint j = i + 1; j < len; ++j)
                    {
                        mdr.DValue jObj      = array.Elements[j];
                        double compareResult = 0;
                        if (jObj.ValueType == mdr.ValueTypes.Undefined)
                        {
                            compareResult = 1;
                        }
                        else if (minObj.ValueType == mdr.ValueTypes.Undefined)
                        {
                            compareResult = -1;
                        }
                        else if (argsCount == 1 && function.ValueType == mdr.ValueTypes.Function)
                        {
                            callFrame.Function = function.AsDFunction();
                            callFrame.SetArg(0, ref minObj);
                            callFrame.SetArg(1, ref jObj);
                            callFrame.PassedArgsCount = 2;
                            callFrame.Signature       = new mdr.DFunctionSignature(ref callFrame, 2);
                            callFrame.Function.Call(ref callFrame);
                            compareResult = Operations.Convert.ToInt32.Run(ref callFrame.Return) <= 0 ? 1 : -1;
                        }
                        else
                        {
                            mdr.DValue v1 = mdr.DValue.Create(jObj.AsString());
                            mdr.DValue v2 = mdr.DValue.Create(minObj.AsString());
                            compareResult = Operations.Binary.LessThan.Run(ref v1, ref v2) ? -1 : 1;
                        }

                        if (compareResult < 0)
                        {
                            themin = j;
                            minObj = jObj;
                        }
                    }
                    if (themin > i)
                    {
                        array.Elements[i]      = minObj;
                        array.Elements[themin] = iObj;
                    }
                }
                callFrame.Return.Set(array);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.13
            TargetPrototype.DefineOwnProperty("unshift", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.unshift");
                var thisObj      = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();

                int len       = array.Length;
                int argsCount = callFrame.PassedArgsCount;
                array.ResizeElements(len + argsCount);
                array.Length = len + argsCount;
                if (argsCount != 0 && len != 0)
                {
                    mdr.DValue iObj;
                    for (int i = len; i > 0; --i)
                    {
                        iObj = array.Elements[i - 1];
                        array.Elements[i - 1].Set(0);
                        array.Elements[i + argsCount - 1] = iObj;
                    }
                }
                for (int k = 0; k < argsCount; ++k)
                {
                    array.Elements[k] = callFrame.Arg(k);
                }
                callFrame.Return.Set(array.Length);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.14
            TargetPrototype.DefineOwnProperty("indexOf", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.indexOf");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                int index        = 0;
                if (callFrame.PassedArgsCount > 1)
                {
                    index = Operations.Convert.ToInt32.Run(ref callFrame.Arg1);
                }
                index = index < 0 ? Math.Max(len + index, 0) : Math.Min(index, len);
                mdr.DValue searchElem = callFrame.Arg0;
                for (; index < len; ++index)
                {
                    mdr.DValue indexElem = array.Elements[index];
                    if (indexElem.ValueType != mdr.ValueTypes.Undefined &&
                        Operations.Binary.Equal.Run(ref indexElem, ref searchElem))
                    {
                        callFrame.Return.Set(index);
                        return;
                    }
                }
                callFrame.Return.Set(-1);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.15
            TargetPrototype.DefineOwnProperty("lastIndexOf", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.lastIndexOf");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(-1);
                    return;
                }
                int index = len - 1;
                if (callFrame.PassedArgsCount > 1)
                {
                    index = Operations.Convert.ToInt32.Run(ref callFrame.Arg1);
                }
                index = index < 0 ? len + index : Math.Min(index, len - 1);
                if (index < 0)
                {
                    callFrame.Return.Set(-1);
                    return;
                }
                mdr.DValue searchElem = callFrame.Arg0;
                do
                {
                    mdr.DValue indexElem = array.Elements[index];
                    if (indexElem.ValueType != mdr.ValueTypes.Undefined &&
                        Operations.Binary.Equal.Run(ref indexElem, ref searchElem))
                    {
                        callFrame.Return.Set(index);
                        return;
                    }
                } while (index-- > 0);
                callFrame.Return.Set(-1);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.16
            TargetPrototype.DefineOwnProperty("every", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.every");
                var thisObj      = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(array);
                }

                // TODO: Commented because argsCount is unused.
                /*int argsCount = callFrame.ArgsCount;*/
                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                bool result            = true;

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, thisObj);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        if (Operations.Convert.ToBoolean.Run(ref callFrame.Return) == false)
                        {
                            result = false;
                            break;
                        }
                    }
                }
                callFrame.Return.Set(result);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.17
            TargetPrototype.DefineOwnProperty("some", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.some");
                var thisObj      = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(array);
                }

                // TODO: Commented because argsCount is unused.
                /*int argsCount = callFrame.ArgsCount;*/
                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                bool result            = false;

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, thisObj);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        if (Operations.Convert.ToBoolean.Run(ref callFrame.Return) == true)
                        {
                            result = true;
                            break;
                        }
                    }
                }
                callFrame.Return.Set(result);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.18
            TargetPrototype.DefineOwnProperty("forEach", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.forEach");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(array);
                }

                mdr.DFunction function = callFrame.Arg0.AsDFunction();

                // TODO: Commented because thisArg is unused.

                /*mdr.DValue thisArg;
                 * if (callFrame.ArgsCount > 1)
                 *  thisArg = callFrame.Arg1;
                 * else
                 *  thisArg = new mdr.DValue();*/

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function        = function;
                        callFrame.PassedArgsCount = 3;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, array);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                    }
                }
                callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.19
            TargetPrototype.DefineOwnProperty("map", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.map");
                mdr.DArray array = callFrame.This.ToDArray();
                int len          = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(array);
                }

                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                mdr.DObject thisArg;
                if (callFrame.PassedArgsCount > 1)
                {
                    thisArg = Operations.Convert.ToObject.Run(ref callFrame.Arg1);
                }
                else
                {
                    thisArg = mdr.Runtime.Instance.GlobalContext;
                }

                mdr.DArray newarray = new mdr.DArray(len);

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function        = function;
                        callFrame.This            = thisArg;
                        callFrame.PassedArgsCount = 3;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, array);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        newarray.Elements[i] = callFrame.Return;
                    }
                }
                callFrame.Return.Set(newarray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            TargetPrototype.DefineOwnProperty("filter", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            TargetPrototype.DefineOwnProperty("reduce", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);
            TargetPrototype.DefineOwnProperty("reduceRight", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);
        }
コード例 #19
0
 public static void Throw(mdr.DArray e)
 {
     throw new JSException(e);
 }
コード例 #20
0
ファイル: Stack.cs プロジェクト: reshadi2/mcjs
 public static void CreateArray(int itemsCount, ref Stack stack)
 {
   //Debug.WriteLine("calling Exec.CreateArray");
   var sp = stack.Sp - 1;
   var array = new mdr.DArray(itemsCount);
   for (var i = itemsCount - 1; i >= 0; --i, --sp)
     array.Elements[i] = stack.Items[sp];
   stack.Items[sp + 1].Set(array);
   stack.Sp = sp + 2;
 }
コード例 #21
0
ファイル: JSString.cs プロジェクト: reshadi2/mcjs
    // ECMA-262 section 15.5.4.14
    void split(ref mdr.CallFrame callFrame)
    {
      Debug.WriteLine("Calling JSString.split()");

      var S = Operations.Convert.ToString.Run(callFrame.This);

      mdr.DArray A = new mdr.DArray();

      var limit = (callFrame.PassedArgsCount > 1 && callFrame.Arg1.ValueType != mdr.ValueTypes.Undefined)
        ? Operations.Convert.ToUInt32.Run(ref callFrame.Arg1)
        : UInt32.MaxValue;

      if (limit == 0)
      {
        callFrame.Return.Set(A);
        return;
      }

      if (callFrame.PassedArgsCount == 0 || callFrame.Arg0.ValueType == mdr.ValueTypes.Undefined)
      {
        A.SetField(0, S);
        callFrame.Return.Set(A);
        return;
      }

      if (string.IsNullOrEmpty(S))
      {
        if (callFrame.PassedArgsCount != 0
          //&& callFrame.Arg0.ValueType != mdr.ValueTypes.Undefined
          && callFrame.Arg0.ValueType == mdr.ValueTypes.String
          && !String.IsNullOrEmpty(callFrame.Arg0.AsString()))
        {
          //A.SetField(0, new mdr.DString(""));
          A.SetField(0, "");
        }
        callFrame.Return.Set(A);
        return;
      }

      int s = S.Length;

      string[] result;
      if (callFrame.Arg0.ValueType == mdr.ValueTypes.String)
      {
        string separator = callFrame.Arg0.AsString();
        if (String.IsNullOrEmpty(separator))
        {
          int i = 0;
          result = new string[s];
          foreach (char c in S)
            result[i++] = new string(c, 1);
        }
        else
        {
          result = S.Split(new string[] { separator }, StringSplitOptions.None);
        }
      }
      else
      {
        Debug.Assert(callFrame.Arg0.ValueType == mdr.ValueTypes.Object, "Does not know what to do with argument type {0} in split", callFrame.Arg0.ValueType);
        mdr.DRegExp regexpSeparator = callFrame.Arg0.AsDObject() as mdr.DRegExp;
        Debug.Assert(regexpSeparator != null, "Does not know what to do with argument type {0} in split", callFrame.Arg0.ValueType);
        //string pattern = regexpSeparator.Value.ToString();
        //result = Regex.Split(S, pattern, RegexOptions.ECMAScript);
        result = regexpSeparator.Value.Split(S);
      }

      for (int i = 0; i < result.Length && i < limit; i++)
      {
        //A.SetField(i, new mdr.DString(result[i]));
        A.SetField(i, result[i]);
      }

      callFrame.Return.Set(A);
    }
コード例 #22
0
ファイル: JSString.cs プロジェクト: reshadi2/mcjs
    // ECMA-262 section 15.5.4.10
    void match(ref mdr.CallFrame callFrame)
    {
      Debug.WriteLine("Calling JSString.match()");
      string S = callFrame.This.ToString();
      mdr.DRegExp rx = callFrame.Arg0.AsDObject() as mdr.DRegExp;
      if (rx == null)
        rx = new mdr.DRegExp(callFrame.Arg0.AsString());
      if (!rx.Global)
      {
        callFrame.Return.Set(rx.ExecImplementation(S));
        return;
      }

      mdr.DArray result = new mdr.DArray();
      int i = 0;
      foreach (Match match in (rx.Value).Matches(S))
      {
        foreach (Group group in match.Groups)
        {
          //result.SetField(i++, new mdr.DString(group.Value.ToString()));
          result.SetField(i++, group.Value);
        }
      }
      callFrame.Return.Set(result);
    }
コード例 #23
0
ファイル: JSArray.cs プロジェクト: reshadi2/mcjs
        public JSArray()
            : base(mdr.Runtime.Instance.DArrayPrototype, "Array")
        {
            JittedCode = (ref mdr.CallFrame callFrame) =>
            {
                mdr.DArray array;

                var argsCount = callFrame.PassedArgsCount;

                if (argsCount == 1)
                {
                    var len = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                    array = new mdr.DArray(len);
                }
                else
                {
                    array = new mdr.DArray(argsCount);
                    switch (argsCount)
                    {
                        case 0: break;
                        case 1: break;
                        case 2:
                            array.Elements[1] = callFrame.Arg1;
                            array.Elements[0] = callFrame.Arg0;
                            break;
                        case 3:
                            array.Elements[2] = callFrame.Arg2;
                            goto case 2;
                        case 4:
                            array.Elements[3] = callFrame.Arg3;
                            goto case 3;
                        default:
                            Debug.Assert(argsCount > mdr.CallFrame.InlineArgsCount, "Code gen must be updated to support new CallFrame");
                            Array.Copy(callFrame.Arguments, 0, array.Elements, mdr.CallFrame.InlineArgsCount, argsCount - mdr.CallFrame.InlineArgsCount);
                            goto case 4;
                    }
                }
                if (IsConstrutor)
                    callFrame.This = (array);
                else
                    callFrame.Return.Set(array);
            };

            // ECMA-262 section 15.4.3.1
            this.DefineOwnProperty("isArray", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.isArray");
                if (callFrame.This.ValueType == mdr.ValueTypes.Array)
                    callFrame.Return.Set(true);
                else
                    callFrame.Return.Set(false);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.2
            TargetPrototype.DefineOwnProperty("toString", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.toString");
                var join = callFrame.This.GetField("join");
                if (join.ValueType == mdr.ValueTypes.Function)// it is callable
                {
                    var joinFun = join.AsDFunction();
                    Debug.Assert(joinFun != null, "Invalid situation!");
                    callFrame.Function = joinFun;
                    //callFrame.This is already set
                    callFrame.Signature = mdr.DFunctionSignature.EmptySignature;
                    callFrame.PassedArgsCount = 0;
                    callFrame.Arguments = null;
                    joinFun.Call(ref callFrame);
                    callFrame.Return.Set(callFrame.Return.AsString());
                }
                else
                    callFrame.Return.Set(callFrame.This.ToString());
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.3
            TargetPrototype.DefineOwnProperty("toLocaleString", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                throw new NotImplementedException("Array.toLocaleString is not implemented");
                // TODO: callFrame.This is not an accurate implementation
                /*mdr.DObject array = callFrame.This;
                mdr.DFunction join = array.GetField("join").ToDObject() as mdr.DFunction;
                if (join != null) // it is callable
                {
                    callFrame.Function = join;
                    callFrame.Signature = mdr.DFunctionSignature.EmptySignature;
                    callFrame.Arguments = null;
                    join.Call(ref callFrame);
                    callFrame.Return.Set(callFrame.Return.ToString());    //TODO: is this the right implementation?
                }
                else
                    callFrame.Return.Set(array.ToString());*/
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.4
            TargetPrototype.DefineOwnProperty("concat", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.concat");
                //The most common case is calling .concat on array object with normal set of arguments
                mdr.DArray newArray;
                var destStartIndex = 0;

                var thisArray = callFrame.This as mdr.DArray;
                if(thisArray != null)
                {
                  newArray = new mdr.DArray(callFrame.PassedArgsCount + thisArray.Length);
                  Array.Copy(thisArray.Elements, 0, newArray.Elements, 0, thisArray.Length);
                  destStartIndex = thisArray.Length;
                }
                else 
                {
                  newArray = new mdr.DArray(callFrame.PassedArgsCount + 1);
                  newArray.Elements[0].Set(callFrame.This);
                  destStartIndex = 1;
                }
                for (int i = 0; i < callFrame.PassedArgsCount; ++i)
                {
                  newArray.Elements[destStartIndex] = callFrame.Arg(i); //This is the common case
                  if (newArray.Elements[destStartIndex].ValueType == mdr.ValueTypes.Array)
                  {
                    var array = newArray.Elements[destStartIndex].AsDArray();
                    //We had already accounted 1 cell for this item, so, we add the missing remaining elements
                    newArray.Length += (array.Length - 1); //Extends newArray.Elements
                    Array.Copy(array.Elements, 0, newArray.Elements, destStartIndex, array.Length);
                    destStartIndex += array.Length;
                  }
                  else
                    ++destStartIndex;
                }
                //concat(newArray, ref callFrame.Arguments[i]);

                callFrame.Return.Set(newArray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.5
            TargetPrototype.DefineOwnProperty("join", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.join");
                string separator = (callFrame.PassedArgsCount == 0 || callFrame.Arg0.ValueType == mdr.ValueTypes.Undefined)
                    ? ","
                    : callFrame.Arg0.AsString();

                callFrame.Return.Set(join(callFrame.This, separator).ToString());
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.6
            TargetPrototype.DefineOwnProperty("pop", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.pop");
                var This = callFrame.This;
                var lenField = This.GetField("length");
                int len = Operations.Convert.ToInt32.Run(ref lenField);
                if (len == 0)
                {
                    This.SetField("length", 0);
                    callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
                }
                else if (len > 0)
                {
                    var index = len - 1;
                    mdr.DValue element = new mdr.DValue();
                    This.GetField(index, ref element);
                    This.DeletePropertyDescriptor(index.ToString());
                    This.SetField("length", index);
                    callFrame.Return.Set(ref element);
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.7
            TargetPrototype.DefineOwnProperty("push", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.push");
                var This = callFrame.This;
                var lenField = This.GetField("length");
                int len = Operations.Convert.ToInt32.Run(ref lenField);
                mdr.DValue arg = new mdr.DValue();
                for (int i = 0; i < callFrame.PassedArgsCount; ++i)
                {
                    arg = callFrame.Arg(i);
                    This.SetField(len, ref arg);
                    len++;
                }
                This.SetField("length", len);
                callFrame.Return.Set(len);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.8
            TargetPrototype.DefineOwnProperty("reverse", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.reverse");
                var This = callFrame.This;
                var lenField = This.GetField("length");
                int len = Operations.Convert.ToInt32.Run(ref lenField);
                int middle = len / 2;
                mdr.DValue lowerValue = new mdr.DValue();
                mdr.DValue upperValue = new mdr.DValue();
                bool lowerExists, upperExists;
                for (int lower = 0; lower != middle; lower++)
                {
                    int upper = len - lower - 1;
                    lowerExists = This.HasProperty(lower);
                    upperExists = This.HasProperty(upper);
                    if (lowerExists && upperExists)
                    {
                        This.GetField(lower, ref lowerValue);
                        This.GetField(upper, ref upperValue);
                        This.SetField(lower, ref upperValue);
                        This.SetField(upper, ref lowerValue);
                    }
                    else if (!lowerExists && upperExists)
                    {
                        This.GetField(upper, ref upperValue);
                        This.SetField(lower, ref upperValue);
                        This.DeletePropertyDescriptor(upper.ToString());
                    }
                    else if (lowerExists && !upperExists)
                    {
                        This.GetField(lower, ref lowerValue);
                        This.SetField(upper, ref lowerValue);
                        This.DeletePropertyDescriptor(lower.ToString());
                    }
                }
                callFrame.Return.Set(This);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.9
            TargetPrototype.DefineOwnProperty("shift", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.shift");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                if (array == null || array.Length == 0)
                    //callFrame.Return.ValueType = mdr.ValueTypes.Undefined;
                    callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
                else
                {
                    callFrame.Return.Set(ref array.Elements[0]);
                    for (int k = 1; k < len; k++)
                        array.Elements[k - 1].Set(ref array.Elements[k]);

                    array.Length--;
                }
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.10
            TargetPrototype.DefineOwnProperty("slice", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.slice");
                /*  TODO: This is the implementation for a case that "this" is a DArray. Use this faster implementation after adding PackedArray optimization.
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                int relativeStart = callFrame.Arg0.ToInt32();
                int k = (relativeStart < 0) ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                int relativeEnd = (callFrame.Arg1.ValueType == mdr.ValueTypes.Undefined) ? len : callFrame.Arg1.ToInt32();
                int final = (relativeEnd < 0) ? Math.Max(relativeEnd + len, 0) : Math.Min(relativeEnd, len);
                mdr.DArray newArray = new mdr.DArray((final - k > 0) ? (final - k) : 0);
                for (int n = 0; k < final; k++, n++)
                    newArray.Elements[n].Set(ref array.Elements[k]);
                callFrame.Return.Set(newArray);
                 */

                var This = callFrame.This;
                var lenField = This.GetField("length");
                int len = Operations.Convert.ToInt32.Run(ref lenField);
                int relativeStart = 0;
                if (callFrame.PassedArgsCount > 0 ) 
                  relativeStart = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                int k = (relativeStart < 0) ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                int relativeEnd = ((callFrame.Arg1.ValueType == mdr.ValueTypes.Undefined) || (callFrame.PassedArgsCount < 2)) ? len : Operations.Convert.ToInt32.Run(ref callFrame.Arg1 );
                int final = (relativeEnd < 0) ? Math.Max(relativeEnd + len, 0) : Math.Min(relativeEnd, len);
                mdr.DArray newArray = new mdr.DArray((final - k > 0) ? (final - k) : 0);
                mdr.DValue item = new mdr.DValue();
                for (int n = 0; k < final; k++, n++)
                {
                    This.GetField(k, ref item);
                    newArray.Elements[n].Set(ref item);
                }
                callFrame.Return.Set(newArray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.12
            //TODO: splice is generic and can be applied to other objects
            TargetPrototype.DefineOwnProperty("splice", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.splice");
                if (callFrame.PassedArgsCount < 2)
                {
                    callFrame.Return.Set(JSRuntime.Instance.DefaultDUndefined);
                    return;
                }
                var A = new mdr.DArray();
                var This = callFrame.This as mdr.DArray;
                if (This == null)
                    throw new Exception("Object is not an array, but splice must work with generic objects. Please fix it!");
                int len = This.Length;
                int relativeStart = Operations.Convert.ToInt32.Run(ref callFrame.Arg0);
                int actualStart = relativeStart < 0 ? Math.Max(len + relativeStart, 0) : Math.Min(relativeStart, len);
                int actualDeleteCount = Math.Min(Math.Max(Operations.Convert.ToInt32.Run(ref callFrame.Arg1), 0), len - actualStart);

                A.Length = actualDeleteCount;
                for (int k = 0; k < actualDeleteCount; k++)
                {
                    int from = relativeStart + k;
                    if (from < len)
                        A.Elements[k].Set(ref This.Elements[from]);
                }

                int itemCount = callFrame.PassedArgsCount - 2;
                if (itemCount < actualDeleteCount)
                {
                    for (int k = actualStart; k < len - actualDeleteCount; k++)
                    {
                        int from = k + actualDeleteCount;
                        int to = k + itemCount;
                        // if (from < len) // This condition will always hold
                        This.Elements[to].Set(ref This.Elements[from]);
                        // from will always be less than less and therefore the element exists in the array 
                        //TODO: can we assume any index less than Length exist? When an element is deleted from middle of the Elements, is Length adjusted?
                        /*
                        else
                        {
                            This.RemoveElements(to, len - actualDeleteCount - k);
                            break;
                        }*/
                    }
                    This.RemoveElements(len - actualDeleteCount + itemCount, actualDeleteCount - itemCount);
                    This.Length = len - actualDeleteCount + itemCount;
                }
                else if (itemCount > actualDeleteCount)
                {
                    This.Length = len - actualDeleteCount + itemCount;
                    for (int k = len - actualDeleteCount; k > actualStart; k--)
                    {
                        int from = k + actualDeleteCount - 1;
                        int to = k + itemCount - 1;
                        //if (from < len) //This condition will always hold
                        This.Elements[to].Set(ref This.Elements[from]);
                    }
                }

                for (int k = 0; k < itemCount; k++)
                    This.Elements[k + actualStart] = callFrame.Arg(k + 2);

                
                callFrame.Return.Set(A);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.11
            TargetPrototype.DefineOwnProperty("sort", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.sort");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                if (len == 0)
                    callFrame.Return.Set(array);

                int argsCount = callFrame.PassedArgsCount;
                mdr.DValue function = callFrame.Arg0;

                for (uint i = 0; i < len - 1; ++i)
                {
                    mdr.DValue iObj = array.Elements[i];
                    uint themin = i;
                    mdr.DValue minObj = iObj;
                    for (uint j = i + 1; j < len; ++j)
                    {
                        mdr.DValue jObj = array.Elements[j];
                        double compareResult = 0;
                        if (jObj.ValueType == mdr.ValueTypes.Undefined)
                            compareResult = 1;
                        else if (minObj.ValueType == mdr.ValueTypes.Undefined)
                            compareResult = -1;
                        else if (argsCount == 1 && function.ValueType == mdr.ValueTypes.Function)
                        {
                            callFrame.Function = function.AsDFunction();
                            callFrame.SetArg(0, ref minObj);
                            callFrame.SetArg(1, ref jObj);
                            callFrame.PassedArgsCount = 2;
                            callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 2);
                            callFrame.Function.Call(ref callFrame);
                            compareResult = Operations.Convert.ToInt32.Run(ref callFrame.Return) <= 0 ? 1 : -1;
                        }
                        else
                        {
                            mdr.DValue v1 = mdr.DValue.Create(jObj.AsString());
                            mdr.DValue v2 = mdr.DValue.Create(minObj.AsString());
                            compareResult = Operations.Binary.LessThan.Run(ref v1, ref v2) ? -1 : 1;
                        }

                        if (compareResult < 0)
                        {
                            themin = j;
                            minObj = jObj;
                        }
                    }
                    if (themin > i)
                    {
                        array.Elements[i] = minObj;
                        array.Elements[themin] = iObj;
                    }
                }
                callFrame.Return.Set(array);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.13
            TargetPrototype.DefineOwnProperty("unshift", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.unshift");
                var thisObj = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();

                int len = array.Length;
                int argsCount = callFrame.PassedArgsCount;
                array.ResizeElements(len + argsCount);
                array.Length = len + argsCount;
                if (argsCount != 0 && len != 0)
                {
                    mdr.DValue iObj;
                    for (int i = len; i > 0; --i)
                    {
                        iObj = array.Elements[i - 1];
                        array.Elements[i - 1].Set(0);
                        array.Elements[i + argsCount - 1] = iObj;

                    }
                }
                for (int k = 0; k < argsCount; ++k)
                {
                    array.Elements[k] = callFrame.Arg(k);
                }
                callFrame.Return.Set(array.Length);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.14
            TargetPrototype.DefineOwnProperty("indexOf", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.indexOf");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                int index = 0;
                if (callFrame.PassedArgsCount > 1)
                    index = Operations.Convert.ToInt32.Run(ref callFrame.Arg1);
                index = index < 0 ? Math.Max(len + index, 0) : Math.Min(index, len);
                mdr.DValue searchElem = callFrame.Arg0;
                for (; index < len; ++index)
                {
                    mdr.DValue indexElem = array.Elements[index];
                    if (indexElem.ValueType != mdr.ValueTypes.Undefined
                        && Operations.Binary.Equal.Run(ref indexElem, ref searchElem))
                    {
                        callFrame.Return.Set(index);
                        return;
                    }
                }
                callFrame.Return.Set(-1);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.15
            TargetPrototype.DefineOwnProperty("lastIndexOf", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.lastIndexOf");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                if (len == 0)
                {
                    callFrame.Return.Set(-1);
                    return;
                }
                int index = len - 1;
                if (callFrame.PassedArgsCount > 1)
                    index = Operations.Convert.ToInt32.Run(ref callFrame.Arg1);
                index = index < 0 ? len + index : Math.Min(index, len - 1);
                if (index < 0)
                {
                    callFrame.Return.Set(-1);
                    return;
                }
                mdr.DValue searchElem = callFrame.Arg0;
                do
                {
                    mdr.DValue indexElem = array.Elements[index];
                    if (indexElem.ValueType != mdr.ValueTypes.Undefined
                        && Operations.Binary.Equal.Run(ref indexElem, ref searchElem))
                    {
                        callFrame.Return.Set(index);
                        return;
                    }
                } while (index-- > 0);
                callFrame.Return.Set(-1);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.16
            TargetPrototype.DefineOwnProperty("every", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.every");
                var thisObj = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();
                int len = array.Length;
                if (len == 0)
                    callFrame.Return.Set(array);

                // TODO: Commented because argsCount is unused.
                /*int argsCount = callFrame.ArgsCount;*/
                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                bool result = true;

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, thisObj);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        if (Operations.Convert.ToBoolean.Run(ref callFrame.Return) == false)
                        {
                            result = false;
                            break;
                        }
                    }
                }
                callFrame.Return.Set(result);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.17
            TargetPrototype.DefineOwnProperty("some", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.some");
                var thisObj = callFrame.This;
                mdr.DArray array = thisObj.ToDArray();
                int len = array.Length;
                if (len == 0)
                    callFrame.Return.Set(array);

                // TODO: Commented because argsCount is unused.
                /*int argsCount = callFrame.ArgsCount;*/
                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                bool result = false;

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, thisObj);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        if (Operations.Convert.ToBoolean.Run(ref callFrame.Return) == true)
                        {
                            result = true;
                            break;
                        }
                    }
                }
                callFrame.Return.Set(result);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.18
            TargetPrototype.DefineOwnProperty("forEach", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.forEach");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                if (len == 0)
                    callFrame.Return.Set(array);

                mdr.DFunction function = callFrame.Arg0.AsDFunction();
 
                // TODO: Commented because thisArg is unused.
                /*mdr.DValue thisArg;
                if (callFrame.ArgsCount > 1)
                    thisArg = callFrame.Arg1;
                else
                    thisArg = new mdr.DValue();*/

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.PassedArgsCount = 3;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, array);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                    }
                }
                callFrame.Return.Set(mdr.Runtime.Instance.DefaultDUndefined);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            // ECMA-262 section 15.4.4.19
            TargetPrototype.DefineOwnProperty("map", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Debug.WriteLine("Calling JSArray.map");
                mdr.DArray array = callFrame.This.ToDArray();
                int len = array.Length;
                if (len == 0)
                    callFrame.Return.Set(array);

                mdr.DFunction function = callFrame.Arg0.AsDFunction();
                mdr.DObject thisArg;
                if (callFrame.PassedArgsCount > 1)
                    thisArg = Operations.Convert.ToObject.Run(ref callFrame.Arg1);
                else
                    thisArg = mdr.Runtime.Instance.GlobalContext;

                mdr.DArray newarray = new mdr.DArray(len);

                for (int i = 0; i < len; ++i)
                {
                    if (array.Elements[i].ValueType != mdr.ValueTypes.Undefined)
                    {
                        callFrame.Function = function;
                        callFrame.This = thisArg;
                        callFrame.PassedArgsCount = 3;
                        callFrame.SetArg(0, ref array.Elements[i]);
                        callFrame.SetArg(1, i);
                        callFrame.SetArg(2, array);
                        callFrame.Signature = new mdr.DFunctionSignature(ref callFrame, 3);
                        callFrame.Function.Call(ref callFrame);
                        newarray.Elements[i] = callFrame.Return;
                    }
                }
                callFrame.Return.Set(newarray);
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            TargetPrototype.DefineOwnProperty("filter", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

            TargetPrototype.DefineOwnProperty("reduce", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);
            TargetPrototype.DefineOwnProperty("reduceRight", new mdr.DFunction((ref mdr.CallFrame callFrame) =>
            {
                Trace.Fail("Unimplemented");
            }), mdr.PropertyDescriptor.Attributes.NotEnumerable | mdr.PropertyDescriptor.Attributes.Data);

        }
コード例 #24
0
ファイル: DRegExp.cs プロジェクト: reshadi2/mcjs
        public mdr.DObject ExecImplementation(string S)
        {
            if (S == null)
                return Runtime.Instance.DefaultDNull;
            Match match = MatchImplementation(S);
            if (match == null)
                return Runtime.Instance.DefaultDNull;

            int n = match.Captures.Count;
            mdr.DArray result = new mdr.DArray(n);
            result.SetField("index", match.Index);
            result.SetField("input", S);
            //result.SetField(0, match.Value);
            if (MatchedGroups != null)
            {
              for (int g = 0; g < MatchedGroups.Count; g++)
              {
                 if (MatchedGroups[g].Captures.Count > 0)
                 {
                    result.SetField(g, MatchedGroups[g].Captures[0].Value);
                 }
              }
            }
            return result;
        }