void WorkerScriptController::evaluate(const ScriptSourceCode& sourceCode) { if (isExecutionForbidden()) return; Deprecated::ScriptValue exception; evaluate(sourceCode, &exception); if (exception.jsValue()) { JSLockHolder lock(vm()); reportException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue()); } }
static JSC::JSValue handleInitMessageEvent(JSMessageEvent* jsEvent, JSC::ExecState* exec) { const String& typeArg = exec->argument(0).toString(exec)->value(exec); bool canBubbleArg = exec->argument(1).toBoolean(exec); bool cancelableArg = exec->argument(2).toBoolean(exec); const String originArg = exec->argument(4).toString(exec)->value(exec); const String lastEventIdArg = exec->argument(5).toString(exec)->value(exec); DOMWindow* sourceArg = toDOMWindow(exec->argument(6)); std::unique_ptr<MessagePortArray> messagePorts; OwnPtr<ArrayBufferArray> arrayBuffers; if (!exec->argument(7).isUndefinedOrNull()) { messagePorts = std::make_unique<MessagePortArray>(); arrayBuffers = adoptPtr(new ArrayBufferArray); fillMessagePortArray(exec, exec->argument(7), *messagePorts, *arrayBuffers); if (exec->hadException()) return jsUndefined(); } Deprecated::ScriptValue dataArg = Deprecated::ScriptValue(exec->vm(), exec->argument(3)); if (exec->hadException()) return jsUndefined(); MessageEvent& event = jsEvent->impl(); event.initMessageEvent(typeArg, canBubbleArg, cancelableArg, dataArg, originArg, lastEventIdArg, sourceArg, WTF::move(messagePorts)); jsEvent->m_data.set(exec->vm(), jsEvent, dataArg.jsValue()); return jsUndefined(); }
bool injectIDBKeyIntoScriptValue(DOMRequestState* requestState, PassRefPtr<IDBKey> key, Deprecated::ScriptValue& value, const IDBKeyPath& keyPath) { LOG(StorageAPI, "injectIDBKeyIntoScriptValue"); ASSERT(keyPath.type() == IndexedDB::KeyPathType::String); Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath.string(), keyPathElements, error); ASSERT(error == IDBKeyPathParseError::None); if (keyPathElements.isEmpty()) return false; ExecState* exec = requestState->exec(); JSValue parent = ensureNthValueOnKeyPath(exec, value.jsValue(), keyPathElements, keyPathElements.size() - 1); if (parent.isUndefined()) return false; if (!set(exec, parent, keyPathElements.last(), idbKeyToJSValue(exec, exec->lexicalGlobalObject(), key.get()))) return false; return true; }
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCode& ec) { LOG(IndexedDB, "IDBCursor::update"); if (sourcesDeleted()) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (!transaction().isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return nullptr; } if (transaction().isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return nullptr; } if (!m_gotValue) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (isKeyCursor()) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } return effectiveObjectStore().put(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec); }
RefPtr<WebCore::IDBRequest> IDBCursor::update(JSC::ExecState& exec, Deprecated::ScriptValue& value, ExceptionCodeWithMessage& ec) { LOG(IndexedDB, "IDBCursor::update"); if (sourcesDeleted()) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (!transaction().isActive()) { ec.code = IDBDatabaseException::TransactionInactiveError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The transaction is inactive or finished."); return nullptr; } if (transaction().isReadOnly()) { ec.code = IDBDatabaseException::ReadOnlyError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The record may not be updated inside a read-only transaction."); return nullptr; } if (!m_gotValue) { ec.code = IDBDatabaseException::InvalidStateError; return nullptr; } if (isKeyCursor()) { ec.code = IDBDatabaseException::InvalidStateError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The cursor is a key cursor."); return nullptr; } auto& objectStore = effectiveObjectStore(); auto& keyPath = objectStore.info().keyPath(); const bool usesInLineKeys = !keyPath.isNull(); if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = maybeCreateIDBKeyFromScriptValueAndKeyPath(exec, value, keyPath); IDBKeyData keyPathKeyData(keyPathKey.get()); if (!keyPathKey || keyPathKeyData != m_currentPrimaryKeyData) { ec.code = IDBDatabaseException::DataError; ec.message = ASCIILiteral("Failed to execute 'update' on 'IDBCursor': The effective object store of this cursor uses in-line keys and evaluating the key path of the value parameter results in a different value than the cursor's effective key."); return nullptr; } } auto request = effectiveObjectStore().putForCursorUpdate(exec, value.jsValue(), m_deprecatedCurrentPrimaryKey.jsValue(), ec); if (ec.code) return nullptr; ASSERT(request); request->setSource(*this); return request; }
JSValue JSCommandLineAPIHost::inspectedObject(ExecState* exec) { CommandLineAPIHost::InspectableObject* object = impl().inspectedObject(); if (!object) return jsUndefined(); JSLockHolder lock(exec); Deprecated::ScriptValue scriptValue = object->get(exec); if (scriptValue.hasNoValue()) return jsUndefined(); return scriptValue.jsValue(); }
static RefPtr<IDBKey> internalCreateIDBKeyFromScriptValueAndKeyPath(ExecState* exec, const Deprecated::ScriptValue& value, const String& keyPath) { Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath, keyPathElements, error); ASSERT(error == IDBKeyPathParseErrorNone); JSValue jsValue = value.jsValue(); jsValue = getNthValueOnKeyPath(exec, jsValue, keyPathElements, keyPathElements.size()); if (jsValue.isUndefined()) return nullptr; return createIDBKeyFromValue(exec, jsValue); }
bool canInjectIDBKeyIntoScriptValue(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue, const IDBKeyPath& keyPath) { LOG(StorageAPI, "canInjectIDBKeyIntoScriptValue"); ASSERT(keyPath.type() == IDBKeyPath::StringType); Vector<String> keyPathElements; IDBKeyPathParseError error; IDBParseKeyPath(keyPath.string(), keyPathElements, error); ASSERT(error == IDBKeyPathParseErrorNone); if (!keyPathElements.size()) return false; JSC::ExecState* exec = requestState->exec(); return canInjectNthValueOnKeyPath(exec, scriptValue.jsValue(), keyPathElements, keyPathElements.size() - 1); }
JSValue JSCommandLineAPIHost::inspectedObject(ExecState* exec) { if (exec->argumentCount() < 1) return jsUndefined(); CommandLineAPIHost::InspectableObject* object = impl().inspectedObject(exec->uncheckedArgument(0).toInt32(exec)); if (!object) return jsUndefined(); JSLockHolder lock(exec); Deprecated::ScriptValue scriptValue = object->get(exec); if (scriptValue.hasNoValue()) return jsUndefined(); return scriptValue.jsValue(); }
JSValue JSMessageEvent::data(ExecState* exec) const { if (JSValue cachedValue = m_data.get()) return cachedValue; MessageEvent& event = impl(); JSValue result; switch (event.dataType()) { case MessageEvent::DataTypeScriptValue: { Deprecated::ScriptValue scriptValue = event.dataAsScriptValue(); if (scriptValue.hasNoValue()) result = jsNull(); else result = scriptValue.jsValue(); break; } case MessageEvent::DataTypeSerializedScriptValue: if (RefPtr<SerializedScriptValue> serializedValue = event.dataAsSerializedScriptValue()) { MessagePortArray ports = impl().ports(); // FIXME: Why does this suppress exceptions? result = serializedValue->deserialize(exec, globalObject(), &ports, NonThrowing); } else result = jsNull(); break; case MessageEvent::DataTypeString: result = jsStringWithCache(exec, event.dataAsString()); break; case MessageEvent::DataTypeBlob: result = toJS(exec, globalObject(), event.dataAsBlob()); break; case MessageEvent::DataTypeArrayBuffer: result = toJS(exec, globalObject(), event.dataAsArrayBuffer()); break; } // Save the result so we don't have to deserialize the value again. const_cast<JSMessageEvent*>(this)->m_data.set(exec->vm(), this, result); return result; }
void WorkerScriptController::setException(const Deprecated::ScriptValue& exception) { m_workerGlobalScopeWrapper->globalExec()->vm().throwException(m_workerGlobalScopeWrapper->globalExec(), exception.jsValue()); }
RefPtr<WebCore::IDBRequest> IDBObjectStore::deleteFunction(ScriptExecutionContext* context, const Deprecated::ScriptValue& key, ExceptionCode& ec) { return deleteFunction(context, key.jsValue(), ec); }
RefPtr<IDBKey> scriptValueToIDBKey(DOMRequestState* requestState, const Deprecated::ScriptValue& scriptValue) { ExecState* exec = requestState->exec(); return createIDBKeyFromValue(exec, scriptValue.jsValue()); }
void ScriptCallArgumentHandler::appendArgument(const Deprecated::ScriptValue& argument) { m_arguments.append(argument.jsValue()); }
PassRefPtr<IDBRequest> IDBObjectStore::put(IDBDatabaseBackend::PutMode putMode, PassRefPtr<IDBAny> source, JSC::ExecState* state, Deprecated::ScriptValue& value, PassRefPtr<IDBKey> prpKey, ExceptionCode& ec) { RefPtr<IDBKey> key = prpKey; if (m_deleted) { ec = IDBDatabaseException::InvalidStateError; return nullptr; } if (!m_transaction->isActive()) { ec = IDBDatabaseException::TransactionInactiveError; return nullptr; } if (m_transaction->isReadOnly()) { ec = IDBDatabaseException::ReadOnlyError; return nullptr; } RefPtr<SerializedScriptValue> serializedValue = SerializedScriptValue::create(state, value.jsValue(), nullptr, nullptr); if (state->hadException()) return nullptr; if (serializedValue->hasBlobURLs()) { // FIXME: Add Blob/File/FileList support ec = IDBDatabaseException::DataCloneError; return nullptr; } const IDBKeyPath& keyPath = m_metadata.keyPath; const bool usesInLineKeys = !keyPath.isNull(); const bool hasKeyGenerator = autoIncrement(); ScriptExecutionContext* context = scriptExecutionContextFromExecState(state); DOMRequestState requestState(context); if (putMode != IDBDatabaseBackend::CursorUpdate && usesInLineKeys && key) { ec = IDBDatabaseException::DataError; return nullptr; } if (!usesInLineKeys && !hasKeyGenerator && !key) { ec = IDBDatabaseException::DataError; return nullptr; } if (usesInLineKeys) { RefPtr<IDBKey> keyPathKey = createIDBKeyFromScriptValueAndKeyPath(requestState.exec(), value, keyPath); if (keyPathKey && !keyPathKey->isValid()) { ec = IDBDatabaseException::DataError; return nullptr; } if (!hasKeyGenerator && !keyPathKey) { ec = IDBDatabaseException::DataError; return nullptr; } if (hasKeyGenerator && !keyPathKey) { if (!canInjectIDBKeyIntoScriptValue(&requestState, value, keyPath)) { ec = IDBDatabaseException::DataError; return nullptr; } } if (keyPathKey) key = keyPathKey; } if (key && !key->isValid()) { ec = IDBDatabaseException::DataError; return nullptr; } Vector<int64_t> indexIds; Vector<IndexKeys> indexKeys; for (auto& index : m_metadata.indexes) { Vector<IDBKeyData> keyDatas; generateIndexKeysForValue(requestState.exec(), index.value, value, keyDatas); indexIds.append(index.key); // FIXME: Much of the Indexed DB code needs to use IDBKeyData directly to avoid wasteful conversions like this. Vector<RefPtr<IDBKey>> keys; for (auto& keyData : keyDatas) { RefPtr<IDBKey> key = keyData.maybeCreateIDBKey(); if (key) keys.append(key.release()); } indexKeys.append(keys); } RefPtr<IDBRequest> request = IDBRequest::create(context, source, m_transaction.get()); Vector<uint8_t> valueBytes = serializedValue->toWireBytes(); // This is a hack to account for disagreements about whether SerializedScriptValue should deal in Vector<uint8_t> or Vector<char>. // See https://lists.webkit.org/pipermail/webkit-dev/2013-February/023682.html Vector<char>* valueBytesSigned = reinterpret_cast<Vector<char>*>(&valueBytes); RefPtr<SharedBuffer> valueBuffer = SharedBuffer::adoptVector(*valueBytesSigned); backendDB()->put(m_transaction->id(), id(), valueBuffer, key.release(), static_cast<IDBDatabaseBackend::PutMode>(putMode), request, indexIds, indexKeys); return request.release(); }