コード例 #1
0
        // 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();
            }
        }
コード例 #2
0
 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;
 }
コード例 #3
0
        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);
        }
コード例 #4
0
        // 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();
            }
        }
コード例 #5
0
 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;
 }
コード例 #6
0
 // 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();
 }
コード例 #7
0
ファイル: AssemblyCompiler.cs プロジェクト: modulexcite/IL2JS
 // 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();
 }
コード例 #8
0
ファイル: TraceCompiler.cs プロジェクト: modulexcite/IL2JS
 public TraceCompiler(CompilerEnvironment env, Trace trace)
 {
     Env = env;
     Trace = trace;
     if (trace.Flavor != TraceFlavor.Remainder)
     {
         NameSupply = new JST.NameSupply(Constants.Globals);
         RootId = NameSupply.GenSym();
     }
 }
コード例 #9
0
 public TraceCompiler(CompilerEnvironment env, Trace trace)
 {
     Env   = env;
     Trace = trace;
     if (trace.Flavor != TraceFlavor.Remainder)
     {
         NameSupply = new JST.NameSupply(Constants.Globals);
         RootId     = NameSupply.GenSym();
     }
 }
コード例 #10
0
ファイル: TypeCompiler.cs プロジェクト: modulexcite/IL2JS
 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);
 }
コード例 #11
0
 // 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();
 }
コード例 #12
0
 // 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();
 }
コード例 #13
0
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, IImSeq <JST.Expression> arguments)
        {
            var groundMethodRef = SubstituteMember(methodRef);

            if (Method.IsStatic && groundMethodRef.Equals(MethodRef))
            {
                var args =
                    TypeBoundTypeParameterIds.Select(id => id.ToE()).Concat
                        (MethodBoundTypeParameterIds.Select(id => id.ToE())).Concat(arguments).ToSeq();
                return(new JST.CallExpression(MethodId.ToE(), args));
            }
            else
            {
                return(env.JSTHelpers.DefaultMethodCallExpression
                           (this, localNameSupply, groundMethodRef, isFactory, arguments));
            }
        }
コード例 #14
0
 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;
 }
コード例 #15
0
ファイル: AssemblyCompiler.cs プロジェクト: modulexcite/IL2JS
 // 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();
     }
 }
コード例 #16
0
 // 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();
     }
 }
コード例 #17
0
 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));
 }
コード例 #18
0
        // Compile all methods not already compiled by above
        private void CompileMethods(Seq <JST.Statement> body, JST.NameSupply outerNameSupply)
        {
            switch (Env.CompilationMode)
            {
            case CompilationMode.Plain:
            case CompilationMode.Collecting:
                // Already compiled above
                return;

            case CompilationMode.Traced:
                foreach (var methodDef in
                         Methods.Where(d => TypeTrace.Methods.Contains(d.MethodSignature)))
                {
                    if (TypeTrace.Parent.Parent.Flavor == TraceFlavor.Remainder)
                    {
                        // Compile method into stand-alone loader
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.SelfContained);
                        compiler.Emit(body, null);
                    }
                    else
                    {
                        // Bind method definition into method cache
                        var target = TypeDefinitionId.ToE();
                        if (TyconEnv.Type.Arity == 0 && !Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef))
                        {
                            target = JST.Expression.Dot
                                         (target, Constants.TypeConstructObject, Constants.prototype);
                        }
                        target = JST.Expression.Dot(target, Constants.TypeMethodCache);
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                        compiler.Emit(body, target);
                    }
                }
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #19
0
 public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, params JST.Expression[] arguments)
 {
     return(MethodCallExpression(methodRef, localNameSupply, isFactory, new Seq <JST.Expression>(arguments)));
 }
