bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::PropertySlot &slot) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); // for compatibility with the old back-end, normal JS properties // are queried first. if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot)) return true; QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); if (flags & QScriptClass::HandlesReadAccess) { QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id); slot.setValue(engine->scriptValueToJSCValue(value)); return true; } return false; }
bool ClassObjectDelegate::getOwnPropertySlot(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::PropertySlot &slot) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); // for compatibility with the old back-end, normal JS properties // are queried first. if (QScriptObjectDelegate::getOwnPropertySlot(object, exec, propertyName, slot)) return true; QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); if (flags & QScriptClass::HandlesReadAccess) { QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id); if (!value.isValid()) { // The class claims to have the property, but returned an invalid // value. Silently convert to undefined to avoid the invalid value // "escaping" into JS. value = QScriptValue(QScriptValue::UndefinedValue); } slot.setValue(engine->scriptValueToJSCValue(value)); return true; } return false; }
bool ClassObjectDelegate::getPropertyAttributes(const QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, unsigned &attribs) const { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); if (flags & QScriptClass::HandlesReadAccess) { QScriptValue::PropertyFlags flags = m_scriptClass->propertyFlags(scriptObject, scriptName, id); attribs = 0; if (flags & QScriptValue::ReadOnly) attribs |= JSC::ReadOnly; if (flags & QScriptValue::SkipInEnumeration) attribs |= JSC::DontEnum; if (flags & QScriptValue::Undeletable) attribs |= JSC::DontDelete; if (flags & QScriptValue::PropertyGetter) attribs |= JSC::Getter; if (flags & QScriptValue::PropertySetter) attribs |= JSC::Setter; attribs |= flags & QScriptValue::UserRange; return true; } return QScriptObjectDelegate::getPropertyAttributes(object, exec, propertyName, attribs); }
void ClassObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); if (flags & QScriptClass::HandlesWriteAccess) { m_scriptClass->setProperty(scriptObject, scriptName, id, engine->scriptValueFromJSCValue(value)); return; } QScriptObjectDelegate::put(object, exec, propertyName, value, slot); }
/*! Returns the `this' object associated with this QScriptContext. */ QScriptValue QScriptContext::thisObject() const { JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); JSC::JSValue result = engine->thisForContext(frame); if (!result || result.isNull()) result = frame->globalThisValue(); return engine->scriptValueFromJSCValue(result); }
/*! Returns the callee. The callee is the function object that this QScriptContext represents an invocation of. */ QScriptValue QScriptContext::callee() const { const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *eng = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(eng); if (frame->callee() == eng->originalGlobalObject()) { // This is a pushContext()-created context; the callee is a lie. Q_ASSERT(QScriptEnginePrivate::contextFlags(const_cast<JSC::CallFrame*>(frame)) & QScriptEnginePrivate::NativeContext); return QScriptValue(); } return eng->scriptValueFromJSCValue(frame->callee()); }
QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, QScriptDeclarativeClass *scriptClass, Object *object) { Q_ASSERT(engine); Q_ASSERT(scriptClass); QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine)); JSC::ExecState* exec = p->currentFrame; QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object)); return p->scriptValueFromJSCValue(result); }
bool ClassObjectDelegate::getOwnPropertyDescriptor(QScriptObject *object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::PropertyDescriptor &descriptor) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); // for compatibility with the old back-end, normal JS properties // are queried first. if (QScriptObjectDelegate::getOwnPropertyDescriptor(object, exec, propertyName, descriptor)) return true; QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags qflags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesReadAccess, &id); if (qflags & QScriptClass::HandlesReadAccess) { QScriptValue::PropertyFlags pflags = m_scriptClass->propertyFlags(scriptObject, scriptName, id); unsigned attribs = 0; if (pflags & QScriptValue::ReadOnly) attribs |= JSC::ReadOnly; if (pflags & QScriptValue::SkipInEnumeration) attribs |= JSC::DontEnum; if (pflags & QScriptValue::Undeletable) attribs |= JSC::DontDelete; if (pflags & QScriptValue::PropertyGetter) attribs |= JSC::Getter; if (pflags & QScriptValue::PropertySetter) attribs |= JSC::Setter; attribs |= pflags & QScriptValue::UserRange; // Rather than calling the getter, we could return an access descriptor here. QScriptValue value = m_scriptClass->property(scriptObject, scriptName, id); if (!value.isValid()) { // The class claims to have the property, but returned an invalid // value. Silently convert to undefined to avoid the invalid value // "escaping" into JS. value = QScriptValue(QScriptValue::UndefinedValue); } descriptor.setDescriptor(engine->scriptValueToJSCValue(value), attribs); return true; } return false; }
/*! \internal \since 4.5 Removes the front object from this context's scope chain, and returns the removed object. If the scope chain is already empty, this function returns an invalid QScriptValue. */ QScriptValue QScriptContext::popScope() { activationObject(); //ensure the creation of the normal scope for native context JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); JSC::ScopeChainNode *scope = frame->scopeChain(); Q_ASSERT(scope != 0); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); QScriptValue result = engine->scriptValueFromJSCValue(scope->object); if (!scope->next) { // We cannot have a null scope chain, so just zap the object pointer. scope->object = 0; } else { frame->setScopeChain(scope->pop()); } return result; }
void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, bool includeNonEnumerable) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject); if (it != 0) { while (it->hasNext()) { it->next(); QString name = it->name().toString(); propertyNames.add(JSC::Identifier(exec, name)); } delete it; } QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, includeNonEnumerable); }
/* Returns the scope chain entry at \a index. If index is less than 0, returns entries starting at the end. For example, scopeChainValue(context, -1) will return the value last in the scope chain. */ QScriptValue QScriptDeclarativeClass::scopeChainValue(QScriptContext *context, int index) { context->activationObject(); //ensure the creation of the normal scope for native context const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(context); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); if (index < 0) { int count = 0; for (it = node->begin(); it != node->end(); ++it) ++count; index = qAbs(index); if (index > count) return QScriptValue(); else index = count - index; } for (it = node->begin(); it != node->end(); ++it) { if (index == 0) { JSC::JSObject *object = *it; if (!object) return QScriptValue(); if (object->inherits(&QScript::QScriptActivationObject::info) && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) { // Return the object that property access is being delegated to object = static_cast<QScript::QScriptActivationObject*>(object)->delegate(); } return engine->scriptValueFromJSCValue(object); } else { --index; } } return QScriptValue(); }
void DeclarativeObjectDelegate::put(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName, JSC::JSValue value, JSC::PutPropertySlot &slot) { QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScriptDeclarativeClass::Identifier identifier = (void *)propertyName.ustring().rep(); QScriptDeclarativeClassPrivate *p = QScriptDeclarativeClassPrivate::get(m_class); p->context = reinterpret_cast<QScriptContext *>(exec); QScriptClass::QueryFlags flags = m_class->queryProperty(m_object, identifier, QScriptClass::HandlesWriteAccess); if (flags & QScriptClass::HandlesWriteAccess) { m_class->setProperty(m_object, identifier, engine->scriptValueFromJSCValue(value)); p->context = 0; return; } p->context = 0; QScriptObjectDelegate::put(object, exec, propertyName, value, slot); }
void ClassObjectDelegate::getOwnPropertyNames(QScriptObject* object, JSC::ExecState *exec, JSC::PropertyNameArray &propertyNames, JSC::EnumerationMode mode) { // For compatibility with the old back-end, normal JS properties // are added first. QScriptObjectDelegate::getOwnPropertyNames(object, exec, propertyNames, mode); QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptClassPropertyIterator *it = m_scriptClass->newIterator(scriptObject); if (it != 0) { while (it->hasNext()) { it->next(); QString name = it->name().toString(); propertyNames.add(JSC::Identifier(exec, name)); } delete it; } }
bool ClassObjectDelegate::deleteProperty(QScriptObject* object, JSC::ExecState *exec, const JSC::Identifier &propertyName) { // ### avoid duplication of put() QScriptEnginePrivate *engine = scriptEngineFromExec(exec); QScript::SaveFrameHelper saveFrame(engine, exec); QScriptValue scriptObject = engine->scriptValueFromJSCValue(object); QScriptString scriptName; QScriptStringPrivate scriptName_d(engine, propertyName, QScriptStringPrivate::StackAllocated); QScriptStringPrivate::init(scriptName, &scriptName_d); uint id = 0; QScriptClass::QueryFlags flags = m_scriptClass->queryProperty( scriptObject, scriptName, QScriptClass::HandlesWriteAccess, &id); if (flags & QScriptClass::HandlesWriteAccess) { if (m_scriptClass->propertyFlags(scriptObject, scriptName, id) & QScriptValue::Undeletable) return false; m_scriptClass->setProperty(scriptObject, scriptName, id, QScriptValue()); return true; } return QScriptObjectDelegate::deleteProperty(object, exec, propertyName); }
/*! \internal \since 4.5 Returns the scope chain of this QScriptContext. */ QScriptValueList QScriptContext::scopeChain() const { activationObject(); //ensure the creation of the normal scope for native context const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); QScriptValueList result; JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); for (it = node->begin(); it != node->end(); ++it) { JSC::JSObject *object = *it; if (!object) continue; if (object->inherits(&QScript::QScriptActivationObject::info) && (static_cast<QScript::QScriptActivationObject*>(object)->delegate() != 0)) { // Return the object that property access is being delegated to object = static_cast<QScript::QScriptActivationObject*>(object)->delegate(); } result.append(engine->scriptValueFromJSCValue(object)); } return result; }