// ---------------------------------------------------------------------- // 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)); }
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)); }
// 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 }
// ---------------------------------------------------------------------- // 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)); }
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)); }