protected override object EvaluateInternal() { var a = _engine.Array.ConstructFast(_hasSpreads ? 0 : (uint)_expressions.Length); var expressions = _expressions; uint arrayIndexCounter = 0; for (uint i = 0; i < (uint)expressions.Length; i++) { var expr = expressions[i]; if (expr == null) { arrayIndexCounter++; continue; } if (_hasSpreads && expr is JintSpreadExpression jse) { jse.GetValueAndCheckIterator(out var objectInstance, out var iterator); // optimize for array if (objectInstance is ArrayInstance ai) { var length = ai.GetLength(); var newLength = arrayIndexCounter + length; a.EnsureCapacity(newLength); a.CopyValues(ai, sourceStartIndex: 0, targetStartIndex: arrayIndexCounter, length); arrayIndexCounter += length; a.SetLength(newLength); } else { var protocol = new ArraySpreadProtocol(_engine, a, iterator, arrayIndexCounter); protocol.Execute(); arrayIndexCounter += protocol._addedCount; } } else { var value = expr.GetValue(); a.SetIndexValue(arrayIndexCounter++, value, updateLength: false); } } if (_hasSpreads) { a.SetLength(arrayIndexCounter); } return(a); }
protected override ExpressionResult EvaluateInternal(EvaluationContext context) { var engine = context.Engine; var a = engine.Realm.Intrinsics.Array.ArrayCreate(_hasSpreads ? 0 : (uint)_expressions.Length); uint arrayIndexCounter = 0; foreach (var expr in _expressions) { if (expr == null) { arrayIndexCounter++; continue; } if (_hasSpreads && expr is JintSpreadExpression jse) { jse.GetValueAndCheckIterator(context, out var objectInstance, out var iterator); // optimize for array if (objectInstance is ArrayInstance ai) { var length = ai.GetLength(); var newLength = arrayIndexCounter + length; a.EnsureCapacity(newLength); a.CopyValues(ai, sourceStartIndex: 0, targetStartIndex: arrayIndexCounter, length); arrayIndexCounter += length; a.SetLength(newLength); } else { var protocol = new ArraySpreadProtocol(engine, a, iterator, arrayIndexCounter); protocol.Execute(); arrayIndexCounter += protocol._addedCount; } } else { var value = expr.GetValue(context).Value; a.SetIndexValue(arrayIndexCounter++, value, updateLength: false); } } if (_hasSpreads) { a.SetLength(arrayIndexCounter); } return(NormalCompletion(a)); }
protected JsValue[] BuildArgumentsWithSpreads(JintExpression[] jintExpressions) { var args = new System.Collections.Generic.List <JsValue>(jintExpressions.Length); for (var i = 0; i < jintExpressions.Length; i++) { var jintExpression = jintExpressions[i]; if (jintExpression is JintSpreadExpression jse) { jse.GetValueAndCheckIterator(out var objectInstance, out var iterator); // optimize for array if (objectInstance is ArrayInstance ai) { var length = ai.GetLength(); for (uint j = 0; j < length; ++j) { if (ai.TryGetValue(j, out var value)) { args.Add(value); } } } else { var protocol = new ArraySpreadProtocol(_engine, args, iterator); protocol.Execute(); } } else { args.Add(jintExpression.GetValue().Clone()); } } return(args.ToArray()); }