JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();
    JSValue value = exec->argument(0);
    if (!value.asCell()->inherits(&JSFunction::s_info))
        return jsUndefined();
    JSFunction* function = jsCast<JSFunction*>(value);

    const SourceCode* sourceCode = function->sourceCode();
    if (!sourceCode)
        return jsUndefined();
    int lineNumber = sourceCode->firstLine();
    if (lineNumber)
        lineNumber -= 1; // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
    UString scriptId = UString::number(sourceCode->provider()->asID());

    JSObject* location = constructEmptyObject(exec);
    location->putDirect(exec->globalData(), Identifier(exec, "lineNumber"), jsNumber(lineNumber));
    location->putDirect(exec->globalData(), Identifier(exec, "scriptId"), jsString(exec, scriptId));

    JSObject* result = constructEmptyObject(exec);
    result->putDirect(exec->globalData(), Identifier(exec, "location"), location);
    UString name = function->name(exec);
    if (!name.isEmpty())
        result->putDirect(exec->globalData(), Identifier(exec, "name"), jsString(exec, name));
    UString displayName = function->displayName(exec);
    if (!displayName.isEmpty())
        result->putDirect(exec->globalData(), Identifier(exec, "displayName"), jsString(exec, displayName));
    // FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
    //     https://bugs.webkit.org/show_bug.cgi?id=87192
    return result;
}
EncodedJSValue JSC_HOST_CALL objectConstructorCreate(ExecState* exec)
{
    if (!exec->argument(0).isObject() && !exec->argument(0).isNull())
        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Object prototype may only be an Object or null.")));
    JSValue proto = exec->argument(0);
    JSObject* newObject = proto.isObject()
        ? constructEmptyObject(exec, asObject(proto))
        : constructEmptyObject(exec, exec->lexicalGlobalObject()->nullPrototypeObjectStructure());
    if (exec->argument(1).isUndefined())
        return JSValue::encode(newObject);
    if (!exec->argument(1).isObject())
        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Property descriptor list must be an Object.")));
    return JSValue::encode(defineProperties(exec, newObject, asObject(exec->argument(1))));
}
Beispiel #3
0
JSValue LiteralParser::parseObject()
{
    StackGuard guard(this);
    if (!guard.isSafe())
        return abortParse();
    JSObject* object = constructEmptyObject(m_exec);
    
    while (m_lexer.next() == TokString) {
        Lexer::LiteralParserToken identifierToken = m_lexer.currentToken();
        
        // Check for colon
        if (m_lexer.next() != TokColon)
            return abortParse();
        m_lexer.next();
        
        JSValue value = parseExpression();
        if (!value || m_aborted)
            return abortParse();
        
        Identifier ident(m_exec, identifierToken.start + 1, identifierToken.end - identifierToken.start - 2);
        object->putDirect(ident, value);
        
        if (m_lexer.currentToken().type != TokComma)
            break;
    }
    
    if (m_lexer.currentToken().type != TokRBrace)
        return abortParse();
    m_lexer.next();
    return object;
}
JSObject* createIteratorResultObject(ExecState* exec, JSValue value, bool done)
{
    JSObject* resultObject = constructEmptyObject(exec);
    resultObject->putDirect(exec->vm(), exec->propertyNames().done, jsBoolean(done));
    resultObject->putDirect(exec->vm(), exec->propertyNames().value, value);
    return resultObject;
}
Beispiel #5
0
JSObject* createIteratorResultObject(ExecState* exec, JSValue value, bool done)
{
    JSObject* resultObject = constructEmptyObject(exec, exec->lexicalGlobalObject()->iteratorResultObjectStructure());
    resultObject->putDirect(exec->vm(), donePropertyOffset, jsBoolean(done));
    resultObject->putDirect(exec->vm(), valuePropertyOffset, value);
    return resultObject;
}
Beispiel #6
0
bool JSFunction::getOwnPropertySlot(JSCell* cell, ExecState* exec, PropertyName propertyName, PropertySlot& slot)
{
    JSFunction* thisObject = jsCast<JSFunction*>(cell);
    if (thisObject->isHostFunction())
        return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);

    if (propertyName == exec->propertyNames().prototype) {
        JSGlobalData& globalData = exec->globalData();
        PropertyOffset offset = thisObject->getDirectOffset(globalData, propertyName);
        if (!isValidOffset(offset)) {
            JSObject* prototype = constructEmptyObject(exec);
            prototype->putDirect(globalData, exec->propertyNames().constructor, thisObject, DontEnum);
            thisObject->putDirect(globalData, exec->propertyNames().prototype, prototype, DontDelete | DontEnum);
            offset = thisObject->getDirectOffset(globalData, exec->propertyNames().prototype);
            ASSERT(isValidOffset(offset));
        }

        slot.setValue(thisObject, thisObject->getDirect(offset), offset);
    }

    if (propertyName == exec->propertyNames().arguments) {
        if (thisObject->jsExecutable()->isStrictMode()) {
            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
            if (!result) {
                thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
                ASSERT(result);
            }
            return result;
        }
        slot.setCacheableCustom(thisObject, argumentsGetter);
        return true;
    }

    if (propertyName == exec->propertyNames().length) {
        slot.setCacheableCustom(thisObject, lengthGetter);
        return true;
    }

    if (propertyName == exec->propertyNames().name) {
        slot.setCacheableCustom(thisObject, nameGetter);
        return true;
    }

    if (propertyName == exec->propertyNames().caller) {
        if (thisObject->jsExecutable()->isStrictMode()) {
            bool result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
            if (!result) {
                thisObject->putDirectAccessor(exec, propertyName, thisObject->globalObject()->throwTypeErrorGetterSetter(exec), DontDelete | DontEnum | Accessor);
                result = Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
                ASSERT(result);
            }
            return result;
        }
        slot.setCacheableCustom(thisObject, callerGetter);
        return true;
    }

    return Base::getOwnPropertySlot(thisObject, exec, propertyName, slot);
}
EncodedJSValue JSC_HOST_CALL webAssemblyModuleImports(ExecState* exec)
{
    VM& vm = exec->vm();
    auto* globalObject = exec->lexicalGlobalObject();
    auto throwScope = DECLARE_THROW_SCOPE(vm);

    JSWebAssemblyModule* module = jsDynamicCast<JSWebAssemblyModule*>(vm, exec->argument(0));
    if (!module)
        return JSValue::encode(throwException(exec, throwScope, createTypeError(exec, "WebAssembly.Module.imports called with non WebAssembly.Module argument"_s)));

    JSArray* result = constructEmptyArray(exec, nullptr, globalObject);
    RETURN_IF_EXCEPTION(throwScope, { });

    const auto& imports = module->moduleInformation().imports;
    if (imports.size()) {
        Identifier module = Identifier::fromString(exec, "module");
        Identifier name = Identifier::fromString(exec, "name");
        Identifier kind = Identifier::fromString(exec, "kind");
        for (const Wasm::Import& imp : imports) {
            JSObject* obj = constructEmptyObject(exec);
            RETURN_IF_EXCEPTION(throwScope, { });
            obj->putDirect(vm, module, jsString(exec, String::fromUTF8(imp.module)));
            obj->putDirect(vm, name, jsString(exec, String::fromUTF8(imp.field)));
            obj->putDirect(vm, kind, jsString(exec, String(makeString(imp.kind))));
            result->push(exec, obj);
            RETURN_IF_EXCEPTION(throwScope, { });
        }
    }

    return JSValue::encode(result);
}
JSValue Origin::toJS(ExecState* exec) const
{
    JSObject* result = constructEmptyObject(exec);
    result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
    result->putDirect(exec->vm(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
    return result;
}
Beispiel #9
0
String JSCryptoKeySerializationJWK::serialize(ExecState* exec, const CryptoKey& key)
{
    std::unique_ptr<CryptoKeyData> keyData = key.exportData();
    if (!keyData) {
        // This generally shouldn't happen as long as all key types implement exportData(), but as underlying libraries return errors, there may be some rare failure conditions.
        throwTypeError(exec, "Couldn't export key material");
        return String();
    }

    JSObject* result = constructEmptyObject(exec);

    addJWKAlgorithmToJSON(exec, result, key);
    if (exec->hadException())
        return String();

    addBoolToJSON(exec, result, "extractable", key.extractable());

    addJWKUseToJSON(exec, result, key.usagesBitmap());
    if (exec->hadException())
        return String();

    if (isCryptoKeyDataOctetSequence(*keyData))
        buildJSONForOctetSequence(exec, toCryptoKeyDataOctetSequence(*keyData).octetSequence(), result);
    else if (isCryptoKeyDataRSAComponents(*keyData))
        buildJSONForRSAComponents(exec, toCryptoKeyDataRSAComponents(*keyData), result);
    else {
        throwTypeError(exec, "Key doesn't support exportKey");
        return String();
    }
    if (exec->hadException())
        return String();

    return JSONStringify(exec, result, 4);
}
JSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec, JSObject*, JSValue, const ArgList& args)
{
    if (!args.at(0).isObject())
        return throwError(exec, TypeError, "Requested property descriptor of a value that is not an object.");
    UString propertyName = args.at(1).toString(exec);
    if (exec->hadException())
        return jsNull();
    JSObject* object = asObject(args.at(0));
    PropertyDescriptor descriptor;
    if (!object->getOwnPropertyDescriptor(exec, Identifier(exec, propertyName), descriptor))
        return jsUndefined();
    if (exec->hadException())
        return jsUndefined();

    JSObject* description = constructEmptyObject(exec);
    if (!descriptor.isAccessorDescriptor()) {
        description->putDirect(exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
        description->putDirect(exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
    } else {
        description->putDirect(exec->propertyNames().get, descriptor.getter() ? descriptor.getter() : jsUndefined(), 0);
        description->putDirect(exec->propertyNames().set, descriptor.setter() ? descriptor.setter() : jsUndefined(), 0);
    }
    
    description->putDirect(exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
    description->putDirect(exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);

    return description;
}
Beispiel #11
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 JSInjectedScriptHost::weakSetEntries(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    JSValue value = exec->uncheckedArgument(0);
    JSWeakSet* weakSet = jsDynamicCast<JSWeakSet*>(value);
    if (!weakSet)
        return jsUndefined();

    unsigned fetched = 0;
    unsigned numberToFetch = 100;

    JSValue numberToFetchArg = exec->argument(1);
    double fetchDouble = numberToFetchArg.toInteger(exec);
    if (fetchDouble >= 0)
        numberToFetch = static_cast<unsigned>(fetchDouble);

    JSArray* array = constructEmptyArray(exec, nullptr);
    for (auto it = weakSet->weakMapData()->begin(); it != weakSet->weakMapData()->end(); ++it) {
        JSObject* entry = constructEmptyObject(exec);
        entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), it->key);
        array->putDirectIndex(exec, fetched++, entry);
        if (numberToFetch && fetched >= numberToFetch)
            break;
    }

    return array;
}
Beispiel #13
0
void JSCryptoKeySerializationJWK::buildJSONForRSAComponents(JSC::ExecState* exec, const CryptoKeyDataRSAComponents& data, JSC::JSObject* result)
{
    addToJSON(exec, result, "kty", "RSA");
    addToJSON(exec, result, "n", base64URLEncode(data.modulus()));
    addToJSON(exec, result, "e", base64URLEncode(data.exponent()));

    if (data.type() == CryptoKeyDataRSAComponents::Type::Public)
        return;

    addToJSON(exec, result, "d", base64URLEncode(data.privateExponent()));

    if (!data.hasAdditionalPrivateKeyParameters())
        return;

    addToJSON(exec, result, "p", base64URLEncode(data.firstPrimeInfo().primeFactor));
    addToJSON(exec, result, "q", base64URLEncode(data.secondPrimeInfo().primeFactor));
    addToJSON(exec, result, "dp", base64URLEncode(data.firstPrimeInfo().factorCRTExponent));
    addToJSON(exec, result, "dq", base64URLEncode(data.secondPrimeInfo().factorCRTExponent));
    addToJSON(exec, result, "qi", base64URLEncode(data.secondPrimeInfo().factorCRTCoefficient));

    if (data.otherPrimeInfos().isEmpty())
        return;

    JSArray* oth = constructEmptyArray(exec, 0, exec->lexicalGlobalObject(), data.otherPrimeInfos().size());
    for (size_t i = 0, size = data.otherPrimeInfos().size(); i < size; ++i) {
        JSObject* jsPrimeInfo = constructEmptyObject(exec);
        addToJSON(exec, jsPrimeInfo, "r", base64URLEncode(data.otherPrimeInfos()[i].primeFactor));
        addToJSON(exec, jsPrimeInfo, "d", base64URLEncode(data.otherPrimeInfos()[i].factorCRTExponent));
        addToJSON(exec, jsPrimeInfo, "t", base64URLEncode(data.otherPrimeInfos()[i].factorCRTCoefficient));
        oth->putDirectIndex(exec, i, jsPrimeInfo);
    }
    result->putDirect(exec->vm(), Identifier(exec, "oth"), oth);
}
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;
}
static JSObject* constructInternalProperty(ExecState* exec, const String& name, JSValue value)
{
    JSObject* result = constructEmptyObject(exec);
    result->putDirect(exec->vm(), Identifier::fromString(exec, "name"), jsString(exec, name));
    result->putDirect(exec->vm(), Identifier::fromString(exec, "value"), value);
    return result;
}
static JSArray* getJSListenerFunctions(ExecState& state, Document* document, const EventListenerInfo& listenerInfo)
{
    VM& vm = state.vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSArray* result = constructEmptyArray(&state, nullptr);
    RETURN_IF_EXCEPTION(scope, nullptr);
    size_t handlersCount = listenerInfo.eventListenerVector.size();
    for (size_t i = 0, outputIndex = 0; i < handlersCount; ++i) {
        const JSEventListener* jsListener = JSEventListener::cast(&listenerInfo.eventListenerVector[i]->callback());
        if (!jsListener) {
            ASSERT_NOT_REACHED();
            continue;
        }

        // Hide listeners from other contexts.
        if (&jsListener->isolatedWorld() != &currentWorld(&state))
            continue;

        JSObject* function = jsListener->jsFunction(document);
        if (!function)
            continue;

        JSObject* listenerEntry = constructEmptyObject(&state);
        listenerEntry->putDirect(vm, Identifier::fromString(&state, "listener"), function);
        listenerEntry->putDirect(vm, Identifier::fromString(&state, "useCapture"), jsBoolean(listenerInfo.eventListenerVector[i]->useCapture()));
        result->putDirectIndex(&state, outputIndex++, JSValue(listenerEntry));
    }
    return result;
}
Beispiel #17
0
JSCell* DFG_OPERATION operationNewObject(ExecState* exec)
{
    JSGlobalData* globalData = &exec->globalData();
    NativeCallFrameTracer tracer(globalData, exec);
    
    return constructEmptyObject(exec);
}
EncodedJSValue JSC_HOST_CALL objectConstructorGetOwnPropertyDescriptor(ExecState* exec)
{
    if (!exec->argument(0).isObject())
        return throwVMError(exec, createTypeError(exec, ASCIILiteral("Requested property descriptor of a value that is not an object.")));
    String propertyName = exec->argument(1).toString(exec)->value(exec);
    if (exec->hadException())
        return JSValue::encode(jsNull());
    JSObject* object = asObject(exec->argument(0));
    PropertyDescriptor descriptor;
    if (!object->methodTable()->getOwnPropertyDescriptor(object, exec, Identifier(exec, propertyName), descriptor))
        return JSValue::encode(jsUndefined());
    if (exec->hadException())
        return JSValue::encode(jsUndefined());

    JSObject* description = constructEmptyObject(exec);
    if (!descriptor.isAccessorDescriptor()) {
        description->putDirect(exec->vm(), exec->propertyNames().value, descriptor.value() ? descriptor.value() : jsUndefined(), 0);
        description->putDirect(exec->vm(), exec->propertyNames().writable, jsBoolean(descriptor.writable()), 0);
    } else {
        ASSERT(descriptor.getter());
        ASSERT(descriptor.setter());
        description->putDirect(exec->vm(), exec->propertyNames().get, descriptor.getter(), 0);
        description->putDirect(exec->vm(), exec->propertyNames().set, descriptor.setter(), 0);
    }

    description->putDirect(exec->vm(), exec->propertyNames().enumerable, jsBoolean(descriptor.enumerable()), 0);
    description->putDirect(exec->vm(), exec->propertyNames().configurable, jsBoolean(descriptor.configurable()), 0);

    return JSValue::encode(description);
}
EncodedJSValue JSC_HOST_CALL IntlCollatorPrototypeFuncResolvedOptions(ExecState* exec)
{
    // 10.3.5 Intl.Collator.prototype.resolvedOptions() (ECMA-402 2.0)
    IntlCollator* collator = jsDynamicCast<IntlCollator*>(exec->thisValue());
    if (!collator)
        return JSValue::encode(throwTypeError(exec, ASCIILiteral("Intl.Collator.prototype.resolvedOptions called on value that's not an object initialized as a Collator")));

    // The function returns a new object whose properties and attributes are set as if
    // constructed by an object literal assigning to each of the following properties the
    // value of the corresponding internal slot of this Collator object (see 10.4): locale,
    // usage, sensitivity, ignorePunctuation, collation, as well as those properties shown
    // in Table 1 whose keys are included in the %Collator%[[relevantExtensionKeys]]
    // internal slot of the standard built-in object that is the initial value of
    // Intl.Collator.

    VM& vm = exec->vm();
    JSObject* options = constructEmptyObject(exec);
    options->putDirect(vm, vm.propertyNames->locale, jsString(exec, collator->locale()));
    options->putDirect(vm, vm.propertyNames->usage, jsString(exec, collator->usage()));
    options->putDirect(vm, vm.propertyNames->sensitivity, jsString(exec, collator->sensitivity()));
    options->putDirect(vm, vm.propertyNames->ignorePunctuation, jsBoolean(collator->ignorePunctuation()));
    options->putDirect(vm, vm.propertyNames->collation, jsString(exec, collator->collation()));
    options->putDirect(vm, vm.propertyNames->numeric, jsBoolean(collator->numeric()));
    return JSValue::encode(options);
}
Beispiel #20
0
JSObject* IntlCollator::resolvedOptions(ExecState& state)
{
    // 10.3.5 Intl.Collator.prototype.resolvedOptions() (ECMA-402 2.0)
    // The function returns a new object whose properties and attributes are set as if
    // constructed by an object literal assigning to each of the following properties the
    // value of the corresponding internal slot of this Collator object (see 10.4): locale,
    // usage, sensitivity, ignorePunctuation, collation, as well as those properties shown
    // in Table 1 whose keys are included in the %Collator%[[relevantExtensionKeys]]
    // internal slot of the standard built-in object that is the initial value of
    // Intl.Collator.

    if (!m_initializedCollator) {
        initializeCollator(state, jsUndefined(), jsUndefined());
        ASSERT(!state.hadException());
    }

    VM& vm = state.vm();
    JSObject* options = constructEmptyObject(&state);
    options->putDirect(vm, vm.propertyNames->locale, jsString(&state, m_locale));
    options->putDirect(vm, vm.propertyNames->usage, jsNontrivialString(&state, ASCIILiteral(usageString(m_usage))));
    options->putDirect(vm, vm.propertyNames->sensitivity, jsNontrivialString(&state, ASCIILiteral(sensitivityString(m_sensitivity))));
    options->putDirect(vm, vm.propertyNames->ignorePunctuation, jsBoolean(m_ignorePunctuation));
    options->putDirect(vm, vm.propertyNames->collation, jsString(&state, m_collation));
    options->putDirect(vm, vm.propertyNames->numeric, jsBoolean(m_numeric));
    return options;
}
static JSArray* getJSListenerFunctions(ExecState* exec, Document* document, const EventListenerInfo& listenerInfo)
{
    JSArray* result = constructEmptyArray(exec, nullptr);
    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);
        if (!function)
            continue;

        JSObject* listenerEntry = constructEmptyObject(exec);
        listenerEntry->putDirect(exec->vm(), Identifier::fromString(exec, "listener"), function);
        listenerEntry->putDirect(exec->vm(), Identifier::fromString(exec, "useCapture"), jsBoolean(listenerInfo.eventListenerVector[i].useCapture));
        result->putDirectIndex(exec, outputIndex++, JSValue(listenerEntry));
    }
    return result;
}
JSValue JSInjectedScriptHost::getEventListeners(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();
    JSValue value = exec->argument(0);
    if (!value.isObject() || value.isNull())
        return jsUndefined();
    Node* node = toNode(value);
    if (!node)
        return jsUndefined();
    // This can only happen for orphan DocumentType nodes.
    Document* document = node->document();
    if (!node->document())
        return jsUndefined();

    Vector<EventListenerInfo> listenersArray;
    impl()->getEventListenersImpl(node, listenersArray);

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

    return result;
}
Beispiel #23
0
JSValue JSInjectedScriptHost::functionDetails(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    JSValue value = exec->uncheckedArgument(0);
    if (!value.asCell()->inherits(JSFunction::info()))
        return jsUndefined();

    // FIXME: This should provide better details for JSBoundFunctions.

    JSFunction* function = jsCast<JSFunction*>(value);
    const SourceCode* sourceCode = function->sourceCode();
    if (!sourceCode)
        return jsUndefined();

    // In the inspector protocol all positions are 0-based while in SourceCode they are 1-based
    int lineNumber = sourceCode->firstLine();
    if (lineNumber)
        lineNumber -= 1;
    int columnNumber = sourceCode->startColumn();
    if (columnNumber)
        columnNumber -= 1;

    VM& vm = exec->vm();
    String scriptID = String::number(sourceCode->provider()->asID());
    JSObject* location = constructEmptyObject(exec);
    location->putDirect(vm, Identifier::fromString(exec, "scriptId"), jsString(exec, scriptID));
    location->putDirect(vm, Identifier::fromString(exec, "lineNumber"), jsNumber(lineNumber));
    location->putDirect(vm, Identifier::fromString(exec, "columnNumber"), jsNumber(columnNumber));

    JSObject* result = constructEmptyObject(exec);
    result->putDirect(vm, Identifier::fromString(exec, "location"), location);

    String name = function->name();
    if (!name.isEmpty())
        result->putDirect(vm, Identifier::fromString(exec, "name"), jsString(exec, name));

    String displayName = function->displayName(vm);
    if (!displayName.isEmpty())
        result->putDirect(vm, Identifier::fromString(exec, "displayName"), jsString(exec, displayName));

    // FIXME: provide function scope data in "scopesRaw" property when JSC supports it.
    // <https://webkit.org/b/87192> [JSC] expose function (closure) inner context to debugger

    return result;
}
Beispiel #24
0
JSValue JSInjectedScriptHost::iteratorEntries(ExecState* exec)
{
    if (exec->argumentCount() < 1)
        return jsUndefined();

    VM& vm = exec->vm();
    JSValue iterator;
    JSValue value = exec->uncheckedArgument(0);
    if (JSMapIterator* mapIterator = jsDynamicCast<JSMapIterator*>(value))
        iterator = mapIterator->clone(exec);
    else if (JSSetIterator* setIterator = jsDynamicCast<JSSetIterator*>(value))
        iterator = setIterator->clone(exec);
    else if (JSStringIterator* stringIterator = jsDynamicCast<JSStringIterator*>(value))
        iterator = stringIterator->clone(exec);
    else if (JSPropertyNameIterator* propertyNameIterator = jsDynamicCast<JSPropertyNameIterator*>(value)) {
        iterator = propertyNameIterator->clone(exec);
        if (UNLIKELY(vm.exception()))
            return JSValue();
    } else {
        if (JSObject* iteratorObject = jsDynamicCast<JSObject*>(value)) {
            // Array Iterators are created in JS for performance reasons. Thus the only way to know we have one is to
            // look for a property that is unique to them.
            if (JSValue nextIndex = iteratorObject->getDirect(vm, vm.propertyNames->builtinNames().arrayIteratorNextIndexPrivateName()))
                iterator = cloneArrayIteratorObject(exec, vm, iteratorObject, nextIndex);
        }
    }
    if (!iterator)
        return jsUndefined();

    unsigned numberToFetch = 5;
    JSValue numberToFetchArg = exec->argument(1);
    double fetchDouble = numberToFetchArg.toInteger(exec);
    if (fetchDouble >= 0)
        numberToFetch = static_cast<unsigned>(fetchDouble);

    JSArray* array = constructEmptyArray(exec, nullptr);
    if (UNLIKELY(vm.exception()))
        return jsUndefined();

    for (unsigned i = 0; i < numberToFetch; ++i) {
        JSValue next = iteratorStep(exec, iterator);
        if (UNLIKELY(vm.exception()))
            break;
        if (next.isFalse())
            break;

        JSValue nextValue = iteratorValue(exec, next);
        if (UNLIKELY(vm.exception()))
            break;

        JSObject* entry = constructEmptyObject(exec);
        entry->putDirect(exec->vm(), Identifier::fromString(exec, "value"), nextValue);
        array->putDirectIndex(exec, i, entry);
    }

    iteratorClose(exec, iterator);

    return array;
}
Beispiel #25
0
JSValue Bytecode::toJS(ExecState* exec) const
{
    JSObject* result = constructEmptyObject(exec);
    result->putDirect(exec->globalData(), exec->propertyNames().bytecodeIndex, jsNumber(m_bytecodeIndex));
    result->putDirect(exec->globalData(), exec->propertyNames().opcode, jsString(exec, String::fromUTF8(opcodeNames[m_opcodeID])));
    result->putDirect(exec->globalData(), exec->propertyNames().description, jsString(exec, String::fromUTF8(m_description)));
    return result;
}
static JSObject* createRotationRateObject(const DeviceMotionData::RotationRate* rotationRate, ExecState* exec)
{
    JSObject* object = constructEmptyObject(exec);
    object->putDirect(exec->globalData(), Identifier(exec, "alpha"), rotationRate->canProvideAlpha() ? jsNumber(rotationRate->alpha()) : jsNull());
    object->putDirect(exec->globalData(), Identifier(exec, "beta"),  rotationRate->canProvideBeta()  ? jsNumber(rotationRate->beta())  : jsNull());
    object->putDirect(exec->globalData(), Identifier(exec, "gamma"), rotationRate->canProvideGamma() ? jsNumber(rotationRate->gamma()) : jsNull());
    return object;
}
static JSObject* createAccelerationObject(const DeviceMotionData::Acceleration* acceleration, ExecState& state)
{
    JSObject* object = constructEmptyObject(&state);
    object->putDirect(state.vm(), Identifier::fromString(&state, "x"), acceleration->canProvideX() ? jsNumber(acceleration->x()) : jsNull());
    object->putDirect(state.vm(), Identifier::fromString(&state, "y"), acceleration->canProvideY() ? jsNumber(acceleration->y()) : jsNull());
    object->putDirect(state.vm(), Identifier::fromString(&state, "z"), acceleration->canProvideZ() ? jsNumber(acceleration->z()) : jsNull());
    return object;
}
static JSObject* createAccelerationObject(const DeviceMotionData::Acceleration* acceleration, ExecState* exec)
{
    JSObject* object = constructEmptyObject(exec);
    object->putDirect(exec->globalData(), Identifier(exec, "x"), acceleration->canProvideX() ? jsNumber(acceleration->x()) : jsNull());
    object->putDirect(exec->globalData(), Identifier(exec, "y"), acceleration->canProvideY() ? jsNumber(acceleration->y()) : jsNull());
    object->putDirect(exec->globalData(), Identifier(exec, "z"), acceleration->canProvideZ() ? jsNumber(acceleration->z()) : jsNull());
    return object;
}
static JSObject* createRotationRateObject(const DeviceMotionData::RotationRate* rotationRate, ExecState& state)
{
    JSObject* object = constructEmptyObject(&state);
    object->putDirect(state.vm(), Identifier::fromString(&state, "alpha"), rotationRate->canProvideAlpha() ? jsNumber(rotationRate->alpha()) : jsNull());
    object->putDirect(state.vm(), Identifier::fromString(&state, "beta"),  rotationRate->canProvideBeta()  ? jsNumber(rotationRate->beta())  : jsNull());
    object->putDirect(state.vm(), Identifier::fromString(&state, "gamma"), rotationRate->canProvideGamma() ? jsNumber(rotationRate->gamma()) : jsNull());
    return object;
}
JSValue Compilation::toJS(ExecState* exec) const
{
    JSObject* result = constructEmptyObject(exec);

    result->putDirect(exec->vm(), exec->propertyNames().bytecodesID, jsNumber(m_bytecodes->id()));
    result->putDirect(exec->vm(), 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->vm(), 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->vm(), exec->propertyNames().descriptions, descriptions);

    JSArray* counters = constructEmptyArray(exec, 0);
    for (auto it = m_counters.begin(), end = m_counters.end(); it != end; ++it) {
        JSObject* counterEntry = constructEmptyObject(exec);
        counterEntry->putDirect(exec->vm(), exec->propertyNames().origin, it->key.toJS(exec));
        counterEntry->putDirect(exec->vm(), exec->propertyNames().executionCount, jsNumber(it->value->count()));
        counters->push(exec, counterEntry);
    }
    result->putDirect(exec->vm(), 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->vm(), 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->vm(), exec->propertyNames().osrExits, exits);

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

    return result;
}