EncodedJSValue JSC_HOST_CALL moduleLoaderPrototypeRequestedModules(ExecState* exec)
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSModuleRecord* moduleRecord = jsDynamicCast<JSModuleRecord*>(vm, exec->argument(0));
    if (!moduleRecord) {
        scope.release();
        return JSValue::encode(constructEmptyArray(exec, nullptr));
    }

    JSArray* result = constructEmptyArray(exec, nullptr, moduleRecord->requestedModules().size());
    RETURN_IF_EXCEPTION(scope, encodedJSValue());
    size_t i = 0;
    for (auto& key : moduleRecord->requestedModules()) {
        result->putDirectIndex(exec, i++, jsString(exec, key.get()));
        RETURN_IF_EXCEPTION(scope, encodedJSValue());
    }
    return JSValue::encode(result);
}
EncodedJSValue JSC_HOST_CALL boundFunctionCall(ExecState* exec)
{
    JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->callee());

    ASSERT(isJSArray(boundFunction->boundArgs())); // Currently this is true!
    JSArray* boundArgs = asArray(boundFunction->boundArgs());

    MarkedArgumentBuffer args;
    for (unsigned i = 0; i < boundArgs->length(); ++i)
        args.append(boundArgs->getIndex(i));
    for (unsigned i = 0; i < exec->argumentCount(); ++i)
        args.append(exec->argument(i));

    JSObject* targetFunction = boundFunction->targetFunction();
    CallData callData;
    CallType callType = getCallData(targetFunction, callData);
    ASSERT(callType != CallTypeNone);
    return JSValue::encode(call(exec, targetFunction, callType, callData, boundFunction->boundThis(), args));
}
Example #3
0
    void finishCreation(JSGlobalData& globalData, const Vector<String>& arguments)
    {
        Base::finishCreation(globalData);
        
        addFunction(globalData, "debug", functionDebug, 1);
        addFunction(globalData, "describe", functionDescribe, 1);
        addFunction(globalData, "print", functionPrint, 1);
        addFunction(globalData, "quit", functionQuit, 0);
        addFunction(globalData, "gc", functionGC, 0);
#ifndef NDEBUG
        addFunction(globalData, "dumpCallFrame", functionDumpCallFrame, 0);
        addFunction(globalData, "releaseExecutableMemory", functionReleaseExecutableMemory, 0);
#endif
        addFunction(globalData, "version", functionVersion, 1);
        addFunction(globalData, "run", functionRun, 1);
        addFunction(globalData, "load", functionLoad, 1);
        addFunction(globalData, "checkSyntax", functionCheckSyntax, 1);
        addFunction(globalData, "jscStack", functionJSCStack, 1);
#if !defined(__LB_SHELL__)
        addFunction(globalData, "readline", functionReadline, 0);
#endif
        addFunction(globalData, "preciseTime", functionPreciseTime, 0);
#if ENABLE(SAMPLING_FLAGS)
        addFunction(globalData, "setSamplingFlags", functionSetSamplingFlags, 1);
        addFunction(globalData, "clearSamplingFlags", functionClearSamplingFlags, 1);
#endif
        
        addConstructableFunction(globalData, "Uint8Array", constructJSUint8Array, 1);
        addConstructableFunction(globalData, "Uint8ClampedArray", constructJSUint8ClampedArray, 1);
        addConstructableFunction(globalData, "Uint16Array", constructJSUint16Array, 1);
        addConstructableFunction(globalData, "Uint32Array", constructJSUint32Array, 1);
        addConstructableFunction(globalData, "Int8Array", constructJSInt8Array, 1);
        addConstructableFunction(globalData, "Int16Array", constructJSInt16Array, 1);
        addConstructableFunction(globalData, "Int32Array", constructJSInt32Array, 1);
        addConstructableFunction(globalData, "Float32Array", constructJSFloat32Array, 1);
        addConstructableFunction(globalData, "Float64Array", constructJSFloat64Array, 1);

        JSArray* array = constructEmptyArray(globalExec(), 0);
        for (size_t i = 0; i < arguments.size(); ++i)
            array->putDirectIndex(globalExec(), i, jsString(globalExec(), arguments[i]));
        putDirect(globalData, Identifier(globalExec(), "arguments"), array);
    }
