EncodedJSValue JSC_HOST_CALL JSAudioContextConstructor::constructJSAudioContext(ExecState* exec) { JSAudioContextConstructor* jsConstructor = jsCast<JSAudioContextConstructor*>(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 = static_cast<Document*>(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 { // Constructor for offline (render-target) AudioContext which renders into an AudioBuffer. // new AudioContext(in unsigned long numberOfChannels, in unsigned long numberOfFrames, in float sampleRate); 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 = AudioContext::createOfflineContext(document, numberOfChannels, numberOfFrames, sampleRate, ec); if (ec) { setDOMException(exec, ec); return throwVMError(exec, createSyntaxError(exec, "Error creating OfflineAudioContext")); } } if (!audioContext.get()) return throwVMError(exec, createReferenceError(exec, "Error creating AudioContext")); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), AudioContext, audioContext.get())); }
JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident) { if (exec->propertyNames().isPrivateName(ident)) { String message(makeString("Can't find private variable: @", exec->propertyNames().lookUpPublicName(ident).string())); return createReferenceError(exec, message); } String message(makeString("Can't find variable: ", ident.string())); return createReferenceError(exec, message); }
EncodedJSValue JSC_HOST_CALL JSKeyboardEventConstructor::constructJSKeyboardEvent(ExecState* exec) { JSKeyboardEventConstructor* jsConstructor = jsCast<JSKeyboardEventConstructor*>(exec->callee()); ScriptExecutionContext* executionContext = jsConstructor->scriptExecutionContext(); if (!executionContext) return throwVMError(exec, createReferenceError(exec, "Constructor associated execution context is unavailable")); AtomicString eventType = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); KeyboardEventInit eventInit; JSValue initializerValue = exec->argument(1); if (!initializerValue.isUndefinedOrNull()) { // Given the above test, this will always yield an object. JSObject* initializerObject = initializerValue.toObject(exec); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(exec, initializerObject); // Attempt to fill in the EventInit. if (!fillKeyboardEventInit(eventInit, dictionary)) return JSValue::encode(jsUndefined()); } RefPtr<KeyboardEvent> event = KeyboardEvent::create(eventType, eventInit); return JSValue::encode(toJS(exec, jsConstructor->globalObject(), event.get())); }
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 JSTestInterfaceConstructor::constructJSTestInterface(ExecState* exec) { ScriptExecutionContext* context = static_cast<JSTestInterfaceConstructor*>(exec->callee())->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "Reference error")); return JSValue::encode(asObject(toJS(exec, static_cast<JSTestInterfaceConstructor*>(exec->callee())->globalObject(), TestInterface::create(context)))); }
static EncodedJSValue JSC_HOST_CALL constructHTMLOptionElement(ExecState* exec) { JSOptionConstructor* jsConstructor = static_cast<JSOptionConstructor*>(exec->callee()); Document* document = jsConstructor->document(); if (!document) return throwVMError(exec, createReferenceError(exec, "Option constructor associated document is unavailable")); String data; if ((exec->argumentCount() >= 1) && !exec->argument(0).isUndefined()) data = ustringToString(exec->argument(0).toString(exec)); String value; if ((exec->argumentCount() >= 2) && !exec->argument(1).isUndefined()) value = ustringToString(exec->argument(1).toString(exec)); bool defaultSelected = (exec->argumentCount() >= 3) && exec->argument(2).toBoolean(exec); bool selected = (exec->argumentCount() >= 4) && exec->argument(3).toBoolean(exec); ExceptionCode ec = 0; RefPtr<HTMLOptionElement> element = HTMLOptionElement::createForJSConstructor(document, data, value, defaultSelected, selected, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), element.release()))); }
static EncodedJSValue JSC_HOST_CALL constructImage(ExecState* exec) { JSImageConstructor* jsConstructor = jsCast<JSImageConstructor*>(exec->callee()); Document* document = jsConstructor->document(); if (!document) return throwVMError(exec, createReferenceError(exec, "Image constructor associated document is unavailable")); // Calling toJS on the document causes the JS document wrapper to be // added to the window object. This is done to ensure that JSDocument::visit // will be called, which will cause the image element to be marked if necessary. toJS(exec, jsConstructor->globalObject(), document); int width; int height; int* optionalWidth = 0; int* optionalHeight = 0; if (exec->argumentCount() > 0) { width = exec->argument(0).toInt32(exec); optionalWidth = &width; } if (exec->argumentCount() > 1) { height = exec->argument(1).toInt32(exec); optionalHeight = &height; } return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), HTMLImageElement::createForJSConstructor(*document, optionalWidth, optionalHeight)))); }
EncodedJSValue JSC_HOST_CALL JSMessageChannelConstructor::constructJSMessageChannel(ExecState* exec) { JSMessageChannelConstructor* jsConstructor = static_cast<JSMessageChannelConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "MessageChannel constructor associated document is unavailable")); return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), MessageChannel::create(context)))); }
EncodedJSValue JSC_HOST_CALL JSMessageChannelConstructor::constructJSMessageChannel(ExecState* exec) { JSMessageChannelConstructor* castedThis = jsCast<JSMessageChannelConstructor*>(exec->callee()); ScriptExecutionContext* context = castedThis->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "MessageChannel constructor associated document is unavailable")); RefPtr<MessageChannel> object = MessageChannel::create(*context); return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get()))); }
JSValue createUndefinedVariableError(ExecState* exec, const Identifier& ident, unsigned bytecodeOffset, CodeBlock* codeBlock) { int startOffset = 0; int endOffset = 0; int divotPoint = 0; int line = codeBlock->expressionRangeForBytecodeOffset(exec, bytecodeOffset, divotPoint, startOffset, endOffset); UString message(makeUString("Can't find variable: ", ident.ustring())); JSObject* exception = addErrorInfo(exec, createReferenceError(exec, message), line, codeBlock->ownerExecutable()->source(), divotPoint, startOffset, endOffset); return exception; }
EncodedJSValue JSC_HOST_CALL JSXMLHttpRequestConstructor::constructJSXMLHttpRequest(ExecState* exec) { JSXMLHttpRequestConstructor* jsConstructor = static_cast<JSXMLHttpRequestConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "XMLHttpRequest constructor associated document is unavailable")); RefPtr<XMLHttpRequest> xmlHttpRequest = XMLHttpRequest::create(context); return JSValue::encode(CREATE_DOM_OBJECT_WRAPPER(exec, jsConstructor->globalObject(), XMLHttpRequest, xmlHttpRequest.get())); }
EncodedJSValue JSC_HOST_CALL JSDeprecatedPeerConnectionConstructor::constructJSDeprecatedPeerConnection(ExecState* exec) { JSDeprecatedPeerConnectionConstructor* jsConstructor = static_cast<JSDeprecatedPeerConnectionConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "DeprecatedPeerConnection constructor associated document is unavailable")); if (exec->argumentCount() < 2) return throwVMError(exec, createTypeError(exec, "Not enough arguments")); String serverConfiguration = ustringToString(exec->argument(0).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(JSValue()); RefPtr<SignalingCallback> signalingCallback = createFunctionOnlyCallback<JSSignalingCallback>(exec, static_cast<JSDOMGlobalObject*>(exec->lexicalGlobalObject()), exec->argument(1)); if (exec->hadException()) return JSValue::encode(JSValue()); RefPtr<DeprecatedPeerConnection> peerConnection = DeprecatedPeerConnection::create(context, serverConfiguration, signalingCallback.release()); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), DeprecatedPeerConnection, peerConnection.get())); }
EncodedJSValue JSC_HOST_CALL JSWebSocketConstructor::constructJSWebSocket(ExecState* exec) { JSWebSocketConstructor* jsConstructor = static_cast<JSWebSocketConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "WebSocket constructor associated document is unavailable")); if (!exec->argumentCount()) return throwVMError(exec, createSyntaxError(exec, "Not enough arguments")); String urlString = ustringToString(exec->argument(0).toString(exec)->value(exec)); if (exec->hadException()) return throwVMError(exec, createSyntaxError(exec, "wrong URL")); RefPtr<WebSocket> webSocket = WebSocket::create(context); ExceptionCode ec = 0; if (exec->argumentCount() < 2) webSocket->connect(urlString, ec); else { JSValue protocolsValue = exec->argument(1); if (isJSArray(protocolsValue)) { Vector<String> protocols; JSArray* protocolsArray = asArray(protocolsValue); for (unsigned i = 0; i < protocolsArray->length(); ++i) { String protocol = ustringToString(protocolsArray->getIndex(i).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(JSValue()); protocols.append(protocol); } webSocket->connect(urlString, protocols, ec); } else { String protocol = ustringToString(protocolsValue.toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(JSValue()); webSocket->connect(urlString, protocol, ec); } } setDOMException(exec, ec); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), WebSocket, webSocket.get())); }
EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::constructJSTestInterface(ExecState* exec) { JSTestInterfaceConstructor* jsConstructor = static_cast<JSTestInterfaceConstructor*>(exec->callee()); if (exec->argumentCount() < 1) return throwVMError(exec, createTypeError(exec, "Not enough arguments")); ExceptionCode ec = 0; const String& str1(ustringToString(MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 0, DefaultIsUndefined).toString(exec)->value(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& str2(ustringToString(MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).isEmpty() ? UString() : MAYBE_MISSING_PARAMETER(exec, 1, DefaultIsUndefined).toString(exec)->value(exec))); if (exec->hadException()) return JSValue::encode(jsUndefined()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "TestInterface constructor associated document is unavailable")); RefPtr<TestInterface> object = TestInterface::create(context, str1, str2, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), object.get()))); }
EncodedJSValue JSC_HOST_CALL JSTestInterfaceConstructor::constructJSTestInterface(ExecState* exec) { JSTestInterfaceConstructor* castedThis = jsCast<JSTestInterfaceConstructor*>(exec->callee()); if (exec->argumentCount() < 1) return throwVMError(exec, createNotEnoughArgumentsError(exec)); ExceptionCode ec = 0; const String& str1(exec->argument(0).isEmpty() ? String() : exec->argument(0).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); const String& str2(exec->argument(1).isEmpty() ? String() : exec->argument(1).toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); ScriptExecutionContext* context = castedThis->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "TestInterface constructor associated document is unavailable")); RefPtr<TestInterface> object = TestInterface::create(context, str1, str2, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, castedThis->globalObject(), object.get()))); }
static EncodedJSValue JSC_HOST_CALL constructAudio(ExecState* exec) { JSAudioConstructor* jsConstructor = static_cast<JSAudioConstructor*>(exec->callee()); Document* document = jsConstructor->document(); if (!document) return throwVMError(exec, createReferenceError(exec, "Audio constructor associated document is unavailable")); // Calling toJS on the document causes the JS document wrapper to be // added to the window object. This is done to ensure that JSDocument::visitChildren // will be called, which will cause the audio element to be marked if necessary. toJS(exec, jsConstructor->globalObject(), document); // FIXME: This converts an undefined argument to the string "undefined", but possibly we // should treat it as if no argument was passed instead, by checking the value of exec->argument // rather than looking at exec->argumentCount. String src; if (exec->argumentCount() > 0) src = ustringToString(exec->argument(0).toString(exec)); return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), HTMLAudioElement::createForJSConstructor(document, src)))); }
JSValue JSIDBObjectStore::createIndex(ExecState* exec) { ScriptExecutionContext* context = jsCast<JSDOMGlobalObject*>(exec->lexicalGlobalObject())->scriptExecutionContext(); if (!context) return exec->vm().throwException(exec, createReferenceError(exec, "IDBObjectStore script execution context is unavailable")); if (exec->argumentCount() < 2) return exec->vm().throwException(exec, createNotEnoughArgumentsError(exec)); String name = exec->argument(0).toString(exec)->value(exec); if (exec->hadException()) return jsUndefined(); IDBKeyPath keyPath = idbKeyPathFromValue(exec, exec->argument(1)); if (exec->hadException()) return jsUndefined(); JSValue optionsValue = exec->argument(2); if (!optionsValue.isUndefinedOrNull() && !optionsValue.isObject()) return throwTypeError(exec, "Not an object."); bool unique = false; bool multiEntry = false; if (!optionsValue.isUndefinedOrNull()) { unique = optionsValue.get(exec, Identifier(exec, "unique")).toBoolean(exec); if (exec->hadException()) return jsUndefined(); multiEntry = optionsValue.get(exec, Identifier(exec, "multiEntry")).toBoolean(exec); if (exec->hadException()) return jsUndefined(); } ExceptionCode ec = 0; JSValue result = toJS(exec, globalObject(), impl().createIndex(context, name, keyPath, unique, multiEntry, ec).get()); setDOMException(exec, ec); return result; }
EncodedJSValue JSC_HOST_CALL JSEventSourceConstructor::constructJSEventSource(ExecState* exec) { if (exec->argumentCount() < 1) return throwVMError(exec, createTypeError(exec, "Not enough arguments")); UString url = exec->argument(0).toString(exec); if (exec->hadException()) return JSValue::encode(JSValue()); JSEventSourceConstructor* jsConstructor = static_cast<JSEventSourceConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "EventSource constructor associated document is unavailable")); ExceptionCode ec = 0; RefPtr<EventSource> eventSource = EventSource::create(ustringToString(url), context, ec); if (ec) { setDOMException(exec, ec); return JSValue::encode(JSValue()); } return JSValue::encode(asObject(toJS(exec, jsConstructor->globalObject(), eventSource.release()))); }
JSObject* createErrorForInvalidGlobalAssignment(ExecState* exec, const UString& propertyName) { return createReferenceError(exec, makeUString("Strict mode forbids implicit creation of global property '", propertyName, "'")); }
JSObject* createUndefinedVariableError(ExecState* exec, const Identifier& ident) { UString message(makeUString("Can't find variable: ", ident.ustring())); return createReferenceError(exec, message); }
EncodedJSValue JSC_HOST_CALL JSBlobConstructor::constructJSBlob(ExecState* exec) { JSBlobConstructor* jsConstructor = jsCast<JSBlobConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "Blob constructor associated document is unavailable")); if (!exec->argumentCount()) { RefPtr<Blob> blob = Blob::create(); return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get())); } unsigned blobPartsLength = 0; JSObject* blobParts = toJSSequence(exec, exec->argument(0), blobPartsLength); if (exec->hadException()) return JSValue::encode(jsUndefined()); ASSERT(blobParts); String type; String endings = ASCIILiteral("transparent"); if (exec->argumentCount() > 1) { JSValue blobPropertyBagValue = exec->argument(1); if (!blobPropertyBagValue.isObject()) return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object")); // Given the above test, this will always yield an object. JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(exec, blobPropertyBagObject); // Attempt to get the endings property and validate it. bool containsEndings = dictionary.get("endings", endings); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (containsEndings) { if (endings != "transparent" && endings != "native") return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\"")); } // Attempt to get the type property. dictionary.get("type", type); if (exec->hadException()) return JSValue::encode(jsUndefined()); } ASSERT(endings == "transparent" || endings == "native"); BlobBuilder blobBuilder; for (unsigned i = 0; i < blobPartsLength; ++i) { JSValue item = blobParts->get(exec, i); if (exec->hadException()) return JSValue::encode(jsUndefined()); #if ENABLE(BLOB) if (ArrayBuffer* arrayBuffer = toArrayBuffer(item)) blobBuilder.append(arrayBuffer); else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item)) blobBuilder.append(arrayBufferView.release()); else #endif if (Blob* blob = toBlob(item)) blobBuilder.append(blob); else { String string = item.toString(exec)->value(exec); if (exec->hadException()) return JSValue::encode(jsUndefined()); blobBuilder.append(string, endings); } } RefPtr<Blob> blob = Blob::create(blobBuilder.finalize(), Blob::normalizedContentType(type)); return JSValue::encode(CREATE_DOM_WRAPPER(jsConstructor->globalObject(), Blob, blob.get())); }
JSObject* RuntimeObject::throwInvalidAccessError(ExecState* exec) { return exec->vm().throwException(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); }
JSObject* createTDZError(ExecState* exec) { return createReferenceError(exec, "Cannot access uninitialized variable."); }
EncodedJSValue JSC_HOST_CALL JSBlobConstructor::constructJSBlob(ExecState* exec) { JSBlobConstructor* jsConstructor = jsCast<JSBlobConstructor*>(exec->callee()); ScriptExecutionContext* context = jsConstructor->scriptExecutionContext(); if (!context) return throwVMError(exec, createReferenceError(exec, "Blob constructor associated document is unavailable")); if (!exec->argumentCount()) { RefPtr<Blob> blob = Blob::create(); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get())); } JSValue firstArg = exec->argument(0); if (!isJSArray(firstArg)) return throwVMError(exec, createTypeError(exec, "First argument of the constructor is not of type Array")); String type; String endings = "transparent"; if (exec->argumentCount() > 1) { JSValue blobPropertyBagValue = exec->argument(1); if (!blobPropertyBagValue.isObject()) return throwVMError(exec, createTypeError(exec, "Second argument of the constructor is not of type Object")); // Given the above test, this will always yield an object. JSObject* blobPropertyBagObject = blobPropertyBagValue.toObject(exec); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(exec, blobPropertyBagObject); // Attempt to get the endings property and validate it. bool containsEndings = dictionary.get("endings", endings); if (exec->hadException()) return JSValue::encode(jsUndefined()); if (containsEndings) { if (endings != "transparent" && endings != "native") return throwVMError(exec, createTypeError(exec, "The endings property must be either \"transparent\" or \"native\"")); } // Attempt to get the type property. dictionary.get("type", type); if (exec->hadException()) return JSValue::encode(jsUndefined()); } ASSERT(endings == "transparent" || endings == "native"); // FIXME: this would be better if the WebKitBlobBuilder were a stack object to avoid the allocation. RefPtr<WebKitBlobBuilder> blobBuilder = WebKitBlobBuilder::create(); JSArray* array = asArray(firstArg); unsigned length = array->length(); for (unsigned i = 0; i < length; ++i) { JSValue item = array->getIndex(i); #if ENABLE(BLOB) if (item.inherits(&JSArrayBuffer::s_info)) blobBuilder->append(toArrayBuffer(item)); else #endif if (item.inherits(&JSBlob::s_info)) blobBuilder->append(toBlob(item)); else { String string = ustringToString(item.toString(exec)->value(exec)); if (exec->hadException()) return JSValue::encode(jsUndefined()); blobBuilder->append(string, endings, ASSERT_NO_EXCEPTION); } } RefPtr<Blob> blob = blobBuilder->getBlob(type); return JSValue::encode(CREATE_DOM_WRAPPER(exec, jsConstructor->globalObject(), Blob, blob.get())); }
EncodedJSValue JSC_HOST_CALL constructJSFile(ExecState& exec) { auto* constructor = jsCast<DOMConstructorObject*>(exec.callee()); ScriptExecutionContext* context = constructor->scriptExecutionContext(); if (!context) return throwVMError(&exec, createReferenceError(&exec, "File constructor associated document is unavailable")); JSValue arg = exec.argument(0); if (arg.isUndefinedOrNull()) return throwVMTypeError(&exec, ASCIILiteral("First argument to File constructor must be a valid sequence, was undefined or null")); unsigned blobPartsLength = 0; JSObject* blobParts = toJSSequence(exec, arg, blobPartsLength); if (exec.hadException()) return JSValue::encode(jsUndefined()); ASSERT(blobParts); arg = exec.argument(1); if (arg.isUndefined()) return throwVMTypeError(&exec, ASCIILiteral("Second argument to File constructor must be a valid string, was undefined")); String filename = arg.toWTFString(&exec).replace('/', ':'); if (exec.hadException()) return JSValue::encode(jsUndefined()); String normalizedType; Optional<int64_t> lastModified; arg = exec.argument(2); if (!arg.isUndefinedOrNull()) { JSObject* filePropertyBagObject = arg.getObject(); if (!filePropertyBagObject) return throwVMTypeError(&exec, ASCIILiteral("Third argument of the constructor is not of type Object")); // Create the dictionary wrapper from the initializer object. JSDictionary dictionary(&exec, filePropertyBagObject); // Attempt to get the type property. String type; dictionary.get("type", type); if (exec.hadException()) return JSValue::encode(jsUndefined()); normalizedType = Blob::normalizedContentType(type); // Only try to parse the lastModified date if there was not an invalid type argument. if (type.isEmpty() || !normalizedType.isEmpty()) { dictionary.get("lastModified", lastModified); if (exec.hadException()) return JSValue::encode(jsUndefined()); } } if (!lastModified) lastModified = currentTimeMS(); BlobBuilder blobBuilder; for (unsigned i = 0; i < blobPartsLength; ++i) { JSValue item = blobParts->get(&exec, i); if (exec.hadException()) return JSValue::encode(jsUndefined()); if (ArrayBuffer* arrayBuffer = toArrayBuffer(item)) blobBuilder.append(arrayBuffer); else if (RefPtr<ArrayBufferView> arrayBufferView = toArrayBufferView(item)) blobBuilder.append(WTFMove(arrayBufferView)); else if (Blob* blob = JSBlob::toWrapped(item)) blobBuilder.append(blob); else { String string = item.toWTFString(&exec); if (exec.hadException()) return JSValue::encode(jsUndefined()); blobBuilder.append(string, ASCIILiteral("transparent")); } } auto file = File::create(blobBuilder.finalize(), filename, normalizedType, lastModified.value()); return JSValue::encode(CREATE_DOM_WRAPPER(constructor->globalObject(), File, WTFMove(file))); }
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())); }
JSObject* JSNPObject::throwInvalidAccessError(ExecState* exec) { return throwError(exec, createReferenceError(exec, "Trying to access object from destroyed plug-in.")); }
JSObject* createReferenceError(ExecState* exec, const String& message) { return createReferenceError(exec->lexicalGlobalObject(), message); }
JSObject* createReferenceError(ExecState* exec, const String& message) { return createReferenceError(exec, message, nullptr); }