// ----------------------------------------------------------------------
        // Initialize
        // ----------------------------------------------------------------------

        // Build a function which will call the module initializer (if any) and effect the export of methods which
        // don't need an instance to bind into (if any)
        private void EmitInitializeFunction(Seq <JST.Statement> body)
        {
            var innerNameSupply = NameSupply.Fork();
            var innerBody       = new Seq <JST.Statement>();

            // Export non-instance methods
            foreach (var typeDef in typeDefs)
            {
                var tyconEnv = assmEnv.AddType(typeDef);
                foreach (var methodDef in typeDef.Members.OfType <CST.MethodDef>().Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsExported(assmEnv.Assembly, typeDef, methodDef) &&
                        !Env.InteropManager.IsBindToInstance(assmEnv.Assembly, typeDef, methodDef))
                    {
                        Env.InteropManager.AppendExport
                            (innerNameSupply,
                            rootId,
                            assmEnv.Assembly, typeDef, methodDef,
                            null,
                            innerBody,
                            (ns, asm, typ, meth, b, a) => Env.JSTHelpers.AppendCallExportedMethod(this, ns, asm, typ, meth, b, a));
                    }
                }
            }

            SetupTypes(innerBody);

            // Invoke any <Module>::.cctor
            if (moduleInitializer != null)
            {
                innerBody.Add
                    (new JST.ExpressionStatement
                        (MethodCallExpression(moduleInitializer, innerNameSupply, false, new Seq <JST.Expression>())));
            }

            var func = new JST.FunctionExpression(null, new JST.Statements(innerBody));

            // Simplify
            var simpCtxt = new JST.SimplifierContext(false, Env.DebugMode, NameSupply.Fork(), null);

            func = (JST.FunctionExpression)func.Simplify(simpCtxt, EvalTimes.Bottom);

            if (Env.DebugMode)
            {
                body.Add(new JST.CommentStatement("Assembly initializer"));
            }
            body.Add(JST.Statement.DotAssignment(assemblyId.ToE(), Constants.AssemblyInitialize, func));
        }
Beispiel #2
0
        public void Emit()
        {
            var assm = typeof (RuntimeCompiler).Assembly;
            var res = "Microsoft.LiveLabs.JavaScript.IL2JS." + Constants.RuntimeFileName;
            var runtime = default(JST.Program);
            using (var runtimeStream = assm.GetManifestResourceStream(res))
            {
                if (runtimeStream == null)
                    throw new InvalidOperationException("unable to find runtime resource");
                runtime = JST.Program.FromStream(Constants.RuntimeFileName, runtimeStream, true);
            }

            var mode = default(string);
            switch (env.CompilationMode)
            {
            case CompilationMode.Plain:
                mode = "plain";
                break;
            case CompilationMode.Collecting:
                mode = "collecting";
                break;
            case CompilationMode.Traced:
                mode = "traced";
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }

            var body = default(ISeq<JST.Statement>);
            if (env.DebugMode)
            {
                body = new Seq<JST.Statement>();
                body.Add
                    (JST.Statement.Var(Constants.DebugLevel, new JST.NumericLiteral(env.DebugLevel)));
                body.Add(JST.Statement.Var(Constants.DebugId, new JST.BooleanLiteral(true)));
                body.Add(JST.Statement.Var(Constants.ModeId, new JST.StringLiteral(mode)));
                body.Add(JST.Statement.Var(Constants.SafeId, new JST.BooleanLiteral(env.SafeInterop)));
                foreach (var s in runtime.Body.Body)
                    body.Add(s);
            }
            else
            {
                // Simplify
                var simpCtxt =
                    new JST.SimplifierContext(true, env.DebugMode, new JST.NameSupply(Constants.Globals), null).
                        InFreshStatements();
                simpCtxt.Bind(Constants.DebugId, new JST.BooleanLiteral(false));
                simpCtxt.Bind(Constants.ModeId, new JST.StringLiteral(mode));
                simpCtxt.Bind(Constants.SafeId, new JST.BooleanLiteral(env.SafeInterop));
                simpCtxt.Add(JST.Statement.Var(Constants.DebugLevel, new JST.NumericLiteral(env.DebugLevel)));
                runtime.Body.Simplify(simpCtxt, EvalTimes.Bottom, false);
                body = simpCtxt.Statements;
            }

            var opts = new OrdMap<JST.Identifier, JST.Expression>();
            var mscorlibName = new JST.StringLiteral
                (CST.CSTWriter.WithAppend(env.Global, CST.WriterStyle.Uniform, env.Global.MsCorLibName.Append));
            opts.Add(Constants.SetupMscorlib, mscorlibName);
            var target = default(string);
            switch (env.Target)
            {
            case Target.Browser:
                target = "browser";
                break;
            case Target.CScript:
                target = "cscript";
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }
            opts.Add(Constants.SetupTarget, new JST.StringLiteral(target));
            var loadPaths = env.LoadPaths.Select<string, JST.Expression>(FixupPath).ToSeq();
            if (loadPaths.Count == 0)
                loadPaths.Add(new JST.StringLiteral(""));
            opts.Add(Constants.SetupSearchPaths, new JST.ArrayLiteral(loadPaths));

            if (env.DebugMode)
                body.Add(new JST.CommentStatement("Setup runtime"));
            var rootId = new JST.Identifier(env.Root);
            body.Add(JST.Statement.Var(rootId, new JST.ObjectLiteral()));
            body.Add(JST.Statement.Call(Constants.NewRuntime.ToE(), rootId.ToE(), new JST.ObjectLiteral(opts)));

            var program = new JST.Program(new JST.Statements(body));
            var runtimeFileName = Path.Combine(env.OutputDirectory, Constants.RuntimeFileName);
            program.ToFile(runtimeFileName, env.PrettyPrint);
            env.Log(new GeneratedJavaScriptFile("runtime", runtimeFileName));
        }
