protected override void Initialize() { _body = Build(_engine, _statement.Body); if (_statement.Init != null) { if (_statement.Init.Type == Nodes.VariableDeclaration) { var d = (VariableDeclaration)_statement.Init; if (d.Kind != VariableDeclarationKind.Var) { _boundNames = new List <string>(); d.GetBoundNames(_boundNames); } _initStatement = new JintVariableDeclaration(_engine, d); _shouldCreatePerIterationEnvironment = d.Kind == VariableDeclarationKind.Let; } else { _initExpression = JintExpression.Build(_engine, (Expression)_statement.Init); } } if (_statement.Test != null) { _test = JintExpression.Build(_engine, _statement.Test); } if (_statement.Update != null) { _increment = JintExpression.Build(_engine, _statement.Update); } }
protected override void Initialize(EvaluationContext context) { _block = Build(_statement.Block); if (_statement.Finalizer != null) { _finalizer = Build(_statement.Finalizer); } }
public JintTryStatement(Engine engine, TryStatement statement) : base(engine, statement) { _block = Build(engine, statement.Block); if (_statement.Handler != null) { _catch = Build(engine, _statement.Handler.Body); _catchParamName = ((Identifier)_statement.Handler.Param).Name; } if (statement.Finalizer != null) { _finalizer = Build(engine, _statement.Finalizer); } }
protected override void Initialize(EvaluationContext context) { _lhsKind = LhsKind.Assignment; var engine = context.Engine; if (_leftNode is VariableDeclaration variableDeclaration) { _lhsKind = variableDeclaration.Kind == VariableDeclarationKind.Var ? LhsKind.VarBinding : LhsKind.LexicalBinding; var variableDeclarationDeclaration = variableDeclaration.Declarations[0]; var id = variableDeclarationDeclaration.Id; if (_lhsKind == LhsKind.LexicalBinding) { _tdzNames = new List <string>(1); id.GetBoundNames(_tdzNames); } if (id is BindingPattern bindingPattern) { _destructuring = true; _assignmentPattern = bindingPattern; } else { var identifier = (Identifier)id; _expr = new JintIdentifierExpression(identifier); } } else if (_leftNode is BindingPattern bindingPattern) { _destructuring = true; _assignmentPattern = bindingPattern; } else if (_leftNode is MemberExpression memberExpression) { _expr = new JintMemberExpression(memberExpression); } else { _expr = new JintIdentifierExpression((Identifier)_leftNode); } _body = Build(_forBody); _right = JintExpression.Build(engine, _rightExpression); }
protected override void Initialize(EvaluationContext context) { _body = Build(_statement.Body); _object = JintExpression.Build(context.Engine, _statement.Object); }
/// <summary> /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset /// </summary> private Completion BodyEvaluation( JintExpression lhs, JintStatement stmt, IIterator iteratorRecord, IterationKind iterationKind, LhsKind lhsKind, IteratorKind iteratorKind = IteratorKind.Sync) { var oldEnv = _engine.ExecutionContext.LexicalEnvironment; var v = Undefined.Instance; var destructuring = _destructuring; string lhsName = null; var completionType = CompletionType.Normal; var close = false; try { while (true) { LexicalEnvironment iterationEnv = null; if (!iteratorRecord.TryIteratorStep(out var nextResult)) { close = true; return(new Completion(CompletionType.Normal, v, null, Location)); } if (iteratorKind == IteratorKind.Async) { // nextResult = await nextResult; } var nextValue = nextResult.Get(CommonProperties.Value); close = true; Reference lhsRef = null; if (lhsKind != LhsKind.LexicalBinding) { if (!destructuring) { lhsRef = (Reference)lhs.Evaluate(); } } else { iterationEnv = LexicalEnvironment.NewDeclarativeEnvironment(_engine, oldEnv); if (_tdzNames != null) { BindingInstantiation(iterationEnv); } _engine.UpdateLexicalEnvironment(iterationEnv); if (!destructuring) { if (lhsName == null) { lhsName = ((Identifier)((VariableDeclaration)_leftNode).Declarations[0].Id).Name; } lhsRef = _engine.ResolveBinding(lhsName); } } if (!destructuring) { // If lhsRef is an abrupt completion, then // Let status be lhsRef. if (lhsKind == LhsKind.LexicalBinding) { lhsRef.InitializeReferencedBinding(nextValue); } else { _engine.PutValue(lhsRef, nextValue); } } else { BindingPatternAssignmentExpression.ProcessPatterns( _engine, _assignmentPattern, nextValue, iterationEnv, checkObjectPatternPropertyReference: _lhsKind != LhsKind.VarBinding); if (lhsKind == LhsKind.Assignment) { // DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument. } else if (lhsKind == LhsKind.VarBinding) { // BindingInitialization for lhs passing nextValue and undefined as the arguments. } else { // BindingInitialization for lhs passing nextValue and iterationEnv as arguments } } var result = stmt.Execute(); _engine.UpdateLexicalEnvironment(oldEnv); if (!ReferenceEquals(result.Value, null)) { v = result.Value; } if (result.Type == CompletionType.Break && (result.Identifier == null || result.Identifier == _statement?.LabelSet?.Name)) { return(new Completion(CompletionType.Normal, v, null, Location)); } if (result.Type != CompletionType.Continue || (result.Identifier != null && result.Identifier != _statement?.LabelSet?.Name)) { if (result.Type != CompletionType.Normal) { return(result); } } } } catch { completionType = CompletionType.Throw; throw; } finally { if (close) { iteratorRecord.Close(completionType); } _engine.UpdateLexicalEnvironment(oldEnv); } }
protected override void Initialize(EvaluationContext context) { _labelSetName = _statement.LabelSet?.Name; _body = Build(_statement.Body); _test = JintExpression.Build(context.Engine, _statement.Test); }
public JintDoWhileStatement(Engine engine, DoWhileStatement statement) : base(engine, statement) { _body = Build(_engine, statement.Body); _test = JintExpression.Build(engine, statement.Test); _labelSetName = statement.LabelSet?.Name; }
public JintWhileStatement(Engine engine, WhileStatement statement) : base(engine, statement) { _labelSetName = _statement?.LabelSet?.Name; _body = Build(engine, statement.Body); _test = JintExpression.Build(engine, statement.Test); }
public JintLabeledStatement(Engine engine, LabeledStatement statement) : base(engine, statement) { _body = Build(engine, statement.Body); _labelName = statement.Label.Name; }
/// <summary> /// https://tc39.es/ecma262/#sec-runtime-semantics-forin-div-ofbodyevaluation-lhs-stmt-iterator-lhskind-labelset /// </summary> private Completion BodyEvaluation( EvaluationContext context, JintExpression lhs, JintStatement stmt, IteratorInstance iteratorRecord, IterationKind iterationKind, LhsKind lhsKind, IteratorKind iteratorKind = IteratorKind.Sync) { var engine = context.Engine; var oldEnv = engine.ExecutionContext.LexicalEnvironment; var v = Undefined.Instance; var destructuring = _destructuring; string lhsName = null; var completionType = CompletionType.Normal; var close = false; try { while (true) { EnvironmentRecord iterationEnv = null; if (!iteratorRecord.TryIteratorStep(out var nextResult)) { close = true; return(new Completion(CompletionType.Normal, v, null, Location)); } if (iteratorKind == IteratorKind.Async) { // nextResult = await nextResult; ExceptionHelper.ThrowNotImplementedException("await"); } var nextValue = nextResult.Get(CommonProperties.Value); close = true; var lhsRef = new ExpressionResult(); if (lhsKind != LhsKind.LexicalBinding) { if (!destructuring) { lhsRef = lhs.Evaluate(context); } } else { iterationEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv); if (_tdzNames != null) { BindingInstantiation(iterationEnv); } engine.UpdateLexicalEnvironment(iterationEnv); if (!destructuring) { var identifier = (Identifier)((VariableDeclaration)_leftNode).Declarations[0].Id; lhsName ??= identifier.Name; lhsRef = new ExpressionResult(ExpressionCompletionType.Normal, engine.ResolveBinding(lhsName), identifier.Location); } } if (context.DebugMode) { context.Engine.DebugHandler.OnStep(_leftNode); } var status = new Completion(); if (!destructuring) { if (lhsRef.IsAbrupt()) { close = true; status = new Completion(lhsRef); } else if (lhsKind == LhsKind.LexicalBinding) { ((Reference)lhsRef.Value).InitializeReferencedBinding(nextValue); } else { engine.PutValue((Reference)lhsRef.Value, nextValue); } } else { status = BindingPatternAssignmentExpression.ProcessPatterns( context, _assignmentPattern, nextValue, iterationEnv, checkObjectPatternPropertyReference: _lhsKind != LhsKind.VarBinding); if (lhsKind == LhsKind.Assignment) { // DestructuringAssignmentEvaluation of assignmentPattern using nextValue as the argument. } else if (lhsKind == LhsKind.VarBinding) { // BindingInitialization for lhs passing nextValue and undefined as the arguments. } else { // BindingInitialization for lhs passing nextValue and iterationEnv as arguments } } if (status.IsAbrupt()) { engine.UpdateLexicalEnvironment(oldEnv); if (_iterationKind == IterationKind.AsyncIterate) { iteratorRecord.Close(status.Type); return(status); } if (iterationKind == IterationKind.Enumerate) { return(status); } iteratorRecord.Close(status.Type); return(status); } var result = stmt.Execute(context); engine.UpdateLexicalEnvironment(oldEnv); if (!ReferenceEquals(result.Value, null)) { v = result.Value; } if (result.Type == CompletionType.Break && (result.Target == null || result.Target == _statement?.LabelSet?.Name)) { completionType = CompletionType.Normal; return(new Completion(CompletionType.Normal, v, null, Location)); } if (result.Type != CompletionType.Continue || (result.Target != null && result.Target != _statement?.LabelSet?.Name)) { completionType = result.Type; if (result.IsAbrupt()) { close = true; return(result); } } } } catch { completionType = CompletionType.Throw; throw; } finally { if (close) { try { iteratorRecord.Close(completionType); } catch { // if we already have and exception, use it if (completionType != CompletionType.Throw) { throw; } } } engine.UpdateLexicalEnvironment(oldEnv); } }
public JintWithStatement(Engine engine, WithStatement statement) : base(engine, statement) { _body = Build(engine, statement.Body); _object = JintExpression.Build(engine, _statement.Object); }
protected override Completion ExecuteInternal(EvaluationContext context) { var engine = context.Engine; int callStackSizeBeforeExecution = engine.CallStack.Count; var b = _block.Execute(context); if (b.Type == CompletionType.Throw) { // initialize lazily if (_statement.Handler is not null && _catch is null) { _catch = Build(_statement.Handler.Body); } // execute catch if (_statement.Handler is not null) { // Quick-patch for call stack not being unwinded when an exception is caught. // Ideally, this should instead be solved by always popping the stack when returning // from a call, regardless of whether it throws (i.e. CallStack.Pop() in finally clause // in Engine.Call/Engine.Construct - however, that method currently breaks stack traces // in error messages. while (callStackSizeBeforeExecution < engine.CallStack.Count) { engine.CallStack.Pop(); } // https://tc39.es/ecma262/#sec-runtime-semantics-catchclauseevaluation var thrownValue = b.Value; var oldEnv = engine.ExecutionContext.LexicalEnvironment; var catchEnv = JintEnvironment.NewDeclarativeEnvironment(engine, oldEnv, catchEnvironment: true); var boundNames = new List <string>(); _statement.Handler.Param.GetBoundNames(boundNames); foreach (var argName in boundNames) { catchEnv.CreateMutableBinding(argName, false); } engine.UpdateLexicalEnvironment(catchEnv); var catchParam = _statement.Handler?.Param; catchParam.BindingInitialization(context, thrownValue, catchEnv); b = _catch.Execute(context); engine.UpdateLexicalEnvironment(oldEnv); } } if (_finalizer != null) { var f = _finalizer.Execute(context); if (f.Type == CompletionType.Normal) { return(b); } return(f.UpdateEmpty(Undefined.Instance)); } return(b.UpdateEmpty(Undefined.Instance)); }
protected override void Initialize(EvaluationContext context) { _statementConsequent = Build(_statement.Consequent); _test = JintExpression.Build(context.Engine, _statement.Test); _alternate = _statement.Alternate != null?Build(_statement.Alternate) : null; }
public JintIfStatement(Engine engine, IfStatement statement) : base(engine, statement) { _statementConsequent = Build(engine, _statement.Consequent); _test = JintExpression.Build(engine, _statement.Test); _alternate = _statement.Alternate != null?Build(engine, _statement.Alternate) : null; }
protected override void Initialize(EvaluationContext context) { _body = Build(_statement.Body); _labelName = _statement.Label.Name; }