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));
        }
예제 #3
0
        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)));
     }
 }
예제 #5
0
 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)));
     }
 }
예제 #6
0
        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)));
     }
 }
예제 #8
0
        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);
            }
        }