Beispiel #1
0
 /// <summary>
 /// Create a new SmalltalkObject for a given SmalltalkClass.
 /// </summary>
 /// <param name="cls">The SmalltalkClass that this object will be instance of.</param>
 public SmalltalkObject(SmalltalkClass cls)
 {
     if (cls == null)
         throw new ArgumentNullException();
     this.Class = cls;
     this.InstanceVariables = new object[cls.InstanceSize];
 }
 public SmalltalkDynamicMetaObject(Expression expression, BindingRestrictions restrictions, SmalltalkClass cls, object value)
     : base(expression, restrictions, value)
 {
     if (cls == null)
         throw new ArgumentNullException("cls");
     this.Class = cls;
 }
        /// <summary>
        /// Look-up a method implementation starting with the given class.
        /// </summary>
        /// <param name="cls">Class where to start searching for the method (unless superLookupScope) is set.</param>
        /// <param name="superLookupScope">If set, start the lookup from the superclass of this class.</param>
        /// <param name="lookupFunction">Function to perform the method lookup.</param>
        /// <returns>Returns the compiled method for the given selector or null if none was found.</returns>
        public static CompiledMethod LookupMethod(ref SmalltalkClass cls, Symbol superLookupScope, Func <SmalltalkClass, CompiledMethod> lookupFunction)
        {
            if (lookupFunction == null)
            {
                throw new ArgumentNullException("lookupFunction");
            }

            while (cls != null)
            {
                if (superLookupScope == null)
                {
                    CompiledMethod method = lookupFunction(cls);
                    if (method != null)
                    {
                        return(method);
                    }
                }
                else
                {
                    if (cls.Name == superLookupScope)
                    {
                        superLookupScope = null;
                    }
                }
                cls = cls.Superclass;
            }

            // No method ... no luck;
            return(null);
        }
 public ClassRelatedBindingScope(SmalltalkClass cls, BindingScope outerScope)
     : base(outerScope)
 {
     if (cls == null)
         throw new ArgumentNullException();
     this.Class = cls;
 }
Beispiel #5
0
        public Expression CompileMethod(MethodNode parseTree, SmalltalkClass cls, Expression self, Expression executionContext, Expression[] arguments)
        {
            if (parseTree == null)
            {
                throw new ArgumentNullException("parseTree");
            }
            if (cls == null)
            {
                throw new ArgumentNullException("cls");
            }
            if (self == null)
            {
                throw new ArgumentNullException("self");
            }
            if (arguments == null)
            {
                throw new ArgumentNullException("arguments");
            }

            RootCompilationContext context = this.GetCompilationContext(parseTree, cls, self, executionContext, arguments);
            MethodVisitor          visitor = new MethodVisitor(context);
            Expression             code    = parseTree.Accept(visitor);

            return(code);
        }
Beispiel #6
0
 public NativeCompiledMethod(SmalltalkClass cls, Symbol selector, MethodType methodType, MethodInfo nativeMethod)
     : base(cls, selector, methodType)
 {
     if (nativeMethod == null)
     {
         throw new ArgumentNullException("nativeMethod");
     }
     this.NativeMethod = nativeMethod;
 }
Beispiel #7
0
 public ClassVariableBinding(string name, SmalltalkClass cls, RTB.ClassVariableBinding binding)
     : base(name, binding)
 {
     if (cls == null)
     {
         throw new ArgumentNullException("cls");
     }
     this.Class = cls;
 }
 public ClassRelatedBindingScope(SmalltalkClass cls, BindingScope outerScope)
     : base(outerScope)
 {
     if (cls == null)
     {
         throw new ArgumentNullException();
     }
     this.Class = cls;
 }
 public RuntimeCompiledMethod(SmalltalkClass cls, Symbol selector, MethodType methodType, MethodNode parseTree, IDebugInfoService debugInfoService)
     : base(cls, selector, methodType)
 {
     if (parseTree == null)
     {
         throw new ArgumentNullException();
     }
     this.ParseTree        = parseTree;
     this.DebugInfoService = debugInfoService;
 }
