JSValue JSWebKitSubtleCrypto::digest(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 2)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForDigest(state, scope, algorithm->identifier(), state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    auto data = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(1));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
        fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    auto result = algorithm->digest(*parameters, data, WTFMove(successCallback), WTFMove(failureCallback));
    if (result.hasException()) {
        propagateException(state, scope, result.releaseException());
        return { };
    }

    return promise;
}
// Custom functions
JSValue JSXMLHttpRequest::open(ExecState& state)
{
    if (state.argumentCount() < 2)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));

    const URL& url = wrapped().scriptExecutionContext()->completeURL(state.uncheckedArgument(1).toString(&state)->value(&state));
    String method = state.uncheckedArgument(0).toString(&state)->value(&state);

    ExceptionCode ec = 0;
    if (state.argumentCount() >= 3) {
        bool async = state.uncheckedArgument(2).toBoolean(&state);
        if (!state.argument(3).isUndefined()) {
            String user = valueToStringWithNullCheck(&state, state.uncheckedArgument(3));

            if (!state.argument(4).isUndefined()) {
                String password = valueToStringWithNullCheck(&state, state.uncheckedArgument(4));
                wrapped().open(method, url, async, user, password, ec);
            } else
                wrapped().open(method, url, async, user, ec);
        } else
            wrapped().open(method, url, async, ec);
    } else
        wrapped().open(method, url, ec);

    setDOMException(&state, ec);
    return jsUndefined();
}
JSValue JSWebKitSubtleCrypto::exportKey(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 2)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto keyFormat = cryptoKeyFormatFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(1));
    if (!key)
        return throwTypeError(&state, scope);

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](const Vector<uint8_t>& result) mutable {
        fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), result.data(), result.size());
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    WebCore::exportKey(state, keyFormat, *key, WTFMove(successCallback), WTFMove(failureCallback));
    RETURN_IF_EXCEPTION(scope, JSValue());

    return promise;
}
JSValue JSCommandLineAPIHost::inspect(ExecState& state)
{
    if (state.argumentCount() < 2)
        return jsUndefined();
    wrapped().inspectImpl(Inspector::toInspectorValue(state, state.uncheckedArgument(0)),
        Inspector::toInspectorValue(state, state.uncheckedArgument(1)));
    return jsUndefined();
}
JSValue JSXSLTProcessor::removeParameter(ExecState& state)
{
    if (state.argument(1).isUndefinedOrNull())
        return jsUndefined();
    String namespaceURI = state.uncheckedArgument(0).toString(&state)->value(&state);
    String localName = state.uncheckedArgument(1).toString(&state)->value(&state);
    wrapped().removeParameter(namespaceURI, localName);
    return jsUndefined();
}
JSValue JSWebKitSubtleCrypto::verify(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 4)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(0));
    ASSERT(scope.exception() || algorithm);
    if (!algorithm)
        return jsUndefined();

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForVerify(&state, algorithm->identifier(), state.uncheckedArgument(0));
    ASSERT(scope.exception() || parameters);
    if (!parameters)
        return jsUndefined();

    RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(state.uncheckedArgument(1));
    if (!key)
        return throwTypeError(&state, scope);

    if (!key->allows(CryptoKeyUsageVerify)) {
        wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'verify'"));
        setDOMException(&state, NOT_SUPPORTED_ERR);
        return jsUndefined();
    }

    CryptoOperationData signature;
    auto success = cryptoOperationDataFromJSValue(&state, state.uncheckedArgument(2), signature);
    ASSERT(scope.exception() || success);
    if (!success)
        return jsUndefined();

    CryptoOperationData data;
    success = cryptoOperationDataFromJSValue(&state, state.uncheckedArgument(3), data);
    ASSERT(scope.exception() || success);
    if (!success)
        return jsUndefined();

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](bool result) mutable {
        wrapper->resolve(result);
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(nullptr);
    };

    auto result = algorithm->verify(*parameters, *key, signature, data, WTFMove(successCallback), WTFMove(failureCallback));
    if (result.hasException()) {
        propagateException(state, scope, result.releaseException());
        return { };
    }

    return promise;
}
JSValue JSWebKitSubtleCrypto::wrapKey(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 4)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto keyFormat = cryptoKeyFormatFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(1));
    if (!key)
        return throwTypeError(&state, scope);

    RefPtr<CryptoKey> wrappingKey = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(2));
    if (!key)
        return throwTypeError(&state, scope);

    if (!wrappingKey->allows(CryptoKeyUsageWrapKey)) {
        wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'wrapKey'"));
        throwNotSupportedError(state, scope);
        return jsUndefined();
    }

    auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(3));
    RETURN_IF_EXCEPTION(scope, { });

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForEncrypt(state, scope, algorithm->identifier(), state.uncheckedArgument(3));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();

    auto exportSuccessCallback = [keyFormat, algorithm, parameters, wrappingKey, wrapper](const Vector<uint8_t>& exportedKeyData) mutable {
        auto encryptSuccessCallback = [wrapper](const Vector<uint8_t>& encryptedData) mutable {
            fulfillPromiseWithArrayBuffer(wrapper.releaseNonNull(), encryptedData.data(), encryptedData.size());
        };
        auto encryptFailureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
        };
        auto result = algorithm->encryptForWrapKey(*parameters, *wrappingKey, std::make_pair(exportedKeyData.data(), exportedKeyData.size()), WTFMove(encryptSuccessCallback), WTFMove(encryptFailureCallback));
        if (result.hasException()) {
            // FIXME: Report failure details to console, and possibly to calling script once there is a standardized way to pass errors to WebCrypto promise reject functions.
            wrapper->reject(); // FIXME: This should reject with an Exception.
        }
    };

    auto exportFailureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    WebCore::exportKey(state, keyFormat, *key, WTFMove(exportSuccessCallback), WTFMove(exportFailureCallback));

    return promise;
}
JSValue JSXSLTProcessor::setParameter(ExecState& state)
{
    if (state.argument(1).isUndefinedOrNull() || state.argument(2).isUndefinedOrNull())
        return jsUndefined(); // Throw exception?
    String namespaceURI = state.uncheckedArgument(0).toString(&state)->value(&state);
    String localName = state.uncheckedArgument(1).toString(&state)->value(&state);
    String value = state.uncheckedArgument(2).toString(&state)->value(&state);
    wrapped().setParameter(namespaceURI, localName, value);
    return jsUndefined();
}
JSValue JSCommandLineAPIHost::inspect(ExecState& state)
{
    if (state.argumentCount() >= 2) {
        Deprecated::ScriptValue object(state.vm(), state.uncheckedArgument(0));
        Deprecated::ScriptValue hints(state.vm(), state.uncheckedArgument(1));
        wrapped().inspectImpl(object.toInspectorValue(&state), hints.toInspectorValue(&state));
    }

    return jsUndefined();
}
JSValue JSWebKitSubtleCrypto::generateKey(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 1)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto algorithm = createAlgorithmFromJSValue(state, state.uncheckedArgument(0));
    ASSERT(scope.exception() || algorithm);
    if (!algorithm)
        return jsUndefined();

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForGenerateKey(&state, algorithm->identifier(), state.uncheckedArgument(0));
    ASSERT(scope.exception() || parameters);
    if (!parameters)
        return jsUndefined();

    bool extractable = false;
    if (state.argumentCount() >= 2) {
        extractable = state.uncheckedArgument(1).toBoolean(&state);
        RETURN_IF_EXCEPTION(scope, JSValue());
    }

    CryptoKeyUsageBitmap keyUsages = 0;
    if (state.argumentCount() >= 3) {
        auto success = cryptoKeyUsagesFromJSValue(state, state.argument(2), keyUsages);
        ASSERT(scope.exception() || success);
        if (!success)
            return jsUndefined();
    }

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](CryptoKey* key, CryptoKeyPair* keyPair) mutable {
        ASSERT(key || keyPair);
        ASSERT(!key || !keyPair);
        if (key)
            wrapper->resolve(key);
        else
            wrapper->resolve(keyPair);
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(nullptr);
    };

    auto result = algorithm->generateKey(*parameters, extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback), *scriptExecutionContextFromExecState(&state));
    if (result.hasException()) {
        propagateException(state, scope, result.releaseException());
        return { };
    }

    return promise;
}
Beispiel #11
0
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)));
}
Beispiel #12
0
static inline void documentWrite(ExecState& state, JSHTMLDocument* thisDocument, NewlineRequirement addNewline)
{
    HTMLDocument* document = &thisDocument->wrapped();
    // DOM only specifies single string argument, but browsers allow multiple or no arguments.

    size_t size = state.argumentCount();

    String firstString = state.argument(0).toString(&state)->value(&state);
    SegmentedString segmentedString = firstString;
    if (size != 1) {
        if (!size)
            segmentedString.clear();
        else {
            for (size_t i = 1; i < size; ++i) {
                String subsequentString = state.uncheckedArgument(i).toString(&state)->value(&state);
                segmentedString.append(SegmentedString(subsequentString));
            }
        }
    }
    if (addNewline)
        segmentedString.append(SegmentedString(String(&newlineCharacter, 1)));

    Document* activeDocument = findCallingDocument(state);
    document->write(segmentedString, activeDocument);
}
JSValue JSCommandLineAPIHost::getEventListeners(ExecState& state)
{
    if (state.argumentCount() < 1)
        return jsUndefined();

    JSValue value = state.uncheckedArgument(0);
    if (!value.isObject() || value.isNull())
        return jsUndefined();

    Node* node = JSNode::toWrapped(value);
    if (!node)
        return jsUndefined();

    Vector<EventListenerInfo> listenersArray;
    wrapped().getEventListenersImpl(node, listenersArray);

    JSObject* result = constructEmptyObject(&state);
    for (size_t i = 0; i < listenersArray.size(); ++i) {
        JSArray* listeners = getJSListenerFunctions(state, &node->document(), listenersArray[i]);
        if (!listeners->length())
            continue;
        AtomicString eventType = listenersArray[i].eventType;
        result->putDirect(state.vm(), Identifier::fromString(&state, eventType.impl()), JSValue(listeners));
    }

    return result;
}
JSValue JSWebKitSubtleCrypto::verify(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 4)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForVerify(state, scope, algorithm->identifier(), state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<CryptoKey> key = JSCryptoKey::toWrapped(vm, state.uncheckedArgument(1));
    if (!key)
        return throwTypeError(&state, scope);

    if (!key->allows(CryptoKeyUsageVerify)) {
        wrapped().document()->addConsoleMessage(MessageSource::JS, MessageLevel::Error, ASCIILiteral("Key usages do not include 'verify'"));
        throwNotSupportedError(state, scope);
        return jsUndefined();
    }

    auto signature = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(2));
    RETURN_IF_EXCEPTION(scope, { });

    auto data = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(3));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](bool result) mutable {
        wrapper->resolve<IDLBoolean>(result);
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    auto result = algorithm->verify(*parameters, *key, signature, data, WTFMove(successCallback), WTFMove(failureCallback));
    if (result.hasException()) {
        propagateException(state, scope, result.releaseException());
        return { };
    }

    return promise;
}
JSValue JSWebKitSubtleCrypto::importKey(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 3)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto keyFormat = cryptoKeyFormatFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    auto data = cryptoOperationDataFromJSValue(state, scope, state.uncheckedArgument(1));
    RETURN_IF_EXCEPTION(scope, { });

    RefPtr<CryptoAlgorithm> algorithm;
    RefPtr<CryptoAlgorithmParametersDeprecated> parameters;
    if (!state.uncheckedArgument(2).isNull()) {
        algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(2));
        RETURN_IF_EXCEPTION(scope, { });

        parameters = JSCryptoAlgorithmDictionary::createParametersForImportKey(state, scope, algorithm->identifier(), state.uncheckedArgument(2));
        RETURN_IF_EXCEPTION(scope, { });
    }

    bool extractable = state.argument(3).toBoolean(&state);
    RETURN_IF_EXCEPTION(scope, JSValue());

    CryptoKeyUsageBitmap keyUsages = 0;
    if (state.argumentCount() >= 5) {
        keyUsages = cryptoKeyUsagesFromJSValue(state, scope, state.uncheckedArgument(4));
        RETURN_IF_EXCEPTION(scope, { });
    }

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](CryptoKey& result) mutable {
        wrapper->resolve<IDLInterface<CryptoKey>>(result);
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    WebCore::importKey(state, keyFormat, data, WTFMove(algorithm), WTFMove(parameters), extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback));
    RETURN_IF_EXCEPTION(scope, JSValue());

    return promise;
}
JSValue JSWebKitSubtleCrypto::generateKey(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (state.argumentCount() < 1)
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    auto algorithm = createAlgorithmFromJSValue(state, scope, state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    auto parameters = JSCryptoAlgorithmDictionary::createParametersForGenerateKey(state, scope, algorithm->identifier(), state.uncheckedArgument(0));
    RETURN_IF_EXCEPTION(scope, { });

    bool extractable = state.argument(1).toBoolean(&state);
    RETURN_IF_EXCEPTION(scope, { });

    CryptoKeyUsageBitmap keyUsages = 0;
    if (state.argumentCount() >= 3) {
        keyUsages = cryptoKeyUsagesFromJSValue(state, scope, state.uncheckedArgument(2));
        RETURN_IF_EXCEPTION(scope, { });
    }

    RefPtr<DeferredPromise> wrapper = createDeferredPromise(state, domWindow());
    auto promise = wrapper->promise();
    auto successCallback = [wrapper](KeyOrKeyPair&& keyOrKeyPair) mutable {
        WTF::switchOn(keyOrKeyPair,
            [&wrapper] (RefPtr<CryptoKey>& key) {
                wrapper->resolve<IDLInterface<CryptoKey>>(*key);
            },
            [&wrapper] (CryptoKeyPair& keyPair) {
                wrapper->resolve<IDLDictionary<CryptoKeyPair>>(keyPair);
            }
        );
    };
    auto failureCallback = [wrapper]() mutable {
        wrapper->reject(); // FIXME: This should reject with an Exception.
    };

    auto result = algorithm->generateKey(*parameters, extractable, keyUsages, WTFMove(successCallback), WTFMove(failureCallback), *scriptExecutionContextFromExecState(&state));
    if (result.hasException()) {
        propagateException(state, scope, result.releaseException());
        return { };
    }

    return promise;
}
JSValue JSWebGL2RenderingContext::getIndexedParameter(ExecState& exec)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (exec.argumentCount() != 2)
        return throwException(&exec, scope, createNotEnoughArgumentsError(&exec));

    WebGL2RenderingContext& context = wrapped();
    unsigned pname = exec.uncheckedArgument(0).toInt32(&exec);
    if (exec.hadException())
        return jsUndefined();
    unsigned index = exec.uncheckedArgument(1).toInt32(&exec);
    if (exec.hadException())
        return jsUndefined();
    WebGLGetInfo info = context.getIndexedParameter(pname, index);
    return toJS(&exec, globalObject(), info);
}
Beispiel #18
0
JSValue JSNode::insertBefore(ExecState& state)
{
    if (UNLIKELY(state.argumentCount() < 2))
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));

    JSValue newChildValue = state.uncheckedArgument(0);
    auto* newChild = JSNode::toWrapped(newChildValue);
    if (UNLIKELY(!newChild))
        return JSValue::decode(throwArgumentTypeError(state, 0, "node", "Node", "insertBefore", "Node"));

    ExceptionCode ec = 0;
    if (UNLIKELY(!wrapped().insertBefore(*newChild, JSNode::toWrapped(state.uncheckedArgument(1)), ec))) {
        setDOMException(&state, ec);
        return jsUndefined();
    }

    ASSERT(!ec);
    return newChildValue;
}
JSValue JSCommandLineAPIHost::storageId(ExecState& state)
{
    if (state.argumentCount() < 1)
        return jsUndefined();

    Storage* storage = JSStorage::toWrapped(state.uncheckedArgument(0));
    if (storage)
        return jsStringWithCache(&state, wrapped().storageIdImpl(storage));

    return jsUndefined();
}
JSValue JSCommandLineAPIHost::databaseId(ExecState& state)
{
    if (state.argumentCount() < 1)
        return jsUndefined();

    Database* database = JSDatabase::toWrapped(state.uncheckedArgument(0));
    if (database)
        return jsStringWithCache(&state, wrapped().databaseIdImpl(database));

    return jsUndefined();
}
JSValue JSWebGLRenderingContextBase::getShaderParameter(ExecState& state)
{
    if (state.argumentCount() != 2)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    
    ExceptionCode ec = 0;
    WebGLRenderingContextBase& context = wrapped();
    if (!state.uncheckedArgument(0).isUndefinedOrNull() && !state.uncheckedArgument(0).inherits(JSWebGLShader::info()))
        return throwTypeError(&state);
    WebGLShader* shader = JSWebGLShader::toWrapped(state.uncheckedArgument(0));
    unsigned pname = state.uncheckedArgument(1).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    WebGLGetInfo info = context.getShaderParameter(shader, pname, ec);
    if (ec) {
        setDOMException(&state, ec);
        return jsUndefined();
    }
    return toJS(&state, globalObject(), info);
}
JSValue JSWebGLRenderingContextBase::getUniform(ExecState& state)
{
    if (state.argumentCount() != 2)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    
    ExceptionCode ec = 0;
    WebGLRenderingContextBase& context = wrapped();
    WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0));
    if (!program && !state.uncheckedArgument(0).isUndefinedOrNull())
        return throwTypeError(&state);
    WebGLUniformLocation* location = JSWebGLUniformLocation::toWrapped(state.uncheckedArgument(1));
    if (!location && !state.uncheckedArgument(1).isUndefinedOrNull())
        return throwTypeError(&state);
    WebGLGetInfo info = context.getUniform(program, location, ec);
    if (ec) {
        setDOMException(&state, ec);
        return jsUndefined();
    }
    return toJS(&state, globalObject(), info);
}
JSValue JSWebGLRenderingContextBase::getExtension(ExecState& state)
{
    if (state.argumentCount() < 1)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    
    WebGLRenderingContextBase& context = wrapped();
    const String name = state.uncheckedArgument(0).toString(&state)->value(&state);
    if (state.hadException())
        return jsUndefined();
    WebGLExtension* extension = context.getExtension(name);
    return toJS(&state, globalObject(), extension);
}
JSValue JSDocument::createTouchList(ExecState& state)
{
    auto touchList = TouchList::create();

    for (size_t i = 0; i < state.argumentCount(); ++i) {
        auto* item = JSTouch::toWrapped(state.uncheckedArgument(i));
        if (!item)
            return JSValue::decode(throwArgumentTypeError(state, i, "touches", "Document", "createTouchList", "Touch"));

        touchList->append(*item);
    }
    return toJSNewlyCreated(&state, globalObject(), WTFMove(touchList));
}
JSValue JSWebGLRenderingContextBase::getAttachedShaders(ExecState& state)
{
    if (state.argumentCount() < 1)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    ExceptionCode ec = 0;
    WebGLRenderingContextBase& context = wrapped();
    WebGLProgram* program = JSWebGLProgram::toWrapped(state.uncheckedArgument(0));
    if (!program && !state.uncheckedArgument(0).isUndefinedOrNull())
        return throwTypeError(&state);
    Vector<RefPtr<WebGLShader>> shaders;
    bool succeed = context.getAttachedShaders(program, shaders, ec);
    if (ec) {
        setDOMException(&state, ec);
        return jsNull();
    }
    if (!succeed)
        return jsNull();
    JSC::MarkedArgumentBuffer list;
    for (size_t ii = 0; ii < shaders.size(); ++ii)
        list.append(toJS(&state, globalObject(), shaders[ii].get()));
    return constructArray(&state, 0, globalObject(), list);
}
JSValue JSHTMLAllCollection::item(ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (UNLIKELY(state.argumentCount() < 1))
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    String argument = state.uncheckedArgument(0).toWTFString(&state);
    if (Optional<uint32_t> index = parseIndex(*argument.impl()))
        return toJS(&state, globalObject(), wrapped().item(index.value()));
    return namedItems(state, this, Identifier::fromString(&state, argument));
}
Beispiel #27
0
static JSValue handlePostMessage(DOMWindow& impl, ExecState& state)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (UNLIKELY(state.argumentCount() < 2))
        return throwException(&state, scope, createNotEnoughArgumentsError(&state));

    Vector<RefPtr<MessagePort>> messagePorts;
    Vector<RefPtr<JSC::ArrayBuffer>> arrayBuffers;

    // This function has variable arguments and can be:
    // Per current spec:
    //   postMessage(message, targetOrigin)
    //   postMessage(message, targetOrigin, {sequence of transferrables})
    // Legacy non-standard implementations in webkit allowed:
    //   postMessage(message, {sequence of transferrables}, targetOrigin);
    int targetOriginArgIndex = 1;
    if (state.argumentCount() > 2) {
        int transferablesArgIndex = 2;
        if (state.uncheckedArgument(2).isString()) {
            targetOriginArgIndex = 2;
            transferablesArgIndex = 1;
        }
        extractTransferables(state, state.argument(transferablesArgIndex), messagePorts, arrayBuffers);
    }
    RETURN_IF_EXCEPTION(scope, JSValue());

    auto message = SerializedScriptValue::create(state, state.uncheckedArgument(0), messagePorts, WTFMove(arrayBuffers));
    RETURN_IF_EXCEPTION(scope, JSValue());

    String targetOrigin = convert<IDLNullable<IDLUSVString>>(state, state.uncheckedArgument(targetOriginArgIndex));
    RETURN_IF_EXCEPTION(scope, JSValue());

    propagateException(state, scope, impl.postMessage(message.releaseNonNull(), WTFMove(messagePorts), targetOrigin, callerDOMWindow(&state)));

    return jsUndefined();
}
static JSValue getObjectParameter(JSWebGLRenderingContextBase* obj, ExecState& state, ObjectType objectType)
{
    if (state.argumentCount() != 2)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    
    ExceptionCode ec = 0;
    WebGLRenderingContextBase& context = obj->wrapped();
    unsigned target = state.uncheckedArgument(0).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    unsigned pname = state.uncheckedArgument(1).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    WebGLGetInfo info;
    switch (objectType) {
    case kBuffer:
        info = context.getBufferParameter(target, pname, ec);
        break;
    case kRenderbuffer:
        info = context.getRenderbufferParameter(target, pname, ec);
        break;
    case kTexture:
        info = context.getTexParameter(target, pname, ec);
        break;
    case kVertexAttrib:
        // target => index
        info = context.getVertexAttrib(target, pname, ec);
        break;
    default:
        notImplemented();
        break;
    }
    if (ec) {
        setDOMException(&state, ec);
        return jsUndefined();
    }
    return toJS(&state, obj->globalObject(), info);
}
JSValue JSWebGLRenderingContextBase::getFramebufferAttachmentParameter(ExecState& state)
{
    if (state.argumentCount() != 3)
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));
    
    ExceptionCode ec = 0;
    WebGLRenderingContextBase& context = wrapped();
    unsigned target = state.uncheckedArgument(0).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    unsigned attachment = state.uncheckedArgument(1).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    unsigned pname = state.uncheckedArgument(2).toInt32(&state);
    if (state.hadException())
        return jsUndefined();
    WebGLGetInfo info = context.getFramebufferAttachmentParameter(target, attachment, pname, ec);
    if (ec) {
        setDOMException(&state, ec);
        return jsUndefined();
    }
    return toJS(&state, globalObject(), info);
}
Beispiel #30
0
JSValue JSNode::replaceChild(ExecState& state)
{
    if (UNLIKELY(state.argumentCount() < 2))
        return state.vm().throwException(&state, createNotEnoughArgumentsError(&state));

    auto* newChild = JSNode::toWrapped(state.uncheckedArgument(0));
    JSValue oldChildValue = state.uncheckedArgument(1);
    auto* oldChild = JSNode::toWrapped(oldChildValue);
    if (UNLIKELY(!newChild || !oldChild)) {
        if (!newChild)
            return JSValue::decode(throwArgumentTypeError(state, 0, "node", "Node", "replaceChild", "Node"));
        return JSValue::decode(throwArgumentTypeError(state, 1, "child", "Node", "replaceChild", "Node"));
    }

    ExceptionCode ec = 0;
    if (UNLIKELY(!wrapped().replaceChild(*newChild, *oldChild, ec))) {
        setDOMException(&state, ec);
        return jsUndefined();
    }

    ASSERT(!ec);
    return oldChildValue;
}