コード例 #20
0
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        // Emit bindings for static or instance methods, but not for virtuals or interface methods
        //  - Invoked from TypeDefinitionCompiler for higher-kinded type definitions
        //  - Invoked from TypeCompiler for first-kinded type definitions
        public void EmitMethods(Seq <JST.Statement> body, JST.Expression lhs, JST.NameSupply outerNameSupply, JST.Expression target, bool isStatic)
        {
            switch (Env.CompilationMode)
            {
            case CompilationMode.Plain:
            {
                // Method definitions are bound directly into target
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                        compiler.Emit(body, target);
                    }
                }
                break;
            }

            case CompilationMode.Collecting:
            {
                // Method definitions are bound into MethodCache, redirectors are bound into target
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var slot       = Env.GlobalMapping.ResolveMethodDefToSlot(TyconEnv.Assembly, TyconEnv.Type, methodDef);
                        var methodName = CST.CSTWriter.WithAppend
                                             (Env.Global, CST.WriterStyle.Uniform, methodDef.MethodSignature.Append);
                        body.Add
                            (JST.Statement.DotCall
                                (RootId.ToE(),
                                Constants.RootCollectingBindMethodBuilder,
                                lhs,
                                new JST.BooleanLiteral(isStatic),
                                new JST.StringLiteral(slot),
                                new JST.StringLiteral(methodName)));
                        var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                        compiler.Emit(body, JST.Expression.Dot(target, Constants.TypeMethodCache));
                    }
                }
                break;
            }

            case CompilationMode.Traced:
            {
                // Methods in the initial trace or this trace will be bound directly.
                // Methods in a trace other than above are bound via builder which is given trace name.
                // Remaining methods are built via builder with null trace name.
                var traceToArgs   = new Map <string, Seq <JST.Expression> >();
                var remainingArgs = new Seq <JST.Expression>();
                remainingArgs.Add(TypeDefinitionId.ToE());
                remainingArgs.Add(new JST.BooleanLiteral(isStatic));
                remainingArgs.Add(new JST.NullExpression());
                foreach (var methodDef in Methods.Where(m => m.Invalid == null))
                {
                    if (Env.InteropManager.IsStatic(TyconEnv.Assembly, TyconEnv.Type, methodDef) == isStatic)
                    {
                        var slot     = Env.GlobalMapping.ResolveMethodDefToSlot(TyconEnv.Assembly, TyconEnv.Type, methodDef);
                        var defTrace = Env.Traces.MethodToTrace[methodDef.QualifiedMemberName(Env.Global, TyconEnv.Assembly, TyconEnv.Type)];
                        if (defTrace.Flavor == TraceFlavor.OnDemand && defTrace != TypeTrace.Parent.Parent)
                        {
                            // Method definition in in another trace, bind redirector for it.
                            var args = default(Seq <JST.Expression>);
                            if (!traceToArgs.TryGetValue(defTrace.Name, out args))
                            {
                                args = new Seq <JST.Expression>();
                                args.Add(lhs);
                                args.Add(new JST.BooleanLiteral(isStatic));
                                args.Add(new JST.StringLiteral(defTrace.Name));
                                traceToArgs.Add(defTrace.Name, args);
                            }
                            args.Add(new JST.StringLiteral(slot));
                        }
                        else if (defTrace.Flavor == TraceFlavor.Remainder)
                        {
                            // Method definition is in a stand-alone loader, bind redirector for it.
                            remainingArgs.Add(new JST.StringLiteral(slot));
                        }
                        else
                        {
                            // Method definition is bound directly
                            var compiler = new MethodCompiler(this, outerNameSupply, methodDef, MethodCompilationMode.DirectBind);
                            compiler.Emit(body, target);
                        }
                    }
                }
                foreach (var kv in traceToArgs)
                {
                    body.Add(JST.Statement.DotCall(RootId.ToE(), Constants.RootBindMethodBuilders, kv.Value));
                }
                if (remainingArgs.Count > 3)
                {
                    body.Add(JST.Statement.DotCall(RootId.ToE(), Constants.RootBindMethodBuilders, remainingArgs));
                }
                break;
            }

            default:
                throw new ArgumentOutOfRangeException();
            }
        }
コード例 #21
0
        // ----------------------------------------------------------------------
        // Methods
        // ----------------------------------------------------------------------

        public JST.Expression MethodCallExpression(CST.MethodRef methodRef, JST.NameSupply localNameSupply, bool isFactory, IImSeq <JST.Expression> arguments)
        {
            return(env.JSTHelpers.DefaultMethodCallExpression(this, localNameSupply, methodRef, isFactory, arguments));
        }
コード例 #22
0
        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);
        }