bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { DebuggerScope* scope = jsCast<DebuggerScope*>(object); ASSERT(scope->isValid()); if (!scope->isValid()) return false; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); slot.setThisValue(JSValue(thisObject)); // By default, JSObject::getPropertySlot() will look in the DebuggerScope's prototype // chain and not the wrapped scope, and JSObject::getPropertySlot() cannot be overridden // to behave differently for the DebuggerScope. // // Instead, we'll treat all properties in the wrapped scope and its prototype chain as // the own properties of the DebuggerScope. This is fine because the WebInspector // does not presently need to distinguish between what's owned at each level in the // prototype chain. Hence, we'll invoke getPropertySlot() on the wrapped scope here // instead of getOwnPropertySlot(). bool result = thisObject->getPropertySlot(exec, propertyName, slot); if (result && slot.isValue() && slot.getValue(exec, propertyName) == jsTDZValue()) { // FIXME: // We hit a scope property that has the TDZ empty value. // Currently, we just lie to the inspector and claim that this property is undefined. // This is not ideal and we should fix it. // https://bugs.webkit.org/show_bug.cgi?id=144977 slot.setValue(slot.slotBase(), DontEnum, jsUndefined()); return true; } return result; }
bool DebuggerScope::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool shouldThrow) { DebuggerScope* scope = jsCast<DebuggerScope*>(object); ASSERT(scope->isValid()); if (!scope->isValid()) return false; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); return thisObject->methodTable()->defineOwnProperty(thisObject, exec, propertyName, descriptor, shouldThrow); }
void DebuggerScope::getOwnPropertyNames(JSObject* object, ExecState* exec, PropertyNameArray& propertyNames, EnumerationMode mode) { DebuggerScope* scope = jsCast<DebuggerScope*>(object); ASSERT(scope->isValid()); if (!scope->isValid()) return; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); thisObject->methodTable()->getPropertyNames(thisObject, exec, propertyNames, mode); }
bool DebuggerScope::deleteProperty(JSCell* cell, ExecState* exec, PropertyName propertyName) { DebuggerScope* scope = jsCast<DebuggerScope*>(cell); ASSERT(scope->isValid()); if (!scope->isValid()) return false; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); return thisObject->methodTable()->deleteProperty(thisObject, exec, propertyName); }
void DebuggerScope::put(JSCell* cell, ExecState* exec, PropertyName propertyName, JSValue value, PutPropertySlot& slot) { DebuggerScope* scope = jsCast<DebuggerScope*>(cell); ASSERT(scope->isValid()); if (!scope->isValid()) return; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); slot.setThisValue(JSValue(thisObject)); thisObject->methodTable()->put(thisObject, exec, propertyName, value, slot); }
bool DebuggerScope::getOwnPropertySlot(JSObject* object, ExecState* exec, PropertyName propertyName, PropertySlot& slot) { DebuggerScope* scope = jsCast<DebuggerScope*>(object); ASSERT(scope->isValid()); if (!scope->isValid()) return false; JSObject* thisObject = JSScope::objectAtScope(scope->jsScope()); slot.setThisValue(JSValue(thisObject)); // By default, JSObject::getPropertySlot() will look in the DebuggerScope's prototype // chain and not the wrapped scope, and JSObject::getPropertySlot() cannot be overridden // to behave differently for the DebuggerScope. // // Instead, we'll treat all properties in the wrapped scope and its prototype chain as // the own properties of the DebuggerScope. This is fine because the WebInspector // does not presently need to distinguish between what's owned at each level in the // prototype chain. Hence, we'll invoke getPropertySlot() on the wrapped scope here // instead of getOwnPropertySlot(). return thisObject->getPropertySlot(exec, propertyName, slot); }
void DebuggerScope::invalidateChain() { DebuggerScope* scope = this; while (scope) { ASSERT(scope->isValid()); DebuggerScope* nextScope = scope->m_next.get(); scope->m_next.clear(); scope->m_scope.clear(); scope = nextScope; } }