EncodedJSValue JSC_HOST_CALL constructJSRTCPeerConnection(ExecState* exec) { // Spec says that we must have at least one arument, the RTCConfiguration. if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; Dictionary rtcConfiguration(exec, exec->argument(0)); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (!rtcConfiguration.isObject()) return throwVMError(exec, createTypeError(exec, "RTCPeerConnection argument must be a valid Dictionary")); DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee()); ScriptExecutionContext* scriptExecutionContext = jsConstructor->scriptExecutionContext(); if (!scriptExecutionContext) return throwVMError(exec, createReferenceError(exec, "RTCPeerConnection constructor associated document is unavailable")); auto peerConnection = RTCPeerConnection::create(*scriptExecutionContext, rtcConfiguration, ec); if (ec == TYPE_MISMATCH_ERR) { setDOMException(exec, ec); return throwVMError(exec, createTypeError(exec, "Invalid RTCPeerConnection constructor arguments")); } if (ec) { setDOMException(exec, ec); return throwVMError(exec, createTypeError(exec, "Error creating RTCPeerConnection")); } return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), RTCPeerConnection, peerConnection.releaseNonNull())); }
EncodedJSValue JSC_HOST_CALL constructJSRTCSessionDescription(ExecState* exec) { ExceptionCode ec = 0; Dictionary sessionInit; if (exec->argumentCount() > 0) { sessionInit = Dictionary(exec, exec->argument(0)); if (!sessionInit.isObject()) return throwVMError(exec, createTypeError(exec, "Optional RTCSessionDescription constructor argument must be a valid Dictionary")); if (exec->hadException()) return JSValue::encode(jsUndefined()); } DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee()); RefPtr<RTCSessionDescription> sessionDescription = RTCSessionDescription::create(sessionInit, ec); if (ec == TYPE_MISMATCH_ERR) { setDOMException(exec, ec); return throwVMError(exec, createTypeError(exec, "Invalid RTCSessionDescription constructor arguments")); } if (ec) { setDOMException(exec, ec); return throwVMError(exec, createTypeError(exec, "Error creating RTCSessionDescription")); } return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), RTCSessionDescription, sessionDescription.get())); }
EncodedJSValue JSC_HOST_CALL constructJSWorker(ExecState& exec) { VM& vm = exec.vm(); auto scope = DECLARE_THROW_SCOPE(vm); DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec.callee()); if (!exec.argumentCount()) return throwVMError(&exec, scope, createNotEnoughArgumentsError(&exec)); String scriptURL = exec.uncheckedArgument(0).toWTFString(&exec); if (exec.hadException()) return JSValue::encode(JSValue()); // See section 4.8.2 step 14 of WebWorkers for why this is the lexicalGlobalObject. DOMWindow& window = asJSDOMWindow(exec.lexicalGlobalObject())->wrapped(); ExceptionCode ec = 0; ASSERT(window.document()); RefPtr<Worker> worker = Worker::create(*window.document(), scriptURL, ec); if (ec) { setDOMException(&exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(toJSNewlyCreated(&exec, jsConstructor->globalObject(), WTFMove(worker))); }
EncodedJSValue JSC_HOST_CALL constructJSDataCue(ExecState* exec) { DOMConstructorObject* castedThis = jsCast<DOMConstructorObject*>(exec->callee()); if (exec->argumentCount() < 3) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; double startTime(exec->argument(0).toNumber(exec)); if (UNLIKELY(exec->hadException())) return JSValue::encode(jsUndefined()); double endTime(exec->argument(1).toNumber(exec)); if (UNLIKELY(exec->hadException())) return JSValue::encode(jsUndefined()); ScriptExecutionContext* context = castedThis->scriptExecutionContext(); if (!context) return throwConstructorDocumentUnavailableError(*exec, "DataCue"); String type; #if ENABLE(DATACUE_VALUE) if (exec->argumentCount() > 3) { if (!exec->argument(3).isString()) return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type String")); type = exec->argument(3).getString(exec); } #endif JSValue valueArgument = exec->argument(2); if (valueArgument.isUndefinedOrNull()) { setDOMException(exec, TypeError); return JSValue::encode(JSValue()); } RefPtr<DataCue> object; if (valueArgument.isCell() && valueArgument.asCell()->inherits(std::remove_pointer<JSArrayBuffer*>::type::info())) { ArrayBuffer* data(toArrayBuffer(valueArgument)); if (UNLIKELY(exec->hadException())) return JSValue::encode(jsUndefined()); object = DataCue::create(*context, startTime, endTime, data, type, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get()))); } #if !ENABLE(DATACUE_VALUE) return JSValue::encode(jsUndefined()); #else object = DataCue::create(*context, startTime, endTime, valueArgument, type); return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get()))); #endif }
EncodedJSValue JSC_HOST_CALL constructJSMutationObserver(ExecState* exec) { if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); JSObject* object = exec->argument(0).getObject(); CallData callData; if (!object || object->methodTable()->getCallData(object, callData) == CallType::None) return throwVMError(exec, createTypeError(exec, "Callback argument must be a function")); DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee()); auto callback = JSMutationCallback::create(object, jsConstructor->globalObject()); JSObject* jsObserver = asObject(toJS(exec, jsConstructor->globalObject(), MutationObserver::create(WTFMove(callback)))); PrivateName propertyName; jsObserver->putDirect(jsConstructor->globalObject()->vm(), propertyName, object); return JSValue::encode(jsObserver); }
EncodedJSValue JSC_HOST_CALL constructJSMutationObserver(ExecState& exec) { VM& vm = exec.vm(); auto scope = DECLARE_THROW_SCOPE(vm); if (exec.argumentCount() < 1) return throwVMError(&exec, scope, createNotEnoughArgumentsError(&exec)); JSObject* object = exec.uncheckedArgument(0).getObject(); CallData callData; if (!object || object->methodTable()->getCallData(object, callData) == CallType::None) return throwArgumentTypeError(exec, scope, 0, "callback", "MutationObserver", nullptr, "MutationCallback"); DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec.jsCallee()); auto callback = JSMutationCallback::create(object, jsConstructor->globalObject()); JSObject* jsObserver = asObject(toJSNewlyCreated(&exec, jsConstructor->globalObject(), MutationObserver::create(WTFMove(callback)))); PrivateName propertyName; jsObserver->putDirect(vm, propertyName, object); return JSValue::encode(jsObserver); }
EncodedJSValue JSC_HOST_CALL constructJSWorker(ExecState* exec) { DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee()); if (!exec->argumentCount()) return throwVMError(exec, createNotEnoughArgumentsError(exec)); String scriptURL = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(JSValue()); // See section 4.8.2 step 14 of WebWorkers for why this is the lexicalGlobalObject. DOMWindow& window = asJSDOMWindow(exec->lexicalGlobalObject())->impl(); ExceptionCode ec = 0; ASSERT(window.document()); RefPtr<Worker> worker = Worker::create(*window.document(), scriptURL, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), worker.release()))); }
EncodedJSValue JSC_HOST_CALL constructJSAudioContext(ExecState* exec) { DOMConstructorObject* jsConstructor = jsCast<DOMConstructorObject*>(exec->callee()); if (!jsConstructor) return throwVMError(exec, createReferenceError(exec, "AudioContext constructor callee is unavailable")); ScriptExecutionContext* scriptExecutionContext = jsConstructor->scriptExecutionContext(); if (!scriptExecutionContext) return throwVMError(exec, createReferenceError(exec, "AudioContext constructor script execution context is unavailable")); if (!scriptExecutionContext->isDocument()) return throwVMError(exec, createReferenceError(exec, "AudioContext constructor called in a script execution context which is not a document")); Document& document = toDocument(*scriptExecutionContext); RefPtr<AudioContext> audioContext; if (!exec->argumentCount()) { // Constructor for default AudioContext which talks to audio hardware. ExceptionCode ec = 0; audioContext = AudioContext::create(document, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } if (!audioContext.get()) return throwVMError(exec, createSyntaxError(exec, "audio resources unavailable for AudioContext construction")); } else { #if ENABLE(LEGACY_WEB_AUDIO) // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer. // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); document.addConsoleMessage(MessageSource::JS, MessageLevel::Warning, ASCIILiteral("Deprecated AudioContext constructor: use OfflineAudioContext instead")); if (exec->argumentCount() < 3) return throwVMError(exec, createNotEnoughArgumentsError(exec)); int32_t numberOfChannels = exec->argument(0).toInt32(exec); int32_t numberOfFrames = exec->argument(1).toInt32(exec); float sampleRate = exec->argument(2).toFloat(exec); if (numberOfChannels <= 0 || numberOfChannels > 10) return throwVMError(exec, createSyntaxError(exec, "Invalid number of channels")); if (numberOfFrames <= 0) return throwVMError(exec, createSyntaxError(exec, "Invalid number of frames")); if (sampleRate <= 0) return throwVMError(exec, createSyntaxError(exec, "Invalid sample rate")); ExceptionCode ec = 0; audioContext = OfflineAudioContext::create(document, numberOfChannels, numberOfFrames, sampleRate, ec); if (ec) { setDOMException(exec, ec); return throwVMError(exec, createSyntaxError(exec, "Error creating OfflineAudioContext")); } #else return throwVMError(exec, createSyntaxError(exec, "Illegal AudioContext constructor")); #endif } if (!audioContext.get()) return throwVMError(exec, createReferenceError(exec, "Error creating AudioContext")); return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), AudioContext, audioContext.get())); }