Beispiel #10
0
 private static bool InheritsFrom(SmalltalkClass self, SmalltalkClass cls)
 {
     while (self != null)
     {
         if (self.Superclass == cls)
         {
             return(true);
         }
         self = self.Superclass;
     }
     return(false);
 }
 void IDefinitionInstallerContext.RegisterNewClass(SmalltalkClass cls, ISourceReference sourceReference)
 {
     if (cls == null)
     {
         throw new ArgumentNullException("cls");
     }
     if (sourceReference == null)
     {
         throw new ArgumentNullException("sourceReference");
     }
     this._newClasses.Add(new Tuple <SmalltalkClass, ISourceReference>(cls, sourceReference));
 }
 /// <summary>
 /// Look-up for a class method implementation given a method selector and a class.
 /// </summary>
 /// <param name="selector">Method selector to look for.</param>
 /// <param name="cls">Class where to start searching for the method (unless superLookupScope) is set.</param>
 /// <param name="superLookupScope">If set, start the lookup from the superclass of this class.</param>
 /// <returns>Returns the compiled method for the given selector or null if none was found.</returns>
 /// <remarks>If the method is not found, this functions does not searches the instance side of the class.</remarks>
 public static CompiledMethod LookupClassMethod(Symbol selector, ref SmalltalkClass cls, Symbol superLookupScope)
 {
     return(MethodLookupHelper.LookupMethod(ref cls, superLookupScope, c =>
     {
         CompiledMethod method;
         if (c.ClassBehavior.TryGetValue(selector, out method))
         {
             return method;
         }
         return null;
     }));
 }
            public override IDiscreteBinding GetBinding(ExecutionContext executionContext)
            {
                SmalltalkClass cls = executionContext.Runtime.GetClass(this.ClassName);

                if (cls == null)
                {
                    return(null);
                }
                ClassVariableBinding binding = null;

                cls.ClassVariableBindings.TryGetValue(this.VariableName, out binding);
                return(binding);
            }
        /// <summary>
        /// Create a new CompiledMethod.
        /// </summary>
        /// <param name="cls">The class that defines the method.</param>
        /// <param name="selector">The selector of the method.</param>
        /// <param name="methodType">The type of method - either a class or an instance method.</param>
        protected CompiledMethod(SmalltalkClass cls, Symbol selector, MethodType methodType)
        {
            if (cls == null)
            {
                throw new ArgumentNullException("cls");
            }
            if (selector == null)
            {
                throw new ArgumentNullException("selector");
            }

            this.Class    = cls;
            this.Selector = selector;
            this.Type     = methodType;
        }
        public static string GetMoniker(SmalltalkClass cls, ClassVariableBinding binding)
        {
            if (cls == null)
            {
                throw new ArgumentNullException("cls");
            }
            if (binding == null)
            {
                throw new ArgumentNullException("binding");
            }

            return(DiscreteBindingCallSiteBinderBase.GetMoniker(
                       DiscreteBindingCallSiteBinderBase.ClassVariablePrefix,
                       cls.Name.Value,
                       binding.Name.Value));
        }
Beispiel #16
0
 public static BindingScope ForClassInitializer(SmalltalkClass cls, SmalltalkNameScope globalNameScope)
 {
     if (cls == null)
     {
         throw new ArgumentNullException("cls");
     }
     if (globalNameScope == null)
     {
         throw new ArgumentNullException("globalNameScope");
     }
     //statement_scope := class_funtion_scope + local_scope + reserved_scope       // Class Initializer - X3J20:3.4.3
     //home_context_scope := class_funtion_scope
     return(new ClassFunctionScope(cls,
                                   new ClassScope(cls,
                                                  new PoolVariableScope(cls,
                                                                        new GlobalScope(globalNameScope)))));
 }
