Esempio n. 1
0
 public void Emit()
 {
     if (Trace.Flavor == TraceFlavor.Remainder)
     {
         foreach (var kv in Trace.AssemblyMap)
         {
             var compiler = new AssemblyCompiler(this, kv.Value);
             compiler.Emit(null);
         }
     }
     else
     {
         var rootEnv = Env.Global.Environment();
         var body = new Seq<JST.Statement>();
         body.Add(JST.Statement.Var(RootId, new JST.Identifier(Env.Root).ToE()));
         foreach (var nm in rootEnv.AllLoadedAssembliesInLoadOrder().Where(Trace.AssemblyMap.ContainsKey))
         {
             var compiler = new AssemblyCompiler(this, Trace.AssemblyMap[nm]);
             compiler.Emit(body);
         }
         var program = new JST.Program
             (new JST.Statements
                  (new JST.ExpressionStatement
                       (new JST.StatementsPseudoExpression(new JST.Statements(body), null))));
         var fileName = Path.Combine(Env.OutputDirectory, Trace.Name + ".js");
         program.ToFile(fileName, Env.PrettyPrint);
         Env.Log(new GeneratedJavaScriptFile("trace '" + Trace.Name + "'", fileName));
     }
 }
Esempio n. 2
0
 public void Emit()
 {
     if (Trace.Flavor == TraceFlavor.Remainder)
     {
         foreach (var kv in Trace.AssemblyMap)
         {
             var compiler = new AssemblyCompiler(this, kv.Value);
             compiler.Emit(null);
         }
     }
     else
     {
         var rootEnv = Env.Global.Environment();
         var body    = new Seq <JST.Statement>();
         body.Add(JST.Statement.Var(RootId, new JST.Identifier(Env.Root).ToE()));
         foreach (var nm in rootEnv.AllLoadedAssembliesInLoadOrder().Where(Trace.AssemblyMap.ContainsKey))
         {
             var compiler = new AssemblyCompiler(this, Trace.AssemblyMap[nm]);
             compiler.Emit(body);
         }
         var program = new JST.Program
                           (new JST.Statements
                               (new JST.ExpressionStatement
                                   (new JST.StatementsPseudoExpression(new JST.Statements(body), null))));
         var fileName = Path.Combine(Env.OutputDirectory, Trace.Name + ".js");
         program.ToFile(fileName, Env.PrettyPrint);
         Env.Log(new GeneratedJavaScriptFile("trace '" + Trace.Name + "'", fileName));
     }
 }
        // ----------------------------------------------------------------------
        // Entry point from AssemblyCompiler
        // ----------------------------------------------------------------------

        public void Emit(Seq<JST.Statement> body)
        {
            if (Env.BreakOnBreak &&
                Env.AttributeHelper.TypeHasAttribute(TyconEnv.Assembly, TyconEnv.Type, Env.AttributeHelper.BreakAttributeRef, false, false))
                System.Diagnostics.Debugger.Break();

            CollectMembers();

            var typeName = CST.CSTWriter.WithAppend
                (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Type.EffectiveName(Env.Global).Append);
            var slotName = Env.GlobalMapping.ResolveTypeDefToSlot(TyconEnv.Assembly, TyconEnv.Type);

            if (TypeTrace != null && TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Self-loader fragment
                var assmName = CST.CSTWriter.WithAppend
                    (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Assembly.Name.Append);
                var funcBody = new Seq<JST.Statement>();
                BuildTypeStructure(funcBody);
                var func = new JST.FunctionExpression
                    (new Seq<JST.Identifier> { RootId, AssemblyId, TypeDefinitionId }, new JST.Statements(funcBody));
                var loaderBody = new Seq<JST.Statement>();
                if (Env.DebugMode)
                    loaderBody.Add(new JST.CommentStatement(TyconEnv.ToString()));
                loaderBody.Add
                    (JST.Statement.DotCall
                         (new JST.Identifier(Env.Root).ToE(),
                          Constants.RootBindType,
                          new JST.StringLiteral(assmName),
                          new JST.StringLiteral(slotName),
                          new JST.StringLiteral(typeName),
                          func));
                var program = new JST.Program(new JST.Statements(loaderBody));
                var typePath = Path.Combine
                    (Path.Combine(Env.OutputDirectory, JST.Lexemes.StringToFileName(assmName)), slotName);
                var fileName = Path.Combine(typePath, Constants.TypeFileName);
                program.ToFile(fileName, Env.PrettyPrint);
                Env.Log(new GeneratedJavaScriptFile("type '" + TyconEnv.TypeConstructorRef + "'", fileName));

                CompileMethods(null, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Just passisng through
                CompileMethods(body, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType)
            {
                // Type defined elsewhere, include some/all methods only
                body.Add
                    (JST.Statement.Var
                         (TypeDefinitionId,
                          JST.Expression.DotCall
                              (AssemblyId.ToE(),
                               new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                               Env.JSTHelpers.PhaseExpression(TypePhase.Slots))));
                CompileMethods(body, NameSupply);
            }
            else
            {
                // Inline type definition and some/all methods
                if (Env.DebugMode)
                    body.Add(new JST.CommentStatement(TyconEnv.ToString()));
                // We must construct the type explicity to phase 1 rather than using type compiler environment
                // since it thinks the type is already at phase 2.
                body.Add
                    (JST.Statement.Var
                         (TypeDefinitionId,
                          JST.Expression.DotCall
                              (AssemblyId.ToE(),
                               new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                               Env.JSTHelpers.PhaseExpression(TypePhase.Id))));
                BuildTypeStructure(body);
                CompileMethods(body, NameSupply);
            }
        }
Esempio n. 4
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));
        }
