JSObjectRef JSObjectCallAsConstructor(JSContextRef ctx, JSObjectRef object, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { ExecState* exec = toJS(ctx); VM& vm = exec->vm(); JSLockHolder locker(vm); auto scope = DECLARE_CATCH_SCOPE(vm); if (!object) return 0; JSObject* jsObject = toJS(object); ConstructData constructData; ConstructType constructType = jsObject->methodTable(vm)->getConstructData(jsObject, constructData); if (constructType == ConstructType::None) return 0; MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; i++) argList.append(toJS(exec, arguments[i])); if (UNLIKELY(argList.hasOverflowed())) { auto throwScope = DECLARE_THROW_SCOPE(vm); throwOutOfMemoryError(exec, throwScope); handleExceptionIfNeeded(scope, exec, exception); return 0; } JSObjectRef result = toRef(profiledConstruct(exec, ProfilingReason::API, jsObject, constructType, constructData, argList)); if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow) result = 0; return result; }
CallbackResult<typename IDLDOMString::ImplementationType> JSTestCallbackFunction::handleEvent(typename IDLLong::ParameterType argument) { if (!canInvokeCallback()) return CallbackResultType::UnableToExecute; Ref<JSTestCallbackFunction> protectedThis(*this); auto& globalObject = *m_data->globalObject(); auto& vm = globalObject.vm(); JSLockHolder lock(vm); auto& state = *globalObject.globalExec(); JSValue thisValue = jsUndefined(); MarkedArgumentBuffer args; args.append(toJS<IDLLong>(argument)); ASSERT(!args.hasOverflowed()); NakedPtr<JSC::Exception> returnedException; auto jsResult = m_data->invokeCallback(thisValue, args, JSCallbackData::CallbackType::Function, Identifier(), returnedException); if (returnedException) { reportException(&state, returnedException); return CallbackResultType::ExceptionThrown; } auto throwScope = DECLARE_THROW_SCOPE(vm); auto returnValue = convert<IDLDOMString>(state, jsResult); RETURN_IF_EXCEPTION(throwScope, CallbackResultType::ExceptionThrown); return WTFMove(returnValue); }
JSValue iteratorNext(ExecState* exec, IterationRecord iterationRecord, JSValue argument) { VM& vm = exec->vm(); auto scope = DECLARE_THROW_SCOPE(vm); JSValue iterator = iterationRecord.iterator; JSValue nextFunction = iterationRecord.nextMethod; CallData nextFunctionCallData; CallType nextFunctionCallType = getCallData(vm, nextFunction, nextFunctionCallData); if (nextFunctionCallType == CallType::None) return throwTypeError(exec, scope); MarkedArgumentBuffer nextFunctionArguments; if (!argument.isEmpty()) nextFunctionArguments.append(argument); ASSERT(!nextFunctionArguments.hasOverflowed()); JSValue result = call(exec, nextFunction, nextFunctionCallType, nextFunctionCallData, iterator, nextFunctionArguments); RETURN_IF_EXCEPTION(scope, JSValue()); if (!result.isObject()) return throwTypeError(exec, scope, "Iterator result interface is not an object."_s); return result; }
JSObjectRef JSObjectMakeRegExp(JSContextRef ctx, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); VM& vm = exec->vm(); JSLockHolder locker(vm); auto scope = DECLARE_CATCH_SCOPE(vm); MarkedArgumentBuffer argList; for (size_t i = 0; i < argumentCount; ++i) argList.append(toJS(exec, arguments[i])); if (UNLIKELY(argList.hasOverflowed())) { auto throwScope = DECLARE_THROW_SCOPE(vm); throwOutOfMemoryError(exec, throwScope); handleExceptionIfNeeded(scope, exec, exception); return 0; } JSObject* result = constructRegExp(exec, exec->lexicalGlobalObject(), argList); if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow) result = 0; return toRef(result); }
JSObjectRef JSObjectMakeFunction(JSContextRef ctx, JSStringRef name, unsigned parameterCount, const JSStringRef parameterNames[], JSStringRef body, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) { if (!ctx) { ASSERT_NOT_REACHED(); return 0; } ExecState* exec = toJS(ctx); VM& vm = exec->vm(); JSLockHolder locker(vm); auto scope = DECLARE_CATCH_SCOPE(vm); startingLineNumber = std::max(1, startingLineNumber); Identifier nameID = name ? name->identifier(&vm) : Identifier::fromString(exec, "anonymous"); MarkedArgumentBuffer args; for (unsigned i = 0; i < parameterCount; i++) args.append(jsString(exec, parameterNames[i]->string())); args.append(jsString(exec, body->string())); if (UNLIKELY(args.hasOverflowed())) { auto throwScope = DECLARE_THROW_SCOPE(vm); throwOutOfMemoryError(exec, throwScope); handleExceptionIfNeeded(scope, exec, exception); return 0; } auto sourceURLString = sourceURL ? sourceURL->string() : String(); JSObject* result = constructFunction(exec, exec->lexicalGlobalObject(), args, nameID, SourceOrigin { sourceURLString }, sourceURLString, TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); if (handleExceptionIfNeeded(scope, exec, exception) == ExceptionStatus::DidThrow) result = 0; return toRef(result); }
void ReadableStream::pipeTo(ReadableStreamSink& sink) { auto& state = *m_globalObject->globalExec(); JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData); const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamPipeToPrivateName(); auto readableStreamPipeTo = m_globalObject->get(&state, privateName); ASSERT(readableStreamPipeTo.isFunction(state.vm())); MarkedArgumentBuffer arguments; arguments.append(readableStream()); arguments.append(toJS(&state, m_globalObject.get(), sink)); ASSERT(!arguments.hasOverflowed()); ReadableStreamInternal::callFunction(state, readableStreamPipeTo, JSC::jsUndefined(), arguments); }
void iteratorClose(ExecState* exec, IterationRecord iterationRecord) { VM& vm = exec->vm(); auto throwScope = DECLARE_THROW_SCOPE(vm); auto catchScope = DECLARE_CATCH_SCOPE(vm); Exception* exception = nullptr; if (UNLIKELY(catchScope.exception())) { exception = catchScope.exception(); catchScope.clearException(); } JSValue returnFunction = iterationRecord.iterator.get(exec, vm.propertyNames->returnKeyword); RETURN_IF_EXCEPTION(throwScope, void()); if (returnFunction.isUndefined()) { if (exception) throwException(exec, throwScope, exception); return; } CallData returnFunctionCallData; CallType returnFunctionCallType = getCallData(vm, returnFunction, returnFunctionCallData); if (returnFunctionCallType == CallType::None) { if (exception) throwException(exec, throwScope, exception); else throwTypeError(exec, throwScope); return; } MarkedArgumentBuffer returnFunctionArguments; ASSERT(!returnFunctionArguments.hasOverflowed()); JSValue innerResult = call(exec, returnFunction, returnFunctionCallType, returnFunctionCallData, iterationRecord.iterator, returnFunctionArguments); if (exception) { throwException(exec, throwScope, exception); return; } RETURN_IF_EXCEPTION(throwScope, void()); if (!innerResult.isObject()) { throwTypeError(exec, throwScope, "Iterator result interface is not an object."_s); return; } }
std::pair<Ref<ReadableStream>, Ref<ReadableStream>> ReadableStream::tee() { auto& state = *m_globalObject->globalExec(); JSVMClientData* clientData = static_cast<JSVMClientData*>(state.vm().clientData); const Identifier& privateName = clientData->builtinFunctions().readableStreamInternalsBuiltins().readableStreamTeePrivateName(); auto readableStreamTee = m_globalObject->get(&state, privateName); ASSERT(readableStreamTee.isFunction(state.vm())); MarkedArgumentBuffer arguments; arguments.append(readableStream()); arguments.append(JSC::jsBoolean(true)); ASSERT(!arguments.hasOverflowed()); auto returnedValue = ReadableStreamInternal::callFunction(state, readableStreamTee, JSC::jsUndefined(), arguments); auto results = Detail::SequenceConverter<IDLInterface<ReadableStream>>::convert(state, returnedValue); ASSERT(results.size() == 2); return std::make_pair(results[0].releaseNonNull(), results[1].releaseNonNull()); }
void ReadableStream::lock() { auto& state = *m_globalObject->globalExec(); VM& vm = state.vm(); auto scope = DECLARE_CATCH_SCOPE(vm); auto& clientData = *static_cast<JSVMClientData*>(vm.clientData); auto* constructor = JSC::asObject(m_globalObject->get(&state, clientData.builtinNames().ReadableStreamDefaultReaderPrivateName())); ConstructData constructData; ConstructType constructType = constructor->methodTable(vm)->getConstructData(constructor, constructData); ASSERT(constructType != ConstructType::None); MarkedArgumentBuffer args; args.append(readableStream()); ASSERT(!args.hasOverflowed()); JSC::construct(&state, constructor, constructType, constructData, args); scope.assertNoException(); }
Ref<ReadableStream> ReadableStream::create(JSC::ExecState& execState, RefPtr<ReadableStreamSource>&& source) { VM& vm = execState.vm(); auto scope = DECLARE_CATCH_SCOPE(vm); auto& clientData = *static_cast<JSVMClientData*>(vm.clientData); auto& globalObject = *JSC::jsCast<JSDOMGlobalObject*>(execState.lexicalGlobalObject()); auto* constructor = JSC::asObject(globalObject.get(&execState, clientData.builtinNames().ReadableStreamPrivateName())); ConstructData constructData; ConstructType constructType = constructor->methodTable(vm)->getConstructData(constructor, constructData); ASSERT(constructType != ConstructType::None); MarkedArgumentBuffer args; args.append(source ? toJSNewlyCreated(&execState, &globalObject, source.releaseNonNull()) : JSC::jsUndefined()); ASSERT(!args.hasOverflowed()); auto newReadableStream = jsDynamicCast<JSReadableStream*>(vm, JSC::construct(&execState, constructor, constructType, constructData, args)); scope.assertNoException(); return create(globalObject, *newReadableStream); }
// FIXME: This should use the IDLUnion JSConverter. JSValue convertToJSValue(ExecState& state, JSDOMGlobalObject& globalObject, const WebGLAny& any) { return WTF::switchOn(any, [] (std::nullptr_t) { return jsNull(); }, [] (bool value) { return jsBoolean(value); }, [] (int value) { return jsNumber(value); }, [] (unsigned value) { return jsNumber(value); }, [] (long long value) { return jsNumber(value); }, [] (float value) { return jsNumber(value); }, [&] (const String& value) { return jsStringWithCache(&state, value); }, [&] (const Vector<bool>& values) { MarkedArgumentBuffer list; for (auto& value : values) list.append(jsBoolean(value)); RELEASE_ASSERT(!list.hasOverflowed()); return constructArray(&state, 0, &globalObject, list); }, [&] (const Vector<int>& values) { MarkedArgumentBuffer list; for (auto& value : values) list.append(jsNumber(value)); RELEASE_ASSERT(!list.hasOverflowed()); return constructArray(&state, 0, &globalObject, list); }, [&] (const RefPtr<Float32Array>& array) { return toJS(&state, &globalObject, array.get()); }, [&] (const RefPtr<Int32Array>& array) { return toJS(&state, &globalObject, array.get()); }, [&] (const RefPtr<Uint8Array>& array) { return toJS(&state, &globalObject, array.get()); }, [&] (const RefPtr<Uint32Array>& array) { return toJS(&state, &globalObject, array.get()); }, [&] (const RefPtr<WebGLBuffer>& buffer) { return toJS(&state, &globalObject, buffer.get()); }, [&] (const RefPtr<WebGLFramebuffer>& buffer) { return toJS(&state, &globalObject, buffer.get()); }, [&] (const RefPtr<WebGLProgram>& program) { return toJS(&state, &globalObject, program.get()); }, [&] (const RefPtr<WebGLRenderbuffer>& buffer) { return toJS(&state, &globalObject, buffer.get()); }, [&] (const RefPtr<WebGLTexture>& texture) { return toJS(&state, &globalObject, texture.get()); }, [&] (const RefPtr<WebGLVertexArrayObjectOES>& array) { return toJS(&state, &globalObject, array.get()); } #if ENABLE(WEBGL2) , [&] (const RefPtr<WebGLVertexArrayObject>& array) { return toJS(&state, &globalObject, array.get()); } #endif ); }