// 15.3.4.5 Function.prototype.bind (thisArg [, arg1 [, arg2, ...]])
EncodedJSValue JSC_HOST_CALL functionProtoFuncBind(ExecState* exec)
{
    JSGlobalObject* globalObject = exec->callee()->globalObject();

    // Let Target be the this value.
    JSValue target = exec->hostThisValue();

    // If IsCallable(Target) is false, throw a TypeError exception.
    CallData callData;
    CallType callType = getCallData(target, callData);
    if (callType == CallTypeNone)
        return throwVMTypeError(exec);
    // Primitive values are not callable.
    ASSERT(target.isObject());
    JSObject* targetObject = asObject(target);

    // Let A be a new (possibly empty) internal list of all of the argument values provided after thisArg (arg1, arg2 etc), in order.
    size_t numBoundArgs = exec->argumentCount() > 1 ? exec->argumentCount() - 1 : 0;
    JSArray* boundArgs = JSArray::tryCreateUninitialized(exec->globalData(), globalObject->arrayStructure(), numBoundArgs);
    if (!boundArgs)
        return JSValue::encode(throwOutOfMemoryError(exec));

    for (size_t i = 0; i < numBoundArgs; ++i)
        boundArgs->initializeIndex(exec->globalData(), i, exec->argument(i + 1));
    boundArgs->completeInitialization(numBoundArgs);

    // If the [[Class]] internal property of Target is "Function", then ...
    // Else set the length own property of F to 0.
    unsigned length = 0;
    if (targetObject->inherits(&JSFunction::s_info)) {
        ASSERT(target.get(exec, exec->propertyNames().length).isNumber());
        // a. Let L be the length property of Target minus the length of A.
        // b. Set the length own property of F to either 0 or L, whichever is larger.
        unsigned targetLength = (unsigned)target.get(exec, exec->propertyNames().length).asNumber();
        if (targetLength > numBoundArgs)
            length = targetLength - numBoundArgs;
    }

    Identifier name(exec, target.get(exec, exec->propertyNames().name).toString(exec)->value(exec));

    return JSValue::encode(JSBoundFunction::create(exec, globalObject, targetObject, exec->argument(0), boundArgs, length, name));
}
Example #5
0
EncodedJSValue JSC_HOST_CALL boundFunctionConstruct(ExecState* exec)
{
    JSBoundFunction* boundFunction = jsCast<JSBoundFunction*>(exec->jsCallee());

    JSArray* boundArgs = boundFunction->boundArgs();

    MarkedArgumentBuffer args;
    if (boundArgs) {
        for (unsigned i = 0; i < boundArgs->length(); ++i)
            args.append(boundArgs->getIndexQuickly(i));
    }
    for (unsigned i = 0; i < exec->argumentCount(); ++i)
        args.append(exec->uncheckedArgument(i));

    JSObject* targetFunction = boundFunction->targetFunction();
    ConstructData constructData;
    ConstructType constructType = getConstructData(targetFunction, constructData);
    ASSERT(constructType != ConstructType::None);
    return JSValue::encode(construct(exec, targetFunction, constructType, constructData, args));
}
static EncodedJSValue JSC_HOST_CALL promiseAllCountdownFunction(ExecState* exec)
{
    JSValue x = exec->argument(0);
    VM& vm = exec->vm();
    JSObject* F = exec->callee();

    // 1. Let 'index' be the value of F's [[Index]] internal slot.
    uint32_t index = F->get(exec, vm.propertyNames->indexPrivateName).asUInt32();

    // 2. Let 'values' be the value of F's [[Values]] internal slot..
    JSArray* values = jsCast<JSArray*>(F->get(exec, vm.propertyNames->valuesPrivateName));

    // 3. Let 'deferred' be the value of F's [[Deferred]] internal slot.
    JSPromiseDeferred* deferred = jsCast<JSPromiseDeferred*>(F->get(exec, vm.propertyNames->deferredPrivateName));

    // 4. Let 'countdownHolder' be the value of F's [[CountdownHolder]] internal slot.
    NumberObject* countdownHolder = jsCast<NumberObject*>(F->get(exec, vm.propertyNames->countdownHolderPrivateName));

    // 5. Let 'result' be the result of calling the [[DefineOwnProperty]] internal method
    //    of 'values' with arguments 'index' and Property Descriptor { [[Value]]: x,
    //    [[Writable]]: true, [[Enumerable]]: true, [[Configurable]]: true }.
    values->putDirectIndex(exec, index, x);

    // 6. RejectIfAbrupt(result, deferred).
    if (exec->hadException())
        abruptRejection(exec, deferred);

    // 7. Set countdownHolder.[[Countdown]] to countdownHolder.[[Countdown]] - 1.
    uint32_t newCountdownValue = countdownHolder->internalValue().asUInt32() - 1;
    countdownHolder->setInternalValue(vm, JSValue(newCountdownValue));

    // 8. If countdownHolder.[[Countdown]] is 0,
    if (!newCountdownValue) {
        // i. Return the result of calling the [[Call]] internal method of deferred.[[Resolve]]
        //    with undefined as thisArgument and a List containing 'values' as argumentsList.
        performDeferredResolve(exec, deferred, values);
    }

    // 9. Return.
    return JSValue::encode(jsUndefined());
}
static JSArray* getJSListenerFunctions(ExecState* exec, Document* document, const EventListenerInfo& listenerInfo)
{
    JSArray* result = constructEmptyArray(exec);
    size_t handlersCount = listenerInfo.eventListenerVector.size();
    for (size_t i = 0, outputIndex = 0; i < handlersCount; ++i) {
        const JSEventListener* jsListener = JSEventListener::cast(listenerInfo.eventListenerVector[i].listener.get());
        if (!jsListener) {
            ASSERT_NOT_REACHED();
            continue;
        }
        // Hide listeners from other contexts.
        if (jsListener->isolatedWorld() != currentWorld(exec))
            continue;
        JSObject* function = jsListener->jsFunction(document);
        JSObject* listenerEntry = constructEmptyObject(exec);
        listenerEntry->putDirect(exec->globalData(), Identifier(exec, "listener"), function);
        listenerEntry->putDirect(exec->globalData(), Identifier(exec, "useCapture"), jsBoolean(listenerInfo.eventListenerVector[i].useCapture));
        result->putDirectIndex(exec, outputIndex++, JSValue(listenerEntry));
    }
    return result;
}
Example #8
0
JSArray* createRegExpMatchesArray(ExecState* exec, JSString* input, RegExp* regExp, MatchResult result)
{
    ASSERT(result);
    VM& vm = exec->vm();
    JSArray* array = JSArray::tryCreateUninitialized(vm, exec->lexicalGlobalObject()->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), regExp->numSubpatterns() + 1);
    RELEASE_ASSERT(array);

    SamplingRegion samplingRegion("Reifying substring properties");

    array->initializeIndex(vm, 0, jsSubstring(exec, input, result.start, result.end - result.start), ArrayWithContiguous);

    if (unsigned numSubpatterns = regExp->numSubpatterns()) {
        Vector<int, 32> subpatternResults;
        int position = regExp->match(vm, input->value(exec), result.start, subpatternResults);
        ASSERT_UNUSED(position, position >= 0 && static_cast<size_t>(position) == result.start);
        ASSERT(result.start == static_cast<size_t>(subpatternResults[0]));
        ASSERT(result.end == static_cast<size_t>(subpatternResults[1]));

        for (unsigned i = 1; i <= numSubpatterns; ++i) {
            int start = subpatternResults[2 * i];
            if (start >= 0)
                array->initializeIndex(vm, i, jsSubstring(exec, input, start, subpatternResults[2 * i + 1] - start), ArrayWithContiguous);
            else
                array->initializeIndex(vm, i, jsUndefined(), ArrayWithContiguous);
        }
    }

    array->putDirect(vm, vm.propertyNames->index, jsNumber(result.start));
    array->putDirect(vm, vm.propertyNames->input, input);

    return array;
}
Example #9
0
JSValue Database::toJS(ExecState* exec) const
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSObject* result = constructEmptyObject(exec);
    
    JSArray* bytecodes = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, JSValue());
    for (unsigned i = 0; i < m_bytecodes.size(); ++i)
        bytecodes->putDirectIndex(exec, i, m_bytecodes[i].toJS(exec));
    result->putDirect(vm, exec->propertyNames().bytecodes, bytecodes);
    
    JSArray* compilations = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, JSValue());
    for (unsigned i = 0; i < m_compilations.size(); ++i)
        compilations->putDirectIndex(exec, i, m_compilations[i]->toJS(exec));
    result->putDirect(vm, exec->propertyNames().compilations, compilations);
    
    JSArray* events = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, JSValue());
    for (unsigned i = 0; i < m_events.size(); ++i)
        events->putDirectIndex(exec, i, m_events[i].toJS(exec));
    result->putDirect(vm, exec->propertyNames().events, events);
    
    return result;
}
JSValue JSInspectorFrontendHost::showContextMenu(ExecState* exec)
{
    if (exec->argumentCount() < 2)
        return jsUndefined();
#if ENABLE(CONTEXT_MENUS)
    Event* event = toEvent(exec->argument(0));

    JSArray* array = asArray(exec->argument(1));
    Vector<ContextMenuItem*> items;

    for (size_t i = 0; i < array->length(); ++i) {
        JSObject* item = asObject(array->getIndex(i));
        JSValue label = item->get(exec, Identifier(exec, "label"));
        JSValue type = item->get(exec, Identifier(exec, "type"));
        JSValue id = item->get(exec, Identifier(exec, "id"));
        JSValue enabled = item->get(exec, Identifier(exec, "enabled"));
        JSValue checked = item->get(exec, Identifier(exec, "checked"));
        if (!type.isString())
            continue;

        String typeString = ustringToString(type.toString(exec)->value(exec));
        if (typeString == "separator") {
            items.append(new ContextMenuItem(SeparatorType,
                                             ContextMenuItemCustomTagNoAction,
                                             String()));
        } else {
            ContextMenuAction typedId = static_cast<ContextMenuAction>(ContextMenuItemBaseCustomTag + id.toInt32(exec));
            ContextMenuItem* menuItem = new ContextMenuItem((typeString == "checkbox" ? CheckableActionType : ActionType), typedId, ustringToString(label.toString(exec)->value(exec)));
            if (!enabled.isUndefined())
                menuItem->setEnabled(enabled.toBoolean(exec));
            if (!checked.isUndefined())
                menuItem->setChecked(checked.toBoolean(exec));
            items.append(menuItem);
        }
    }

    impl()->showContextMenu(event, items);
#endif
    return jsUndefined();
}
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()));
}
void ArrayAllocationProfile::updateIndexingType()
{
    // This is awkwardly racy but totally sound even when executed concurrently. The
    // worst cases go something like this:
    //
    // - Two threads race to execute this code; one of them succeeds in updating the
    //   m_currentIndexingType and the other either updates it again, or sees a null
    //   m_lastArray; if it updates it again then at worst it will cause the profile
    //   to "forget" some array. That's still sound, since we don't promise that
    //   this profile is a reflection of any kind of truth.
    //
    // - A concurrent thread reads m_lastArray, but that array is now dead. While
    //   it's possible for that array to no longer be reachable, it cannot actually
    //   be freed, since we require the GC to wait until all concurrent JITing
    //   finishes.
    
    JSArray* lastArray = m_lastArray;
    if (!lastArray)
        return;
    m_currentIndexingType = leastUpperBoundOfIndexingTypes(m_currentIndexingType, lastArray->structure()->indexingType());
    m_lastArray = 0;
}
Example #13
0
JSValue Compilation::toJS(ExecState* exec) const
{
    JSObject* result = constructEmptyObject(exec);
    
    result->putDirect(exec->globalData(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
    result->putDirect(exec->globalData(), exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind))));
    
    JSArray* profiledBytecodes = constructEmptyArray(exec, 0);
    for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i)
        profiledBytecodes->putDirectIndex(exec, i, m_profiledBytecodes[i].toJS(exec));
    result->putDirect(exec->globalData(), exec->propertyNames().profiledBytecodes, profiledBytecodes);
    
    JSArray* descriptions = constructEmptyArray(exec, 0);
    for (unsigned i = 0; i < m_descriptions.size(); ++i)
        descriptions->putDirectIndex(exec, i, m_descriptions[i].toJS(exec));
    result->putDirect(exec->globalData(), exec->propertyNames().descriptions, descriptions);
    
    JSArray* counters = constructEmptyArray(exec, 0);
    HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator end = m_counters.end();
    for (HashMap<OriginStack, OwnPtr<ExecutionCounter> >::const_iterator iter = m_counters.begin(); iter != end; ++iter) {
        JSObject* counterEntry = constructEmptyObject(exec);
        counterEntry->putDirect(exec->globalData(), exec->propertyNames().origin, iter->key.toJS(exec));
        counterEntry->putDirect(exec->globalData(), exec->propertyNames().executionCount, jsNumber(iter->value->count()));
        counters->push(exec, counterEntry);
    }
    result->putDirect(exec->globalData(), exec->propertyNames().counters, counters);
    
    JSArray* exitSites = constructEmptyArray(exec, 0);
    for (unsigned i = 0; i < m_osrExitSites.size(); ++i)
        exitSites->putDirectIndex(exec, i, m_osrExitSites[i].toJS(exec));
    result->putDirect(exec->globalData(), exec->propertyNames().osrExitSites, exitSites);
    
    JSArray* exits = constructEmptyArray(exec, 0);
    for (unsigned i = 0; i < m_osrExits.size(); ++i)
        exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec));
    result->putDirect(exec->globalData(), exec->propertyNames().osrExits, exits);
    
    return result;
}
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();
}
static RefPtr<IDBKey> createIDBKeyFromValue(ExecState* exec, JSValue value, Vector<JSArray*>& stack)
{
    if (value.isNumber() && !std::isnan(value.toNumber(exec)))
        return IDBKey::createNumber(value.toNumber(exec));
    if (value.isString())
        return IDBKey::createString(value.toString(exec)->value(exec));
    if (value.inherits(DateInstance::info()) && !std::isnan(valueToDate(exec, value)))
        return IDBKey::createDate(valueToDate(exec, value));
    if (value.isObject()) {
        JSObject* object = asObject(value);
        if (isJSArray(object) || object->inherits(JSArray::info())) {
            JSArray* array = asArray(object);
            size_t length = array->length();

            if (stack.contains(array))
                return nullptr;
            if (stack.size() >= maximumDepth)
                return nullptr;
            stack.append(array);

            Vector<RefPtr<IDBKey>> subkeys;
            for (size_t i = 0; i < length; i++) {
                JSValue item = array->getIndex(exec, i);
                RefPtr<IDBKey> subkey = createIDBKeyFromValue(exec, item, stack);
                if (!subkey)
                    subkeys.append(IDBKey::createInvalid());
                else
                    subkeys.append(subkey);
            }

            stack.removeLast();
            return IDBKey::createArray(subkeys);
        }
    }
    return nullptr;
}
static bool cryptoKeyUsagesFromJSValue(ExecState& state, JSValue value, CryptoKeyUsageBitmap& result)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    if (!isJSArray(value)) {
        throwTypeError(&state, scope);
        return false;
    }

    result = 0;

    JSArray* array = asArray(value);
    for (size_t i = 0; i < array->length(); ++i) {
        JSValue element = array->getIndex(&state, i);
        String usageString = element.toString(&state)->value(&state);
        RETURN_IF_EXCEPTION(scope, false);
        if (usageString == "encrypt")
            result |= CryptoKeyUsageEncrypt;
        else if (usageString == "decrypt")
            result |= CryptoKeyUsageDecrypt;
        else if (usageString == "sign")
            result |= CryptoKeyUsageSign;
        else if (usageString == "verify")
            result |= CryptoKeyUsageVerify;
        else if (usageString == "deriveKey")
            result |= CryptoKeyUsageDeriveKey;
        else if (usageString == "deriveBits")
            result |= CryptoKeyUsageDeriveBits;
        else if (usageString == "wrapKey")
            result |= CryptoKeyUsageWrapKey;
        else if (usageString == "unwrapKey")
            result |= CryptoKeyUsageUnwrapKey;
    }
    return true;
}
void C_AwesomiumBrowserManager::DispatchJavaScriptMethod(C_AwesomiumBrowserInstance* pBrowserInstance, std::string objectName, std::string objectMethod, std::vector<std::string> methodArguments)
{
	//WebView* pWebView = m_webViews[pWebTab];

	JSValue response = pBrowserInstance->GetWebView()->ExecuteJavascriptWithResult(WSLit(objectName.c_str()), WSLit(""));
	if (response.IsObject())
	{
		JSObject object = response.ToObject();
		JSArray arguments;

		for (auto argument : methodArguments)
			arguments.Push(WSLit(argument.c_str()));

		object.InvokeAsync(WSLit(objectMethod.c_str()), arguments);
	}

	//m_pWebBrowser->DispatchJavaScriptMethod(pWebTab, objectName, objectMethod, methodArguments);
	/*
	for (auto arg : args)
	{
	DevMsg("Argument: %s\n", arg->text.c_str());
	}
	*/
}
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();

}
Example #19
0
JSValue LiteralParser::parseArray()
{
    StackGuard guard(this);
    if (!guard.isSafe())
        return abortParse();
    JSArray* array = constructEmptyArray(m_exec);
    while (true) {
        m_lexer.next();
        JSValue value = parseExpression();
        if (m_aborted)
            return JSValue();
        if (!value)
            break;
        array->push(m_exec, value);

        if (m_lexer.currentToken().type != TokComma)
            break;
    }
    if (m_lexer.currentToken().type != TokRBracket)
        return abortParse();

    m_lexer.next();
    return array;
}
static void addUsagesToJSON(ExecState* exec, JSObject* json, CryptoKeyUsage usages)
{
    JSArray* keyOps = constructEmptyArray(exec, 0, exec->lexicalGlobalObject(), 0);

    unsigned index = 0;
    if (usages & CryptoKeyUsageSign)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("sign")));
    if (usages & CryptoKeyUsageVerify)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("verify")));
    if (usages & CryptoKeyUsageEncrypt)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("encrypt")));
    if (usages & CryptoKeyUsageDecrypt)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("decrypt")));
    if (usages & CryptoKeyUsageWrapKey)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("wrapKey")));
    if (usages & CryptoKeyUsageUnwrapKey)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("unwrapKey")));
    if (usages & CryptoKeyUsageDeriveKey)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("deriveKey")));
    if (usages & CryptoKeyUsageDeriveBits)
        keyOps->putDirectIndex(exec, index++, jsString(exec, ASCIILiteral("deriveBits")));

    json->putDirect(exec->vm(), Identifier(exec, "key_ops"), keyOps);
}
Example #21
0
// Defined in ES5.1 15.4.5.1
bool JSArray::defineOwnProperty(JSObject* object, ExecState* exec, PropertyName propertyName, const PropertyDescriptor& descriptor, bool throwException)
{
    JSArray* array = jsCast<JSArray*>(object);

    // 3. If P is "length", then
    if (propertyName == exec->propertyNames().length) {
        // All paths through length definition call the default [[DefineOwnProperty]], hence:
        // from ES5.1 8.12.9 7.a.
        if (descriptor.configurablePresent() && descriptor.configurable())
            return reject(exec, throwException, "Attempting to change configurable attribute of unconfigurable property.");
        // from ES5.1 8.12.9 7.b.
        if (descriptor.enumerablePresent() && descriptor.enumerable())
            return reject(exec, throwException, "Attempting to change enumerable attribute of unconfigurable property.");

        // a. If the [[Value]] field of Desc is absent, then
        // a.i. Return the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", Desc, and Throw as arguments.
        if (descriptor.isAccessorDescriptor())
            return reject(exec, throwException, "Attempting to change access mechanism for an unconfigurable property.");
        // from ES5.1 8.12.9 10.a.
        if (!array->isLengthWritable() && descriptor.writablePresent() && descriptor.writable())
            return reject(exec, throwException, "Attempting to change writable attribute of unconfigurable property.");
        // This descriptor is either just making length read-only, or changing nothing!
        if (!descriptor.value()) {
            if (descriptor.writablePresent())
                array->setLengthWritable(exec, descriptor.writable());
            return true;
        }
        
        // b. Let newLenDesc be a copy of Desc.
        // c. Let newLen be ToUint32(Desc.[[Value]]).
        unsigned newLen = descriptor.value().toUInt32(exec);
        // d. If newLen is not equal to ToNumber( Desc.[[Value]]), throw a RangeError exception.
        if (newLen != descriptor.value().toNumber(exec)) {
            exec->vm().throwException(exec, createRangeError(exec, ASCIILiteral("Invalid array length")));
            return false;
        }

        // Based on SameValue check in 8.12.9, this is always okay.
        // FIXME: Nothing prevents this from being called on a RuntimeArray, and the length function will always return 0 in that case.
        if (newLen == array->length()) {
            if (descriptor.writablePresent())
                array->setLengthWritable(exec, descriptor.writable());
            return true;
        }

        // e. Set newLenDesc.[[Value] to newLen.
        // f. If newLen >= oldLen, then
        // f.i. Return the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", newLenDesc, and Throw as arguments.
        // g. Reject if oldLenDesc.[[Writable]] is false.
        if (!array->isLengthWritable())
            return reject(exec, throwException, "Attempting to change value of a readonly property.");
        
        // h. If newLenDesc.[[Writable]] is absent or has the value true, let newWritable be true.
        // i. Else,
        // i.i. Need to defer setting the [[Writable]] attribute to false in case any elements cannot be deleted.
        // i.ii. Let newWritable be false.
        // i.iii. Set newLenDesc.[[Writable] to true.
        // j. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", newLenDesc, and Throw as arguments.
        // k. If succeeded is false, return false.
        // l. While newLen < oldLen repeat,
        // l.i. Set oldLen to oldLen – 1.
        // l.ii. Let deleteSucceeded be the result of calling the [[Delete]] internal method of A passing ToString(oldLen) and false as arguments.
        // l.iii. If deleteSucceeded is false, then
        if (!array->setLength(exec, newLen, throwException)) {
            // 1. Set newLenDesc.[[Value] to oldLen+1.
            // 2. If newWritable is false, set newLenDesc.[[Writable] to false.
            // 3. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", newLenDesc, and false as arguments.
            // 4. Reject.
            if (descriptor.writablePresent())
                array->setLengthWritable(exec, descriptor.writable());
            return false;
        }

        // m. If newWritable is false, then
        // i. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length",
        //    Property Descriptor{[[Writable]]: false}, and false as arguments. This call will always
        //    return true.
        if (descriptor.writablePresent())
            array->setLengthWritable(exec, descriptor.writable());
        // n. Return true.
        return true;
    }

    // 4. Else if P is an array index (15.4), then
    // a. Let index be ToUint32(P).
    if (Optional<uint32_t> optionalIndex = parseIndex(propertyName)) {
        // b. Reject if index >= oldLen and oldLenDesc.[[Writable]] is false.
        uint32_t index = optionalIndex.value();
        // FIXME: Nothing prevents this from being called on a RuntimeArray, and the length function will always return 0 in that case.
        if (index >= array->length() && !array->isLengthWritable())
            return reject(exec, throwException, "Attempting to define numeric property on array with non-writable length property.");
        // c. Let succeeded be the result of calling the default [[DefineOwnProperty]] internal method (8.12.9) on A passing P, Desc, and false as arguments.
        // d. Reject if succeeded is false.
        // e. If index >= oldLen
        // e.i. Set oldLenDesc.[[Value]] to index + 1.
        // e.ii. Call the default [[DefineOwnProperty]] internal method (8.12.9) on A passing "length", oldLenDesc, and false as arguments. This call will always return true.
        // f. Return true.
        return array->defineOwnIndexedProperty(exec, index, descriptor, throwException);
    }

    return array->JSObject::defineOwnNonIndexProperty(exec, propertyName, descriptor, throwException);
}
Example #22
0
JSValue collectMatches(VM& vm, ExecState* exec, JSString* string, const String& s, RegExpConstructor* constructor, RegExp* regExp, const FixEndFunc& fixEnd)
{
    auto scope = DECLARE_THROW_SCOPE(vm);

    MatchResult result = constructor->performMatch(vm, regExp, string, s, 0);
    if (!result)
        return jsNull();
    
    static unsigned maxSizeForDirectPath = 100000;
    
    JSArray* array = constructEmptyArray(exec, nullptr);
    if (UNLIKELY(vm.exception()))
        return jsUndefined();

    auto iterate = [&] () {
        size_t end = result.end;
        size_t length = end - result.start;
        array->push(exec, JSRopeString::createSubstringOfResolved(vm, string, result.start, length));
        if (!length)
            end = fixEnd(end);
        result = constructor->performMatch(vm, regExp, string, s, end);
    };
    
    do {
        if (array->length() >= maxSizeForDirectPath) {
            // First do a throw-away match to see how many matches we'll get.
            unsigned matchCount = 0;
            MatchResult savedResult = result;
            do {
                if (array->length() + matchCount >= MAX_STORAGE_VECTOR_LENGTH) {
                    throwOutOfMemoryError(exec, scope);
                    return jsUndefined();
                }
                
                size_t end = result.end;
                matchCount++;
                if (result.empty())
                    end = fixEnd(end);
                
                // Using RegExpConstructor::performMatch() instead of calling RegExp::match()
                // directly is a surprising but profitable choice: it means that when we do OOM, we
                // will leave the cached result in the state it ought to have had just before the
                // OOM! On the other hand, if this loop concludes that the result is small enough,
                // then the iterate() loop below will overwrite the cached result anyway.
                result = constructor->performMatch(vm, regExp, string, s, end);
            } while (result);
            
            // OK, we have a sensible number of matches. Now we can create them for reals.
            result = savedResult;
            do
                iterate();
            while (result);
            
            return array;
        }
        
        iterate();
    } while (result);
    
    return array;
}
JSValue IntlNumberFormat::formatToParts(ExecState& exec, double value)
{
    VM& vm = exec.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);

    // FormatNumberToParts (ECMA-402)
    // https://tc39.github.io/ecma402/#sec-formatnumbertoparts
    // https://tc39.github.io/ecma402/#sec-partitionnumberpattern

    if (!m_initializedNumberFormat)
        return throwTypeError(&exec, scope, "Intl.NumberFormat.prototype.formatToParts called on value that's not an object initialized as a NumberFormat"_s);

    UErrorCode status = U_ZERO_ERROR;
    auto fieldItr = std::unique_ptr<UFieldPositionIterator, UFieldPositionIteratorDeleter>(ufieldpositer_open(&status));
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to open field position iterator"_s);

    status = U_ZERO_ERROR;
    Vector<UChar, 32> result(32);
    auto resultLength = unum_formatDoubleForFields(m_numberFormat.get(), value, result.data(), result.size(), fieldItr.get(), &status);
    if (status == U_BUFFER_OVERFLOW_ERROR) {
        status = U_ZERO_ERROR;
        result.grow(resultLength);
        unum_formatDoubleForFields(m_numberFormat.get(), value, result.data(), resultLength, fieldItr.get(), &status);
    }
    if (U_FAILURE(status))
        return throwTypeError(&exec, scope, "failed to format a number."_s);

    int32_t literalFieldType = -1;
    auto literalField = IntlNumberFormatField(literalFieldType, resultLength);
    Vector<IntlNumberFormatField> fields(resultLength, literalField);
    int32_t beginIndex = 0;
    int32_t endIndex = 0;
    auto fieldType = ufieldpositer_next(fieldItr.get(), &beginIndex, &endIndex);
    while (fieldType >= 0) {
        auto size = endIndex - beginIndex;
        for (auto i = beginIndex; i < endIndex; ++i) {
            // Only override previous value if new value is more specific.
            if (fields[i].size >= size)
                fields[i] = IntlNumberFormatField(fieldType, size);
        }
        fieldType = ufieldpositer_next(fieldItr.get(), &beginIndex, &endIndex);
    }

    JSGlobalObject* globalObject = exec.jsCallee()->globalObject(vm);
    JSArray* parts = JSArray::tryCreate(vm, globalObject->arrayStructureForIndexingTypeDuringAllocation(ArrayWithContiguous), 0);
    if (!parts)
        return throwOutOfMemoryError(&exec, scope);
    unsigned index = 0;

    auto resultString = String(result.data(), resultLength);
    auto typePropertyName = Identifier::fromString(&vm, "type");
    auto literalString = jsString(&exec, "literal"_s);

    int32_t currentIndex = 0;
    while (currentIndex < resultLength) {
        auto startIndex = currentIndex;
        auto fieldType = fields[currentIndex].type;
        while (currentIndex < resultLength && fields[currentIndex].type == fieldType)
            ++currentIndex;
        auto partType = fieldType == literalFieldType ? literalString : jsString(&exec, partTypeString(UNumberFormatFields(fieldType), value));
        auto partValue = jsSubstring(&vm, resultString, startIndex, currentIndex - startIndex);
        JSObject* part = constructEmptyObject(&exec);
        part->putDirect(vm, typePropertyName, partType);
        part->putDirect(vm, vm.propertyNames->value, partValue);
        parts->putDirectIndex(&exec, index++, part);
        RETURN_IF_EXCEPTION(scope, { });
    }

    return parts;
}
Example #24
0
JSValue JSC_HOST_CALL stringProtoFuncSplit(ExecState* exec, JSObject*, JSValue thisValue, const ArgList& args)
{
    UString s = thisValue.toThisString(exec);

    JSValue a0 = args.at(0);
    JSValue a1 = args.at(1);

    JSArray* result = constructEmptyArray(exec);
    unsigned i = 0;
    int p0 = 0;
    unsigned limit = a1.isUndefined() ? 0xFFFFFFFFU : a1.toUInt32(exec);
    if (a0.isObject(&RegExpObject::info)) {
        RegExp* reg = asRegExpObject(a0)->regExp();
        if (s.isEmpty() && reg->match(s, 0) >= 0) {
            // empty string matched by regexp -> empty array
            return result;
        }
        int pos = 0;
        while (i != limit && pos < s.size()) {
            OwnArrayPtr<int> ovector;
            int mpos = reg->match(s, pos, &ovector);
            if (mpos < 0)
                break;
            int mlen = ovector[1] - ovector[0];
            pos = mpos + (mlen == 0 ? 1 : mlen);
            if (mpos != p0 || mlen) {
                result->put(exec, i++, jsSubstring(exec, s, p0, mpos - p0));
                p0 = mpos + mlen;
            }
            for (unsigned si = 1; si <= reg->numSubpatterns(); ++si) {
                int spos = ovector[si * 2];
                if (spos < 0)
                    result->put(exec, i++, jsUndefined());
                else
                    result->put(exec, i++, jsSubstring(exec, s, spos, ovector[si * 2 + 1] - spos));
            }
        }
    } else {
        UString u2 = a0.toString(exec);
        if (u2.isEmpty()) {
            if (s.isEmpty()) {
                // empty separator matches empty string -> empty array
                return result;
            }
            while (i != limit && p0 < s.size() - 1)
                result->put(exec, i++, jsSingleCharacterSubstring(exec, s, p0++));
        } else {
            int pos;
            while (i != limit && (pos = s.find(u2, p0)) >= 0) {
                result->put(exec, i++, jsSubstring(exec, s, p0, pos - p0));
                p0 = pos + u2.size();
            }
        }
    }

    // add remaining string
    if (i != limit)
        result->put(exec, i++, jsSubstring(exec, s, p0, s.size() - p0));

    return result;
}
Example #25
0
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()));
}
Example #26
0
std::unique_ptr<CryptoKeyData> JSCryptoKeySerializationJWK::keyDataRSAComponents() const
{
    Vector<uint8_t> modulus;
    Vector<uint8_t> exponent;
    Vector<uint8_t> privateExponent;

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "n", modulus)) {
        if (!m_exec->hadException())
            throwTypeError(m_exec, "Required JWK \"n\" member is missing");
        return nullptr;
    }

    if (!keySizeIsValid(modulus.size() * 8)) {
        throwTypeError(m_exec, "Key size is not valid for " + m_jwkAlgorithmName);
        return nullptr;
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "e", exponent)) {
        if (!m_exec->hadException())
            throwTypeError(m_exec, "Required JWK \"e\" member is missing");
        return nullptr;
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "d", modulus)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPublic(modulus, exponent);
    }

    CryptoKeyDataRSAComponents::PrimeInfo firstPrimeInfo;
    CryptoKeyDataRSAComponents::PrimeInfo secondPrimeInfo;
    Vector<CryptoKeyDataRSAComponents::PrimeInfo> otherPrimeInfos;
    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "p", firstPrimeInfo.primeFactor)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dp", firstPrimeInfo.factorCRTExponent)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "q", secondPrimeInfo.primeFactor)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "dq", secondPrimeInfo.factorCRTExponent)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
    }

    if (!getBigIntegerVectorFromJSON(m_exec, m_json.get(), "qi", secondPrimeInfo.factorCRTCoefficient)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivate(modulus, exponent, privateExponent);
    }

    JSArray* otherPrimeInfoJSArray;
    if (!getJSArrayFromJSON(m_exec, m_json.get(), "oth", otherPrimeInfoJSArray)) {
        if (m_exec->hadException())
            return nullptr;
        return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
    }

    for (size_t i = 0; i < otherPrimeInfoJSArray->length(); ++i) {
        CryptoKeyDataRSAComponents::PrimeInfo info;
        JSValue element = otherPrimeInfoJSArray->getIndex(m_exec, i);
        if (m_exec->hadException())
            return nullptr;
        if (!element.isObject()) {
            throwTypeError(m_exec, "JWK \"oth\" array member is not an object");
            return nullptr;
        }
        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "r", info.primeFactor)) {
            if (!m_exec->hadException())
                throwTypeError(m_exec, "Cannot get prime factor for a prime in \"oth\" dictionary");
            return nullptr;
        }
        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "d", info.factorCRTExponent)) {
            if (!m_exec->hadException())
                throwTypeError(m_exec, "Cannot get factor CRT exponent for a prime in \"oth\" dictionary");
            return nullptr;
        }
        if (!getBigIntegerVectorFromJSON(m_exec, asObject(element), "t", info.factorCRTCoefficient)) {
            if (!m_exec->hadException())
                throwTypeError(m_exec, "Cannot get factor CRT coefficient for a prime in \"oth\" dictionary");
            return nullptr;
        }
        otherPrimeInfos.append(info);
    }

    return CryptoKeyDataRSAComponents::createPrivateWithAdditionalData(modulus, exponent, privateExponent, firstPrimeInfo, secondPrimeInfo, otherPrimeInfos);
}
Example #27
0
JSValue JSInjectedScriptHost::getInternalProperties(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    VM& vm = exec->vm();
    JSValue value = exec->uncheckedArgument(0);

    if (JSPromise* promise = jsDynamicCast<JSPromise*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        switch (promise->status(exec->vm())) {
        case JSPromise::Status::Pending:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("pending"))));
            break;
        case JSPromise::Status::Fulfilled:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("resolved"))));
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
            break;
        case JSPromise::Status::Rejected:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("rejected"))));
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
            break;
        }
        // FIXME: <https://webkit.org/b/141664> Web Inspector: ES6: Improved Support for Promises - Promise Reactions
        return array;
    }

    if (JSBoundFunction* boundFunction = jsDynamicCast<JSBoundFunction*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "targetFunction", boundFunction->targetFunction()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundThis", boundFunction->boundThis()));
        if (boundFunction->boundArgs())
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundArgs", boundFunction->boundArgs()));
        return array;
    }

    if (ProxyObject* proxy = jsDynamicCast<ProxyObject*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("target"), proxy->target()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("handler"), proxy->handler()));
        return array;
    }

    if (JSObject* iteratorObject = jsDynamicCast<JSObject*>(value)) {
        if (iteratorObject->getDirect(exec->vm(), exec->vm().propertyNames->builtinNames().arrayIteratorNextIndexPrivateName())) {
            JSValue iteratedValue = iteratorObject->getDirect(exec->vm(), exec->vm().propertyNames->builtinNames().iteratedObjectPrivateName());
            JSValue kind = iteratorObject->getDirect(exec->vm(), exec->vm().propertyNames->builtinNames().arrayIteratorKindPrivateName());

            unsigned index = 0;
            JSArray* array = constructEmptyArray(exec, nullptr, 2);
            if (UNLIKELY(vm.exception()))
                return jsUndefined();
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, "array", iteratedValue));
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", kind));
            return array;
        }
    }

    if (JSArrayIterator* arrayIterator = jsDynamicCast<JSArrayIterator*>(value)) {
        String kind;
        switch (arrayIterator->kind(exec)) {
        case ArrayIterateKey:
            kind = ASCIILiteral("key");
            break;
        case ArrayIterateValue:
            kind = ASCIILiteral("value");
            break;
        case ArrayIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "array", arrayIterator->iteratedValue(exec)));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }

    if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(value)) {
        String kind;
        switch (mapIterator->kind()) {
        case MapIterateKey:
            kind = ASCIILiteral("key");
            break;
        case MapIterateValue:
            kind = ASCIILiteral("value");
            break;
        case MapIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "map", mapIterator->iteratedValue()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }
        
    if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(value)) {
        String kind;
        switch (setIterator->kind()) {
        case SetIterateKey:
            kind = ASCIILiteral("key");
            break;
        case SetIterateValue:
            kind = ASCIILiteral("value");
            break;
        case SetIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "set", setIterator->iteratedValue()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }

    if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 1);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "string", stringIterator->iteratedValue(exec)));
        return array;
    }

    if (JSPropertyNameIterator* propertyNameIterator = jsDynamicCast<JSPropertyNameIterator*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 1);
        if (UNLIKELY(vm.exception()))
            return jsUndefined();
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "object", propertyNameIterator->iteratedValue()));
        return array;
    }

    return jsUndefined();
}
JSValue Compilation::toJS(ExecState* exec) const
{
    VM& vm = exec->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSObject* result = constructEmptyObject(exec);
    RETURN_IF_EXCEPTION(scope, { });
    result->putDirect(vm, exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
    result->putDirect(vm, exec->propertyNames().compilationKind, jsString(exec, String::fromUTF8(toCString(m_kind))));

    JSArray* profiledBytecodes = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, { });
    for (unsigned i = 0; i < m_profiledBytecodes.size(); ++i) {
        auto value = m_profiledBytecodes[i].toJS(exec);
        RETURN_IF_EXCEPTION(scope, { });
        profiledBytecodes->putDirectIndex(exec, i, value);
        RETURN_IF_EXCEPTION(scope, { });
    }
    result->putDirect(vm, exec->propertyNames().profiledBytecodes, profiledBytecodes);

    JSArray* descriptions = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, { });
    for (unsigned i = 0; i < m_descriptions.size(); ++i) {
        auto value = m_descriptions[i].toJS(exec);
        RETURN_IF_EXCEPTION(scope, { });
        descriptions->putDirectIndex(exec, i, value);
        RETURN_IF_EXCEPTION(scope, { });
    }
    result->putDirect(vm, exec->propertyNames().descriptions, descriptions);

    JSArray* counters = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, { });
    for (auto it = m_counters.begin(), end = m_counters.end(); it != end; ++it) {
        JSObject* counterEntry = constructEmptyObject(exec);
        RETURN_IF_EXCEPTION(scope, { });
        auto value = it->key.toJS(exec);
        RETURN_IF_EXCEPTION(scope, { });
        counterEntry->putDirect(vm, exec->propertyNames().origin, value);
        counterEntry->putDirect(vm, exec->propertyNames().executionCount, jsNumber(it->value->count()));
        counters->push(exec, counterEntry);
        RETURN_IF_EXCEPTION(scope, { });
    }
    result->putDirect(vm, exec->propertyNames().counters, counters);

    JSArray* exitSites = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, { });
    for (unsigned i = 0; i < m_osrExitSites.size(); ++i) {
        auto value = m_osrExitSites[i].toJS(exec);
        RETURN_IF_EXCEPTION(scope, { });
        exitSites->putDirectIndex(exec, i, value);
        RETURN_IF_EXCEPTION(scope, { });
    }
    result->putDirect(vm, exec->propertyNames().osrExitSites, exitSites);

    JSArray* exits = constructEmptyArray(exec, 0);
    RETURN_IF_EXCEPTION(scope, { });
    for (unsigned i = 0; i < m_osrExits.size(); ++i) {
        exits->putDirectIndex(exec, i, m_osrExits[i].toJS(exec));
        RETURN_IF_EXCEPTION(scope, { });
    }
    result->putDirect(vm, exec->propertyNames().osrExits, exits);

    result->putDirect(vm, exec->propertyNames().numInlinedGetByIds, jsNumber(m_numInlinedGetByIds));
    result->putDirect(vm, exec->propertyNames().numInlinedPutByIds, jsNumber(m_numInlinedPutByIds));
    result->putDirect(vm, exec->propertyNames().numInlinedCalls, jsNumber(m_numInlinedCalls));
    result->putDirect(vm, exec->propertyNames().jettisonReason, jsString(exec, String::fromUTF8(toCString(m_jettisonReason))));
    if (!m_additionalJettisonReason.isNull())
        result->putDirect(vm, exec->propertyNames().additionalJettisonReason, jsString(exec, String::fromUTF8(m_additionalJettisonReason)));

    result->putDirect(vm, exec->propertyNames().uid, m_uid.toJS(exec));

    return result;
}
JSValue JSInjectedScriptHost::getInternalProperties(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    JSValue value = exec->uncheckedArgument(0);

#if ENABLE(PROMISES)
    if (JSPromise* promise = jsDynamicCast<JSPromise*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr);
        switch (promise->status(exec->vm())) {
        case JSPromise::Status::Pending:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("pending"))));
            break;
        case JSPromise::Status::Fulfilled:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("resolved"))));
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
            break;
        case JSPromise::Status::Rejected:
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("status"), jsNontrivialString(exec, ASCIILiteral("rejected"))));
            array->putDirectIndex(exec, index++, constructInternalProperty(exec, ASCIILiteral("result"), promise->result(exec->vm())));
            break;
        }
        // FIXME: <https://webkit.org/b/141664> Web Inspector: ES6: Improved Support for Promises - Promise Reactions
        return array;
    }
