/*
 * Copyright (c) 2016 Apple Inc.
 * Copyright (c) 2016 Apple Inc. All rights reserved.
 * 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 * 
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 * THE POSSIBILITY OF SUCH DAMAGE.
 * 
 */

// DO NOT EDIT THIS FILE. It is automatically generated from JavaScript files for
// builtins by the script: Source/JavaScriptCore/Scripts/generate-js-builtins.py

#include "config.h"
#include "FetchRequestBuiltins.h"

#if ENABLE(FETCH_API)

#include "WebCoreJSClientData.h"
#include <heap/HeapInlines.h>
#include <runtime/Executable.h>
#include <runtime/Intrinsic.h>
#include <runtime/JSCJSValueInlines.h>
#include <runtime/JSCellInlines.h>
#include <runtime/StructureInlines.h>
#include <runtime/VM.h>

namespace WebCore {

const JSC::ConstructAbility s_fetchRequestInitializeFetchRequestCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const int s_fetchRequestInitializeFetchRequestCodeLength = 662;
static const JSC::Intrinsic s_fetchRequestInitializeFetchRequestCodeIntrinsic = JSC::NoIntrinsic;
const char* s_fetchRequestInitializeFetchRequestCode =
    "(function (input, init)\n" \
    "{\n" \
    "    \"use strict\";\n" \
    "    if (init === @undefined)\n" \
    "        init = { };\n" \
    "    else if (!@isObject(init))\n" \
    "        throw new @TypeError(\"Request init must be an object\");\n" \
    "    let headers = this.@initializeWith(input, init);\n" \
    "    @assert(headers instanceof @Headers);\n" \
    "    let inputIsRequest = input instanceof @Request;\n" \
    "    if (\"headers\" in init)\n" \
    "        @fillFetchHeaders(headers, init.headers)\n" \
    "    else if (inputIsRequest)\n" \
    "        @fillFetchHeaders(headers, input.headers)\n" \
    "    let hasInitBody = init.body !== @undefined && init.body !== null;\n" \
    "    this.@setBody(hasInitBody ? init.body : null, inputIsRequest ? input : null);\n" \
    "    return this;\n" \
    "})\n" \
;


#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, argumentCount) \
JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
{\
    JSVMClientData* clientData = static_cast<JSVMClientData*>(vm.clientData); \
    return clientData->builtinFunctions().fetchRequestBuiltins().codeName##Executable()->link(vm, clientData->builtinFunctions().fetchRequestBuiltins().codeName##Source(), Nullopt, s_##codeName##Intrinsic); \
}
WEBCORE_FOREACH_FETCHREQUEST_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
#undef DEFINE_BUILTIN_GENERATOR


} // namespace WebCore

#endif // ENABLE(FETCH_API)