Beispiel #3
0
        // Build a function which will add (redirections to) exported instance methods into given unmanaged instance
        private void EmitBindInstanceExports(Seq<JST.Statement> body, JST.Expression lhs)
        {
            if (TypeCompEnv.Type.Extends == null || Parent.ExportedInstanceMethods.Count > 0)
            {
                var innerTypeCompEnv = TypeCompEnv.EnterFunction();
                var parameters = new Seq<JST.Identifier>();
                parameters.Add(innerTypeCompEnv.NameSupply.GenSym());
                var innerBody = new Seq<JST.Statement>();

                // Need to account for [NoInterop]
#if false
                var usage = new Usage();
                foreach (var methodDef in Parent.ExportedInstanceMethods)
                {
                    var memEnv = TypeCompEnv.AddMember(methodDef);

                    // We'll generally need these types to invoke import/exports
                    foreach (var p in methodDef.ValueParameters)
                        memEnv.SubstituteType(p.Type).AccumUsage(usage, true);
                    if (methodDef.Result != null)
                        memEnv.SubstituteType(methodDef.Result.Type).AccumUsage(usage, true);
                }
                innerTypeCompEnv.BindUsage(innerBody, usage, TypePhase.Constructed);
#endif

                if (TypeCompEnv.Type.Extends != null &&
                    !(TypeCompEnv.Type.Extends.Style(TypeCompEnv) is CST.ObjectTypeStyle))
                {
                    // Bind exports from base
                    innerBody.Add
                        (JST.Statement.DotCall
                             (innerTypeCompEnv.ResolveType(TypeCompEnv.Type.Extends, TypePhase.Slots),
                              Constants.TypeBindInstanceExports,
                              parameters[0].ToE()));
                }

                foreach (var methodDef in Parent.ExportedInstanceMethods)
                {
                    Env.InteropManager.AppendExport
                        (innerTypeCompEnv.NameSupply,
                         RootId,
                         TypeCompEnv.Assembly,
                         TypeCompEnv.Type,
                         methodDef,
                         parameters[0].ToE(),
                         innerBody,
                         (ns, asm, typ, mem, b, a) =>
                         Env.JSTHelpers.AppendCallExportedMethod(innerTypeCompEnv, ns, asm, typ, mem, b, a));
                }

                var func = new JST.FunctionExpression(parameters, new JST.Statements(innerBody));

                // Simplify
                var simpCtxt = new JST.SimplifierContext(false, Env.DebugMode, NameSupply.Fork(), null);
                func = (JST.FunctionExpression)func.Simplify(simpCtxt, EvalTimes.Bottom);

                body.Add(JST.Statement.DotAssignment(lhs, Constants.TypeBindInstanceExports, func));
            }
            // else: default is ok
        }
Beispiel #4
0
        // ----------------------------------------------------------------------
        // Initialize
        // ----------------------------------------------------------------------

        // Build a function which will call the module initializer (if any) and effect the export of methods which
        // don't need an instance to bind into (if any)
        private void EmitInitializeFunction(Seq<JST.Statement> body)
        {
            var innerNameSupply = NameSupply.Fork();
            var innerBody = new Seq<JST.Statement>();

            // Export non-instance methods
            foreach (var typeDef in typeDefs)
            {
                var tyconEnv = assmEnv.AddType(typeDef);
                foreach (var methodDef in typeDef.Members.OfType<CST.MethodDef>().Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsExported(assmEnv.Assembly,typeDef, methodDef) &&
                        !Env.InteropManager.IsBindToInstance(assmEnv.Assembly, typeDef, methodDef))
                    {
                        Env.InteropManager.AppendExport
                            (innerNameSupply,
                             rootId,
                             assmEnv.Assembly, typeDef, methodDef,
                             null,
                             innerBody,
                             (ns, asm, typ, meth, b, a) => Env.JSTHelpers.AppendCallExportedMethod(this, ns, asm, typ, meth, b, a));
                    }
                }
            }

            SetupTypes(innerBody);

            // Invoke any <Module>::.cctor
            if (moduleInitializer != null)
                innerBody.Add
                    (new JST.ExpressionStatement
                         (MethodCallExpression(moduleInitializer, innerNameSupply, false, new Seq<JST.Expression>())));

            var func = new JST.FunctionExpression(null, new JST.Statements(innerBody));

            // Simplify
            var simpCtxt = new JST.SimplifierContext(false, Env.DebugMode, NameSupply.Fork(), null);
            func = (JST.FunctionExpression)func.Simplify(simpCtxt, EvalTimes.Bottom);

            if (Env.DebugMode)
                body.Add(new JST.CommentStatement("Assembly initializer"));
            body.Add(JST.Statement.DotAssignment(assemblyId.ToE(), Constants.AssemblyInitialize, func));
        }