Beispiel #17
0
 public static BindingScope ForClassMethod(SmalltalkClass cls, SmalltalkNameScope globalNameScope)
 {
     if (cls == null)
     {
         throw new ArgumentNullException("cls");
     }
     if (globalNameScope == null)
     {
         throw new ArgumentNullException("globalNameScope");
     }
     //class_scope := (global_scope + pool_variable_scope) + inheritable_class_variable_scope      // X3J20:3.3.2.3
     //class_funtion_scope := class_scope + class_instance_variable_scope                          // X3J20:3.3.2.3
     return(new ClassFunctionScope(cls,
                                   new ClassScope(cls,
                                                  new PoolVariableScope(cls,
                                                                        new GlobalScope(globalNameScope)))));
 }
 protected MethodGenerator(NativeCompiler compiler, SmalltalkClass cls, MethodDictionary methods)
     : base(compiler)
 {
     if (cls == null)
     {
         throw new ArgumentNullException("cls");
     }
     if (methods == null)
     {
         throw new ArgumentNullException("methods");
     }
     this.Class   = cls;
     this.Methods = methods;
     this.LiteralEncodingStrategy         = new NativeLiteralEncodingStrategy(this);
     this.DynamicCallStrategy             = new NativeDynamicCallStrategy(this);
     this.DiscreteBindingEncodingStrategy = new NativeDiscreteBindingEncodingStrategy(this);
 }
Beispiel #19
0
        protected override NameBinding ResolveBinding(string name)
        {
            // inheritable_class_variable_scope
            SmalltalkClass cls = this.Class;

            RTB.ClassVariableBinding binding;
            while (cls != null)
            {
                cls.ClassVariableBindings.TryGetValue(name, out binding);
                if (binding != null)
                {
                    return(new ClassVariableBinding(name, cls, binding));
                }
                cls = cls.Superclass;
            }
            return(null); // null means try outer scope.
        }
Beispiel #20
0
        public LambdaExpression CompileMethodLambda(MethodNode parseTree, SmalltalkClass cls, string methodName)
        {
            if (parseTree == null)
            {
                throw new ArgumentNullException("parseTree");
            }

            // Declare parameter expression for each argument ....
            ParameterExpression[] arguments = MethodCompiler.CreateParametersForMethod(parseTree);

            // Compile the method !!!
            Expression body = this.CompileMethod(parseTree, cls, arguments[0], arguments[1], arguments.Skip(2).Cast <Expression>().ToArray());

            // Finally, create a lambda expression out of it.
            return(Expression.Lambda(
                       body,
                       methodName,
                       true, // always compile the rules with tail call optimization,
                       arguments));
        }
 private ClassMethodGenerator(NativeCompiler compiler, SmalltalkClass cls, MethodDictionary methods)
     : base(compiler, cls, methods)
 {
 }
Beispiel #22
0
 private bool InheritsFrom(SmalltalkClass self, SmalltalkClass cls)
 {
     while (self != null)
     {
         if (self.Superclass == cls)
             return true;
         self = self.Superclass;
     }
     return false;
 }
Beispiel #23
0
 public static BindingScope ForInstanceMethod(SmalltalkClass cls, SmalltalkNameScope globalNameScope)
 {
     if (cls == null)
         throw new ArgumentNullException("cls");
     if (globalNameScope == null)
         throw new ArgumentNullException("globalNameScope");
     //class_scope := (global_scope + pool_variable_scope) + inheritable_class_variable_scope      // X3J20:3.3.2.3
     //instance_function_scope := class_scope + instance_variable_scope                            // X3J20:3.3.2.3
     return new InstanceFunctionScope(cls,
         new ClassScope(cls,
             new PoolVariableScope(cls,
                 new GlobalScope(globalNameScope))));
 }
 /// <summary>
 /// Look-up for an instance method implementation given a method selector and a class.
 /// </summary>
 /// <param name="selector">Method selector to look for.</param>
 /// <param name="cls">Class where to start searching for the method (unless superLookupScope) is set.</param>
 /// <param name="superLookupScope">If set, start the lookup from the superclass of this class.</param>
 /// <returns>Returns the compiled method for the given selector or null if none was found.</returns>
 public static CompiledMethod LookupInstanceMethod(Symbol selector, ref SmalltalkClass cls, ref Symbol superLookupScope)
 {
     return MethodLookupHelper.LookupMethod(ref cls, ref superLookupScope, delegate(SmalltalkClass c)
     {
         CompiledMethod method;
         if (c.InstanceBehavior.TryGetValue(selector, out method))
             return method;
         return null;
     });
 }
