1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980 |
- using Jint.Native;
- namespace Jint.Runtime.Interpreter.Expressions
- {
- internal sealed class JintNewExpression : JintExpression
- {
- private JintExpression _calleeExpression = null!;
- private JintExpression[] _jintArguments = Array.Empty<JintExpression>();
- private bool _hasSpreads;
- private bool _initialized;
- public JintNewExpression(NewExpression expression) : base(expression)
- {
- }
- private void Initialize()
- {
- var expression = (NewExpression) _expression;
- _calleeExpression = Build(expression.Callee);
- if (expression.Arguments.Count <= 0)
- {
- return;
- }
- _jintArguments = new JintExpression[expression.Arguments.Count];
- for (var i = 0; i < _jintArguments.Length; i++)
- {
- var argument = expression.Arguments[i];
- _jintArguments[i] = Build(argument);
- _hasSpreads |= argument.Type == NodeType.SpreadElement;
- }
- }
- protected override object EvaluateInternal(EvaluationContext context)
- {
- if (!_initialized)
- {
- Initialize();
- _initialized = true;
- }
- var engine = context.Engine;
- // todo: optimize by defining a common abstract class or interface
- var jsValue = _calleeExpression.GetValue(context);
- JsValue[] arguments;
- if (_jintArguments.Length == 0)
- {
- arguments = Array.Empty<JsValue>();
- }
- else if (_hasSpreads)
- {
- arguments = BuildArgumentsWithSpreads(context, _jintArguments);
- }
- else
- {
- arguments = engine._jsValueArrayPool.RentArray(_jintArguments.Length);
- BuildArguments(context, _jintArguments, arguments);
- }
- // Reset the location to the "new" keyword so that if an Error object is
- // constructed below, the stack trace will capture the correct location.
- context.LastSyntaxElement = _expression;
- if (!jsValue.IsConstructor)
- {
- ExceptionHelper.ThrowTypeError(engine.Realm, _calleeExpression.SourceText + " is not a constructor");
- }
- // construct the new instance using the Function's constructor method
- var instance = engine.Construct(jsValue, arguments, jsValue, _calleeExpression);
- engine._jsValueArrayPool.ReturnArray(arguments);
- return instance;
- }
- }
- }
|