void DefaultGCActivityCallbackPlatformData::trigger(CFRunLoopTimerRef timer, void *info) { Heap* heap = static_cast<Heap*>(info); APIEntryShim shim(heap->globalData()); heap->collectAllGarbage(); CFRunLoopTimerSetNextFireDate(timer, CFAbsoluteTimeGetCurrent() + decade); }
/*! Returns true if the function was called as a constructor (e.g. \c{"new foo()"}); otherwise returns false. When a function is called as constructor, the thisObject() contains the newly constructed object to be initialized. \note This function is only guaranteed to work for a context corresponding to native functions. */ bool QScriptContext::isCalledAsConstructor() const { JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); //For native functions, look up flags. uint flags = QScriptEnginePrivate::contextFlags(frame); if (flags & QScriptEnginePrivate::NativeContext) return flags & QScriptEnginePrivate::CalledAsConstructorContext; //Not a native function, try to look up in the bytecode if we where called from op_construct JSC::Instruction* returnPC = frame->returnPC(); if (!returnPC) return false; JSC::CallFrame *callerFrame = QScriptEnginePrivate::frameForContext(parentContext()); if (!callerFrame) return false; if (returnPC[-JSC::op_construct_length].u.opcode == frame->interpreter()->getOpcode(JSC::op_construct)) { //We are maybe called from the op_construct opcode which has 6 opperands. //But we need to check we are not called from op_call with 4 opperands //we make sure that the returnPC[-1] (thisRegister) is smaller than the returnPC[-3] (registerOffset) //as if it was an op_call, the returnPC[-1] would be the registerOffset, bigger than returnPC[-3] (funcRegister) return returnPC[-1].u.operand < returnPC[-3].u.operand; } return false; }
/*! \overload Throws an error with the given \a text. Returns the created error object. \sa throwValue(), state() */ QScriptValue QScriptContext::throwError(const QString &text) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSObject *result = JSC::throwError(frame, JSC::GeneralError, text); return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); }
/*! \internal \since 4.5 Adds the given \a object to the front of this context's scope chain. If \a object is not an object, this function does nothing. */ void QScriptContext::pushScope(const QScriptValue &object) { activationObject(); //ensure the creation of the normal scope for native context if (!object.isObject()) return; else if (object.engine() != engine()) { qWarning("QScriptContext::pushScope() failed: " "cannot push an object created in " "a different engine"); return; } JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); JSC::JSObject *jscObject = JSC::asObject(engine->scriptValueToJSCValue(object)); if (jscObject == engine->originalGlobalObjectProxy) jscObject = engine->originalGlobalObject(); JSC::ScopeChainNode *scope = frame->scopeChain(); Q_ASSERT(scope != 0); if (!scope->object) { // pushing to an "empty" chain if (!jscObject->isGlobalObject()) { qWarning("QScriptContext::pushScope() failed: initial object in scope chain has to be the Global Object"); return; } scope->object = jscObject; } else frame->setScopeChain(scope->push(jscObject)); }
/*! Sets the `this' object associated with this QScriptContext to be \a thisObject. If \a thisObject is not an object, this function does nothing. */ void QScriptContext::setThisObject(const QScriptValue &thisObject) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); if (!thisObject.isObject()) return; if (thisObject.engine() != engine()) { qWarning("QScriptContext::setThisObject() failed: " "cannot set an object created in " "a different engine"); return; } if (frame == frame->lexicalGlobalObject()->globalExec()) { engine()->setGlobalObject(thisObject); return; } JSC::JSValue jscThisObject = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(thisObject); JSC::CodeBlock *cb = frame->codeBlock(); if (cb != 0) { frame[cb->thisRegister()] = jscThisObject; } else { JSC::Register* thisRegister = QScriptEnginePrivate::thisRegisterForFrame(frame); thisRegister[0] = jscThisObject; } }
/*! Throws an \a error with the given \a text. Returns the created error object. The \a text will be stored in the \c{message} property of the error object. The error object will be initialized to contain information about the location where the error occurred; specifically, it will have properties \c{lineNumber}, \c{fileName} and \c{stack}. These properties are described in \l {QtScript Extensions to ECMAScript}. \sa throwValue(), state() */ QScriptValue QScriptContext::throwError(Error error, const QString &text) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::ErrorType jscError = JSC::GeneralError; switch (error) { case UnknownError: break; case ReferenceError: jscError = JSC::ReferenceError; break; case SyntaxError: jscError = JSC::SyntaxError; break; case TypeError: jscError = JSC::TypeError; break; case RangeError: jscError = JSC::RangeError; break; case URIError: jscError = JSC::URIError; break; } JSC::JSObject *result = JSC::throwError(frame, jscError, text); return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); }
/*! Returns the parent context of this QScriptContext. */ QScriptContext *QScriptContext::parentContext() const { const JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::CallFrame *callerFrame = frame->callerFrame()->removeHostCallFrameFlag(); return QScriptEnginePrivate::contextForFrame(callerFrame); }
void Dawg::iterate_words(const UNICHARSET &unicharset, TessCallback1<const char *> *cb) const { std::unique_ptr<TessCallback1<const WERD_CHOICE *>> shim( NewPermanentTessCallback(CallWithUTF8, cb)); WERD_CHOICE word(&unicharset); iterate_words_rec(word, 0, shim.get()); }
QScriptProgramPrivate::~QScriptProgramPrivate() { if (engine) { QScript::APIShim shim(engine); _executable.clear(); } }
void HeapTimer::timerDidFire(CFRunLoopTimerRef timer, void* context) { JSLock* apiLock = static_cast<JSLock*>(context); apiLock->lock(); VM* vm = apiLock->vm(); // The VM has been destroyed, so we should just give up. if (!vm) { apiLock->unlock(); return; } HeapTimer* heapTimer = 0; if (vm->heap.activityCallback()->m_timer.get() == timer) heapTimer = vm->heap.activityCallback(); else if (vm->heap.sweeper()->m_timer.get() == timer) heapTimer = vm->heap.sweeper(); else RELEASE_ASSERT_NOT_REACHED(); { APIEntryShim shim(vm); heapTimer->doWork(); } apiLock->unlock(); }
/*! Throws an exception with the given \a value. Returns the value thrown (the same as the argument). \sa throwError(), state() */ QScriptValue QScriptContext::throwValue(const QScriptValue &value) { JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSValue jscValue = QScript::scriptEngineFromExec(frame)->scriptValueToJSCValue(value); frame->setException(jscValue); return value; }
QScriptProgramPrivate::~QScriptProgramPrivate() { if (engine) { QScript::APIShim shim(engine); _executable.clear(); engine->unregisterScriptProgram(this); } }
/*! Returns the flags of the last property that was jumped over using next() or previous(). \sa value() */ QScriptValue::PropertyFlags QScriptValueIterator::flags() const { Q_D(const QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return 0; QScript::APIShim shim(d->engine()); return d->object()->propertyFlags(*d->current); }
/*! Returns the value of the last property that was jumped over using next() or previous(). \sa setValue(), name() */ QScriptValue QScriptValueIterator::value() const { Q_D(const QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return QScriptValue(); QScript::APIShim shim(d->engine()); JSC::JSValue jsValue = d->object()->property(*d->current); return d->engine()->scriptValueFromJSCValue(jsValue); }
QScriptDeclarativeClass::PersistentIdentifier::~PersistentIdentifier() { if (engine) { QScript::APIShim shim(engine); ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); } else { ((JSC::Identifier &)d).JSC::Identifier::~Identifier(); } }
/*! Removes the last property that was jumped over using next() or previous(). \sa setValue() */ void QScriptValueIterator::remove() { Q_D(QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return; QScript::APIShim shim(d->engine()); d->object()->setProperty(*d->current, JSC::JSValue()); d->propertyNames.erase(d->current); }
/*! Sets the \a value of the last property that was jumped over using next() or previous(). \sa value(), name() */ void QScriptValueIterator::setValue(const QScriptValue &value) { Q_D(QScriptValueIterator); if (!d || !d->initialized || !d->engine()) return; QScript::APIShim shim(d->engine()); JSC::JSValue jsValue = d->engine()->scriptValueToJSCValue(value); d->object()->setProperty(*d->current, jsValue); }
~QScriptValueIteratorPrivate() { if (!initialized) return; QScriptEnginePrivate *eng_p = engine(); if (!eng_p) return; QScript::APIShim shim(eng_p); propertyNames.clear(); //destroying the identifiers need to be done under the APIShim guard }
bool HeapTimer::timerEvent(void* info) { HeapTimer* agent = static_cast<HeapTimer*>(info); APIEntryShim shim(agent->m_vm); agent->doWork(); agent->m_timer = 0; return ECORE_CALLBACK_CANCEL; }
/*! 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); }
void HeapTimer::timerEvent(QTimerEvent*) { QMutexLocker lock(&m_mutex); if (m_newThread) { // We need to wait with processing until we are on the right thread. return; } APIEntryShim shim(m_vm); doWork(); }
/*! 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()); }
QScriptDeclarativeClass::PersistentIdentifier QScriptDeclarativeClass::createPersistentIdentifier(const Identifier &id) { QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(d_ptr->engine)); QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; PersistentIdentifier rv(p); new (&rv.d) JSC::Identifier(exec, (JSC::UString::Rep *)id); rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep(); return rv; }
QScriptDeclarativeClass::Value QScriptDeclarativeClass::newObjectValue(QScriptEngine *engine,QScriptDeclarativeClass *scriptClass, Object *object) { Q_ASSERT(engine); Q_ASSERT(scriptClass); QScriptEnginePrivate *p = QScriptEnginePrivate::cs_getPrivate(engine); QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object)); return jscToValue(JSC::JSValue(result)); }
QScriptValue QScriptContext::activationObject() const { JSC::CallFrame *frame = const_cast<JSC::ExecState*>(QScriptEnginePrivate::frameForContext(this)); QScript::APIShim shim(QScript::scriptEngineFromExec(frame)); JSC::JSObject *result = 0; uint flags = QScriptEnginePrivate::contextFlags(frame); if ((flags & QScriptEnginePrivate::NativeContext) && !(flags & QScriptEnginePrivate::HasScopeContext)) { //For native functions, lazily create it if needed QScript::QScriptActivationObject *scope = new (frame) QScript::QScriptActivationObject(frame); frame->setScopeChain(frame->scopeChain()->copy()->push(scope)); result = scope; QScriptEnginePrivate::setContextFlags(frame, flags | QScriptEnginePrivate::HasScopeContext); } else { // look in scope chain JSC::ScopeChainNode *node = frame->scopeChain(); JSC::ScopeChainIterator it(node); for (it = node->begin(); it != node->end(); ++it) { if ((*it) && (*it)->isVariableObject()) { result = *it; break; } } } if (!result) { if (!parentContext()) return engine()->globalObject(); qWarning("QScriptContext::activationObject: could not get activation object for frame"); return QScriptValue(); /*JSC::CodeBlock *codeBlock = frame->codeBlock(); if (!codeBlock) { // non-Qt native function Q_ASSERT(true); //### this should in theorry not happen result = new (frame)QScript::QScriptActivationObject(frame); } else { // ### this is wrong JSC::FunctionBodyNode *body = static_cast<JSC::FunctionBodyNode*>(codeBlock->ownerNode()); result = new (frame)JSC::JSActivation(frame, body); }*/ } if (result && result->inherits(&QScript::QScriptActivationObject::info) && (static_cast<QScript::QScriptActivationObject*>(result)->delegate() != 0)) { // Return the object that property access is being delegated to result = static_cast<QScript::QScriptActivationObject*>(result)->delegate(); } return QScript::scriptEngineFromExec(frame)->scriptValueFromJSCValue(result); }
/*! Sets the activation object of this QScriptContext to be the given \a activation. If \a activation is not an object, this function does nothing. \note For a context corresponding to a JavaScript function, this is only guaranteed to work if there was an QScriptEngineAgent active on the engine while the function was evaluated. */ void QScriptContext::setActivationObject(const QScriptValue &activation) { if (!activation.isObject()) return; else if (activation.engine() != engine()) { qWarning("QScriptContext::setActivationObject() failed: " "cannot set an object created in " "a different engine"); return; } JSC::CallFrame *frame = QScriptEnginePrivate::frameForContext(this); QScriptEnginePrivate *engine = QScript::scriptEngineFromExec(frame); QScript::APIShim shim(engine); JSC::JSObject *object = JSC::asObject(engine->scriptValueToJSCValue(activation)); if (object == engine->originalGlobalObjectProxy) object = engine->originalGlobalObject(); uint flags = QScriptEnginePrivate::contextFlags(frame); if ((flags & QScriptEnginePrivate::NativeContext) && !(flags & QScriptEnginePrivate::HasScopeContext)) { //For native functions, we create a scope node JSC::JSObject *scope = object; if (!scope->isVariableObject()) { // Create a QScriptActivationObject that acts as a proxy scope = new (frame) QScript::QScriptActivationObject(frame, scope); } frame->setScopeChain(frame->scopeChain()->copy()->push(scope)); QScriptEnginePrivate::setContextFlags(frame, flags | QScriptEnginePrivate::HasScopeContext); return; } // else replace the first activation object in the scope chain JSC::ScopeChainNode *node = frame->scopeChain(); while (node != 0) { if (node->object && node->object->isVariableObject()) { if (!object->isVariableObject()) { if (node->object->inherits(&QScript::QScriptActivationObject::info)) { static_cast<QScript::QScriptActivationObject*>(node->object)->setDelegate(object); } else { // Create a QScriptActivationObject that acts as a proxy node->object = new (frame) QScript::QScriptActivationObject(frame, object); } } else { node->object = object; } break; } node = node->next; } }
QScriptValue QScriptDeclarativeClass::newObject(QScriptEngine *engine, QScriptDeclarativeClass *scriptClass, Object *object) { Q_ASSERT(engine); Q_ASSERT(scriptClass); QScriptEnginePrivate *p = static_cast<QScriptEnginePrivate *>(QObjectPrivate::get(engine)); QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; QScriptObject *result = new (exec) QScriptObject(p->scriptObjectStructure); result->setDelegate(new QScript::DeclarativeObjectDelegate(scriptClass, object)); return p->scriptValueFromJSCValue(result); }
QScriptDeclarativeClass::PersistentIdentifier QScriptDeclarativeClass::createPersistentIdentifier(const QString &str) { QScriptEnginePrivate *p = QScriptEnginePrivate::cs_getPrivate(d_ptr->engine); QScript::APIShim shim(p); JSC::ExecState* exec = p->currentFrame; PersistentIdentifier rv(p); new (&rv.d) JSC::Identifier(exec, (UChar *)str.constData(), str.size()); rv.identifier = (void *)((JSC::Identifier &)rv.d).ustring().rep(); return rv; }
void HeapTimer::timerDidFire(CFRunLoopTimerRef, void* info) { HeapTimer* agent = static_cast<HeapTimer*>(info); agent->m_shutdownMutex.lock(); if (!agent->m_globalData) { agent->m_shutdownMutex.unlock(); delete agent; return; } { // We don't ref here to prevent us from resurrecting the ref count of a "dead" JSGlobalData. APIEntryShim shim(agent->m_globalData, APIEntryShimWithoutLock::DontRefGlobalData); agent->doWork(); } agent->m_shutdownMutex.unlock(); }
/*! \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; }