Beispiel #25
0
        /// <summary>
        /// Validate that the definition of the class object does not break any rules set by the Smalltalk standard.
        /// </summary>
        /// <param name="installer">Context within which the validation is to be performed.</param>
        /// <returns>Returns true if successful, otherwise false.</returns>
        protected internal override bool ValidateObject(IDefinitionInstallerContext installer)
        {
            if (installer == null)
            {
                throw new ArgumentNullException();
            }
            // 1. Get the binding to the global
            Symbol       name    = installer.Runtime.GetSymbol(this.Name.Value);
            ClassBinding binding = installer.GetLocalClassBinding(name);

            // 2. Check consistency that we didn't mess up in the implementation.
            if (binding == null)
            {
                throw new InvalidOperationException("Should have found a binding, because CreateGlobalBinding() created it!");
            }
            if (binding.Value == null)
            {
                throw new InvalidOperationException("Should not be an empty binding, because CreateGlobalObject() just created it!");
            }
            // 3. Get the class object.
            SmalltalkClass cls = binding.Value;
            // 4. Validate that superclass is correct
            List <Symbol> classes = new List <Symbol>();

            classes.Add(cls.Name);
            SmalltalkClass tmp = cls.Superclass;

            while (tmp != null)
            {
                if (classes.IndexOf(tmp.Name) != -1)
                {
                    return(installer.ReportError(this.SuperclassName, String.Format(
                                                     InstallerErrors.ClassCircularReference, this.SuperclassName.Value, this.Name.Value)));
                }
                classes.Add(tmp.Name);
                tmp = tmp.Superclass;
            }

            if (cls.InstanceState != SmalltalkClass.InstanceStateEnum.ByteIndexable)
            {
                tmp = cls;
                while (tmp != null)
                {
                    if (tmp.InstanceState == SmalltalkClass.InstanceStateEnum.ByteIndexable)
                    {
                        return(installer.ReportError(this.InstanceState, InstallerErrors.ClassCannotChangeInstanceState));
                    }
                    tmp = tmp.Superclass;
                }
            }

            foreach (PoolBinding pool in cls.ImportedPoolBindings)
            {
                if (pool.Value == null)
                {
                    SourceReference <string> src = this.ImportedPoolNames.SingleOrDefault(sr => sr.Value == pool.Name.Value);
                    if (src == null)
                    {
                        throw new InvalidOperationException("Should not be null, cause we just added this pool in CreateGlobalObject().");
                    }
                    return(installer.ReportError(src, InstallerErrors.ClassMissingPoolDefinition));
                }
            }

            // NB: We must give some source reference, but since we don't have for the whole class, we use the name.
            installer.RegisterNewClass(cls, this.Name);

            return(true); // OK
        }