#endif

    if (JSBoundFunction* boundFunction = jsDynamicCast<JSBoundFunction*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 3);
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "targetFunction", boundFunction->targetFunction()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundThis", boundFunction->boundThis()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "boundArgs", boundFunction->boundArgs()));
        return array;
    }

    if (JSArrayIterator* arrayIterator = jsDynamicCast<JSArrayIterator*>(value)) {
        String kind;
        switch (arrayIterator->kind(exec)) {
        case ArrayIterateKey:
            kind = ASCIILiteral("key");
            break;
        case ArrayIterateValue:
            kind = ASCIILiteral("value");
            break;
        case ArrayIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "array", arrayIterator->iteratedValue(exec)));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }

    if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(value)) {
        String kind;
        switch (mapIterator->kind()) {
        case MapIterateKey:
            kind = ASCIILiteral("key");
            break;
        case MapIterateValue:
            kind = ASCIILiteral("value");
            break;
        case MapIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "map", mapIterator->iteratedValue()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }
        
    if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(value)) {
        String kind;
        switch (setIterator->kind()) {
        case SetIterateKey:
            kind = ASCIILiteral("key");
            break;
        case SetIterateValue:
            kind = ASCIILiteral("value");
            break;
        case SetIterateKeyValue:
            kind = ASCIILiteral("key+value");
            break;
        }
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 2);
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "set", setIterator->iteratedValue()));
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "kind", jsNontrivialString(exec, kind)));
        return array;
    }

    if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(value)) {
        unsigned index = 0;
        JSArray* array = constructEmptyArray(exec, nullptr, 1);
        array->putDirectIndex(exec, index++, constructInternalProperty(exec, "string", stringIterator->iteratedValue(exec)));
        return array;
    }

    return jsUndefined();
}
void MenuListener::OnShowPopupMenu(WebView *caller, const WebPopupMenuInfo &menu_info)
{
//	DevMsg("DISABLED FOR TESTING!\n");
//	return;

	//C_WebTab* pWebTab = g_pAnarchyManager->GetWebManager()->GetWebBrowser()->FindWebTab(caller);
	//C_WebTab* pHudWebTab = g_pAnarchyManager->GetWebManager()->GetHudWebTab();
	//WebView* pHudWebView = g_pAnarchyManager->GetWebManager()->GetWebBrowser()->FindWebView(pHudWebTab);

	C_AwesomiumBrowserInstance* pAwesomiumBrowserInstance = g_pAnarchyManager->GetAwesomiumBrowserManager()->FindAwesomiumBrowserInstance(caller);	// FIXME: This should be a general EmbeddedInstance of any type.
	C_AwesomiumBrowserInstance* pHudBrowserInstance = g_pAnarchyManager->GetAwesomiumBrowserManager()->FindAwesomiumBrowserInstance("hud");
	WebView* pHudWebView = pHudBrowserInstance->GetWebView();

	DevMsg("Pop menu detected!\n");

	std::vector<std::string> methodArguments;
	methodArguments.push_back(pAwesomiumBrowserInstance->GetId());
	methodArguments.push_back(VarArgs("%i", menu_info.bounds.x));
	methodArguments.push_back(VarArgs("%i", menu_info.bounds.y));
	methodArguments.push_back(VarArgs("%i", menu_info.bounds.width));
	methodArguments.push_back(VarArgs("%i", menu_info.bounds.height));
	methodArguments.push_back(VarArgs("%i", menu_info.item_height));
	methodArguments.push_back(VarArgs("%f", menu_info.item_font_size));
	methodArguments.push_back(VarArgs("%i", menu_info.selected_item));
	methodArguments.push_back(VarArgs("%i", menu_info.right_aligned));

	for (int i = 0; i < menu_info.items.size(); i++)
	{
		if (menu_info.items[i].type == kWebMenuItemType_Option)
			methodArguments.push_back("Option");
		else if (menu_info.items[i].type == kWebMenuItemType_CheckableOption)
			methodArguments.push_back("CheckableOption");
		else if (menu_info.items[i].type == kWebMenuItemType_Group)
			methodArguments.push_back("Group");
		else if (menu_info.items[i].type == kWebMenuItemType_Separator)
			methodArguments.push_back("Separator");

		methodArguments.push_back(WebStringToCharString(menu_info.items[i].label));
		methodArguments.push_back(WebStringToCharString(menu_info.items[i].tooltip));
		methodArguments.push_back(VarArgs("%i", menu_info.items[i].action));
		methodArguments.push_back(VarArgs("%i", menu_info.items[i].right_to_left));
		methodArguments.push_back(VarArgs("%i", menu_info.items[i].has_directional_override));
		methodArguments.push_back(VarArgs("%i", menu_info.items[i].enabled));
		methodArguments.push_back(VarArgs("%i", menu_info.items[i].checked));
	}
	
	std::string objectName = "window.arcadeHud";
	std::string objectMethod = "showPopupMenu";

	JSValue response = pHudWebView->ExecuteJavascriptWithResult(WSLit(objectName.c_str()), WSLit(""));
	if (response.IsObject())
	{
		JSObject object = response.ToObject();
		JSArray arguments;

		for (auto argument : methodArguments)
			arguments.Push(WSLit(argument.c_str()));

		object.InvokeAsync(WSLit(objectMethod.c_str()), arguments);
	}
}