Esempio n. 5
0
        private void EmitStart()
        {
            var assmName = CST.CSTWriter.WithAppend(Env.Global, CST.WriterStyle.Uniform, assmEnv.Assembly.Name.Append);

            var startId = new JST.Identifier("start");
            var exId    = new JST.Identifier("e");

            var globalRootId = new JST.Identifier(Env.Root);
            var startStmnt   = JST.Statement.DotCall
                                   (globalRootId.ToE(), Constants.RootStart, new JST.StringLiteral(assmName));

            if (!Env.DebugMode)
            {
                startStmnt = new JST.TryStatement
                                 (new JST.Statements(startStmnt),
                                 new JST.CatchClause
                                     (exId,
                                     new JST.Statements
                                         (JST.Statement.DotCall
                                             (new JST.Identifier(Env.Root).ToE(),
                                             Constants.RootWriteLine,
                                             new JST.BinaryExpression
                                                 (new JST.StringLiteral("UNCAUGHT EXCEPTION: "),
                                                 JST.BinaryOp.Plus,
                                                 JST.Expression.DotCall
                                                     (globalRootId.ToE(), Constants.RootExceptionDescription, exId.ToE()))))));
            }

            var scriptBody = new Seq <JST.Statement>();

            switch (Env.Target)
            {
            case Target.Browser:
            {
                var startFuncBody = new Seq <JST.Statement>();
#if !JSCRIPT_IS_CORRECT
                startFuncBody.Add(JST.Statement.Var(exId));
#endif
                startFuncBody.Add(startStmnt);
                var startFunc = new JST.FunctionDeclaration(startId, null, new JST.Statements(startFuncBody));

                var windowId           = new JST.Identifier("window");
                var addEventListenerId = new JST.Identifier("addEventListner");
                var attachEventId      = new JST.Identifier("attachEvent");
                var onloadId           = new JST.Identifier("onload");
                scriptBody.Add(startFunc);
                scriptBody.Add
                    (new JST.IfStatement
                        (JST.Expression.Dot(windowId.ToE(), addEventListenerId),
                        new JST.Statements
                            (JST.Statement.DotCall
                                (windowId.ToE(),
                                addEventListenerId,
                                new JST.StringLiteral("load"),
                                startId.ToE(),
                                new JST.BooleanLiteral(false))),
                        new JST.Statements
                            (new JST.IfStatement
                                (JST.Expression.Dot(windowId.ToE(), attachEventId),
                                new JST.Statements
                                    (JST.Statement.DotCall
                                        (windowId.ToE(),
                                        attachEventId,
                                        new JST.StringLiteral("onload"),
                                        startId.ToE())),
                                new JST.Statements
                                    (JST.Statement.DotAssignment(windowId.ToE(), onloadId, startId.ToE()))))));
                break;
            }

            case Target.CScript:
                scriptBody.Add(startStmnt);
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            var startProgram  = new JST.Program(new JST.Statements(scriptBody));
            var startFileName = Path.Combine(Env.OutputDirectory, Constants.StartFileName);
            startProgram.ToFile(startFileName, Env.PrettyPrint);
            Env.Log(new GeneratedJavaScriptFile("startup for assembly '" + assmName + "'", startFileName));
        }
Esempio n. 6
0
        // ----------------------------------------------------------------------
        // Entry point from compiler driver
        // ----------------------------------------------------------------------

        public void Emit(Seq <JST.Statement> body)
        {
            if (Env.BreakOnBreak &&
                Env.AttributeHelper.AssemblyHasAttribute(assmEnv.Assembly, Env.AttributeHelper.BreakAttributeRef, false, false))
            {
                System.Diagnostics.Debugger.Break();
            }

            var assmName = CST.CSTWriter.WithAppend(Env.Global, CST.WriterStyle.Uniform, assmEnv.Assembly.Name.Append);

            CollectTypes();

            if (assemblyTrace == null ||
                assemblyTrace.IncludeAssembly && assemblyTrace.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Self-loader fragment, possibly containing entire assembly
                var assmBody = new Seq <JST.Statement>();
                BuildAssembly(assmBody);
                CompileTypes(assmBody);
                EmitInitializeFunction(assmBody);

                var assmFunc = new JST.FunctionExpression(new Seq <JST.Identifier> {
                    rootId, assemblyId
                }, new JST.Statements(assmBody));
                var assmLoader = new Seq <JST.Statement>();
                if (Env.DebugMode)
                {
                    assmLoader.Add(new JST.CommentStatement(assmEnv.ToString()));
                }
                assmLoader.Add
                    (JST.Statement.DotCall
                        (new JST.Identifier(Env.Root).ToE(),
                        Constants.RootBindAssembly,
                        new JST.StringLiteral(assmName),
                        assmFunc));

                var assmProgram = new JST.Program(new JST.Statements(assmLoader));
                var assmPath    = Path.Combine(Env.OutputDirectory, JST.Lexemes.StringToFileName(assmName));
                var finalName   = default(string);
                switch (Env.CompilationMode)
                {
                case CompilationMode.Plain:
                case CompilationMode.Collecting:
                    finalName = Constants.AllFileName;
                    break;

                case CompilationMode.Traced:
                    finalName = Constants.AssemblyFileName;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                var assmFileName = Path.Combine(assmPath, finalName);
                assmProgram.ToFile(assmFileName, Env.PrettyPrint);
                Env.Log(new GeneratedJavaScriptFile("assembly '" + assmName + "'", assmFileName));
            }
            else if (!assemblyTrace.IncludeAssembly && assemblyTrace.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Just passing through
                CompileTypes(body);
            }
            else if (!assemblyTrace.IncludeAssembly)
            {
                // Assembly defined elsewhere, include some/all types only in trace
                body.Add
                    (JST.Statement.Var
                        (assemblyId,
                        new JST.IndexExpression
                            (JST.Expression.Dot(rootId.ToE(), Constants.RootAssemblyCache),
                            new JST.StringLiteral(assmName))));
                CompileTypes(body);
            }
            else
            {
                // Inline assembly definition and some/all types
                body.Add
                    (JST.Statement.Var
                        (assemblyId,
                        JST.Expression.DotCall
                            (rootId.ToE(), Constants.RootCreateAssembly, new JST.StringLiteral(assmName))));
                BuildAssembly(body);
                CompileTypes(body);
                EmitInitializeFunction(body);
            }

            if (assmEnv.Assembly.EntryPoint != null && (assemblyTrace == null || assemblyTrace.IncludeAssembly))
            {
                EmitStart();
                EmitManifest();
            }
        }
Esempio n. 7
0
        private void EmitStart()
        {
            var assmName = CST.CSTWriter.WithAppend(Env.Global, CST.WriterStyle.Uniform, assmEnv.Assembly.Name.Append);

            var startId = new JST.Identifier("start");
            var exId = new JST.Identifier("e");

            var globalRootId = new JST.Identifier(Env.Root);
            var startStmnt = JST.Statement.DotCall
                (globalRootId.ToE(), Constants.RootStart, new JST.StringLiteral(assmName));
            if (!Env.DebugMode)
            {
                startStmnt = new JST.TryStatement
                    (new JST.Statements(startStmnt),
                     new JST.CatchClause
                         (exId,
                          new JST.Statements
                              (JST.Statement.DotCall
                                   (new JST.Identifier(Env.Root).ToE(),
                                    Constants.RootWriteLine,
                                    new JST.BinaryExpression
                                        (new JST.StringLiteral("UNCAUGHT EXCEPTION: "),
                                         JST.BinaryOp.Plus,
                                         JST.Expression.DotCall
                                             (globalRootId.ToE(), Constants.RootExceptionDescription, exId.ToE()))))));
            }

            var scriptBody = new Seq<JST.Statement>();
            switch (Env.Target)
            {
            case Target.Browser:
                {
                    var startFuncBody = new Seq<JST.Statement>();
#if !JSCRIPT_IS_CORRECT
                    startFuncBody.Add(JST.Statement.Var(exId));
#endif
                    startFuncBody.Add(startStmnt);
                    var startFunc = new JST.FunctionDeclaration(startId, null, new JST.Statements(startFuncBody));

                    var windowId = new JST.Identifier("window");
                    var addEventListenerId = new JST.Identifier("addEventListner");
                    var attachEventId = new JST.Identifier("attachEvent");
                    var onloadId = new JST.Identifier("onload");
                    scriptBody.Add(startFunc);
                    scriptBody.Add
                        (new JST.IfStatement
                             (JST.Expression.Dot(windowId.ToE(), addEventListenerId),
                              new JST.Statements
                                  (JST.Statement.DotCall
                                       (windowId.ToE(),
                                        addEventListenerId,
                                        new JST.StringLiteral("load"),
                                        startId.ToE(),
                                        new JST.BooleanLiteral(false))),
                              new JST.Statements
                                  (new JST.IfStatement
                                       (JST.Expression.Dot(windowId.ToE(), attachEventId),
                                        new JST.Statements
                                            (JST.Statement.DotCall
                                                 (windowId.ToE(),
                                                  attachEventId,
                                                  new JST.StringLiteral("onload"),
                                                  startId.ToE())),
                                        new JST.Statements
                                            (JST.Statement.DotAssignment(windowId.ToE(), onloadId, startId.ToE()))))));
                    break;
                }
            case Target.CScript:
                scriptBody.Add(startStmnt);
                break;
            default:
                throw new ArgumentOutOfRangeException();
            }

            var startProgram = new JST.Program(new JST.Statements(scriptBody));
            var startFileName = Path.Combine(Env.OutputDirectory, Constants.StartFileName);
            startProgram.ToFile(startFileName, Env.PrettyPrint);
            Env.Log(new GeneratedJavaScriptFile("startup for assembly '" + assmName + "'", startFileName));
        }
Esempio n. 8
0
        // ----------------------------------------------------------------------
        // Entry point from compiler driver
        // ----------------------------------------------------------------------

        public void Emit(Seq<JST.Statement> body)
        {
            if (Env.BreakOnBreak &&
                Env.AttributeHelper.AssemblyHasAttribute(assmEnv.Assembly, Env.AttributeHelper.BreakAttributeRef, false, false))
                System.Diagnostics.Debugger.Break();

            var assmName = CST.CSTWriter.WithAppend(Env.Global, CST.WriterStyle.Uniform, assmEnv.Assembly.Name.Append);

            CollectTypes();

            if (assemblyTrace == null ||
                assemblyTrace.IncludeAssembly && assemblyTrace.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Self-loader fragment, possibly containing entire assembly
                var assmBody = new Seq<JST.Statement>();
                BuildAssembly(assmBody);
                CompileTypes(assmBody);
                EmitInitializeFunction(assmBody);

                var assmFunc = new JST.FunctionExpression(new Seq<JST.Identifier> { rootId, assemblyId }, new JST.Statements(assmBody));
                var assmLoader = new Seq<JST.Statement>();
                if (Env.DebugMode)
                    assmLoader.Add(new JST.CommentStatement(assmEnv.ToString()));
                assmLoader.Add
                    (JST.Statement.DotCall
                         (new JST.Identifier(Env.Root).ToE(),
                          Constants.RootBindAssembly,
                          new JST.StringLiteral(assmName),
                          assmFunc));

                var assmProgram = new JST.Program(new JST.Statements(assmLoader));
                var assmPath = Path.Combine(Env.OutputDirectory, JST.Lexemes.StringToFileName(assmName));
                var finalName = default(string);
                switch (Env.CompilationMode)
                {
                case CompilationMode.Plain:
                case CompilationMode.Collecting:
                    finalName = Constants.AllFileName;
                    break;
                case CompilationMode.Traced:
                    finalName = Constants.AssemblyFileName;
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
                }
                var assmFileName = Path.Combine(assmPath, finalName);
                assmProgram.ToFile(assmFileName, Env.PrettyPrint);
                Env.Log(new GeneratedJavaScriptFile("assembly '" + assmName + "'", assmFileName));

            }
            else if (!assemblyTrace.IncludeAssembly && assemblyTrace.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Just passing through
                CompileTypes(body);
            }
            else if (!assemblyTrace.IncludeAssembly)
            {
                // Assembly defined elsewhere, include some/all types only in trace
                body.Add
                    (JST.Statement.Var
                         (assemblyId,
                          new JST.IndexExpression
                              (JST.Expression.Dot(rootId.ToE(), Constants.RootAssemblyCache),
                               new JST.StringLiteral(assmName))));
                CompileTypes(body);
            }
            else
            {
                // Inline assembly definition and some/all types
                body.Add
                    (JST.Statement.Var
                         (assemblyId,
                          JST.Expression.DotCall
                              (rootId.ToE(), Constants.RootCreateAssembly, new JST.StringLiteral(assmName))));
                BuildAssembly(body);
                CompileTypes(body);
                EmitInitializeFunction(body);
            }

            if (assmEnv.Assembly.EntryPoint != null && (assemblyTrace == null || assemblyTrace.IncludeAssembly))
            {
                EmitStart();
                EmitManifest();
            }
        }
Esempio n. 9
0
        // ----------------------------------------------------------------------
        // Entry point from AssemblyCompiler
        // ----------------------------------------------------------------------

        public void Emit(Seq <JST.Statement> body)
        {
            if (Env.BreakOnBreak &&
                Env.AttributeHelper.TypeHasAttribute(TyconEnv.Assembly, TyconEnv.Type, Env.AttributeHelper.BreakAttributeRef, false, false))
            {
                System.Diagnostics.Debugger.Break();
            }

            CollectMembers();

            var typeName = CST.CSTWriter.WithAppend
                               (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Type.EffectiveName(Env.Global).Append);
            var slotName = Env.GlobalMapping.ResolveTypeDefToSlot(TyconEnv.Assembly, TyconEnv.Type);

            if (TypeTrace != null && TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Self-loader fragment
                var assmName = CST.CSTWriter.WithAppend
                                   (Env.Global, CST.WriterStyle.Uniform, TyconEnv.Assembly.Name.Append);
                var funcBody = new Seq <JST.Statement>();
                BuildTypeStructure(funcBody);
                var func = new JST.FunctionExpression
                               (new Seq <JST.Identifier> {
                    RootId, AssemblyId, TypeDefinitionId
                }, new JST.Statements(funcBody));
                var loaderBody = new Seq <JST.Statement>();
                if (Env.DebugMode)
                {
                    loaderBody.Add(new JST.CommentStatement(TyconEnv.ToString()));
                }
                loaderBody.Add
                    (JST.Statement.DotCall
                        (new JST.Identifier(Env.Root).ToE(),
                        Constants.RootBindType,
                        new JST.StringLiteral(assmName),
                        new JST.StringLiteral(slotName),
                        new JST.StringLiteral(typeName),
                        func));
                var program  = new JST.Program(new JST.Statements(loaderBody));
                var typePath = Path.Combine
                                   (Path.Combine(Env.OutputDirectory, JST.Lexemes.StringToFileName(assmName)), slotName);
                var fileName = Path.Combine(typePath, Constants.TypeFileName);
                program.ToFile(fileName, Env.PrettyPrint);
                Env.Log(new GeneratedJavaScriptFile("type '" + TyconEnv.TypeConstructorRef + "'", fileName));

                CompileMethods(null, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType && TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
            {
                // Just passisng through
                CompileMethods(body, NameSupply);
            }
            else if (TypeTrace != null && !TypeTrace.IncludeType)
            {
                // Type defined elsewhere, include some/all methods only
                body.Add
                    (JST.Statement.Var
                        (TypeDefinitionId,
                        JST.Expression.DotCall
                            (AssemblyId.ToE(),
                            new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                            Env.JSTHelpers.PhaseExpression(TypePhase.Slots))));
                CompileMethods(body, NameSupply);
            }
            else
            {
                // Inline type definition and some/all methods
                if (Env.DebugMode)
                {
                    body.Add(new JST.CommentStatement(TyconEnv.ToString()));
                }
                // We must construct the type explicity to phase 1 rather than using type compiler environment
                // since it thinks the type is already at phase 2.
                body.Add
                    (JST.Statement.Var
                        (TypeDefinitionId,
                        JST.Expression.DotCall
                            (AssemblyId.ToE(),
                            new JST.Identifier(Constants.AssemblyTypeBuilderSlot(slotName)),
                            Env.JSTHelpers.PhaseExpression(TypePhase.Id))));
                BuildTypeStructure(body);
                CompileMethods(body, NameSupply);
            }
        }
Esempio n. 10
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));
        }