### Begin File: JSCBuiltins.h
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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

#pragma once

namespace JSC {
class FunctionExecutable;
class VM;

enum class ConstructAbility : uint8_t;
enum class ConstructorKind : uint8_t;
}

namespace JSC {

extern const char s_JSCCombinedCode[];

extern const unsigned s_JSCCombinedCodeLength;

/* InternalClashingNames */
extern const char* const s_internalClashingNamesIsReadableStreamLockedCode;
extern const int s_internalClashingNamesIsReadableStreamLockedCodeLength;
extern const JSC::ConstructAbility s_internalClashingNamesIsReadableStreamLockedCodeConstructAbility;
extern const JSC::ConstructorKind s_internalClashingNamesIsReadableStreamLockedCodeConstructorKind;
extern const char* const s_internalClashingNamesIsReadableStreamLockedCode;
extern const int s_internalClashingNamesIsReadableStreamLockedCodeLength;
extern const JSC::ConstructAbility s_internalClashingNamesIsReadableStreamLockedCodeConstructAbility;
extern const JSC::ConstructorKind s_internalClashingNamesIsReadableStreamLockedCodeConstructorKind;

#define JSC_FOREACH_INTERNALCLASHINGNAMES_BUILTIN_DATA(macro) \
    macro(isReadableStreamLocked, internalClashingNamesIsReadableStreamLocked, 1) \
    macro(isReadableStreamLocked, internalClashingNamesIsReadableStreamLocked, 1) \

#define JSC_FOREACH_BUILTIN_CODE(macro) \
    macro(internalClashingNamesIsReadableStreamLockedCode, isReadableStreamLocked, static_cast<const char*>(nullptr), s_internalClashingNamesIsReadableStreamLockedCodeLength) \
    macro(internalClashingNamesIsReadableStreamLockedCode, isReadableStreamLocked, static_cast<const char*>(nullptr), s_internalClashingNamesIsReadableStreamLockedCodeLength) \

#define JSC_FOREACH_BUILTIN_FUNCTION_NAME(macro) \
    macro(isReadableStreamLocked) \

#define JSC_FOREACH_BUILTIN_FUNCTION_PRIVATE_GLOBAL_NAME(macro) \

#define DECLARE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
    JSC::FunctionExecutable* codeName##Generator(JSC::VM&);

JSC_FOREACH_BUILTIN_CODE(DECLARE_BUILTIN_GENERATOR)
#undef DECLARE_BUILTIN_GENERATOR

} // namespace JSC
### End File: JSCBuiltins.h

### Begin File: JSCBuiltins.cpp
/*
 * Copyright (c) 2015 Canon Inc. All rights reserved.
 * 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 "JSCBuiltins.h"

#include "BuiltinExecutables.h"
#include "HeapInlines.h"
#include "IdentifierInlines.h"
#include "Intrinsic.h"
#include "JSCellInlines.h"
#include "UnlinkedFunctionExecutable.h"
#include "VM.h"

namespace JSC {

const char s_JSCCombinedCode[] = { 40, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 115, 116, 114, 101, 97, 109, 41, 10, 123, 10, 32, 32, 32, 34, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 34, 59, 10, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 33, 33, 115, 116, 114, 101, 97, 109, 46, 64, 114, 101, 97, 100, 101, 114, 59, 10, 125, 41, 10, 40, 102, 117, 110, 99, 116, 105, 111, 110, 32, 40, 115, 116, 114, 101, 97, 109, 41, 10, 123, 10, 32, 32, 32, 34, 117, 115, 101, 32, 115, 116, 114, 105, 99, 116, 34, 59, 10, 10, 32, 32, 32, 32, 114, 101, 116, 117, 114, 110, 32, 33, 33, 115, 116, 114, 101, 97, 109, 46, 64, 114, 101, 97, 100, 101, 114, 59, 10, 125, 41, 10 };

const unsigned s_JSCCombinedCodeLength = 142;

const JSC::ConstructAbility s_internalClashingNamesIsReadableStreamLockedCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_internalClashingNamesIsReadableStreamLockedCodeConstructorKind = JSC::ConstructorKind::None;
const int s_internalClashingNamesIsReadableStreamLockedCodeLength = 71;
static const JSC::Intrinsic s_internalClashingNamesIsReadableStreamLockedCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_internalClashingNamesIsReadableStreamLockedCode =
s_JSCCombinedCode + 0
;

const JSC::ConstructAbility s_internalClashingNamesIsReadableStreamLockedCodeConstructAbility = JSC::ConstructAbility::CannotConstruct;
const JSC::ConstructorKind s_internalClashingNamesIsReadableStreamLockedCodeConstructorKind = JSC::ConstructorKind::None;
const int s_internalClashingNamesIsReadableStreamLockedCodeLength = 71;
static const JSC::Intrinsic s_internalClashingNamesIsReadableStreamLockedCodeIntrinsic = JSC::NoIntrinsic;
const char* const s_internalClashingNamesIsReadableStreamLockedCode =
s_JSCCombinedCode + 71
;


#define DEFINE_BUILTIN_GENERATOR(codeName, functionName, overriddenName, argumentCount) \
JSC::FunctionExecutable* codeName##Generator(JSC::VM& vm) \
{\
    return vm.builtinExecutables()->codeName##Executable()->link(vm, nullptr, vm.builtinExecutables()->codeName##Source(), WTF::nullopt, s_##codeName##Intrinsic); }
JSC_FOREACH_BUILTIN_CODE(DEFINE_BUILTIN_GENERATOR)
#undef DEFINE_BUILTIN_GENERATOR


} // namespace JSC
### End File: JSCBuiltins.cpp
