/// <summary> /// Create a new SuperSendCallSiteBinder. /// </summary> /// <param name="runtime">SmalltalkRuntine that this binder belongs to.</param> /// <param name="selector">Selector of the message being sent.</param> /// <param name="superScope">The name of the class ABOVE which to start the method lookup.</param> public SuperSendCallSiteBinder(SmalltalkRuntime runtime, Symbol selector, Symbol superScope) : base(runtime, selector) { if (superScope == null) throw new ArgumentNullException("superScope"); this.SuperScope = superScope; }
public SmalltalkClass GetClass(Symbol name) { ClassBinding binding = this.Runtime.GlobalScope.GetClassBinding(name); if (binding == null) return null; return binding.Value; }
/// <summary> /// Create a new MessageSendCallSiteBinder. /// </summary> /// <param name="runtime">SmalltalkRuntine that this binder belongs to.</param> /// <param name="selector">Selector of the message being sent.</param> /// <param name="nativeName">Name of the method that the target is asked to bind.</param> /// <param name="argumentCount">Number of method arguments.</param> public MessageSendCallSiteBinder(SmalltalkRuntime runtime, Symbol selector, string nativeName, int argumentCount) : base(runtime, selector) { if (argumentCount < 0) throw new ArgumentOutOfRangeException("argumentCount"); this.NativeName = nativeName; this.ArgumentCount = argumentCount; }
public object GetGlobal(Symbol name) { if (name == null) throw new ArgumentNullException(); object value; if (!this.TryGetGlobal(name, out value)) throw new KeyNotFoundException(name.Value); return value; }
/// <summary> /// Create a new ConstantSendCallSiteBinder. /// </summary> /// <param name="runtime">SmalltalkRuntine that this binder belongs to.</param> /// <param name="selector">Selector of the message being sent.</param> /// <param name="nativeName">Name of the method that the target is asked to bind.</param> /// <param name="argumentCount">Number of method arguments.</param> public ConstantSendCallSiteBinder(SmalltalkRuntime runtime, Symbol selector, string nativeName, int argumentCount) : base(runtime, selector, nativeName, argumentCount) { }
/// <summary> /// Set the value of the given global variable. /// </summary> /// <param name="name">Name of the global variable.</param> /// <param name="value">New value of the global variable.</param> /// <returns>True if the variable exists, otherwise false.</returns> public bool SetGlobal(Symbol name, object value) { GlobalVariableBinding binding = this.GlobalScope.GetGlobalVariableBinding(name); if (binding == null) return false; binding.Value = value; return true; }
/// <summary> /// Get the Smalltalk shared pool with the given name. /// </summary> /// <param name="name">Shared pool name.</param> /// <returns>The Smalltalk shared pool with the given name or null if none found.</returns> public Pool GetPool(Symbol name) { PoolBinding binding = this.GlobalScope.GetPoolBinding(name); if (binding != null) return binding.Value; else return null; }
/// <summary> /// Get global variable or global constant with the given name. /// </summary> /// <param name="name">Global variable or global constant name.</param> /// <param name="exists">True if the global variable or global constant exists, otherwise false.</param> /// <returns>Value of the global variable or global constant. If not found, null is returned.</returns> public object GetGlobal(Symbol name, out bool exists) { GlobalVariableOrConstantBinding binding = this.GlobalScope.GetGlobalVariableOrConstantBinding(name); if (binding == null) { exists = false; return null; } else { exists = true; return binding.Value; } }
/// <summary> /// Get global variable or global constant with the given name. /// </summary> /// <param name="name">Global variable or global constant name.</param> /// <returns>Value of the global variable or global constant. If not found, null is returned.</returns> public object GetGlobal(Symbol name) { bool na; return this.GetGlobal(name, out na); }
public bool TryGetGlobal(Symbol name, out object value) { GlobalVariableOrConstantBinding binding = this.Runtime.GlobalScope.GetGlobalVariableOrConstantBinding(name); if ((binding == null) || !binding.HasBeenSet) { value = null; return false; } value = binding.Value; return true; }
public bool TrySetGlobal(Symbol name, object value) { GlobalVariableBinding binding = this.Runtime.GlobalScope.GetGlobalVariableBinding(name); if ((binding == null) || binding.IsConstantBinding) return false; binding.Value = value; return true; }
public void SetGlobal(Symbol name, object value) { if (name == null) throw new ArgumentNullException(); if (!this.TrySetGlobal(name, value)) throw new KeyNotFoundException(name.Value); }
public Pool GetPool(Symbol name) { PoolBinding binding = this.Runtime.GlobalScope.GetPoolBinding(name); if (binding == null) return null; return binding.Value; }
/// <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; }
/// <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; }); }
/// <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); } } }