Beispiel #26
0
 public static BindingScope ForClassInitializer(SmalltalkClass cls, SmalltalkNameScope globalNameScope)
 {
     if (cls == null)
         throw new ArgumentNullException("cls");
     if (globalNameScope == null)
         throw new ArgumentNullException("globalNameScope");
     //statement_scope := class_funtion_scope + local_scope + reserved_scope       // Class Initializer - X3J20:3.4.3
     //home_context_scope := class_funtion_scope
     return new ClassFunctionScope(cls,
         new ClassScope(cls,
             new PoolVariableScope(cls,
                 new GlobalScope(globalNameScope))));
 }
 public PoolVariableScope(SmalltalkClass cls, GlobalScope outerScope)
     : base(cls, outerScope)
 {
 }
 public override InitializerCompilationResult CompileClassInitializer(SmalltalkRuntime runtime, SmalltalkClass cls)
 {
     return this.CompileClassInitializer(runtime, cls, runtime.GlobalScope);
 }
 protected override bool InternalValidateMethod(IInstallerContext installer, SmalltalkClass cls, IIntermediateCodeValidationErrorSink errorSink)
 {
     return this.IntermediateCode.ValidateClassMethod(cls, installer.NameScope, errorSink);
 }
        /// <summary>
        /// Register a .Net type identified by its type-name to be mapped to the given Smalltalk class.
        /// </summary>
        /// <param name="cls">Required. Smalltalk class to map to.</param>
        /// <param name="typeName">Required. Type-name of the .Net type to be mapped to Smalltalk class. See remarks.</param>
        /// <remarks>
        /// The type-name can be one of:
        /// - Reserved name: "true", "false", "null", "nil", "native", "class", "symbol", "pool", "type"
        /// - C# alias, e.g. "string", "bool", "int", "float" etc.
        /// - IronSmalltak type prefixed with "_", e.g. "_SmalltalkRuntime".
        /// - mscorlib type (without any prefixes), e.g. "System.DateTime".
        /// - Any other type using assembly qualified name, e.g. "System.Numerics.BigInteger, System.Numerics, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"
        /// </remarks>
        public void RegisterClass(SmalltalkClass cls, string typeName)
        {
            if (cls == null)
                throw new ArgumentNullException("cls");
            if (System.String.IsNullOrWhiteSpace(typeName))
                throw new SmalltalkDefinitionException(System.String.Format(
                    "Invalid type name. Check native type mapping for class {0}",
                    cls.Name), new ArgumentNullException("typeName"));

            // Special case handling for Smalltalk specific classes.
            if (typeName == "true")
            {
                this.True = cls;
                return;
            }
            if (typeName == "false")
            {
                this.False = cls;
                return;
            }
            if ((typeName == "null") || (typeName == "nil"))
            {
                this.UndefinedObject = cls;
                return;
            }
            if (typeName == "native")
            {
                this.Native = cls;
                return;
            }
            if (typeName == "class")
            {
                this.Class = cls;
                return;
            }
            if (typeName == "symbol")
            {
                this.Symbol = cls;
                return;
            }
            if (typeName == "pool")
            {
                this.Pool = cls;
                return;
            }
            if (typeName == "type")
            {
                this.SystemType = cls;
                return;
            }
            //struct, enum, delegate, event ... do we need to handle those?

            // Generic classes ... remap C# convenience names to FCL names.
            Type type;
            if (typeName.StartsWith(NativeTypeClassMap.IstTypenamePrefix))
            {
                type = NativeTypeClassMap.GetIstType(typeName);
            }
            else
            {
                typeName = NativeTypeClassMap.RemapTypeName(typeName);
                try
                {
                    type = Type.GetType(typeName, true, false);
                }
                catch (Exception ex)
                {
                    throw new SmalltalkDefinitionException(System.String.Format(
                        "Cannot find type {0}. Check native type mapping for class {1}",
                        typeName, cls.Name), ex);
                }
            }

            // Some very common types are cached directly
            if (type == typeof(object))
                this.Object = cls;
            else if (type == typeof(int))
                this.SmallInteger = cls;
            else if (type == typeof(char))
                this.Character = cls;
            else if (type == typeof(string))
                this.String = cls;
            else if (type == typeof(double))
                this.Float = cls;
            else if (type == typeof(decimal))
                this.SmallDecimal = cls;
            else if (type == typeof(BigInteger))
                this.BigInteger = cls;
            else if (type == typeof(BigDecimal))
                this.BigDecimal = cls;

            // Add the type to the map ...
            this.TypeClassMap[type] = cls;
        }
 protected override bool InternalAddMethod(IInstallerContext installer, SmalltalkClass cls)
 {
     Symbol selector = installer.Runtime.GetSymbol(this.Selector.Value);
     cls.ClassBehavior[selector] = new CompiledMethod(selector, this.IntermediateCode);
     return true;
 }
 protected override CompiledMethod GetMethod(SmalltalkClass cls)
 {
     CompiledMethod result;
     cls.ClassBehavior.TryGetValue(this.Selector.Value, out result);
     return result;
 }
Beispiel #33
0
 public PoolVariableScope(SmalltalkClass cls, GlobalScope outerScope)
     : base(cls, outerScope)
 {
 }
