/// <summary>Delegates to</summary> /// <returns>true iff rhs appears in lhs' proto chain</returns> public static bool JsDelegatesTo(Scriptable lhs, Scriptable rhs) { Scriptable proto = lhs.GetPrototype(); while (proto != null) { if (proto.Equals(rhs)) { return true; } proto = proto.GetPrototype(); } return false; }
public static object NameIncrDecr(Scriptable scopeChain, string id, Context cx, int incrDecrMask) { Scriptable target; object value; do { if (cx.useDynamicScope && scopeChain.GetParentScope() == null) { scopeChain = CheckDynamicScope(cx.topCallScope, scopeChain); } target = scopeChain; do { if (target is NativeWith && target.GetPrototype() is XMLObject) { break; } value = target.Get(id, scopeChain); if (value != ScriptableConstants.NOT_FOUND) { goto search_break; } target = target.GetPrototype(); } while (target != null); scopeChain = scopeChain.GetParentScope(); } while (scopeChain != null); throw NotFoundError(scopeChain, id); search_break: ; return DoScriptableIncrDecr(target, id, scopeChain, value, incrDecrMask); }
private static object NameOrFunction(Context cx, Scriptable scope, Scriptable parentScope, string name, bool asFunctionCall) { object result; Scriptable thisObj = scope; // It is used only if asFunctionCall==true. XMLObject firstXMLObject = null; for (; ; ) { if (scope is NativeWith) { Scriptable withObj = scope.GetPrototype(); if (withObj is XMLObject) { XMLObject xmlObj = (XMLObject)withObj; if (xmlObj.Has(name, xmlObj)) { // function this should be the target object of with thisObj = xmlObj; result = xmlObj.Get(name, xmlObj); break; } if (firstXMLObject == null) { firstXMLObject = xmlObj; } } else { result = ScriptableObject.GetProperty(withObj, name); if (result != ScriptableConstants.NOT_FOUND) { // function this should be the target object of with thisObj = withObj; break; } } } else { if (scope is NativeCall) { // NativeCall does not prototype chain and Scriptable.get // can be called directly. result = scope.Get(name, scope); if (result != ScriptableConstants.NOT_FOUND) { if (asFunctionCall) { // ECMA 262 requires that this for nested funtions // should be top scope thisObj = ScriptableObject.GetTopLevelScope(parentScope); } break; } } else { // Can happen if Rhino embedding decided that nested // scopes are useful for what ever reasons. result = ScriptableObject.GetProperty(scope, name); if (result != ScriptableConstants.NOT_FOUND) { thisObj = scope; break; } } } scope = parentScope; parentScope = parentScope.GetParentScope(); if (parentScope == null) { result = TopScopeName(cx, scope, name); if (result == ScriptableConstants.NOT_FOUND) { if (firstXMLObject == null || asFunctionCall) { throw NotFoundError(scope, name); } // The name was not found, but we did find an XML // object in the scope chain and we are looking for name, // not function. The result should be an empty XMLList // in name context. result = firstXMLObject.Get(name, firstXMLObject); } // For top scope thisObj for functions is always scope itself. thisObj = scope; break; } } if (asFunctionCall) { if (!(result is Callable)) { throw NotFunctionError(result, name); } StoreScriptable(cx, thisObj); } return result; }
/// <summary>Returns the object in the scope chain that has a given property.</summary> /// <remarks> /// Returns the object in the scope chain that has a given property. /// The order of evaluation of an assignment expression involves /// evaluating the lhs to a reference, evaluating the rhs, and then /// modifying the reference with the rhs value. This method is used /// to 'bind' the given name to an object containing that property /// so that the side effects of evaluating the rhs do not affect /// which property is modified. /// Typically used in conjunction with setName. /// See ECMA 10.1.4 /// </remarks> public static Scriptable Bind(Context cx, Scriptable scope, string id) { Scriptable firstXMLObject = null; Scriptable parent = scope.GetParentScope(); if (parent != null) { // Check for possibly nested "with" scopes first while (scope is NativeWith) { Scriptable withObj = scope.GetPrototype(); if (withObj is XMLObject) { XMLObject xmlObject = (XMLObject)withObj; if (xmlObject.Has(cx, id)) { return xmlObject; } if (firstXMLObject == null) { firstXMLObject = xmlObject; } } else { if (ScriptableObject.HasProperty(withObj, id)) { return withObj; } } scope = parent; parent = parent.GetParentScope(); if (parent == null) { goto childScopesChecks_break; } } for (; ; ) { if (ScriptableObject.HasProperty(scope, id)) { return scope; } scope = parent; parent = parent.GetParentScope(); if (parent == null) { goto childScopesChecks_break; } } } childScopesChecks_break: ; // scope here is top scope if (cx.useDynamicScope) { scope = CheckDynamicScope(cx.topCallScope, scope); } if (ScriptableObject.HasProperty(scope, id)) { return scope; } // Nothing was found, but since XML objects always bind // return one if found return firstXMLObject; }
private Ref XmlPrimaryReference(Context cx, XMLName xmlName, Scriptable scope) { XMLObjectImpl xmlObj; XMLObjectImpl firstXml = null; for (; ; ) { // XML object can only present on scope chain as a wrapper // of XMLWithScope if (scope is XMLWithScope) { xmlObj = (XMLObjectImpl)scope.GetPrototype(); if (xmlObj.HasXMLProperty(xmlName)) { break; } if (firstXml == null) { firstXml = xmlObj; } } scope = scope.GetParentScope(); if (scope == null) { xmlObj = firstXml; break; } } // xmlObj == null corresponds to undefined as the target of // the reference if (xmlObj != null) { xmlName.InitXMLObject(xmlObj); } return xmlName; }