static RefPtr<CryptoAlgorithmParameters> createRsaOaepParams(ExecState* exec, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(exec);
        return nullptr;
    }

    JSDictionary jsDictionary(exec, value.getObject());
    auto result = adoptRef(*new CryptoAlgorithmRsaOaepParams);

    if (!getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Required)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    JSValue labelValue = getProperty(exec, value.getObject(), "label");
    if (exec->hadException())
        return nullptr;

    result->hasLabel = !labelValue.isUndefinedOrNull();
    if (!result->hasLabel)
        return WTFMove(result);

    CryptoOperationData labelData;
    if (!cryptoOperationDataFromJSValue(exec, labelValue, labelData)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    result->label.append(labelData.first, labelData.second);

    return WTFMove(result);
}
static std::unique_ptr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState* exec, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(exec);
        return nullptr;
    }

    auto result = std::make_unique<CryptoAlgorithmRsaKeyGenParams>();

    JSValue modulusLengthValue = getProperty(exec, value.getObject(), "modulusLength");
    if (exec->hadException())
        return nullptr;

    // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>.
    result->modulusLength = toUInt32(exec, modulusLengthValue, NormalConversion);
    if (exec->hadException())
        return nullptr;

    JSValue publicExponentValue = getProperty(exec, value.getObject(), "publicExponent");
    if (exec->hadException())
        return nullptr;

    RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue);
    if (!publicExponentArray) {
        throwTypeError(exec, "Expected a Uint8Array in publicExponent");
        return nullptr;
    }
    result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());

    return WTF::move(result);
}
static RefPtr<CryptoAlgorithmParameters> createRsaKeyGenParams(ExecState& state, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(&state);
        return nullptr;
    }

    JSDictionary jsDictionary(&state, value.getObject());
    auto result = adoptRef(*new CryptoAlgorithmRsaKeyGenParams);

    JSValue modulusLengthValue = getProperty(&state, value.getObject(), "modulusLength");
    if (state.hadException())
        return nullptr;

    // FIXME: Why no EnforceRange? Filed as <https://www.w3.org/Bugs/Public/show_bug.cgi?id=23779>.
    result->modulusLength = convert<uint32_t>(state, modulusLengthValue, NormalConversion);
    if (state.hadException())
        return nullptr;

    JSValue publicExponentValue = getProperty(&state, value.getObject(), "publicExponent");
    if (state.hadException())
        return nullptr;

    RefPtr<Uint8Array> publicExponentArray = toUint8Array(publicExponentValue);
    if (!publicExponentArray) {
        throwTypeError(&state, "Expected a Uint8Array in publicExponent");
        return nullptr;
    }
    result->publicExponent.append(publicExponentArray->data(), publicExponentArray->byteLength());

    result->hasHash = getHashAlgorithm(jsDictionary, result->hash, HashRequirement::Optional); 

    return WTFMove(result);
}
Esempio n. 4
0
int JSPrintFunction::rightValue( JSScopeStack* , JSValue *rv, JSParameterListObject *_param )
{
    // int ret = 0;
    
    if ( _param )
    {
	JSValue *v;
	for ( v = _param->firstValue(); v != 0L; v = _param->nextValue() )
	{
	    if ( v->getObject()->isA() == TYPE_JSIntegerObject )
		printf( "%i ", ((JSIntegerObject*)(v->getObject()))->getValue() );
	    else if ( v->getObject()->isA() == TYPE_JSStringObject )
		printf( "%s ", ((JSStringObject*)(v->getObject()))->getString() );
	    else if ( v->getObject()->isA() == TYPE_JSBoolObject )
	    {
		if ( ((JSBoolObject*)(v->getObject()))->getValue() )
		    printf( "TRUE " );
		else
		    printf( "FALSE " );
	    }
	    else if ( v->getObject()->isA() == TYPE_JSFloatObject )
		printf( "%f ", ((JSFloatObject*)(v->getObject()))->getValue() );	    
	}
    }
    
    rv->setObject( new JSObject() );
    rv->setAutoDelete( TRUE );
    rv->setLeftValue( FALSE );

    return 0;
}
Esempio n. 5
0
int JSDocumentWriteFunction::rightValue( JSScopeStack*, JSValue *rv, JSParameterListObject *_param )
{
    int ret = 0;

    QString out;
    
    if ( _param )
    {
	JSValue *v;
	int i = 0;
	for ( v = _param->firstValue(); v != 0L; v = _param->nextValue() )
	{
	    i++;
	    if ( i > 1 )
		object->getJSWindowObject()->getJSEnvironment()->writeOutput( " " );
	    
	    if ( v->getObject()->isA() == TYPE_JSIntegerObject )
	    {
		out.sprintf("%i",((JSIntegerObject*)(v->getObject()))->getValue() );
		object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() );
		//printf( "%i ", ((JSIntegerObject*)(v->getObject()))->getValue() );
	    }
	    else if ( v->getObject()->isA() == TYPE_JSStringObject )
	    {
		out = ((JSStringObject*)(v->getObject()))->getString();
		object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() );
		//printf( "%s ", ((JSStringObject*)(v->getObject()))->getString() );
	    }
	    else if ( v->getObject()->isA() == TYPE_JSBoolObject )
	    {
		if ( ((JSBoolObject*)(v->getObject()))->getValue() )
		{
		    out = "TRUE";
		    object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() );
		    //printf( "TRUE " );
		}
		else
		{
		    out = "FALSE";
		    object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() );
		    //printf( "FALSE " );
		}
	    }
	    else if ( v->getObject()->isA() == TYPE_JSFloatObject )
	    {
		out.sprintf( "%f", ((JSFloatObject*)(v->getObject()))->getValue() );	    
		object->getJSWindowObject()->getJSEnvironment()->writeOutput( out.data() );
		//printf( "%f ", ((JSFloatObject*)(v->getObject()))->getValue() );	    
	    }
	}
    }
    
    rv->setObject( new JSObject() );
    rv->setAutoDelete( TRUE );
    rv->setLeftValue( FALSE );
    
    return ret;
}
static RefPtr<CryptoAlgorithmParameters> createAesCbcParams(ExecState* exec, JSValue value)
{
    if (!value.isObject()) {
        throwTypeError(exec);
        return nullptr;
    }

    JSValue iv = getProperty(exec, value.getObject(), "iv");
    if (exec->hadException())
        return nullptr;

    auto result = adoptRef(*new CryptoAlgorithmAesCbcParams);

    CryptoOperationData ivData;
    if (!cryptoOperationDataFromJSValue(exec, iv, ivData)) {
        ASSERT(exec->hadException());
        return nullptr;
    }

    if (ivData.second != 16) {
        exec->vm().throwException(exec, createError(exec, "AES-CBC initialization data must be 16 bytes"));
        return nullptr;
    }

    memcpy(result->iv.data(), ivData.first, ivData.second);

    return WTFMove(result);
}
Esempio n. 7
0
inline Structure* getBoundFunctionStructure(VM& vm, ExecState* exec, JSGlobalObject* globalObject, JSObject* targetFunction)
{
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue prototype = targetFunction->getPrototype(vm, exec);
    RETURN_IF_EXCEPTION(scope, nullptr);
    JSFunction* targetJSFunction = jsDynamicCast<JSFunction*>(vm, targetFunction);

    // We only cache the structure of the bound function if the bindee is a JSFunction since there
    // isn't any good place to put the structure on Internal Functions.
    if (targetJSFunction) {
        Structure* structure = targetJSFunction->rareData(vm)->getBoundFunctionStructure();
        if (structure && structure->storedPrototype() == prototype && structure->globalObject() == globalObject)
            return structure;
    }

    Structure* result = globalObject->boundFunctionStructure();

    // It would be nice if the structure map was keyed global objects in addition to the other things. Unfortunately, it is not
    // currently. Whoever works on caching structure changes for prototype transistions should consider this problem as well.
    // See: https://bugs.webkit.org/show_bug.cgi?id=152738
    if (prototype.isObject() && prototype.getObject()->globalObject() == globalObject) {
        result = vm.prototypeMap.emptyStructureForPrototypeFromBaseStructure(globalObject, prototype.getObject(), result);
        ASSERT_WITH_SECURITY_IMPLICATION(result->globalObject() == globalObject);
    } else
        result = Structure::create(vm, globalObject, prototype, result->typeInfo(), result->classInfo());

    if (targetJSFunction)
        targetJSFunction->rareData(vm)->setBoundFunctionStructure(vm, result);

    return result;
}
Esempio n. 8
0
bool JSValueIsObjectOfClass(JSContextRef ctx, JSValueRef value, JSClassRef jsClass)
{
    if (!ctx || !jsClass) {
        ASSERT_NOT_REACHED();
        return false;
    }
    ExecState* exec = toJS(ctx);
    JSLockHolder locker(exec);

    JSValue jsValue = toJS(exec, value);
    
    if (JSObject* o = jsValue.getObject()) {
        if (o->inherits(JSProxy::info()))
            o = jsCast<JSProxy*>(o)->target();

        if (o->inherits(JSCallbackObject<JSGlobalObject>::info()))
            return jsCast<JSCallbackObject<JSGlobalObject>*>(o)->inherits(jsClass);
        if (o->inherits(JSCallbackObject<JSDestructibleObject>::info()))
            return jsCast<JSCallbackObject<JSDestructibleObject>*>(o)->inherits(jsClass);
#if JSC_OBJC_API_ENABLED
        if (o->inherits(JSCallbackObject<JSAPIWrapperObject>::info()))
            return jsCast<JSCallbackObject<JSAPIWrapperObject>*>(o)->inherits(jsClass);
#endif
    }
    return false;
}
IterationRecord iteratorForIterable(ExecState* state, JSValue iterable)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    
    JSValue iteratorFunction = iterable.get(state, vm.propertyNames->iteratorSymbol);
    RETURN_IF_EXCEPTION(scope, { });
    
    CallData iteratorFunctionCallData;
    CallType iteratorFunctionCallType = getCallData(vm, iteratorFunction, iteratorFunctionCallData);
    if (iteratorFunctionCallType == CallType::None) {
        throwTypeError(state, scope);
        return { };
    }

    ArgList iteratorFunctionArguments;
    JSValue iterator = call(state, iteratorFunction, iteratorFunctionCallType, iteratorFunctionCallData, iterable, iteratorFunctionArguments);
    RETURN_IF_EXCEPTION(scope, { });

    if (!iterator.isObject()) {
        throwTypeError(state, scope);
        return { };
    }

    JSValue nextMethod = iterator.getObject()->get(state, vm.propertyNames->next);
    RETURN_IF_EXCEPTION(scope, { });

    return { iterator, nextMethod };
}
Esempio n. 10
0
EncodedJSValue JSC_HOST_CALL constructJSHTMLElement(ExecState& exec)
{
    auto* jsConstructor = jsCast<DOMConstructorObject*>(exec.callee());

    auto* context = jsConstructor->scriptExecutionContext();
    if (!is<Document>(context))
        return throwConstructorDocumentUnavailableError(exec, "HTMLElement");
    auto& document = downcast<Document>(*context);

    auto* window = document.domWindow();
    if (!window)
        return throwVMTypeError(&exec, ASCIILiteral("new.target is not a valid custom element constructor"));

    auto* registry = window->customElementsRegistry();
    if (!registry)
        return throwVMTypeError(&exec, ASCIILiteral("new.target is not a valid custom element constructor"));

    VM& vm = exec.vm();
    JSValue newTargetValue = exec.thisValue();
    JSObject* newTarget = newTargetValue.getObject();
    auto* elementInterface = registry->findInterface(newTarget);
    if (!elementInterface)
        return throwVMTypeError(&exec, ASCIILiteral("new.target does not define a custom element"));

    if (!elementInterface->isUpgradingElement()) {
        auto* globalObject = jsConstructor->globalObject();
        Structure* baseStructure = getDOMStructure<JSHTMLElement>(vm, *globalObject);
        auto* newElementStructure = InternalFunction::createSubclassStructure(&exec, newTargetValue, baseStructure);
        if (UNLIKELY(exec.hadException()))
            return JSValue::encode(jsUndefined());

        Ref<HTMLElement> element = HTMLElement::create(elementInterface->name(), document);
        element->setIsUnresolvedCustomElement();
        auto* jsElement = JSHTMLElement::create(newElementStructure, globalObject, element.get());
        cacheWrapper(globalObject->world(), element.ptr(), jsElement);
        return JSValue::encode(jsElement);
    }

    Element* elementToUpgrade = elementInterface->lastElementInConstructionStack();
    if (!elementToUpgrade) {
        throwInvalidStateError(exec, ASCIILiteral("Cannot instantiate a custom element inside its own constrcutor during upgrades"));
        return JSValue::encode(jsUndefined());
    }

    JSValue elementWrapperValue = toJS(&exec, jsConstructor->globalObject(), *elementToUpgrade);
    ASSERT(elementWrapperValue.isObject());

    JSValue newPrototype = newTarget->get(&exec, vm.propertyNames->prototype);
    if (exec.hadException())
        return JSValue::encode(jsUndefined());

    JSObject* elementWrapperObject = asObject(elementWrapperValue);
    JSObject::setPrototype(elementWrapperObject, &exec, newPrototype, true /* shouldThrowIfCantSet */);
    if (exec.hadException())
        return JSValue::encode(jsUndefined());

    elementInterface->didUpgradeLastElementInConstructionStack();

    return JSValue::encode(elementWrapperValue);
}
ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ScriptState* scriptState, int id)
{
    JSLockHolder lock(scriptState);

    SourceCode sourceCode = makeSource(source);
    JSDOMGlobalObject* globalObject = jsCast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
    JSValue globalThisValue = scriptState->globalThisValue();

    JSValue evaluationException;
    JSValue evaluationReturnValue;
    if (isMainThread())
        evaluationReturnValue = JSMainThreadExecState::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException);
    else {
        JSC::JSLockHolder lock(scriptState);
        evaluationReturnValue = JSC::evaluate(scriptState, sourceCode, globalThisValue, &evaluationException);
    }
    if (evaluationException)
        return ScriptObject();

    JSValue functionValue = evaluationReturnValue;
    CallData callData;
    CallType callType = getCallData(functionValue, callData);
    if (callType == CallTypeNone)
        return ScriptObject();

    MarkedArgumentBuffer args;
    args.append(toJS(scriptState, globalObject, m_injectedScriptHost.get()));
    args.append(globalThisValue);
    args.append(jsNumber(id));

    JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
    if (result.isObject())
        return ScriptObject(scriptState, result.getObject());
    return ScriptObject();
}
Deprecated::ScriptObject InjectedScriptManager::createInjectedScript(const String& source, ExecState* scriptState, int id)
{
    JSLockHolder lock(scriptState);

    SourceCode sourceCode = makeSource(source);
    JSGlobalObject* globalObject = scriptState->lexicalGlobalObject();
    JSValue globalThisValue = scriptState->globalThisValue();

    NakedPtr<Exception> evaluationException;
    InspectorEvaluateHandler evaluateHandler = m_environment.evaluateHandler();
    JSValue functionValue = evaluateHandler(scriptState, sourceCode, globalThisValue, evaluationException);
    if (evaluationException)
        return Deprecated::ScriptObject();

    CallData callData;
    CallType callType = getCallData(functionValue, callData);
    if (callType == CallTypeNone)
        return Deprecated::ScriptObject();

    MarkedArgumentBuffer args;
    args.append(m_injectedScriptHost->wrapper(scriptState, globalObject));
    args.append(globalThisValue);
    args.append(jsNumber(id));

    JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
    scriptState->clearException();
    if (result.isObject())
        return Deprecated::ScriptObject(scriptState, result.getObject());

    return Deprecated::ScriptObject();
}
JSValue JSHTMLCanvasElement::getContext(ExecState* exec)
{
    HTMLCanvasElement* canvas = static_cast<HTMLCanvasElement*>(impl());
    const String& contextId = exec->argument(0).toString(exec)->value(exec);
    
    RefPtr<CanvasContextAttributes> attrs;
#if ENABLE(WEBGL)
    if (HTMLCanvasElement::is3dType(contextId)) {
        get3DContextAttributes(exec, attrs);
        if (exec->hadException())
            return jsUndefined();
    }
#endif
    
    CanvasRenderingContext* context = canvas->getContext(contextId, attrs.get());
    if (!context)
        return jsNull();
    JSValue jsValue = toJS(exec, globalObject(), WTF::getPtr(context));
    if (InspectorInstrumentation::canvasAgentEnabled(canvas->document())) {
        ScriptObject contextObject(exec, jsValue.getObject());
        ScriptObject wrapped;
        if (context->is2d())
            wrapped = InspectorInstrumentation::wrapCanvas2DRenderingContextForInstrumentation(canvas->document(), contextObject);
#if ENABLE(WEBGL)
        else if (context->is3d())
            wrapped = InspectorInstrumentation::wrapWebGLRenderingContextForInstrumentation(canvas->document(), contextObject);
#endif
        if (!wrapped.hasNoValue())
            return wrapped.jsValue();
    }
    return jsValue;
}
Esempio n. 14
0
static EncodedJSValue JSC_HOST_CALL typedArrayViewProtoGetterFuncToStringTag(ExecState* exec)
{
    JSValue thisValue = exec->thisValue();
    if (!thisValue.isObject())
        return JSValue::encode(jsUndefined());

    VM& vm = exec->vm();
    switch (thisValue.getObject()->classInfo()->typedArrayStorageType) {
    case TypeUint8Clamped:
        return JSValue::encode(jsString(&vm, "Uint8ClampedArray"));
    case TypeInt32:
        return JSValue::encode(jsString(&vm, "Int32Array"));
    case TypeUint32:
        return JSValue::encode(jsString(&vm, "Uint32Array"));
    case TypeFloat64:
        return JSValue::encode(jsString(&vm, "Float64Array"));
    case TypeFloat32:
        return JSValue::encode(jsString(&vm, "Float32Array"));
    case TypeInt8:
        return JSValue::encode(jsString(&vm, "Int8Array"));
    case TypeUint8:
        return JSValue::encode(jsString(&vm, "Uint8Array"));
    case TypeInt16:
        return JSValue::encode(jsString(&vm, "Int16Array"));
    case TypeUint16:
        return JSValue::encode(jsString(&vm, "Uint16Array"));
    case NotTypedArray:
    case TypeDataView:
        return JSValue::encode(jsUndefined());
    }
    RELEASE_ASSERT_NOT_REACHED();
}
Esempio n. 15
0
ScriptObject InjectedScriptHost::createInjectedScript(const String& source, ScriptState* scriptState, long id)
{
    SourceCode sourceCode = makeSource(stringToUString(source));
    JSLock lock(SilenceAssertionsOnly);
    JSDOMGlobalObject* globalObject = static_cast<JSDOMGlobalObject*>(scriptState->lexicalGlobalObject());
    JSValue globalThisValue = scriptState->globalThisValue();
    Completion comp = JSMainThreadExecState::evaluate(scriptState, globalObject->globalScopeChain(), sourceCode, globalThisValue);
    if (comp.complType() != JSC::Normal && comp.complType() != JSC::ReturnValue)
        return ScriptObject();
    JSValue functionValue = comp.value();
    CallData callData;
    CallType callType = functionValue.getCallData(callData);
    if (callType == CallTypeNone)
        return ScriptObject();

    MarkedArgumentBuffer args;
    args.append(toJS(scriptState, globalObject, this));
    args.append(globalThisValue);
    args.append(jsNumber(scriptState, id));
    args.append(jsString(scriptState, String("JSC")));
    JSValue result = JSC::call(scriptState, functionValue, callType, callData, globalThisValue, args);
    if (result.isObject())
        return ScriptObject(scriptState, result.getObject());
    return ScriptObject();
}
Esempio n. 16
0
JSValue JSPopStateEvent::state(ExecState* exec) const
{
    JSValue cachedValue = m_state.get();
    if (!cachedValue.isEmpty()) {
        // We cannot use a cached object if we are in a different world than the one it was created in.
        if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == &currentWorld(exec))
            return cachedValue;
        ASSERT_NOT_REACHED();
    }

    PopStateEvent& event = impl();

    if (!event.state().hasNoValue()) {
        // We need to make sure a PopStateEvent does not leak objects in its state property across isolated DOM worlds.
        // Ideally, we would check that the worlds have different privileges but that's not possible yet.
        JSValue state = event.state().jsValue();
        if (state.isObject() && &worldForDOMObject(state.getObject()) != &currentWorld(exec)) {
            if (RefPtr<SerializedScriptValue> serializedValue = event.trySerializeState(exec))
                state = serializedValue->deserialize(exec, globalObject(), nullptr);
            else
                state = jsNull();
        }

        return cacheState(exec, const_cast<JSPopStateEvent*>(this), state);
    }

    History* history = event.history();
    if (!history || !event.serializedState())
        return cacheState(exec, const_cast<JSPopStateEvent*>(this), jsNull());

    // There's no cached value from a previous invocation, nor a state value was provided by the
    // event, but there is a history object, so first we need to see if the state object has been
    // deserialized through the history object already.
    // The current history state object might've changed in the meantime, so we need to take care
    // of using the correct one, and always share the same deserialization with history.state.

    bool isSameState = history->isSameAsCurrentState(event.serializedState().get());
    JSValue result;

    if (isSameState) {
        JSHistory* jsHistory = jsCast<JSHistory*>(toJS(exec, globalObject(), history).asCell());
        result = jsHistory->state(exec);
    } else
        result = event.serializedState()->deserialize(exec, globalObject(), 0);

    return cacheState(exec, const_cast<JSPopStateEvent*>(this), result);
}
static EncodedJSValue JSC_HOST_CALL constructJSWebAssemblyModule(ExecState* state)
{
    VM& vm = state->vm();
    auto scope = DECLARE_THROW_SCOPE(vm);
    JSValue val = state->argument(0);

    // If the given bytes argument is not a BufferSource, a TypeError exception is thrown.
    JSArrayBuffer* arrayBuffer = val.getObject() ? jsDynamicCast<JSArrayBuffer*>(val.getObject()) : nullptr;
    JSArrayBufferView* arrayBufferView = val.getObject() ? jsDynamicCast<JSArrayBufferView*>(val.getObject()) : nullptr;
    if (!(arrayBuffer || arrayBufferView))
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("first argument to WebAssembly.Module must be an ArrayBufferView or an ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    if (arrayBufferView ? arrayBufferView->isNeutered() : arrayBuffer->impl()->isNeutered())
        return JSValue::encode(throwException(state, scope, createTypeError(state, ASCIILiteral("underlying TypedArray has been detatched from the ArrayBuffer"), defaultSourceAppender, runtimeTypeForValue(val))));

    size_t byteOffset = arrayBufferView ? arrayBufferView->byteOffset() : 0;
    size_t byteSize = arrayBufferView ? arrayBufferView->length() : arrayBuffer->impl()->byteLength();
    const auto* base = arrayBufferView ? static_cast<uint8_t*>(arrayBufferView->vector()) : static_cast<uint8_t*>(arrayBuffer->impl()->data());

    Wasm::Plan plan(&vm, base + byteOffset, byteSize);
    // On failure, a new WebAssembly.CompileError is thrown.
    plan.run();
    if (plan.failed())
        return JSValue::encode(throwException(state, scope, createWebAssemblyCompileError(state, plan.errorMessage())));

    // On success, a new WebAssembly.Module object is returned with [[Module]] set to the validated Ast.module.
    auto* structure = InternalFunction::createSubclassStructure(state, state->newTarget(), asInternalFunction(state->jsCallee())->globalObject()->WebAssemblyModuleStructure());
    RETURN_IF_EXCEPTION(scope, { });

    // The export symbol table is the same for all Instances of a Module.
    SymbolTable* exportSymbolTable = SymbolTable::create(vm);
    for (auto& exp : plan.exports()) {
        auto offset = exportSymbolTable->takeNextScopeOffset(NoLockingNecessary);
        exportSymbolTable->set(NoLockingNecessary, exp.field.impl(), SymbolTableEntry(VarOffset(offset)));
    }

    // Only wasm-internal functions have a callee, stubs to JS do not.
    unsigned calleeCount = plan.internalFunctionCount();
    JSWebAssemblyModule* result = JSWebAssemblyModule::create(vm, structure, plan.takeModuleInformation(), plan.takeCallLinkInfos(), plan.takeWasmToJSStubs(), plan.takeFunctionIndexSpace(), exportSymbolTable, calleeCount);
    plan.initializeCallees(state->jsCallee()->globalObject(), 
        [&] (unsigned calleeIndex, JSWebAssemblyCallee* jsEntrypointCallee, JSWebAssemblyCallee* wasmEntrypointCallee) {
            result->setJSEntrypointCallee(vm, calleeIndex, jsEntrypointCallee);
            result->setWasmEntrypointCallee(vm, calleeIndex, wasmEntrypointCallee);
        });
    return JSValue::encode(result);
}
Esempio n. 18
0
bool JSValueIsObjectOfClass(JSContextRef, JSValueRef value, JSClassRef jsClass)
{
    JSValue* jsValue = toJS(value);
    
    if (JSObject* o = jsValue->getObject())
        if (o->inherits(&JSCallbackObject::info))
            return static_cast<JSCallbackObject*>(o)->inherits(jsClass);
    return false;
}
template<> DictionaryImplName convertDictionary<DictionaryImplName>(ExecState& state, JSValue value)
{
    VM& vm = state.vm();
    auto throwScope = DECLARE_THROW_SCOPE(vm);
    bool isNullOrUndefined = value.isUndefinedOrNull();
    auto* object = isNullOrUndefined ? nullptr : value.getObject();
    if (UNLIKELY(!isNullOrUndefined && !object)) {
        throwTypeError(&state, throwScope);
        return { };
    }
    DictionaryImplName result;
    JSValue boolMemberValue;
    if (isNullOrUndefined)
        boolMemberValue = jsUndefined();
    else {
        boolMemberValue = object->get(&state, Identifier::fromString(&state, "boolMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!boolMemberValue.isUndefined()) {
        result.boolMember = convert<IDLBoolean>(state, boolMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue callbackMemberValue;
    if (isNullOrUndefined)
        callbackMemberValue = jsUndefined();
    else {
        callbackMemberValue = object->get(&state, Identifier::fromString(&state, "callbackMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!callbackMemberValue.isUndefined()) {
        result.callbackMember = convert<IDLCallbackFunction<JSVoidCallback>>(state, callbackMemberValue, *jsCast<JSDOMGlobalObject*>(state.lexicalGlobalObject()));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue enumMemberValue;
    if (isNullOrUndefined)
        enumMemberValue = jsUndefined();
    else {
        enumMemberValue = object->get(&state, Identifier::fromString(&state, "enumMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!enumMemberValue.isUndefined()) {
        result.enumMember = convert<IDLEnumeration<TestStandaloneDictionary::EnumInStandaloneDictionaryFile>>(state, enumMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    JSValue stringMemberValue;
    if (isNullOrUndefined)
        stringMemberValue = jsUndefined();
    else {
        stringMemberValue = object->get(&state, Identifier::fromString(&state, "stringMember"));
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    if (!stringMemberValue.isUndefined()) {
        result.stringMember = convert<IDLDOMString>(state, stringMemberValue);
        RETURN_IF_EXCEPTION(throwScope, { });
    }
    return result;
}
Esempio n. 20
0
int main(int argc, char **argv)
{
    // expecting a filename
    if (argc < 2) {
        fprintf(stderr, "You have to specify at least one filename\n");
        return -1;
    }
    
    bool ret = true;
    {
        JSLock lock;
        
        // create interpreter w/ global object
        Global* global = new Global();
        RefPtr<Interpreter> interp = new Interpreter(global);
        ExecState *exec = interp->globalExec();
        
        MyObject *myObject = (MyObject *)_NPN_CreateObject (NPP(0), myFunctionPtrs);
        
// FIXME
//        global->put(exec, Identifier("myInterface"), Instance::createRuntimeObject(Instance::CLanguage, (void *)myObject));
        
        for (int i = 1; i < argc; i++) {
            const char *code = readJavaScriptFromFile(argv[i]);
            
            if (code) {
                // run
                Completion comp(interp->evaluate("", 0, code));
                
                if (comp.complType() == Throw) {
                    JSValue *exVal = comp.value();
                    char *msg = exVal->toString(exec).ascii();
                    int lineno = -1;
                    if (exVal->type() == ObjectType) {
                        JSValue *lineVal = exVal->getObject()->get(exec, Identifier("line"));
                        if (lineVal->type() == NumberType)
                            lineno = int(lineVal->toNumber(exec));
                    }
                    if (lineno != -1)
                        fprintf(stderr,"Exception, line %d: %s\n",lineno,msg);
                    else
                        fprintf(stderr,"Exception: %s\n",msg);
                    ret = false;
                }
                else if (comp.complType() == ReturnValue) {
                    char *msg = comp.value()->toString(interp->globalExec()).ascii();
                    fprintf(stderr,"Return value: %s\n",msg);
                }
            }
        }
                
        _NPN_ReleaseObject ((NPObject *)myObject);
        
    } // end block, so that Interpreter and global get deleted
    
    return ret ? 0 : 3;
}
Esempio n. 21
0
JSValue JSMessageEvent::data(ExecState& state) const
{
    if (JSValue cachedValue = m_data.get()) {
        // We cannot use a cached object if we are in a different world than the one it was created in.
        if (!cachedValue.isObject() || &worldForDOMObject(cachedValue.getObject()) == &currentWorld(&state))
            return cachedValue;
        ASSERT_NOT_REACHED();
    }

    MessageEvent& event = wrapped();
    JSValue result;
    switch (event.dataType()) {
    case MessageEvent::DataTypeScriptValue: {
        JSValue dataValue = event.dataAsScriptValue();
        if (!dataValue)
            result = jsNull();
        else {
            // We need to make sure MessageEvents do not leak objects in their state property across isolated DOM worlds.
            // Ideally, we would check that the worlds have different privileges but that's not possible yet.
            if (dataValue.isObject() && &worldForDOMObject(dataValue.getObject()) != &currentWorld(&state)) {
                RefPtr<SerializedScriptValue> serializedValue = event.trySerializeData(&state);
                if (serializedValue)
                    result = serializedValue->deserialize(state, globalObject());
                else
                    result = jsNull();
            } else
                result = dataValue;
        }
        break;
    }

    case MessageEvent::DataTypeSerializedScriptValue:
        if (RefPtr<SerializedScriptValue> serializedValue = event.dataAsSerializedScriptValue()) {
            Vector<RefPtr<MessagePort>> ports = wrapped().ports();
            // FIXME: Why does this suppress exceptions?
            result = serializedValue->deserialize(state, globalObject(), ports, NonThrowing);
        } else
            result = jsNull();
        break;

    case MessageEvent::DataTypeString:
        result = jsStringWithCache(&state, event.dataAsString());
        break;

    case MessageEvent::DataTypeBlob:
        result = toJS(&state, globalObject(), event.dataAsBlob());
        break;

    case MessageEvent::DataTypeArrayBuffer:
        result = toJS(&state, globalObject(), event.dataAsArrayBuffer());
        break;
    }

    // Save the result so we don't have to deserialize the value again.
    m_data.set(state.vm(), this, result);
    return result;
}
Esempio n. 22
0
static RefPtr<InspectorValue> jsToInspectorValue(ExecState* scriptState, JSValue value, int maxDepth)
{
    if (!value) {
        ASSERT_NOT_REACHED();
        return nullptr;
    }

    if (!maxDepth)
        return nullptr;

    maxDepth--;

    if (value.isNull() || value.isUndefined())
        return InspectorValue::null();
    if (value.isBoolean())
        return InspectorValue::create(value.asBoolean());
    if (value.isNumber() && value.isDouble())
        return InspectorValue::create(value.asNumber());
    if (value.isNumber() && value.isMachineInt())
        return InspectorValue::create(static_cast<int>(value.asMachineInt()));
    if (value.isString())
        return InspectorValue::create(value.getString(scriptState));

    if (value.isObject()) {
        if (isJSArray(value)) {
            Ref<InspectorArray> inspectorArray = InspectorArray::create();
            JSArray* array = asArray(value);
            unsigned length = array->length();
            for (unsigned i = 0; i < length; i++) {
                JSValue element = array->getIndex(scriptState, i);
                RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element, maxDepth);
                if (!elementValue)
                    return nullptr;
                inspectorArray->pushValue(WTFMove(elementValue));
            }
            return WTFMove(inspectorArray);
        }
        Ref<InspectorObject> inspectorObject = InspectorObject::create();
        JSObject* object = value.getObject();
        PropertyNameArray propertyNames(scriptState, PropertyNameMode::Strings);
        object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, EnumerationMode());
        for (size_t i = 0; i < propertyNames.size(); i++) {
            const Identifier& name = propertyNames[i];
            JSValue propertyValue = object->get(scriptState, name);
            RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue, maxDepth);
            if (!inspectorValue)
                return nullptr;
            inspectorObject->setValue(name.string(), WTFMove(inspectorValue));
        }
        return WTFMove(inspectorObject);
    }

    ASSERT_NOT_REACHED();
    return nullptr;
}
Esempio n. 23
0
ExceptionOr<Ref<JSCustomXPathNSResolver>> JSCustomXPathNSResolver::create(ExecState& state, JSValue value)
{
    if (value.isUndefinedOrNull())
        return Exception { TypeError };

    auto* resolverObject = value.getObject();
    if (!resolverObject)
        return Exception { TYPE_MISMATCH_ERR };

    return adoptRef(*new JSCustomXPathNSResolver(state.vm(), resolverObject, asJSDOMWindow(state.vmEntryGlobalObject())));
}
Esempio n. 24
0
RefPtr<ReadableJSStream> ReadableJSStream::create(ExecState& state, ScriptExecutionContext& scriptExecutionContext)
{
    // FIXME: We should consider reducing the binding code herei (using Dictionary/regular binding constructor and/or improving the IDL generator). 
    JSObject* jsSource;
    JSValue value = state.argument(0);
    if (value.isObject())
        jsSource = value.getObject();
    else if (!value.isUndefined()) {
        throwVMError(&state, createTypeError(&state, ASCIILiteral("First argument, if any, should be an object")));
        return nullptr;
    } else
        jsSource = JSFinalObject::create(state.vm(), JSFinalObject::createStructure(state.vm(), state.callee()->globalObject(), jsNull(), 1));

    double highWaterMark = 1;
    JSFunction* sizeFunction = nullptr;
    value = state.argument(1);
    if (value.isObject()) {
        JSObject& strategyObject = *value.getObject();
        highWaterMark = normalizeHighWaterMark(state, strategyObject);
        if (state.hadException())
            return nullptr;

        if (!(sizeFunction = jsDynamicCast<JSFunction*>(getPropertyFromObject(state, strategyObject, "size")))) {
            if (!state.hadException())
                throwVMError(&state, createTypeError(&state, ASCIILiteral("size parameter should be a function")));
            return nullptr;
        }
        
    } else if (!value.isUndefined()) {
        throwVMError(&state, createTypeError(&state, ASCIILiteral("Second argument, if any, should be an object")));
        return nullptr;
    }

    RefPtr<ReadableJSStream> readableStream = adoptRef(*new ReadableJSStream(scriptExecutionContext, state, jsSource, highWaterMark, sizeFunction));
    readableStream->doStart(state);

    if (state.hadException())
        return nullptr;

    return readableStream;
}
PassRefPtr<VoidCallback> toVoidCallback(ExecState* exec, JSValue value)
{
    JSObject* object = value.getObject();
    if (!object)
        return 0;
    
    Frame* frame = asJSDOMWindow(exec->dynamicGlobalObject())->impl()->frame();
    if (!frame)
        return 0;
    
    return JSCustomVoidCallback::create(object, frame);
}
Esempio n. 26
0
static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value, int maxDepth)
{
    if (!value) {
        ASSERT_NOT_REACHED();
        return 0;
    }

    if (!maxDepth)
        return 0;
    maxDepth--;

    if (value.isNull() || value.isUndefined())
        return InspectorValue::null();
    if (value.isBoolean())
        return InspectorBasicValue::create(value.asBoolean());
    if (value.isNumber())
        return InspectorBasicValue::create(value.asNumber());
    if (value.isString()) {
        String s = value.getString(scriptState);
        return InspectorString::create(String(s.characters(), s.length()));
    }
    if (value.isObject()) {
        if (isJSArray(value)) {
            RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
            JSArray* array = asArray(value);
            unsigned length = array->length();
            for (unsigned i = 0; i < length; i++) {
                // FIXME: What if the array is in sparse mode? https://bugs.webkit.org/show_bug.cgi?id=95610
                JSValue element = array->getIndexQuickly(i);
                RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element, maxDepth);
                if (!elementValue)
                    return 0;
                inspectorArray->pushValue(elementValue);
            }
            return inspectorArray;
        }
        RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
        JSObject* object = value.getObject();
        PropertyNameArray propertyNames(scriptState);
        object->methodTable()->getOwnPropertyNames(object, scriptState, propertyNames, ExcludeDontEnumProperties);
        for (size_t i = 0; i < propertyNames.size(); i++) {
            const Identifier& name =  propertyNames[i];
            JSValue propertyValue = object->get(scriptState, name);
            RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue, maxDepth);
            if (!inspectorValue)
                return 0;
            inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue);
        }
        return inspectorObject;
    }
    ASSERT_NOT_REACHED();
    return 0;
}
bool JSCryptoAlgorithmDictionary::getAlgorithmIdentifier(ExecState* exec, JSValue value, CryptoAlgorithmIdentifier& algorithmIdentifier)
{
    // typedef (Algorithm or DOMString) AlgorithmIdentifier;

    String algorithmName;

    if (value.isString())
        algorithmName = value.toString(exec)->value(exec);
    else if (value.isObject()) {
        if (value.getObject()->inherits(StringObject::info()))
            algorithmName = asString(asStringObject(value)->internalValue())->value(exec);
        else {
            // FIXME: This doesn't perform some checks mandated by WebIDL for dictionaries:
            // - null and undefined input should be treated as if all elements in the dictionary were undefined;
            // - undefined elements should be treated as having a default value, or as not present if there isn't such;
            // - RegExp and Date objects cannot be converted to dictionaries.
            //
            // This is partially because we don't implement it elsewhere in WebCore yet, and partially because
            // WebCrypto doesn't yet clearly specify what to do with non-present values in most cases anyway.

            JSDictionary dictionary(exec, value.getObject());
            dictionary.get("name", algorithmName);
        }
    }

    if (exec->hadException())
        return false;

    if (!algorithmName.containsOnlyASCII()) {
        throwSyntaxError(exec);
        return false;
    }

    if (!CryptoAlgorithmRegistry::singleton().getIdentifierForName(algorithmName, algorithmIdentifier)) {
        setDOMException(exec, NOT_SUPPORTED_ERR);
        return false;
    }

    return true;
}
static JSObject* getCustomElementCallback(ExecState& state, JSObject& prototype, const Identifier& id)
{
    JSValue callback = prototype.get(&state, id);
    if (state.hadException())
        return nullptr;
    if (callback.isUndefined())
        return nullptr;
    if (!callback.isFunction()) {
        throwTypeError(&state, ASCIILiteral("A custom element callback must be a function"));
        return nullptr;
    }
    return callback.getObject();
}
Esempio n. 29
0
PassRefPtr<JSCustomXPathNSResolver> JSCustomXPathNSResolver::create(ExecState* exec, JSValue value)
{
    if (value.isUndefinedOrNull())
        return 0;

    JSObject* resolverObject = value.getObject();
    if (!resolverObject) {
        setDOMException(exec, TYPE_MISMATCH_ERR);
        return 0;
    }

    return adoptRef(new JSCustomXPathNSResolver(exec, resolverObject, asJSDOMWindow(exec->dynamicGlobalObject())));
}
Esempio n. 30
0
static PassRefPtr<InspectorValue> jsToInspectorValue(ScriptState* scriptState, JSValue value)
{
    if (!value) {
        ASSERT_NOT_REACHED();
        return 0;
    }
    if (value.isNull() || value.isUndefined())
        return InspectorValue::null();
    if (value.isBoolean())
        return InspectorBasicValue::create(value.getBoolean());
    if (value.isNumber())
        return InspectorBasicValue::create(value.uncheckedGetNumber());
    if (value.isString()) {
        UString s = value.getString(scriptState);
        return InspectorString::create(String(s.characters(), s.length()));
    }
    if (value.isObject()) {
        if (isJSArray(&scriptState->globalData(), value)) {
            RefPtr<InspectorArray> inspectorArray = InspectorArray::create();
            JSArray* array = asArray(value);
            unsigned length = array->length();
            for (unsigned i = 0; i < length; i++) {
                JSValue element = array->getIndex(i);
                RefPtr<InspectorValue> elementValue = jsToInspectorValue(scriptState, element);
                if (!elementValue) {
                    ASSERT_NOT_REACHED();
                    elementValue = InspectorValue::null();
                }
                inspectorArray->pushValue(elementValue);
            }
            return inspectorArray;
        }
        RefPtr<InspectorObject> inspectorObject = InspectorObject::create();
        JSObject* object = value.getObject();
        PropertyNameArray propertyNames(scriptState);
        object->getOwnPropertyNames(scriptState, propertyNames);
        for (size_t i = 0; i < propertyNames.size(); i++) {
            const Identifier& name =  propertyNames[i];
            JSValue propertyValue = object->get(scriptState, name);
            RefPtr<InspectorValue> inspectorValue = jsToInspectorValue(scriptState, propertyValue);
            if (!inspectorValue) {
                ASSERT_NOT_REACHED();
                inspectorValue = InspectorValue::null();
            }
            inspectorObject->setValue(String(name.characters(), name.length()), inspectorValue);
        }
        return inspectorObject;
    }
    ASSERT_NOT_REACHED();
    return 0;
}