Beispiel #34
0
 /// <summary>
 /// Create a new ByteIndexable SmalltalkObject for a given SmalltalkClass.
 /// </summary>
 /// <param name="cls">The SmalltalkClass that this object will be instance of.</param>
 /// <param name="objectSize">Number of unnamed instance variables.</param>
 public ByteIndexableSmalltalkObject(SmalltalkClass cls, int objectSize)
     : base(cls)
 {
     if (cls.InstanceState != SmalltalkClass.InstanceStateEnum.ByteIndexable)
         throw new ArgumentOutOfRangeException("Expected a ByteIndexable class");
     if (objectSize < 0)
         throw new ArgumentOutOfRangeException("objectSize");
     this.Contents = new byte[objectSize];
 }
Beispiel #35
0
 public ClassFunctionScope(SmalltalkClass cls, ClassScope outerScope)
     : base(cls, outerScope)
 {
 }
Beispiel #36
0
        protected override RootCompilationContext GetCompilationContext(MethodNode parseTree, SmalltalkClass cls, Expression self, Expression executionContext, Expression[] arguments)
        {
            SmalltalkNameScope globalNameScope = this.CompilerOptions.GlobalNameScope ?? this.Runtime.GlobalScope;

            BindingScope globalScope   = BindingScope.ForClassMethod(cls, globalNameScope);
            BindingScope reservedScope = ReservedScope.ForClassMethod();

            return(new RootCompilationContext(this, globalScope, reservedScope, self, executionContext, arguments, cls.Name, parseTree.Selector));
        }
 protected abstract bool InternalAddMethod(IDefinitionInstallerContext installer, SmalltalkClass cls);
 private InitializerCompilationResult CompileClassInitializer(SmalltalkRuntime runtime, SmalltalkClass cls, SmalltalkNameScope globalNameScope)
 {
     return this.Compile(runtime,
         BindingScope.ForClassInitializer(cls, globalNameScope),
         ReservedScope.ForClassInitializer());
 }
 protected abstract bool InternalValidateMethod(IDefinitionInstallerContext installer, SmalltalkClass cls, ICodeValidationErrorSink errorSink);
 public override bool ValidateClassInitializer(SmalltalkNameScope globalNameScope, SmalltalkClass cls, IIntermediateCodeValidationErrorSink errorSink)
 {
     return this.Validate(globalNameScope, errorSink, rt => this.CompileClassInitializer(rt, cls, globalNameScope));
 }
 private Expression <Func <object, ExecutionContext, object> > CompileClassInitializer(SmalltalkRuntime runtime, SmalltalkNameScope globalNameScope, SmalltalkClass cls)
 {
     return(this.Compile(runtime,
                         BindingScope.ForClassInitializer(cls, globalNameScope),
                         ReservedScope.ForClassInitializer(),
                         String.Format("{0} initializer", this.Binding.Name.Value)));
 }
Beispiel #42
0
 public static BindingScope ForClassInitializer(SmalltalkClass cls)
 {
     return BindingScope.ForClassInitializer(cls, cls.Runtime.GlobalScope);
 }
Beispiel #43
0
 void IInstallerContext.RegisterNewClass(SmalltalkClass cls)
 {
     if (cls == null)
         throw new ArgumentNullException();
     this._newClasses.Add(cls);
 }
