Example #1
0
 public override Et Walk(EtGenerator etgen)
 {
     return Et.Throw(
         AstUtils.SimpleNewHelper(
             JsRuntimeError.Ctor,
             etgen.GenerateConvertToObject(
                 Target.Walk(etgen)
             )
         )
     );
 }
Example #2
0
        public override Et Walk(EtGenerator etgen)
        {
            var args = Args.Select(
                x => EtUtils.Cast<object>(x.Walk(etgen))
            ).ToArray();

            /*
             * This is a fix for calls inside with-statements
             * that look like normal function calls, i.e.
             *
             * with(foo) {
             *     bar();
             * }
             *
             * But 'bar' can here be either a function existing
             * in the global scope, or a method on foo.
             * */
            if (Target is IdentifierNode && etgen.IsInsideWith)
            {
                return Et.Call(
                    etgen.FunctionScope.ScopeExpr,
                    typeof(Scope).GetMethod("Call"),
                    Et.Constant((Target as IdentifierNode).Name),
                    Et.NewArrayInit(
                        typeof(object),
                        args
                    )
                );
            }

            /*
             * This handles normal method calls, i.e.
             *
             * foo.bar();
             *
             * Because we know that 'bar' has to be a method
             * on 'foo' here we can optimize this case during
             * compile time, instead of runtime
             * */
            if (Target is MemberAccessNode)
            {
                var target = (Ast.MemberAccessNode)Target;
                var tmp = Et.Variable(typeof(object), "#tmp");
                var targetExpr = etgen.GenerateConvertToObject(
                        target.Target.Walk(etgen)
                    );

                return Et.Block(
                    new[] { tmp },
                    Et.Assign(
                        tmp,
                        targetExpr
                    ),
                    Et.Dynamic(
                        etgen.Context.CreateInvokeMemberBinder(
                            target.Name,
                            new CallInfo(args.Length + 1)
                        ),
                        typeof(object),
                        ArrayUtils.Insert(
                            tmp,
                            tmp,
                            args
                        )
                    )
                );
            }

            /*
             * This handles all other function invocations
             *
             * foo();               // when outside a with-statement
             * (function(){})();    // inline functions
             * */
            return Et.Dynamic(
                etgen.Context.CreateInvokeBinder(
                    new CallInfo(args.Length)
                ),
                typeof(object),
                ArrayUtils.Insert(
                    Target.Walk(etgen),
                    Et.Property(
                        etgen.GlobalScopeExpr,
                        Scope.PiJsObject
                    ),
                    args
                )
            );
        }