Beispiel #5
0
        public void Emit()
        {
            var assm    = typeof(RuntimeCompiler).Assembly;
            var res     = "Microsoft.LiveLabs.JavaScript.IL2JS." + Constants.RuntimeFileName;
            var runtime = default(JST.Program);

            using (var runtimeStream = assm.GetManifestResourceStream(res))
            {
                if (runtimeStream == null)
                {
                    throw new InvalidOperationException("unable to find runtime resource");
                }
                runtime = JST.Program.FromStream(Constants.RuntimeFileName, runtimeStream, true);
            }

            var mode = default(string);

            switch (env.CompilationMode)
            {
            case CompilationMode.Plain:
                mode = "plain";
                break;

            case CompilationMode.Collecting:
                mode = "collecting";
                break;

            case CompilationMode.Traced:
                mode = "traced";
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var body = default(ISeq <JST.Statement>);

            if (env.DebugMode)
            {
                body = new Seq <JST.Statement>();
                body.Add
                    (JST.Statement.Var(Constants.DebugLevel, new JST.NumericLiteral(env.DebugLevel)));
                body.Add(JST.Statement.Var(Constants.DebugId, new JST.BooleanLiteral(true)));
                body.Add(JST.Statement.Var(Constants.ModeId, new JST.StringLiteral(mode)));
                body.Add(JST.Statement.Var(Constants.SafeId, new JST.BooleanLiteral(env.SafeInterop)));
                foreach (var s in runtime.Body.Body)
                {
                    body.Add(s);
                }
            }
            else
            {
                // Simplify
                var simpCtxt =
                    new JST.SimplifierContext(true, env.DebugMode, new JST.NameSupply(Constants.Globals), null).
                    InFreshStatements();
                simpCtxt.Bind(Constants.DebugId, new JST.BooleanLiteral(false));
                simpCtxt.Bind(Constants.ModeId, new JST.StringLiteral(mode));
                simpCtxt.Bind(Constants.SafeId, new JST.BooleanLiteral(env.SafeInterop));
                simpCtxt.Add(JST.Statement.Var(Constants.DebugLevel, new JST.NumericLiteral(env.DebugLevel)));
                runtime.Body.Simplify(simpCtxt, EvalTimes.Bottom, false);
                body = simpCtxt.Statements;
            }

            var opts         = new OrdMap <JST.Identifier, JST.Expression>();
            var mscorlibName = new JST.StringLiteral
                                   (CST.CSTWriter.WithAppend(env.Global, CST.WriterStyle.Uniform, env.Global.MsCorLibName.Append));

            opts.Add(Constants.SetupMscorlib, mscorlibName);
            var target = default(string);

            switch (env.Target)
            {
            case Target.Browser:
                target = "browser";
                break;

            case Target.CScript:
                target = "cscript";
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            opts.Add(Constants.SetupTarget, new JST.StringLiteral(target));
            var loadPaths = env.LoadPaths.Select <string, JST.Expression>(FixupPath).ToSeq();

            if (loadPaths.Count == 0)
            {
                loadPaths.Add(new JST.StringLiteral(""));
            }
            opts.Add(Constants.SetupSearchPaths, new JST.ArrayLiteral(loadPaths));

            if (env.DebugMode)
            {
                body.Add(new JST.CommentStatement("Setup runtime"));
            }
            var rootId = new JST.Identifier(env.Root);

            body.Add(JST.Statement.Var(rootId, new JST.ObjectLiteral()));
            body.Add(JST.Statement.Call(Constants.NewRuntime.ToE(), rootId.ToE(), new JST.ObjectLiteral(opts)));

            var program         = new JST.Program(new JST.Statements(body));
            var runtimeFileName = Path.Combine(env.OutputDirectory, Constants.RuntimeFileName);

            program.ToFile(runtimeFileName, env.PrettyPrint);
            env.Log(new GeneratedJavaScriptFile("runtime", runtimeFileName));
        }