Beispiel #44
0
 public static BindingScope ForInstanceMethod(SmalltalkClass cls)
 {
     return BindingScope.ForInstanceMethod(cls, cls.Runtime.GlobalScope);
 }
        protected override bool InternalAddMethod(IDefinitionInstallerContext installer, SmalltalkClass cls)
        {
            CompiledMethod method = this.Factory.CreateMethod(this, installer, cls, CompiledMethod.MethodType.Instance);

            if (method == null)
            {
                return(false);
            }
            System.Diagnostics.Debug.Assert(this.Selector.Value == method.Selector.Value);
            cls.InstanceBehavior[method.Selector] = method;
            this.CompiledCode = method;
            return(true);
        }
        /// <summary>
        /// Look-up a method implementation starting with the given class.
        /// </summary>
        /// <param name="cls">Class where to start searching for the method (unless superLookupScope) is set.</param>
        /// <param name="superLookupScope">If set, start the lookup from the superclass of this class.</param>
        /// <param name="lookupFunction">Function to perform the method lookup.</param>
        /// <returns>Returns the compiled method for the given selector or null if none was found.</returns>
        public static CompiledMethod LookupMethod(ref SmalltalkClass cls, ref Symbol superLookupScope, Func<SmalltalkClass, CompiledMethod> lookupFunction)
        {
            if (lookupFunction == null)
                throw new ArgumentNullException("lookupFunction");

            while (cls != null)
            {
                if (superLookupScope == null)
                {
                    CompiledMethod method = lookupFunction(cls);
                    if (method != null)
                        return method;
                }
                else
                {
                    if (cls.Name == superLookupScope)
                        superLookupScope = null;
                }
                cls = cls.Superclass;
            }

            // No method ... no luck;
            return null;
        }
 protected override bool InternalValidateMethod(IDefinitionInstallerContext installer, SmalltalkClass cls, ICodeValidationErrorSink errorSink)
 {
     return(this.Factory.ValidateMethod(this, installer, cls, CompiledMethod.MethodType.Instance, errorSink));
 }
        /// <summary>
        /// This method is the core of the dynamic method lookup system.
        /// It determines the class of an object and looks-up the method implementation
        /// for a given method selector.
        /// </summary>
        /// <param name="runtime">Required.</param>
        /// <param name="selector">Required.</param>
        /// <param name="superLookupScope">Optional.</param>
        /// <param name="receiver">Optional.</param>
        /// <param name="self">Required.</param>
        /// <param name="arguments">Required (currently not used).</param>
        /// <param name="receiverClass">Must Return!</param>
        /// <param name="restrictions">Must Return!</param>
        /// <param name="executableCode">Return null if missing.</param>
        public static void GetMethodInformation(SmalltalkRuntime runtime, 
            Symbol selector,
            Symbol superLookupScope,
            object receiver,
            DynamicMetaObject self,
            DynamicMetaObject[] arguments,
            out SmalltalkClass receiverClass,
            out BindingRestrictions restrictions,
            out Expression executableCode)
        {
            restrictions = null;
            SmalltalkClass cls = null;

            // Special case for Smalltalk classes, because we want the class behavior first ...
            if (receiver is SmalltalkClass)
            {
                cls = (SmalltalkClass)receiver;
                if (cls.Runtime == runtime)
                {
                    receiverClass = runtime.NativeTypeClassMap.Class;
                    if (receiverClass == null)
                        receiverClass = runtime.NativeTypeClassMap.Object;
                    // Lookup method in class behavior
                    CompiledMethod mth = MethodLookupHelper.LookupClassMethod(selector, ref cls, ref superLookupScope);
                    if (mth != null)
                    {
                        // A class method, special restrictions
                        restrictions = BindingRestrictions.GetInstanceRestriction(self.Expression, receiver);
                        var compilationResult = mth.Code.CompileClassMethod(runtime, cls, self, arguments, superLookupScope);
                        if (compilationResult == null)
                        {
                            executableCode = null;
                        }
                        else
                        {
                            executableCode = compilationResult.ExecutableCode;
                            restrictions = compilationResult.MergeRestrictions(restrictions);
                        }
                        return;
                    }
                    // Not in class behavior ... fallback to instance / Object behavior
                    cls = receiverClass;
                    restrictions = BindingRestrictions.GetTypeRestriction(self.Expression, typeof(SmalltalkClass));
                }
            }

            if ((cls == null) || (restrictions == null))
                cls = GetClassAndRestrictions(runtime, receiver, self, arguments, out restrictions);
            receiverClass = cls;

            // Look-up the method
            CompiledMethod method = MethodLookupHelper.LookupInstanceMethod(selector, ref cls, ref superLookupScope);
            if (method == null)
            {
                executableCode = null;
            }
            else
            {
                var compilationResult = method.Code.CompileInstanceMethod(runtime, cls, self, arguments, superLookupScope);
                if (compilationResult == null)
                {
                    executableCode = null;
                }
                else
                {
                    executableCode = compilationResult.ExecutableCode;
                    restrictions = compilationResult.MergeRestrictions(restrictions);
                }

            }
        }
