Ejemplo n.º 1
0
        public BoundProgram Update(BoundBody body)
        {
            if (body == Body)
                return this;

            return new BoundProgram(body);
        }
Ejemplo n.º 2
0
            public override void VisitBody(BoundBody node)
            {
                using (var marker = _typeManager.CreateDefiniteAssignmentMarker(_parentBranch))
                {
                    _branch = marker.CreateDefaultBranch();

                    var block = new Block(_branch, null, false, false, null);

                    PushBlock(block);

                    base.VisitBody(node);

                    PopBlock(block);

                    ResultExpressions = _branch.Expressions;

                    // If the last statement of the body is a return, the return
                    // provides the result expression and we don't have to track
                    // the result expressions.

                    if (
                        node.Body.Nodes.Count == 0 ||
                        node.Body.Nodes[node.Body.Nodes.Count - 1] is BoundReturn
                    )
                        ResultExpressions = null;

                    _branch.IsKilled = true;
                    _branch = null;
                }
            }
Ejemplo n.º 3
0
        public BoundProgram(BoundBody body)
        {
            if (body == null)
                throw new ArgumentNullException("body");

            Body = body;
        }
Ejemplo n.º 4
0
        private static BoundExpression[] Perform(BoundBody node, BoundTypeManager.DefiniteAssignmentMarker.Branch parentBranch)
        {
            var marker = new Marker(node.TypeManager, parentBranch);

            marker.Visit(node);

            return marker.ResultExpressions;
        }
Ejemplo n.º 5
0
            public override void VisitBody(BoundBody node)
            {
                _scope = new Scope(node, _scope);

                using (_scope)
                {
                    base.VisitBody(node);
                }

                _scope = _scope.Parent;
            }
Ejemplo n.º 6
0
        public static ReadOnlyArray<BoundFunction> Gather(BoundBody body)
        {
            if (body == null)
                throw new ArgumentNullException("body");

            var functions = new ReadOnlyArray<BoundFunction>.Builder();

            new Gatherer(functions).Visit(body);

            return functions.ToReadOnlyArray();
        }
Ejemplo n.º 7
0
        public BoundFunction Update(string name, ReadOnlyArray<string> parameters, BoundBody body, SourceLocation location)
        {
            if (
                name == Name &&
                parameters == Parameters &&
                body == Body &&
                location == Location
            )
                return this;

            return new BoundFunction(name, parameters, body, location);
        }
Ejemplo n.º 8
0
        public BoundFunction(string name, ReadOnlyArray<string> parameters, BoundBody body, SourceLocation location)
        {
            if (parameters == null)
                throw new ArgumentNullException("parameters");
            if (body == null)
                throw new ArgumentNullException("body");
            if (location == null)
                throw new ArgumentNullException("location");

            Name = name;
            Parameters = parameters;
            Body = body;
            Location = location;
        }
Ejemplo n.º 9
0
        private static BoundBody Perform(BoundBody node)
        {
            if (node == null)
                throw new ArgumentNullException("node");

            var statistics = new Dictionary<BoundTemporary, Statistics>();

            new Gatherer(statistics).Visit(node);

            Validate(statistics);

            node = (BoundBody)new Rewriter(statistics).Visit(node);

            return node;
        }
Ejemplo n.º 10
0
            public Scope(CodeGenerator generator, ILBuilder il, bool isFunction, BoundBody body, BoundClosureField argumentsClosureField, ITypeBuilder typeBuilder, Scope parent)
            {
                IL = il;
                ArgumentsClosureField = argumentsClosureField;
                Generator = generator;
                _isFunction = isFunction;
                _body = body;
                if (argumentsClosureField != null)
                    ArgumentsEmitter = new ClosureFieldEmitter(generator, argumentsClosureField);
                TypeBuilder = typeBuilder;
                Parent = parent;

                _isStatic = TypeBuilder is IScriptBuilder;
                if (body.MappedArguments != null)
                    _arguments = body.MappedArguments.ToDictionary(p => p.Argument, p => p.Mapped);

                BreakTargets = new Stack<NamedLabel>();
                ContinueTargets = new Stack<NamedLabel>();
            }
Ejemplo n.º 11
0
            public override BoundNode VisitBody(BoundBody node)
            {
                node = (BoundBody)base.VisitBody(node);

                // Add the initialization of the result temporary and the
                // return statement.

                var nodes = new ReadOnlyArray<BoundStatement>.Builder(node.Body.Nodes.Count + 2);

                // We always add the default value. The reason for this is that
                // we're already passed the definite assignment phase, so it won't
                // be inserted for us automatically.

                nodes.Add(new BoundSetVariable(
                    _resultTemporary,
                    new BoundGetVariable(BoundMagicVariable.Undefined),
                    SourceLocation.Missing
                ));

                nodes.AddRange(node.Body.Nodes);

                nodes.Add(new BoundReturn(
                    new BoundGetVariable(_resultTemporary),
                    SourceLocation.Missing
                ));

                return node.Update(
                    node.Body.Update(
                        node.Body.Temporaries,
                        nodes.ToReadOnly(),
                        node.Body.Location
                    ),
                    node.Closure,
                    node.ScopedClosure,
                    node.Arguments,
                    node.Locals,
                    node.MappedArguments,
                    node.Flags,
                    node.TypeManager
                );
            }
Ejemplo n.º 12
0
 public virtual void VisitBody(BoundBody node)
 {
     DefaultVisit(node);
 }
