private TypeCompilerEnvironment (CST.Global global, IImSeq<CST.SkolemDef> skolemDefs, CST.AssemblyDef assembly, CST.TypeDef type, IImSeq<CST.TypeRef> typeBoundArguments, CompilerEnvironment env, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeId, IImSeq<JST.Identifier> typeBoundTypeParameterIds, TypeTrace typeTrace) : base( global, skolemDefs, assembly, type, typeBoundArguments) { this.env = env; NameSupply = nameSupply; this.rootId = rootId; this.assemblyId = assemblyId; this.typeId = typeId; TypeBoundTypeParameterIds = typeBoundTypeParameterIds; boundAssemblies = new Map<CST.AssemblyName, JST.Expression>(); boundTypes = new Map<CST.TypeRef, ExpressionAndPhase>(); this.typeTrace = typeTrace; }
public static TypeCompilerEnvironment EnterType (CompilerEnvironment env, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeId, CST.TypeEnvironment typeEnv, TypeTrace typeTrace) { var typeBoundTypeParameterIds = new Seq <JST.Identifier>(); for (var i = 0; i < typeEnv.Type.Arity; i++) { typeBoundTypeParameterIds.Add(nameSupply.GenSym()); } var res = new TypeCompilerEnvironment (typeEnv.Global, typeEnv.SkolemDefs, typeEnv.Assembly, typeEnv.Type, typeEnv.TypeBoundArguments, env, nameSupply, rootId, assemblyId, typeId, typeBoundTypeParameterIds, typeTrace); res.BindSpecial(); return(res); }
// Trace mode entry point public TypeDefinitionCompiler(AssemblyCompiler parent, TypeTrace typeTrace) { Env = parent.Env; Parent = parent; TyconEnv = parent.AssmEnv.AddType(typeTrace.Type); this.TypeTrace = typeTrace; if (typeTrace.IncludeType && typeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder) { // Create a self-loader fragment file NameSupply = new JST.NameSupply(Constants.Globals); // Will be bound by function passed to root's BindType RootId = NameSupply.GenSym(); AssemblyId = NameSupply.GenSym(); TypeDefinitionId = NameSupply.GenSym(); } else { // Possibly inline type definition and/or method definitions into trace NameSupply = parent.NameSupply; // Already bound by parent RootId = parent.RootId; AssemblyId = parent.AssemblyId; // Will be bound locally TypeDefinitionId = NameSupply.GenSym(); } }
private TypeCompilerEnvironment (CST.Global global, IImSeq <CST.SkolemDef> skolemDefs, CST.AssemblyDef assembly, CST.TypeDef type, IImSeq <CST.TypeRef> typeBoundArguments, CompilerEnvironment env, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeId, IImSeq <JST.Identifier> typeBoundTypeParameterIds, TypeTrace typeTrace) : base( global, skolemDefs, assembly, type, typeBoundArguments) { this.env = env; NameSupply = nameSupply; this.rootId = rootId; this.assemblyId = assemblyId; this.typeId = typeId; TypeBoundTypeParameterIds = typeBoundTypeParameterIds; boundAssemblies = new Map <CST.AssemblyName, JST.Expression>(); boundTypes = new Map <CST.TypeRef, ExpressionAndPhase>(); this.typeTrace = typeTrace; }
// Collecting mode entry point public AssemblyCompiler(CompilerEnvironment env, CST.AssemblyDef assemblyDef) : this(env) { assmEnv = env.Global.Environment().AddAssembly(assemblyDef); assemblyTrace = null; NameSupply = new JST.NameSupply(Constants.Globals); rootId = NameSupply.GenSym(); assemblyId = NameSupply.GenSym(); }
public TraceCompiler(CompilerEnvironment env, Trace trace) { Env = env; Trace = trace; if (trace.Flavor != TraceFlavor.Remainder) { NameSupply = new JST.NameSupply(Constants.Globals); RootId = NameSupply.GenSym(); } }
public TypeCompiler(TypeDefinitionCompiler parent) { // Type compiler is always in context of it's type definition Env = parent.Env; Parent = parent; var typeEnv = parent.TyconEnv.AddSelfTypeBoundArguments(); NameSupply = typeEnv.Type.Arity > 0 ? parent.NameSupply.Fork() : parent.NameSupply; RootId = parent.RootId; AssemblyId = parent.AssemblyId; TypeDefinitionId = parent.TypeDefinitionId; TypeId = typeEnv.Type.Arity > 0 ? NameSupply.GenSym() : parent.TypeDefinitionId; TypeCompEnv = TypeCompilerEnvironment.EnterType(Env, NameSupply, RootId, AssemblyId, TypeId, typeEnv, parent.TypeTrace); }
public JST.Expression ResolveVariablePointer(JST.Identifier id) { var res = default(JST.Expression); if (boundVariablePointers.TryGetValue(id, out res)) { return(res); } else { return(VariablePointerExpression(id)); } }
// Collecting mode entry point public TypeDefinitionCompiler(AssemblyCompiler parent, CST.TypeDef typeDef) { Env = parent.Env; Parent = parent; TyconEnv = parent.AssmEnv.AddType(typeDef); TypeTrace = null; // Inline type definition and method definitions into overall assembly NameSupply = parent.NameSupply; // Already bound by parent RootId = parent.RootId; AssemblyId = parent.AssemblyId; // Will be bound locally TypeDefinitionId = NameSupply.GenSym(); }
private MethodCompilerEnvironment (CST.Global global, IImSeq <CST.SkolemDef> skolemDefs, CST.AssemblyDef assembly, CST.TypeDef type, IImSeq <CST.TypeRef> typeBoundArguments, CST.MethodDef method, IImSeq <CST.TypeRef> methodBoundArguments, IMap <JST.Identifier, CST.Variable> variables, IImSeq <JST.Identifier> valueParameterIds, IImSeq <JST.Identifier> localIds, CompilerEnvironment env, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeDefinitionId, JST.Identifier methodId, IImSeq <JST.Identifier> typeBoundTypeParameterIds, IImSeq <JST.Identifier> methodBoundTypeParameterIds, TypeTrace typeTrace) : base( global, skolemDefs, assembly, type, typeBoundArguments, method, methodBoundArguments, variables, valueParameterIds, localIds) { this.env = env; NameSupply = nameSupply; this.rootId = rootId; this.assemblyId = assemblyId; this.typeDefinitionId = typeDefinitionId; MethodId = methodId; TypeBoundTypeParameterIds = typeBoundTypeParameterIds; MethodBoundTypeParameterIds = methodBoundTypeParameterIds; boundAssemblies = new Map <CST.AssemblyName, JST.Expression>(); boundTypes = new Map <CST.TypeRef, JST.Expression>(); boundVariablePointers = new Map <JST.Identifier, JST.Expression>(); this.typeTrace = typeTrace; }
// Traced mode entry point public AssemblyCompiler(TraceCompiler parent, AssemblyTrace assemblyTrace) : this(parent.Env) { assmEnv = parent.Env.Global.Environment().AddAssembly(assemblyTrace.Assembly); this.assemblyTrace = assemblyTrace; if (assemblyTrace.Parent.Flavor == TraceFlavor.Remainder) { NameSupply = new JST.NameSupply(Constants.Globals); rootId = NameSupply.GenSym(); assemblyId = NameSupply.GenSym(); } else { NameSupply = parent.NameSupply; rootId = parent.RootId; assemblyId = NameSupply.GenSym(); } }
public static MethodCompilerEnvironment EnterUntranslatedMethod (CompilerEnvironment env, JST.NameSupply outerNameSupply, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeDefinitonId, CST.MethodEnvironment methEnv, TypeTrace typeTrace) { return(EnterMethod (env, outerNameSupply, nameSupply, rootId, assemblyId, typeDefinitonId, methEnv.AddVariables(nameSupply, i => false), typeTrace)); }
// ---------------------------------------------------------------------- // Parameters and locals // ---------------------------------------------------------------------- private JST.Expression VariablePointerExpression(JST.Identifier id) { return(env.JSTHelpers.PointerToLvalueExpression(this, NameSupply, id.ToE(), ResolveType(Variable(id).Type))); }
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)); }
private void EnsurePathExists(ISeq<JST.Statement> statements, JST.Expression script, bool isStatic) { var path = JST.Expression.ExplodePath(script); for (var i = isStatic ? 0 : 1; i < path.Count - 1; i++) { var prefixPath = new Seq<JST.PropertyName>(); for (var j = 0; j <= i; j++) prefixPath.Add(path[j]); var prefix = JST.Expression.Path(prefixPath); if (i == 0) { var exId = new JST.Identifier("e"); #if !JSCRIPT_IS_CORRECT statements.Add(JST.Statement.Var(exId)); #endif statements.Add (new JST.TryStatement (new JST.Statements(new JST.ExpressionStatement(prefix)), new JST.CatchClause (exId, new JST.Statements(JST.Statement.Assignment(prefix, new JST.ObjectLiteral()))))); } else if (!path[i].Value.Equals(Constants.prototype.Value, StringComparison.Ordinal)) statements.Add (new JST.IfStatement (JST.Expression.IsNull(prefix), new JST.Statements(JST.Statement.Assignment(prefix, new JST.ObjectLiteral())))); } }
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)); }
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)); }
public static MethodCompilerEnvironment EnterMethod (CompilerEnvironment env, JST.NameSupply outerNameSupply, JST.NameSupply nameSupply, JST.Identifier rootId, JST.Identifier assemblyId, JST.Identifier typeDefinitonId, CST.CompilationEnvironment compEnv, TypeTrace typeTrace) { // BUG: IE messes up scoping for function identifiers. To compensate we must allocate its // identifier in the outer scope var methodId = outerNameSupply.GenSym(); if (env.DebugMode) { var sb = new StringBuilder(); sb.Append(methodId.Value); sb.Append('_'); var namedTypeDef = compEnv.Type as CST.NamedTypeDef; if (namedTypeDef != null) { if (namedTypeDef.Name.Namespace.Length > 0) { JST.Lexemes.AppendStringToIdentifier(sb, namedTypeDef.Name.Namespace.Replace('.', '_')); sb.Append('_'); } foreach (var n in namedTypeDef.Name.Types) { JST.Lexemes.AppendStringToIdentifier(sb, n); sb.Append('_'); } } JST.Lexemes.AppendStringToIdentifier(sb, compEnv.Method.Name); methodId = new JST.Identifier(sb.ToString()); } var typeBoundTypeParameterIds = new Seq <JST.Identifier>(); for (var i = 0; i < compEnv.Type.Arity; i++) { typeBoundTypeParameterIds.Add(nameSupply.GenSym()); } var methodBoundTypeParameterIds = new Seq <JST.Identifier>(); for (var i = 0; i < compEnv.Method.TypeArity; i++) { methodBoundTypeParameterIds.Add(nameSupply.GenSym()); } var res = new MethodCompilerEnvironment (compEnv.Global, compEnv.SkolemDefs, compEnv.Assembly, compEnv.Type, compEnv.TypeBoundArguments, compEnv.Method, compEnv.MethodBoundArguments, compEnv.Variables, compEnv.ValueParameterIds, compEnv.LocalIds, env, nameSupply, rootId, assemblyId, typeDefinitonId, methodId, typeBoundTypeParameterIds, methodBoundTypeParameterIds, typeTrace); res.BindSpecial(); return(res); }
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)); }