Beispiel #49
0
 public ClassScope(SmalltalkClass cls, PoolVariableScope outerScope)
     : base(cls, outerScope)
 {
 }
Beispiel #50
0
 public ClassScope(SmalltalkClass cls, PoolVariableScope outerScope)
     : base(cls, outerScope)
 {
 }
Beispiel #51
0
 public bool ValidateClassInitializer(GlobalInitializer definition, SmalltalkClass cls, IDefinitionInstallerContext installer, ICodeValidationErrorSink errorSink)
 {
     return(((RuntimeGlobalInitializer)this.CreateInitializer(definition, installer)).Validate(installer.NameScope, this.GetErrorSink(errorSink)));
 }
Beispiel #52
0
 public InstanceFunctionScope(SmalltalkClass cls, ClassScope outerScope)
     : base(cls, outerScope)
 {
 }
        /// <summary>
        /// This method is the core of the dynamic method lookup system.
        /// It determines the class of an object and looks-up the method implementation
        /// for a given method selector.
        /// </summary>
        /// <param name="runtime">Required.</param>
        /// <param name="selector">Required.</param>
        /// <param name="superLookupScope">Optional.</param>
        /// <param name="receiver">Optional.</param>
        /// <param name="self">Required.</param>
        /// <param name="executionContext">Required.</param>
        /// <param name="arguments">Required.</param>
        /// <param name="receiverClass">Must Return!</param>
        /// <param name="methodClass">Return null if missing.</param>
        /// <param name="restrictions">Must Return!</param>
        /// <param name="executableCode">Return null if missing.</param>
        public static void GetMethodInformation(SmalltalkRuntime runtime,
                                                Symbol selector,
                                                Symbol superLookupScope,
                                                object receiver,
                                                Expression self,
                                                Expression executionContext,
                                                IEnumerable <Expression> arguments,
                                                out SmalltalkClass receiverClass,
                                                out SmalltalkClass methodClass,
                                                out BindingRestrictions restrictions,
                                                out Expression executableCode)
        {
            restrictions = null;
            SmalltalkClass cls = null;

            // Special case for Smalltalk classes, because we want the class behavior first ...
            if (receiver is SmalltalkClass)
            {
                cls = (SmalltalkClass)receiver;
                if (cls.Runtime == runtime)
                {
                    // The class of a SmalltalkClass object is a special class known by the runtime.
                    receiverClass = runtime.NativeTypeClassMap.Class;
                    if (receiverClass == null)
                    {
                        // And in case it's not set (not normal), we default to object
                        receiverClass = runtime.NativeTypeClassMap.Object;
                    }
                    // Lookup method in class behavior
                    CompiledMethod mth = MethodLookupHelper.LookupClassMethod(selector, ref cls, superLookupScope);
                    if (mth != null)
                    {
                        // A class method, special restrictions
                        methodClass    = cls;
                        restrictions   = BindingRestrictions.GetInstanceRestriction(self, receiver);
                        executableCode = mth.GetExpression(self, executionContext, arguments);
                        if (executableCode != null)
                        {
                            return;
                        }
                    }
                    // Not in class behavior ... fallback to instance / Object behavior
                    cls = receiverClass;
                    superLookupScope = null;
                    // IMPROVE: May need to add Runtime Restrictions too.
                    restrictions = BindingRestrictions.GetTypeRestriction(self, typeof(SmalltalkClass));
                }
            }

            if ((cls == null) || (restrictions == null)) // Will not run for receivers of type SmalltalkClass
            {
                cls = MethodLookupHelper.GetClassAndRestrictions(runtime, receiver, self, arguments, out restrictions);
            }
            receiverClass = cls;

            // Look-up the method
            CompiledMethod method = MethodLookupHelper.LookupInstanceMethod(selector, ref cls, superLookupScope);

            methodClass = cls;
            if (method == null)
            {
                executableCode = null;
            }
            else
            {
                executableCode = method.GetExpression(self, executionContext, arguments);
            }
        }