private bool HandleWhileStatement(JsWhileStatement stmt, StackEntry location, ImmutableStack <StackEntry> stack, ImmutableStack <Tuple <string, State> > breakStack, ImmutableStack <Tuple <string, State> > continueStack, State currentState, State returnState, IList <JsStatement> currentBlock, bool isFirstStatement) { if (!isFirstStatement) { // We have to create a new block for the statement. var topOfLoopState = CreateNewStateValue(currentState.FinallyStack); Enqueue(stack.Push(location), breakStack, continueStack, topOfLoopState, returnState); currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState)); return(false); } else { var afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState); currentBlock.Add(JsStatement.If(JsExpression.LogicalNot(stmt.Condition), new JsGotoStateStatement(afterLoopState.Item1, currentState), null)); var currentName = GetLabelForState(currentState); currentBlock.AddRange(Handle(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(stmt.Body, 0)), breakStack.Push(Tuple.Create(currentName, afterLoopState.Item1)), continueStack.Push(Tuple.Create(currentName, currentState)), currentState, currentState, false, false)); if (!stack.IsEmpty || location.Index < location.Block.Statements.Count - 1) { Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.Item1, returnState); } return(false); } }
public JsExpression Downcast(JsExpression expression, IType sourceType, IType targetType, IRuntimeContext context) { if (_omitDowncasts) { return(expression); } if (sourceType.Kind == TypeKind.Dynamic && targetType.IsKnownType(KnownTypeCode.Boolean)) { return(JsExpression.LogicalNot(JsExpression.LogicalNot(expression))); } JsExpression jsTarget = CompileImportedTypeCheckCode(targetType, ref expression, context, false); if (jsTarget == null) { jsTarget = GetCastTarget(sourceType, targetType, context); } if (jsTarget == null || IsSystemObjectReference(jsTarget)) { return(expression); } return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "cast"), expression, jsTarget)); }
private JsExpression GenerateStructEqualsMethod(ITypeDefinition type, string typeVariableName) { var o = JsExpression.Identifier("o"); var parts = new List <JsExpression>(); foreach (var f in type.Fields.Where(f => !f.IsStatic)) { var expr = GenerateFieldCompare(f, o); if (expr != null) { parts.Add(expr); } } JsExpression typeCompare = JsExpression.Invocation(JsExpression.Member(_systemScript, "isInstanceOfType"), o, JsExpression.Identifier(typeVariableName)); if (parts.Count == 0) { return(JsExpression.FunctionDefinition(new[] { "o" }, JsStatement.Return(typeCompare))); } else { return(JsExpression.FunctionDefinition(new[] { "o" }, JsStatement.Block( JsStatement.If(JsExpression.LogicalNot(typeCompare), JsStatement.Return(JsExpression.False), null ), JsStatement.Return(parts.Aggregate((old, p) => old == null ? p : JsExpression.LogicalAnd(old, p))) ))); } }
public JsExpression ReferenceNotEquals(JsExpression a, JsExpression b, IRuntimeContext context) { if (a.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "isValue"), b)); } else if (b.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "isValue"), a)); } else if (a.NodeType == ExpressionNodeType.String || b.NodeType == ExpressionNodeType.String) { return(JsExpression.NotSame(a, b)); } else { return(JsExpression.LogicalNot(JsExpression.Invocation(JsExpression.Member(CreateTypeReferenceExpression(_systemScript), "referenceEquals"), a, b))); } }
public JsExpression ReferenceNotEquals(JsExpression a, JsExpression b) { if (a.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.MemberAccess(JsExpression.Identifier("ss"), "isValue"), b)); } else if (b.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.MemberAccess(JsExpression.Identifier("ss"), "isValue"), a)); } else if (a.NodeType == ExpressionNodeType.String || b.NodeType == ExpressionNodeType.String) { return(JsExpression.NotSame(a, b)); } else { return(JsExpression.LogicalNot(JsExpression.Invocation(JsExpression.MemberAccess(JsExpression.Identifier("ss"), "referenceEquals"), a, b))); } }
public JsExpression Downcast(JsExpression expression, IType sourceType, IType targetType) { if (_metadataImporter.OmitDowncasts) { return(expression); } if (sourceType.Kind == TypeKind.Dynamic && targetType.IsKnownType(KnownTypeCode.Boolean)) { return(JsExpression.LogicalNot(JsExpression.LogicalNot(expression))); } var jsTarget = GetCastTarget(sourceType, targetType); if (jsTarget == null || IsSystemObjectReference(jsTarget)) { return(expression); } return(JsExpression.Invocation(JsExpression.MemberAccess(_createTypeReferenceExpression(KnownTypeReference.Type), "cast"), expression, jsTarget)); }
public JsExpression ReferenceNotEquals(JsExpression a, JsExpression b) { if (a.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.Member(_createTypeReferenceExpression(ReflectionHelper.ParseReflectionName("System.Script")), "isValue"), b)); } else if (b.NodeType == ExpressionNodeType.Null) { return(JsExpression.Invocation(JsExpression.Member(_createTypeReferenceExpression(ReflectionHelper.ParseReflectionName("System.Script")), "isValue"), a)); } else if (a.NodeType == ExpressionNodeType.String || b.NodeType == ExpressionNodeType.String) { return(JsExpression.NotSame(a, b)); } else { return(JsExpression.LogicalNot(JsExpression.Invocation(JsExpression.Member(_createTypeReferenceExpression(ReflectionHelper.ParseReflectionName("System.Script")), "referenceEquals"), a, b))); } }
private bool HandleForStatement(JsForStatement stmt, StackEntry location, ImmutableStack <StackEntry> stack, ImmutableStack <Tuple <string, State> > breakStack, ImmutableStack <Tuple <string, State> > continueStack, State currentState, State returnState, IList <JsStatement> currentBlock) { if (NeedsBreakBeforeForLoop(currentBlock, stmt, location)) { // We have to create a new block for the statement. var topOfLoopState = CreateNewStateValue(currentState.FinallyStack); Enqueue(stack.Push(new StackEntry(location.Block, location.Index, true)), breakStack, continueStack, topOfLoopState, returnState); if (!(stmt.InitStatement is JsEmptyStatement)) { currentBlock.Add(stmt.InitStatement); } currentBlock.Add(new JsGotoStateStatement(topOfLoopState, currentState)); return(false); } else { var iteratorState = (stmt.IteratorExpression != null ? CreateNewStateValue(currentState.FinallyStack) : currentState); var afterLoopState = GetStateAfterStatement(location, stack, currentState.FinallyStack, returnState); if (stmt.ConditionExpression != null) { currentBlock.Add(new JsIfStatement(JsExpression.LogicalNot(stmt.ConditionExpression), new JsGotoStateStatement(afterLoopState.Item1, currentState), null)); } string currentName = GetLabelForState(currentState); currentBlock.AddRange(Handle(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(stmt.Body, 0)), breakStack.Push(Tuple.Create(currentName, afterLoopState.Item1)), continueStack.Push(Tuple.Create(currentName, iteratorState)), currentState, iteratorState)); if (stmt.IteratorExpression != null) { Enqueue(ImmutableStack <StackEntry> .Empty.Push(new StackEntry(JsBlockStatement.MakeBlock(new JsExpressionStatement(stmt.IteratorExpression)), 0)), breakStack, continueStack, iteratorState, currentState); } if (!stack.IsEmpty || location.Index < location.Block.Statements.Count - 1) { Enqueue(PushFollowing(stack, location), breakStack, continueStack, afterLoopState.Item1, returnState); } return(false); } }