EncodedJSValue JSC_HOST_CALL jsSVGStringListPrototypeFunctionAppendItem(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); JSSVGStringList* castedThis = jsDynamicCast<JSSVGStringList*>(thisValue); if (!castedThis) return throwVMTypeError(exec); ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGStringList::info()); SVGStaticListPropertyTearOff<SVGStringList> & impl = castedThis->impl(); if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; const String& item(exec->argument(0).isEmpty() ? String() : exec->argument(0).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = jsStringWithCache(exec, impl.appendItem(item, ec)); setDOMException(exec, ec); return JSValue::encode(result); }
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; }
EncodedJSValue JSC_HOST_CALL jsSVGStringListPrototypeFunctionRemoveItem(ExecState* exec) { JSValue thisValue = exec->hostThisValue(); JSSVGStringList* castedThis = jsDynamicCast<JSSVGStringList*>(thisValue); if (!castedThis) return throwVMTypeError(exec); ASSERT_GC_OBJECT_INHERITS(castedThis, JSSVGStringList::info()); SVGStaticListPropertyTearOff<SVGStringList> & impl = castedThis->impl(); if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; unsigned index(toUInt32(exec, exec->argument(0), NormalConversion)); if (exec->hadException()) return JSValue::encode(jsUndefined()); JSC::JSValue result = jsStringWithCache(exec, impl.removeItem(index, ec)); setDOMException(exec, ec); return JSValue::encode(result); }
bool JSStorage::nameGetter(ExecState* state, PropertyName propertyName, JSValue& value) { if (propertyName.isSymbol()) return false; auto item = wrapped().getItem(propertyNameToString(propertyName)); if (item.hasException()) { auto& vm = state->vm(); auto scope = DECLARE_THROW_SCOPE(vm); propagateException(*state, scope, item.releaseException()); return false; } auto string = item.releaseReturnValue(); if (string.isNull()) return false; value = jsStringWithCache(state, string); return true; }
bool JSTestCallback::callbackWithSerializedScriptValueParam(PassRefPtr<SerializedScriptValue> srzParam, const String& strArg) { if (!canInvokeCallback()) return true; Ref<JSTestCallback> protect(*this); JSLockHolder lock(m_data->globalObject()->vm()); ExecState* state = m_data->globalObject()->globalExec(); MarkedArgumentBuffer args; args.append(srzParam ? srzParam->deserialize(state, castedThis->globalObject(), 0) : jsNull()); args.append(jsStringWithCache(state, strArg)); NakedPtr<Exception> returnedException; m_data->invokeCallback(args, JSCallbackData::CallbackType::Object, Identifier::fromString(state, "callbackWithSerializedScriptValueParam"), returnedException); if (returnedException) reportException(state, returnedException); return !returnedException; }
JSValue JSSQLResultSetRowList::item(ExecState* exec) { bool indexOk; int index = finiteInt32Value(exec->argument(0), exec, indexOk); if (!indexOk) { setDOMException(exec, TYPE_MISMATCH_ERR); return jsUndefined(); } if (index < 0 || (unsigned)index >= m_impl->length()) { setDOMException(exec, INDEX_SIZE_ERR); return jsUndefined(); } JSObject* object = constructEmptyObject(exec); unsigned numColumns = m_impl->columnNames().size(); unsigned valuesIndex = index * numColumns; for (unsigned i = 0; i < numColumns; i++) { const SQLValue& value = m_impl->values()[valuesIndex + i]; JSValue jsValue; switch (value.type()) { case SQLValue::StringValue: jsValue = jsStringWithCache(exec, value.string()); break; case SQLValue::NullValue: jsValue = jsNull(); break; case SQLValue::NumberValue: jsValue = jsNumber(value.number()); break; default: ASSERT_NOT_REACHED(); } object->putDirect(exec->vm(), Identifier(exec, m_impl->columnNames()[i]), jsValue, DontDelete | ReadOnly); } return object; }
JSValue toJS(ExecState* exec, JSDOMGlobalObject* globalObject, IDBAny* idbAny) { if (!idbAny) return jsNull(); switch (idbAny->type()) { case IDBAny::Type::Undefined: return jsUndefined(); case IDBAny::Type::Null: return jsNull(); case IDBAny::Type::DOMStringList: return toJS(exec, globalObject, idbAny->domStringList()); case IDBAny::Type::IDBCursor: return toJS(exec, globalObject, idbAny->idbCursor()); case IDBAny::Type::IDBCursorWithValue: return wrap<JSIDBCursorWithValue>(globalObject, idbAny->idbCursorWithValue().get()); case IDBAny::Type::IDBDatabase: return toJS(exec, globalObject, idbAny->idbDatabase()); case IDBAny::Type::IDBFactory: return toJS(exec, globalObject, idbAny->idbFactory()); case IDBAny::Type::IDBIndex: return toJS(exec, globalObject, idbAny->idbIndex()); case IDBAny::Type::IDBObjectStore: return toJS(exec, globalObject, idbAny->idbObjectStore()); case IDBAny::Type::IDBTransaction: return toJS(exec, globalObject, idbAny->idbTransaction()); case IDBAny::Type::ScriptValue: return idbAny->scriptValue().jsValue(); case IDBAny::Type::String: return jsStringWithCache(exec, idbAny->string()); case IDBAny::Type::Integer: return jsNumber(idbAny->integer()); case IDBAny::Type::KeyPath: return toJS(exec, globalObject, idbAny->keyPath()); } ASSERT_NOT_REACHED(); return jsUndefined(); }
static JSValue idbKeyToJSValue(ExecState* exec, JSGlobalObject* globalObject, IDBKey* key) { if (!key || !exec) { // This should be undefined, not null. // Spec: http://dvcs.w3.org/hg/IndexedDB/raw-file/tip/Overview.html#idl-def-IDBKeyRange return jsUndefined(); } Locker<JSLock> locker(exec->vm().apiLock()); switch (key->type()) { case KeyType::Array: { const Vector<RefPtr<IDBKey>>& inArray = key->array(); size_t size = inArray.size(); JSArray* outArray = constructEmptyArray(exec, 0, globalObject, size); for (size_t i = 0; i < size; ++i) { IDBKey* arrayKey = inArray.at(i).get(); outArray->putDirectIndex(exec, i, idbKeyToJSValue(exec, globalObject, arrayKey)); } return JSValue(outArray); } case KeyType::String: return jsStringWithCache(exec, key->string()); case KeyType::Date: return jsDateOrNull(exec, key->date()); case KeyType::Number: return jsNumber(key->number()); case KeyType::Min: case KeyType::Max: case KeyType::Invalid: ASSERT_NOT_REACHED(); return jsUndefined(); } ASSERT_NOT_REACHED(); return jsUndefined(); }
JSValue idbKeyDataToJSValue(JSC::ExecState& exec, const IDBKeyData& keyData) { if (keyData.isNull()) return jsUndefined(); Locker<JSLock> locker(exec.vm().apiLock()); switch (keyData.type()) { case KeyType::Array: { const Vector<IDBKeyData>& inArray = keyData.array(); size_t size = inArray.size(); JSArray* outArray = constructEmptyArray(&exec, 0, exec.lexicalGlobalObject(), size); for (size_t i = 0; i < size; ++i) { auto& arrayKey = inArray.at(i); outArray->putDirectIndex(&exec, i, idbKeyDataToJSValue(exec, arrayKey)); } return JSValue(outArray); } case KeyType::String: return jsStringWithCache(&exec, keyData.string()); case KeyType::Date: return jsDateOrNull(&exec, keyData.date()); case KeyType::Number: return jsNumber(keyData.number()); case KeyType::Min: case KeyType::Max: case KeyType::Invalid: ASSERT_NOT_REACHED(); return jsUndefined(); } ASSERT_NOT_REACHED(); return jsUndefined(); }
void JSErrorHandler::handleEvent(ScriptExecutionContext* scriptExecutionContext, Event* event) { if (!is<ErrorEvent>(*event)) return JSEventListener::handleEvent(scriptExecutionContext, event); ASSERT(scriptExecutionContext); if (!scriptExecutionContext) return; ErrorEvent& errorEvent = downcast<ErrorEvent>(*event); JSLockHolder lock(scriptExecutionContext->vm()); JSObject* jsFunction = this->jsFunction(scriptExecutionContext); if (!jsFunction) return; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(scriptExecutionContext, isolatedWorld()); if (!globalObject) return; ExecState* exec = globalObject->globalExec(); CallData callData; CallType callType = jsFunction->methodTable()->getCallData(jsFunction, callData); if (callType != CallTypeNone) { Ref<JSErrorHandler> protectedctor(*this); Event* savedEvent = globalObject->currentEvent(); globalObject->setCurrentEvent(event); MarkedArgumentBuffer args; args.append(jsStringWithCache(exec, errorEvent.message())); args.append(jsStringWithCache(exec, errorEvent.filename())); args.append(jsNumber(errorEvent.lineno())); args.append(jsNumber(errorEvent.colno())); VM& vm = globalObject->vm(); VMEntryScope entryScope(vm, vm.entryScope ? vm.entryScope->globalObject() : globalObject); InspectorInstrumentationCookie cookie = JSMainThreadExecState::instrumentFunctionCall(scriptExecutionContext, callType, callData); NakedPtr<Exception> exception; JSValue returnValue = scriptExecutionContext->isDocument() ? JSMainThreadExecState::profiledCall(exec, JSC::ProfilingReason::Other, jsFunction, callType, callData, globalObject, args, exception) : JSC::profiledCall(exec, JSC::ProfilingReason::Other, jsFunction, callType, callData, globalObject, args, exception); InspectorInstrumentation::didCallFunction(cookie, scriptExecutionContext); globalObject->setCurrentEvent(savedEvent); if (exception) reportException(exec, exception); else { if (returnValue.isTrue()) event->preventDefault(); } } }
static inline JSValue getPropertyValueFallback(ExecState* exec, JSCSSStyleDeclaration* thisObj, unsigned index) { // If the property is a shorthand property (such as "padding"), // it can only be accessed using getPropertyValue. return jsStringWithCache(exec, thisObj->wrapped().getPropertyValueInternal(static_cast<CSSPropertyID>(index))); }
JSObject* JSLazyEventListener::initializeJSFunction(ScriptExecutionContext* executionContext) const { ASSERT(is<Document>(executionContext)); if (!executionContext) return nullptr; ASSERT(!m_code.isNull()); ASSERT(!m_eventParameterName.isNull()); if (m_code.isNull() || m_eventParameterName.isNull()) return nullptr; Document& document = downcast<Document>(*executionContext); if (!document.frame()) return nullptr; if (!document.contentSecurityPolicy()->allowInlineEventHandlers(m_sourceURL, m_sourcePosition.m_line)) return nullptr; ScriptController& script = document.frame()->script(); if (!script.canExecuteScripts(AboutToExecuteScript) || script.isPaused()) return nullptr; JSDOMGlobalObject* globalObject = toJSDOMGlobalObject(executionContext, isolatedWorld()); if (!globalObject) return nullptr; VM& vm = globalObject->vm(); JSLockHolder lock(vm); auto scope = DECLARE_CATCH_SCOPE(vm); ExecState* exec = globalObject->globalExec(); MarkedArgumentBuffer args; args.append(jsNontrivialString(exec, m_eventParameterName)); args.append(jsStringWithCache(exec, m_code)); // We want all errors to refer back to the line on which our attribute was // declared, regardless of any newlines in our JavaScript source text. int overrideLineNumber = m_sourcePosition.m_line.oneBasedInt(); JSObject* jsFunction = constructFunctionSkippingEvalEnabledCheck( exec, exec->lexicalGlobalObject(), args, Identifier::fromString(exec, m_functionName), m_sourceURL, m_sourcePosition, overrideLineNumber); if (UNLIKELY(scope.exception())) { reportCurrentException(exec); scope.clearException(); return nullptr; } JSFunction* listenerAsFunction = jsCast<JSFunction*>(jsFunction); if (m_originalNode) { if (!wrapper()) { // Ensure that 'node' has a JavaScript wrapper to mark the event listener we're creating. // FIXME: Should pass the global object associated with the node setWrapper(vm, asObject(toJS(exec, globalObject, *m_originalNode))); } // Add the event's home element to the scope // (and the document, and the form - see JSHTMLElement::eventHandlerScope) listenerAsFunction->setScope(vm, jsCast<JSNode*>(wrapper())->pushEventHandlerScope(exec, listenerAsFunction->scope())); } return jsFunction; }