JintVariableDeclaration.cs 4.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. using Esprima.Ast;
  2. using Jint.Native;
  3. using Jint.Native.Function;
  4. using Jint.Runtime.Interpreter.Expressions;
  5. namespace Jint.Runtime.Interpreter.Statements
  6. {
  7. internal sealed class JintVariableDeclaration : JintStatement<VariableDeclaration>
  8. {
  9. private ResolvedDeclaration[] _declarations = Array.Empty<ResolvedDeclaration>();
  10. private sealed class ResolvedDeclaration
  11. {
  12. internal JintExpression? Left;
  13. internal BindingPattern? LeftPattern;
  14. internal JintExpression? Init;
  15. internal JintIdentifierExpression? LeftIdentifierExpression;
  16. internal bool EvalOrArguments;
  17. }
  18. public JintVariableDeclaration(VariableDeclaration statement) : base(statement)
  19. {
  20. }
  21. protected override void Initialize(EvaluationContext context)
  22. {
  23. var engine = context.Engine;
  24. _declarations = new ResolvedDeclaration[_statement.Declarations.Count];
  25. for (var i = 0; i < _declarations.Length; i++)
  26. {
  27. var declaration = _statement.Declarations[i];
  28. JintExpression? left = null;
  29. JintExpression? init = null;
  30. BindingPattern? bindingPattern = null;
  31. if (declaration.Id is BindingPattern bp)
  32. {
  33. bindingPattern = bp;
  34. }
  35. else
  36. {
  37. left = JintExpression.Build((Identifier) declaration.Id);
  38. }
  39. if (declaration.Init != null)
  40. {
  41. init = JintExpression.Build(declaration.Init);
  42. }
  43. var leftIdentifier = left as JintIdentifierExpression;
  44. _declarations[i] = new ResolvedDeclaration
  45. {
  46. Left = left,
  47. LeftPattern = bindingPattern,
  48. LeftIdentifierExpression = leftIdentifier,
  49. EvalOrArguments = leftIdentifier?.HasEvalOrArguments == true,
  50. Init = init
  51. };
  52. }
  53. }
  54. protected override Completion ExecuteInternal(EvaluationContext context)
  55. {
  56. var engine = context.Engine;
  57. foreach (var declaration in _declarations)
  58. {
  59. if (_statement.Kind != VariableDeclarationKind.Var && declaration.Left != null)
  60. {
  61. var lhs = (Reference) declaration.Left.Evaluate(context);
  62. var value = JsValue.Undefined;
  63. if (declaration.Init != null)
  64. {
  65. value = declaration.Init.GetValue(context).Clone();
  66. if (declaration.Init._expression.IsFunctionDefinition())
  67. {
  68. ((Function) value).SetFunctionName(lhs.ReferencedName);
  69. }
  70. }
  71. lhs.InitializeReferencedBinding(value);
  72. engine._referencePool.Return(lhs);
  73. }
  74. else if (declaration.Init != null)
  75. {
  76. if (declaration.LeftPattern != null)
  77. {
  78. var environment = _statement.Kind != VariableDeclarationKind.Var
  79. ? engine.ExecutionContext.LexicalEnvironment
  80. : null;
  81. var value = declaration.Init.GetValue(context);
  82. BindingPatternAssignmentExpression.ProcessPatterns(
  83. context,
  84. declaration.LeftPattern,
  85. value,
  86. environment,
  87. checkPatternPropertyReference: _statement.Kind != VariableDeclarationKind.Var);
  88. }
  89. else if (declaration.LeftIdentifierExpression == null
  90. || JintAssignmentExpression.SimpleAssignmentExpression.AssignToIdentifier(
  91. context,
  92. declaration.LeftIdentifierExpression,
  93. declaration.Init,
  94. declaration.EvalOrArguments) is null)
  95. {
  96. // slow path
  97. var lhs = (Reference) declaration.Left!.Evaluate(context);
  98. lhs.AssertValid(engine.Realm);
  99. var value = declaration.Init.GetValue(context).Clone();
  100. if (declaration.Init._expression.IsFunctionDefinition())
  101. {
  102. ((Function) value).SetFunctionName(lhs.ReferencedName);
  103. }
  104. engine.PutValue(lhs, value);
  105. engine._referencePool.Return(lhs);
  106. }
  107. }
  108. }
  109. return Completion.Empty();
  110. }
  111. }
  112. }