Ejemplo n.º 13
0
                public Scope(BoundBody body, Scope parent)
                {
                    Parent = parent;

                    _marker = body.TypeManager.CreateTypeMarker();

                    foreach (var argument in body.Arguments)
                    {
                        if (argument.Closure != null)
                            MarkWrite(body.Closure.Fields[argument.Name], BoundValueType.Unknown);
                    }

                    if (body.MappedArguments != null)
                        _arguments = body.MappedArguments.ToDictionary(p => p.Argument, p => p.Mapped);

                    if (body.MappedArguments != null)
                    {
                        foreach (var mapping in body.MappedArguments)
                        {
                            MarkWrite(mapping.Mapped, BoundValueType.Unknown);
                        }
                    }

                    if (body.Closure != null)
                    {
                        var argumentsClosureField = body.Closure.Fields.SingleOrDefault(p => p.Name == BoundClosure.ArgumentsFieldName);
                        if (argumentsClosureField != null)
                            MarkWrite(argumentsClosureField, BoundValueType.Object);
                    }

                    _magicTypes = body.TypeManager.MagicTypes.ToDictionary(p => p.MagicType, p => p.Type);

                    foreach (var item in _magicTypes)
                    {
                        switch (item.Key)
                        {
                            case BoundMagicVariableType.Arguments:
                            case BoundMagicVariableType.Global:
                                _marker.SpeculateType(item.Value, SpeculatedType.Object, true);
                                _marker.MarkWrite(item.Value, BoundValueType.Object);
                                break;

                            case BoundMagicVariableType.This:
                                _marker.MarkWrite(item.Value, BoundValueType.Unknown);
                                break;

                            default:
                                throw new InvalidOperationException();
                        }
                    }
                }
Ejemplo n.º 14
0
 private static void Perform(BoundBody body)
 {
     new Marker().Visit(body);
 }
Ejemplo n.º 15
0
        private void EmitInitializeArguments(BoundBody body)
        {
            if (body.MappedArguments == null)
                return;

            foreach (var mapping in body.MappedArguments)
            {
                if (mapping.Mapped.Kind == BoundVariableKind.ClosureField)
                {
                    // Closure fields are initialized on the closure, so if we
                    // don't have the index in the arguments, we can just skip
                    // the complete set.

                    var after = IL.DefineLabel();

                    // Get the length of the arguments.
                    _scope.EmitLoad(SpecialLocal.ArgumentsRaw);
                    IL.Emit(OpCodes.Ldlen);
                    // Emit the index we want.
                    IL.EmitConstant(mapping.Argument.Index);
                    // If arguments.Length <= index jump over the set.
                    IL.Emit(OpCodes.Ble, after);

                    EmitSetVariable(
                        mapping.Mapped,
                        new BoundEmitExpression(
                            BoundValueType.Unknown,
                            () =>
                            {
                                // Push the arguments array onto the stack.
                                _scope.EmitLoad(SpecialLocal.ArgumentsRaw);
                                // Get the correct member from the arguments object.
                                IL.EmitConstant(mapping.Argument.Index);
                                // Load the element out of the array.
                                IL.Emit(OpCodes.Ldelem, typeof(object));
                            }
                        )
                    );

                    IL.MarkLabel(after);
                }
                else
                {
                    // Otherwise, we move the branch into the getter because
                    // if we don't have the index, we need to initialize the local
                    // with undefined.

                    EmitSetVariable(
                        mapping.Mapped,
                        new BoundEmitExpression(
                            BoundValueType.Unknown,
                            () =>
                            {
                                var missingIndex = IL.DefineLabel();
                                var after = IL.DefineLabel();

                                // Get the length of the arguments.
                                _scope.EmitLoad(SpecialLocal.ArgumentsRaw);
                                IL.Emit(OpCodes.Ldlen);
                                // Emit the index we want.
                                IL.EmitConstant(mapping.Argument.Index);
                                // If arguments.Length <= index jump over getting the
                                // element from the array.
                                IL.Emit(OpCodes.Ble, missingIndex);

                                // Push the arguments array onto the stack.
                                _scope.EmitLoad(SpecialLocal.ArgumentsRaw);
                                // Get the correct member from the arguments object.
                                IL.EmitConstant(mapping.Argument.Index);
                                // Load the element out of the array.
                                IL.Emit(OpCodes.Ldelem, typeof(object));
                                // Jump to the end of the if.
                                IL.Emit(OpCodes.Br, after);

                                // We're missing the index.
                                IL.MarkLabel(missingIndex);
                                // Load undefined.
                                _scope.EmitLoad(SpecialLocal.Undefined);

                                // Mark the end of the if.
                                IL.MarkLabel(after);
                            }
                        )
                    );
                }
            }
        }
Ejemplo n.º 16
0
        private void EmitClosureSetup(BoundBody body)
        {
            Debug.Assert(body.Closure != null);

            var closure = body.Closure;

            // Check whether the constructor expects a parent.
            if (body.Closure.Parent != null)
                IL.Emit(OpCodes.Ldarg_0);

            // Instantiate the closure.
            IL.Emit(OpCodes.Newobj, closure.Builder.Constructor);

            // Store the reference to the closure in the scope.

            var closureLocal = IL.DeclareLocal(closure.Builder.Type);
            _scope.SetClosureLocal(closureLocal);
            IL.Emit(OpCodes.Stloc, closureLocal);
        }