/*
 * Copyright 2016 Google Inc. All Rights Reserved.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

// This file has been auto-generated by bindings/code_generator_cobalt.py. DO NOT MODIFY!
// Auto-generated from template: bindings/javascriptcore/templates/interface.cc.template

// clang-format off

#include "third_party/WebKit/Source/JavaScriptCore/config.h"

#include "JSCOperationsTestInterface.h"

#include "base/debug/trace_event.h"
#include "cobalt/base/polymorphic_downcast.h"
#include "cobalt/script/global_environment.h"
#include "cobalt/script/opaque_handle.h"
#include "cobalt/script/script_object.h"
#include "JSCArbitraryInterface.h"
#include "cobalt/bindings/testing/arbitrary_interface.h"

#include "cobalt/script/javascriptcore/constructor_base.h"
#include "cobalt/script/javascriptcore/conversion_helpers.h"
#include "cobalt/script/javascriptcore/prototype_base.h"
#include "cobalt/script/javascriptcore/jsc_callback_function.h"
#include "cobalt/script/javascriptcore/jsc_callback_interface_holder.h"
#include "cobalt/script/javascriptcore/jsc_exception_state.h"
#include "cobalt/script/javascriptcore/jsc_global_environment.h"
#include "cobalt/script/javascriptcore/jsc_global_object.h"
#include "cobalt/script/javascriptcore/jsc_object_handle.h"
#include "cobalt/script/javascriptcore/jsc_object_handle_holder.h"
#include "cobalt/script/javascriptcore/type_traits.h"
#include "cobalt/script/javascriptcore/util/binding_helpers.h"
#include "cobalt/script/javascriptcore/util/exception_helpers.h"
#include "third_party/WebKit/Source/JavaScriptCore/interpreter/Interpreter.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/Error.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/FunctionPrototype.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/Identifier.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/JSFunction.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/JSGlobalObject.h"
#include "third_party/WebKit/Source/JavaScriptCore/runtime/ObjectPrototype.h"

namespace {
using cobalt::bindings::testing::OperationsTestInterface;
using cobalt::bindings::testing::JSCOperationsTestInterface;
using cobalt::bindings::testing::ArbitraryInterface;
using cobalt::bindings::testing::JSCArbitraryInterface;
using cobalt::script::CallbackInterfaceTraits;
using cobalt::script::GlobalEnvironment;
using cobalt::script::OpaqueHandle;
using cobalt::script::OpaqueHandleHolder;
using cobalt::script::ScriptObject;
using cobalt::script::Wrappable;

using cobalt::script::javascriptcore::kConversionFlagNullable;
using cobalt::script::javascriptcore::kConversionFlagRestricted;
using cobalt::script::javascriptcore::kConversionFlagTreatNullAsEmptyString;
using cobalt::script::javascriptcore::kConversionFlagTreatUndefinedAsEmptyString;
using cobalt::script::javascriptcore::kNoConversionFlags;
using cobalt::script::javascriptcore::ConstructorBase;
using cobalt::script::javascriptcore::GetWrappableOrSetException;
using cobalt::script::javascriptcore::FromJSValue;
using cobalt::script::javascriptcore::FromWTFString;
using cobalt::script::javascriptcore::JSCCallbackFunction;
using cobalt::script::javascriptcore::JSCCallbackFunctionHolder;
using cobalt::script::javascriptcore::JSCCallbackInterfaceHolder;
using cobalt::script::javascriptcore::JSCEngine;
using cobalt::script::javascriptcore::JSCExceptionState;
using cobalt::script::javascriptcore::JSCGlobalEnvironment;
using cobalt::script::javascriptcore::JSCGlobalObject;
using cobalt::script::javascriptcore::JSCObjectHandle;
using cobalt::script::javascriptcore::JSCObjectHandleHolder;
using cobalt::script::javascriptcore::JSObjectToWrappable;
using cobalt::script::javascriptcore::PrototypeBase;
using cobalt::script::javascriptcore::ScriptObjectRegistry;
using cobalt::script::javascriptcore::ThreadLocalHashTable;
using cobalt::script::javascriptcore::ToJSValue;
using cobalt::script::javascriptcore::ToWTFString;
using cobalt::script::javascriptcore::TypeTraits;
using cobalt::script::javascriptcore::WrapperBase;
using cobalt::script::javascriptcore::util::HasPropertyOnPrototype;
using cobalt::script::javascriptcore::util::GetStackTrace;
}  // namespace

namespace cobalt {
namespace bindings {
namespace testing {

namespace {
JSC::EncodedJSValue functionJSlongFunctionNoArgs(JSC::ExecState*);
JSC::EncodedJSValue functionJSobjectFunctionNoArgs(JSC::ExecState*);
JSC::EncodedJSValue functionJSoptionalArgumentWithDefault(JSC::ExecState*);
JSC::EncodedJSValue functionJSoptionalArguments(JSC::ExecState*);
JSC::EncodedJSValue functionJSoptionalNullableArgumentsWithDefaults(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction1(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction2(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction3(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction4(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedFunction5(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedNullable(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedNullable1(JSC::ExecState*);
JSC::EncodedJSValue functionJSoverloadedNullable2(JSC::ExecState*);
JSC::EncodedJSValue functionJSstringFunctionNoArgs(JSC::ExecState*);
JSC::EncodedJSValue functionJSvariadicPrimitiveArguments(JSC::ExecState*);
JSC::EncodedJSValue functionJSvariadicStringArgumentsAfterOptionalArgument(JSC::ExecState*);
JSC::EncodedJSValue functionJSvoidFunctionLongArg(JSC::ExecState*);
JSC::EncodedJSValue functionJSvoidFunctionNoArgs(JSC::ExecState*);
JSC::EncodedJSValue functionJSvoidFunctionObjectArg(JSC::ExecState*);
JSC::EncodedJSValue functionJSvoidFunctionStringArg(JSC::ExecState*);
JSC::EncodedJSValue staticFunctionJSoverloadedFunction(JSC::ExecState*);
JSC::EncodedJSValue staticFunctionJSoverloadedFunction1(JSC::ExecState*);
JSC::EncodedJSValue staticFunctionJSoverloadedFunction2(JSC::ExecState*);

// These are declared unconditionally, but only defined if needed by the
// interface.
JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name);
void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue jsc_value);
bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name);
bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name);
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name);
bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value);

const bool s_has_named_getter = false;
const bool s_has_named_setter = false;
#if !defined(COBALT_BUILD_TYPE_GOLD)
const bool s_use_debug_missing_property_handler = true;
#else
const bool s_use_debug_missing_property_handler = false;
#endif
}  // namespace

// Class that defines a JS Object representing this interface's Interface Object
// https://www.w3.org/TR/WebIDL/#interface-object
class JSCOperationsTestInterface::InterfaceObject : public ConstructorBase {
 public:
  // Get the Interface Object. Will create a new Interface Object if necessary,
  // otherwise it will return the cached one.
  static JSC::JSObject* GetInstance(JSC::ExecState* exec);
  DECLARE_CLASSINFO();

  // Needed when JSC::OverridesGetOwnPropertySlot StructureFlag is set
  // Must be public so that it can be accessible from getStaticValueSlot<>.
  static bool getOwnPropertySlot(JSC::JSCell* cell, JSC::ExecState* exec,
                                 JSC::PropertyName property_name,
                                 JSC::PropertySlot& slot) {
    InterfaceObject* this_object = JSC::jsCast<InterfaceObject*>(cell);
    ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);

    // Same process as JSC::getStaticPropertySlot<>, which is defined in Lookup.h
    // Since JSFunction::getOwnPropertySlot is protected, we can't call it from
    // the helper function.
    const JSC::HashEntry* entry =
        GetPropertyTable(exec)->entry(exec, property_name);

    if (!entry) // not found, forward to parent
      return Base::getOwnPropertySlot(this_object, exec, property_name, slot);

    if (entry->attributes() & JSC::Function)
        return setUpStaticFunctionSlot(exec, entry, this_object, property_name, slot);

    slot.setCacheableCustom(this_object, entry->propertyGetter());
    return true;
  }

  // static override. Needed to support setting a property.
  static void put(JSC::JSCell* cell, JSC::ExecState* exec_state,
                  JSC::PropertyName property_name, JSC::JSValue value,
                  JSC::PutPropertySlot& slot) {
    InterfaceObject* this_object = JSC::jsCast<InterfaceObject*>(cell);
    ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
    bool found_property = JSC::lookupPut<InterfaceObject>(
        exec_state, property_name, value, GetPropertyTable(exec_state),
        this_object, slot.isStrictMode());
    DLOG_IF(INFO, !found_property) << "Did not find property named " <<
        WTF::String(property_name.publicName()).utf8().data() <<
        " to set on interface object for JSCOperationsTestInterface";
    if (!found_property) {
      BaseClass::put(cell, exec_state, property_name, value, slot);
    }
  }

  // static override. This prevents this object from being called as a normal
  // function, throwing a TypeError if the user attempts to do so.
  static JSC::CallType getCallData(JSC::JSCell*, JSC::CallData&) {
    return JSC::CallTypeNone;
  }

  // static override. This prevents this object from being called as a
  // constructor, throwing a TypeError if the user attempts to do so.
  //
  // This method is defined when no constructors are defined on the IDL.
  static JSC::ConstructType getConstructData(JSC::JSCell*, JSC::ConstructData&) {
    return JSC::ConstructTypeNone;
  }

 private:
  typedef ConstructorBase BaseClass;

  static const unsigned StructureFlags =
      JSC::ImplementsHasInstance |
      JSC::OverridesGetOwnPropertySlot |
      BaseClass::StructureFlags;

  InterfaceObject(JSC::ExecState* exec_state, JSC::JSGlobalObject* global_object, JSC::Structure* structure)
      : BaseClass(exec_state, global_object, structure) { }
  void finishCreation(JSC::ExecState* exec_state,
                      JSC::NativeExecutable* native_executable, int length,
                      const String& name);

  static const JSC::HashTable* GetPropertyTable(JSC::ExecState* exec_state);

  static const JSC::HashTableValue property_table_values[];
  static const JSC::HashTable property_table_prototype;
};

const JSC::HashTableValue JSCOperationsTestInterface::InterfaceObject::property_table_values[] = {
    // static functions will also go here.
    { "overloadedFunction",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(staticFunctionJSoverloadedFunction),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) }
};  // JSCOperationsTestInterface::InterfaceObject::property_table_values

// static
const JSC::HashTable
JSCOperationsTestInterface::InterfaceObject::property_table_prototype = {
    // Sizes will be calculated based on the number of static functions as well.
    4,  // compactSize
    3,  // compactSizeMask
    property_table_values,
    NULL  // table allocated at runtime
};  // JSCOperationsTestInterface::InterfaceObject::property_table_prototype

// static
const JSC::HashTable*
JSCOperationsTestInterface::InterfaceObject::GetPropertyTable(
    JSC::ExecState* exec_state) {
  return ThreadLocalHashTable::GetInstance()->GetHashTable(
      JSCOperationsTestInterface::InterfaceObject::s_classinfo(),
      property_table_prototype);
}

const JSC::ClassInfo JSCOperationsTestInterface::InterfaceObject::s_info = {
    "OperationsTestInterfaceConstructor",  // className
    BaseClass::s_classinfo(),  // parentClass
    NULL,  // static hash-table of properties (not used)
    GetPropertyTable,  // function pointer to get hash-table of properties
    CREATE_METHOD_TABLE(JSCOperationsTestInterface::InterfaceObject)
};  // JSCOperationsTestInterface::InterfaceObject::s_info

void JSCOperationsTestInterface::InterfaceObject::finishCreation(
    JSC::ExecState* exec_state, JSC::NativeExecutable* native_executable,
    int length, const String& name) {
  BaseClass::finishCreation(exec_state, native_executable, length, name);
  ASSERT(inherits(&s_info));
  // Add a 'prototype' property whose value is the prototype object.
  putDirect(exec_state->globalData(),
            exec_state->propertyNames().prototype,
            JSCOperationsTestInterface::GetPrototype(exec_state->lexicalGlobalObject()),
            JSC::DontDelete | JSC::ReadOnly | JSC::DontEnum);
  DCHECK(hasOwnProperty(exec_state, JSC::Identifier(exec_state, "prototype")));
}

// static
JSC::JSObject* JSCOperationsTestInterface::InterfaceObject::GetInstance(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      static_cast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  ASSERT_GC_OBJECT_INHERITS(global_object, JSCGlobalObject::s_classinfo());

  // Try to get the cached interface object, and create a new one if needed.
  JSC::JSObject* interface_object = global_object->object_cache()->GetCachedConstructor(&s_info);
  if (interface_object == NULL) {
    JSC::JSGlobalData& global_data = global_object->globalData();
    JSC::JSObject* parent_prototype = global_object->functionPrototype();
    JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags);
    JSC::Structure* structure = JSC::Structure::create(
        global_data,
        global_object,
        JSC::JSValue(parent_prototype),
        type_info,
        &s_info);

    const int kNumArguments = 0;
    // NativeExecutable must be non-null even if this is not actually callable.
    JSC::NativeExecutable* executable = global_data.getHostFunction(NULL, NULL);

    // Create the new interface object.
    InterfaceObject* new_interface_object =
        new (NotNull, JSC::allocateCell<InterfaceObject>(global_data.heap))
        InterfaceObject(exec_state, global_object, structure);
    new_interface_object->finishCreation(exec_state, executable, kNumArguments, "OperationsTestInterface");
    // Add the interface object to the cache.
    global_object->object_cache()->CacheConstructor(&s_info, new_interface_object);
    interface_object = new_interface_object;
  }
  DCHECK_EQ(global_object->object_cache()->GetCachedConstructor(&s_info), interface_object);
  return interface_object;
}

// End of JSCOperationsTestInterface::InterfaceObject class

// Class that defines a JS Object representing this interface's prototype
class JSCOperationsTestInterface::Prototype : public PrototypeBase {
 public:
  // Get the prototype. Will create a new prototype if necessary, otherwise it
  // will return a cached prototype.
  static JSC::JSObject* GetInstance(JSC::JSGlobalObject* global_object);
  DECLARE_CLASSINFO();

  // Needed when JSC::OverridesGetOwnPropertySlot StructureFlag is set
  // Must be public so that it can be accessible from getStaticValueSlot<>.
  static bool getOwnPropertySlot(JSC::JSCell*, JSC::ExecState*,
                                 JSC::PropertyName,
                                 JSC::PropertySlot&);

 private:
  typedef PrototypeBase BaseClass;

  static const unsigned StructureFlags =
      JSC::OverridesGetOwnPropertySlot |
      BaseClass::StructureFlags;

  Prototype(JSC::JSGlobalObject* global_object, JSC::Structure* structure)
      : BaseClass(global_object, structure) { }

  static JSC::JSValue GetConstructor(JSC::ExecState* exec_state,
      JSC::JSValue slot_base,
      JSC::PropertyName property_name);
  static const JSC::HashTable* GetPropertyTable(JSC::ExecState* exec_state);

  static const JSC::HashTableValue property_table_values[];
  static const JSC::HashTable property_table_prototype;
};

const JSC::HashTableValue JSCOperationsTestInterface::Prototype::property_table_values[] = {
    { "longFunctionNoArgs",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSlongFunctionNoArgs),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "objectFunctionNoArgs",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSobjectFunctionNoArgs),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "optionalArgumentWithDefault",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSoptionalArgumentWithDefault),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "optionalArguments",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSoptionalArguments),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { "optionalNullableArgumentsWithDefaults",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSoptionalNullableArgumentsWithDefaults),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "overloadedFunction",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSoverloadedFunction),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "overloadedNullable",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSoverloadedNullable),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { "stringFunctionNoArgs",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSstringFunctionNoArgs),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "variadicPrimitiveArguments",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvariadicPrimitiveArguments),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "variadicStringArgumentsAfterOptionalArgument",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvariadicStringArgumentsAfterOptionalArgument),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "voidFunctionLongArg",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvoidFunctionLongArg),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { "voidFunctionNoArgs",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvoidFunctionNoArgs),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { "voidFunctionObjectArg",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvoidFunctionObjectArg),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { "voidFunctionStringArg",
        JSC::DontDelete | JSC::Function,
        reinterpret_cast<intptr_t>(functionJSvoidFunctionStringArg),
        static_cast<intptr_t>(1),
        JSC::NoIntrinsic
    },
    { "constructor",
        JSC::DontDelete | JSC::DontEnum,
        reinterpret_cast<intptr_t>(JSCOperationsTestInterface::Prototype::GetConstructor),
        static_cast<intptr_t>(0),
        JSC::NoIntrinsic
    },
    { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) }
};  // JSCOperationsTestInterface::Prototype::property_table_values

// static
const JSC::HashTable JSCOperationsTestInterface::Prototype::property_table_prototype = {
    46,  // compactSize
    31,  // compactSizeMask
    property_table_values,
    NULL  // table allocated at runtime
};  // JSCOperationsTestInterface::Prototype::property_table_prototype

// static
const JSC::HashTable* JSCOperationsTestInterface::Prototype::GetPropertyTable(
    JSC::ExecState* exec_state) {
  return ThreadLocalHashTable::GetInstance()->GetHashTable(
      JSCOperationsTestInterface::Prototype::s_classinfo(), property_table_prototype);
}

const JSC::ClassInfo JSCOperationsTestInterface::Prototype::s_info = {
    "OperationsTestInterfacePrototype",  // className
    BaseClass::s_classinfo(),  // parentClass
    NULL,  // static hash-table of properties (not used)
    GetPropertyTable,  // function pointer to get hash-table of properties
    CREATE_METHOD_TABLE(JSCOperationsTestInterface::Prototype)
};  // JSCOperationsTestInterface::Prototype::s_info

// Look up property slot for querying property values.
bool JSCOperationsTestInterface::Prototype::getOwnPropertySlot(JSC::JSCell* cell,
    JSC::ExecState* exec, JSC::PropertyName property_name,
    JSC::PropertySlot& slot) {
  Prototype* this_object = JSC::jsCast<Prototype*>(cell);
  ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
  return JSC::getStaticPropertySlot<Prototype, JSC::JSObject>(
      exec, GetPropertyTable(exec), this_object, property_name, slot);
}

// static
JSC::JSObject* JSCOperationsTestInterface::Prototype::GetInstance(
    JSC::JSGlobalObject* base_global_object) {
  JSCGlobalObject* global_object =
      static_cast<JSCGlobalObject*>(base_global_object);
  ASSERT_GC_OBJECT_INHERITS(global_object, JSCGlobalObject::s_classinfo());

  // Try to get the cached prototype, and create a new one if needed.
  JSC::JSObject* prototype = global_object->object_cache()->GetCachedPrototype(&s_info);
  if (prototype == NULL) {
    JSC::JSGlobalData& global_data = global_object->globalData();
    JSC::JSLockHolder lock(&global_data);

    JSC::JSObject* parent_prototype = global_object->objectPrototype();
    JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags);
    JSC::Structure* structure = JSC::Structure::create(
        global_data,
        global_object,
        JSC::JSValue(parent_prototype),
        type_info,
        &s_info);

    // Create the new prototype object.
    Prototype* new_prototype =
        new (NotNull, JSC::allocateCell<Prototype>(
            global_data.heap))
        Prototype(global_object, structure);
    new_prototype->finishCreation(global_data);
    // Add the prototype to the cache.
    global_object->object_cache()->CachePrototype(&s_info, new_prototype);
    prototype = new_prototype;
  }
  DCHECK_EQ(global_object->object_cache()->GetCachedPrototype(&s_info), prototype);
  return prototype;
}

// End of JSCOperationsTestInterface::Prototype class

const JSC::HashTableValue JSCOperationsTestInterface::property_table_values[] = {
    { 0, 0, 0, 0, static_cast<JSC::Intrinsic>(0) }
};  // JSCOperationsTestInterface::property_table_values

// static
const JSC::HashTable JSCOperationsTestInterface::property_table_prototype = {
    2,  // compactSize
    1,  // compactSizeMask
    property_table_values,
    NULL  // table allocated at runtime
};  // JSCOperationsTestInterface::property_table_prototype

// static
const JSC::HashTable* JSCOperationsTestInterface::GetPropertyTable(
    JSC::ExecState* exec_state) {
  return ThreadLocalHashTable::GetInstance()->GetHashTable(
      JSCOperationsTestInterface::s_classinfo(), property_table_prototype);
}

#ifdef __LB_SHELL__FORCE_LOGGING__
base::LazyInstance<JSCOperationsTestInterface::NonTrivialStaticFields>
    JSCOperationsTestInterface::non_trivial_static_fields = LAZY_INSTANCE_INITIALIZER;
#endif  // __LB_SHELL__FORCE_LOGGING__

const JSC::ClassInfo JSCOperationsTestInterface::s_info = {
    "OperationsTestInterface",  // className
    BaseClass::s_classinfo(),  // parentClass
    NULL,  // static hash-table of properties (not used)
    GetPropertyTable,  // function pointer to get hash-table of properties
    CREATE_METHOD_TABLE(JSCOperationsTestInterface)
};  // JSCOperationsTestInterface::s_info

// static
JSC::JSObject* JSCOperationsTestInterface::GetPrototype(
    JSC::JSGlobalObject* global_object) {
  return Prototype::GetInstance(global_object);
}

// static
JSC::JSObject* JSCOperationsTestInterface::GetConstructor(
    JSC::ExecState* exec_state) {
  return InterfaceObject::GetInstance(exec_state);
}

// static
JSC::JSValue JSCOperationsTestInterface::Prototype::GetConstructor(
      JSC::ExecState* exec_state,
      JSC::JSValue slot_base,
      JSC::PropertyName property_name) {
  return JSC::JSValue(InterfaceObject::GetInstance(exec_state));
}

// static
JSC::JSObject* JSCOperationsTestInterface::Create(
    JSCGlobalObject* global_object,
    const scoped_refptr<Wrappable>& wrappable) {
  if (!(wrappable->GetWrappableType() == OperationsTestInterface::OperationsTestInterfaceWrappableType())) {
    NOTREACHED() << "Type of wrappable does not match OperationsTestInterface::OperationsTestInterfaceWrappableType()";
    return NULL;
  }
  OperationsTestInterface* impl_ptr =
      base::polymorphic_downcast<OperationsTestInterface*>(wrappable.get());

  JSC::JSGlobalData& global_data = global_object->globalData();

  // Get or Create the prototype object for this interface.
  JSC::JSObject* prototype = Prototype::GetInstance(global_object);
  DCHECK(prototype);

  JSC::JSLockHolder lock(global_data);
  // Create a JSC::Structure object for this instance.
  JSC::TypeInfo type_info(JSC::ObjectType, StructureFlags);
  JSC::Structure* structure = JSC::Structure::create(
      global_data,
      global_object,
      JSC::JSValue(prototype),
      type_info,
      &s_info);

  // Instantiate a new garbage-collected wrapper object.
  JSCOperationsTestInterface* wrapper =
      new (NotNull, JSC::allocateCell<JSCOperationsTestInterface>(global_data.heap))
      JSCOperationsTestInterface(
          &global_data,
          structure,
          global_object->script_object_registry(),
          make_scoped_refptr(impl_ptr));
  wrapper->finishCreation(global_data);
  return wrapper;
}
JSCOperationsTestInterface::JSCOperationsTestInterface(
    JSC::JSGlobalData* global_data,
    JSC::Structure* structure,
    ScriptObjectRegistry* script_object_registry,
    const scoped_refptr<OperationsTestInterface>& impl)
    : BaseClass(global_data, structure, script_object_registry, impl) {
}

void JSCOperationsTestInterface::finishCreation(JSC::JSGlobalData& global_data) {
  BaseClass::finishCreation(global_data);
  DCHECK(inherits(&s_info));
}

JSCOperationsTestInterface::~JSCOperationsTestInterface() {
  // Empty destructor
}

// Look up property slot for querying property values.
bool JSCOperationsTestInterface::getOwnPropertySlot(JSC::JSCell* cell,
    JSC::ExecState* exec, JSC::PropertyName property_name,
    JSC::PropertySlot& slot) {
  JSCOperationsTestInterface* this_object = JSC::jsCast<JSCOperationsTestInterface*>(cell);
  ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
  bool found_property_slot = JSC::getStaticValueSlot<JSCOperationsTestInterface, BaseClass>(
      exec, GetPropertyTable(exec), this_object, property_name, slot);
  if (s_has_named_getter || s_use_debug_missing_property_handler) {
    bool found_property_on_prototype_chain = false;
    if (!found_property_slot && cell->isObject()) {
      JSC::JSValue prototype_value = JSC::asObject(cell)->prototype();
      if (prototype_value.isObject()) {
        JSC::JSObject* prototype = JSC::asObject(prototype_value);
        found_property_on_prototype_chain =
            prototype->hasProperty(exec, property_name);
      }
    }
    if (s_has_named_getter) {
      if (!found_property_slot && !found_property_on_prototype_chain) {
        if (QueryNamedProperty(this_object, exec, property_name)) {
          slot.setCustom(cell, &NamedPropertyGetter);
          found_property_slot = true;
        }
      }
    }
    if (s_use_debug_missing_property_handler) {
      // The property was not found as an own-property, nor was it found on the
      // prototype chain, so set the missing property handler to be called
      // when getting this property value.
      if (!found_property_slot && !found_property_on_prototype_chain) {
        slot.setCustom(cell, &OnGetMissingProperty);
        found_property_slot = true;
      }
    }
  }
  return found_property_slot;
}

// Look up property slot and put the |value|.
void JSCOperationsTestInterface::put(JSC::JSCell* cell, JSC::ExecState* exec,
    JSC::PropertyName property_name, JSC::JSValue value,
    JSC::PutPropertySlot& slot) {
  JSCOperationsTestInterface* this_object = JSC::jsCast<JSCOperationsTestInterface*>(cell);
  ASSERT_GC_OBJECT_INHERITS(this_object, &s_info);
  bool property_handled = false;
  if (s_has_named_setter || s_use_debug_missing_property_handler) {
    // Need to look up the property manually.
    bool has_property = HasOwnPropertyOrPrototypeProperty(
        cell, exec, property_name);

    if (s_has_named_setter) {
      // We didn't find the property on the object or prototype chain, so
      // set or create a new named property.
      if (!has_property) {
        std::string property_name_utf8 = FromWTFString(property_name.publicName());
        NamedPropertySetter(cell, exec, property_name, value);
        property_handled = true;
      }
    }
    if (s_use_debug_missing_property_handler) {
      if (!has_property && !property_handled) {
        property_handled = OnSetMissingProperty(cell, exec, property_name, value);
      }
    }
#ifdef __LB_SHELL__FORCE_LOGGING__
    std::string property_name_utf8 = FromWTFString(property_name.publicName());

    base::AutoLock lock(non_trivial_static_fields.Get().lock_);
    base::hash_set<std::string>& properties_warned_about =
        non_trivial_static_fields.Get().properties_warned_about;

    if (properties_warned_about.find(property_name_utf8) ==
        properties_warned_about.end()) {
      properties_warned_about.insert(property_name_utf8);
      WTF::String class_name = cell->className();
      DLOG_IF(WARNING, !has_property) << "Did not find property named " <<
              property_name_utf8 << " to set on wrapper for "
              << FromWTFString(class_name)
              << std::endl << StackTraceToString(GetStackTrace(exec, 32))
              << std::endl;
    }
#endif  // __LB_SHELL__FORCE_LOGGING__
  }

  if (!property_handled) {
    JSC::lookupPut<JSCOperationsTestInterface, BaseClass>(
        exec, property_name, value, GetPropertyTable(exec), this_object, slot);
  }
}

bool JSCOperationsTestInterface::HasOwnPropertyOrPrototypeProperty(
    JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  JSCOperationsTestInterface* this_object = JSC::jsCast<JSCOperationsTestInterface*>(cell);
  JSC::PropertySlot lookup_slot;
  bool has_property = JSC::getStaticPropertySlot<JSCOperationsTestInterface, BaseClass>(
      exec_state, GetPropertyTable(exec_state), this_object, property_name,
      lookup_slot);
  return has_property || HasPropertyOnPrototype(exec_state, cell, property_name);
}

namespace {

JSC::EncodedJSValue functionJSlongFunctionNoArgs(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call longFunctionNoArgs");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  TypeTraits<int32_t >::ReturnType return_value = impl->LongFunctionNoArgs();
  return JSC::JSValue::encode(ToJSValue(global_object, return_value));

}

JSC::EncodedJSValue functionJSobjectFunctionNoArgs(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call objectFunctionNoArgs");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  TypeTraits<scoped_refptr<ArbitraryInterface> >::ReturnType return_value = impl->ObjectFunctionNoArgs();
  return JSC::JSValue::encode(ToJSValue(global_object, return_value));

}

JSC::EncodedJSValue functionJSoptionalArgumentWithDefault(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call optionalArgumentWithDefault");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  // Optional arguments with default values
  TypeTraits<double >::ConversionType arg1 =
      2.718;

  size_t num_set_arguments = 1;
  if (exec_state->argumentCount() > 0) {
    FromJSValue(exec_state,
        exec_state->argument(0),
        (kConversionFlagRestricted),
        &exception_state,
        &arg1);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
  }
  impl->OptionalArgumentWithDefault(arg1);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoptionalArguments(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call optionalArguments");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg1;
  // Optional arguments
  TypeTraits<int32_t >::ConversionType arg2;
  TypeTraits<int32_t >::ConversionType arg3;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg1);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  size_t num_set_arguments = 1;
  if (exec_state->argumentCount() > 1) {
    FromJSValue(exec_state,
        exec_state->argument(1),
        kNoConversionFlags,
        &exception_state,
        &arg2);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
    ++num_set_arguments;
  }
  if (exec_state->argumentCount() > 2) {
    FromJSValue(exec_state,
        exec_state->argument(2),
        kNoConversionFlags,
        &exception_state,
        &arg3);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
    ++num_set_arguments;
  }
  switch (num_set_arguments) {
    case 1:
      {
        impl->OptionalArguments(arg1);
        return JSC::JSValue::encode(JSC::jsUndefined());
        break;
      }
    case 2:
      {
        impl->OptionalArguments(arg1, arg2);
        return JSC::JSValue::encode(JSC::jsUndefined());
        break;
      }
    case 3:
      {
        impl->OptionalArguments(arg1, arg2, arg3);
        return JSC::JSValue::encode(JSC::jsUndefined());
        break;
      }
    default:
      NOTREACHED();
      return JSC::JSValue::encode(JSC::jsUndefined());
  }

}

JSC::EncodedJSValue functionJSoptionalNullableArgumentsWithDefaults(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call optionalNullableArgumentsWithDefaults");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  // Optional arguments with default values
  TypeTraits<base::optional<bool > >::ConversionType arg1 =
      base::nullopt;
  TypeTraits<scoped_refptr<ArbitraryInterface> >::ConversionType arg2 =
      NULL;

  size_t num_set_arguments = 2;
  if (exec_state->argumentCount() > 0) {
    FromJSValue(exec_state,
        exec_state->argument(0),
        (kConversionFlagNullable),
        &exception_state,
        &arg1);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
  }
  if (exec_state->argumentCount() > 1) {
    FromJSValue(exec_state,
        exec_state->argument(1),
        (kConversionFlagNullable),
        &exception_state,
        &arg2);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
  }
  impl->OptionalNullableArgumentsWithDefaults(arg1, arg2);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedFunction(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call overloadedFunction");
  const size_t num_arguments = exec_state->argumentCount();
  switch(num_arguments) {
    case(0): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      if (true) {
        return functionJSoverloadedFunction1(exec_state);
      }
      break;
    }
    case(1): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      JSC::JSValue arg = exec_state->argument(0);
      if (arg.isNumber()) {
        return functionJSoverloadedFunction2(exec_state);
      }
      if (true) {
        return functionJSoverloadedFunction3(exec_state);
      }
      if (true) {
        return functionJSoverloadedFunction2(exec_state);
      }
      break;
    }
    case(3): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      JSC::JSValue arg = exec_state->argument(2);
      if (arg.inherits(JSCArbitraryInterface::s_classinfo())) {
        return functionJSoverloadedFunction5(exec_state);
      }
      if (true) {
        return functionJSoverloadedFunction4(exec_state);
      }
      break;
    }
  }
  // Invalid number of args
  // http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
  // 4. If S is empty, then throw a TypeError.
  return JSC::throwVMTypeError(exec_state);
}

JSC::EncodedJSValue functionJSoverloadedFunction1(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  impl->OverloadedFunction();
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedFunction2(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedFunction(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedFunction3(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<std::string >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedFunction(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedFunction4(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 3;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg1;
  TypeTraits<int32_t >::ConversionType arg2;
  TypeTraits<int32_t >::ConversionType arg3;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg1);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  DCHECK_LT(1, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(1),
      kNoConversionFlags,
      &exception_state, &arg2);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  DCHECK_LT(2, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(2),
      kNoConversionFlags,
      &exception_state, &arg3);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedFunction(arg1, arg2, arg3);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedFunction5(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 3;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg1;
  TypeTraits<int32_t >::ConversionType arg2;
  TypeTraits<scoped_refptr<ArbitraryInterface> >::ConversionType arg3;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg1);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  DCHECK_LT(1, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(1),
      kNoConversionFlags,
      &exception_state, &arg2);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  DCHECK_LT(2, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(2),
      kNoConversionFlags,
      &exception_state, &arg3);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedFunction(arg1, arg2, arg3);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedNullable(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call overloadedNullable");
  const size_t num_arguments = exec_state->argumentCount();
  switch(num_arguments) {
    case(1): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      JSC::JSValue arg = exec_state->argument(0);
      if (arg.isUndefinedOrNull()) {
        return functionJSoverloadedNullable2(exec_state);
      }
      if (true) {
        return functionJSoverloadedNullable1(exec_state);
      }
      break;
    }
  }
  // Invalid number of args
  // http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
  // 4. If S is empty, then throw a TypeError.
  return JSC::throwVMTypeError(exec_state);
}

JSC::EncodedJSValue functionJSoverloadedNullable1(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedNullable(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSoverloadedNullable2(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<base::optional<bool > >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      (kConversionFlagNullable),
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->OverloadedNullable(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSstringFunctionNoArgs(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call stringFunctionNoArgs");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  TypeTraits<std::string >::ReturnType return_value = impl->StringFunctionNoArgs();
  return JSC::JSValue::encode(ToJSValue(global_object, return_value));

}

JSC::EncodedJSValue functionJSvariadicPrimitiveArguments(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call variadicPrimitiveArguments");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  // Variadic argument
  TypeTraits<std::vector<int32_t> >::ConversionType bools;

  // Get variadic arguments.
  const size_t kFirstVariadicArgIndex = 0;
  if (exec_state->argumentCount() > kFirstVariadicArgIndex) {
    bools.resize(exec_state->argumentCount() - kFirstVariadicArgIndex);
    for (int i = 0; i + kFirstVariadicArgIndex < exec_state->argumentCount(); ++i) {
      FromJSValue(exec_state,
          exec_state->argument(i + kFirstVariadicArgIndex),
          kNoConversionFlags,
          &exception_state,
          &bools[i]);
      if (exception_state.is_exception_set()) {
        return JSC::throwVMError(exec_state, exception_state.exception_object());
      }
    }
  }
  impl->VariadicPrimitiveArguments(bools);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSvariadicStringArgumentsAfterOptionalArgument(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call variadicStringArgumentsAfterOptionalArgument");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  // Optional arguments
  TypeTraits<bool >::ConversionType optional_arg;
  // Variadic argument
  TypeTraits<std::vector<std::string> >::ConversionType strings;

  size_t num_set_arguments = 0;
  if (exec_state->argumentCount() > 0) {
    FromJSValue(exec_state,
        exec_state->argument(0),
        kNoConversionFlags,
        &exception_state,
        &optional_arg);
    if (exception_state.is_exception_set()) {
      return JSC::throwVMError(exec_state, exception_state.exception_object());
    }
    ++num_set_arguments;
  }

  // Get variadic arguments.
  const size_t kLastOptionalArgIndex = 1;
  if (num_set_arguments == kLastOptionalArgIndex) {
    // If the last optional argument has been set, we will call the overload
    // that takes the variadic argument, possibly with an empty vector in the
    // case that there are no more arguments left.
    ++num_set_arguments;
  }
  const size_t kFirstVariadicArgIndex = 1;
  if (exec_state->argumentCount() > kFirstVariadicArgIndex) {
    strings.resize(exec_state->argumentCount() - kFirstVariadicArgIndex);
    for (int i = 0; i + kFirstVariadicArgIndex < exec_state->argumentCount(); ++i) {
      FromJSValue(exec_state,
          exec_state->argument(i + kFirstVariadicArgIndex),
          kNoConversionFlags,
          &exception_state,
          &strings[i]);
      if (exception_state.is_exception_set()) {
        return JSC::throwVMError(exec_state, exception_state.exception_object());
      }
    }
  }
  switch (num_set_arguments) {
    case 0:
      {
        impl->VariadicStringArgumentsAfterOptionalArgument();
        return JSC::JSValue::encode(JSC::jsUndefined());
        break;
      }
    case 2:
      {
        impl->VariadicStringArgumentsAfterOptionalArgument(optional_arg, strings);
        return JSC::JSValue::encode(JSC::jsUndefined());
        break;
      }
    default:
      NOTREACHED();
      return JSC::JSValue::encode(JSC::jsUndefined());
  }

}

JSC::EncodedJSValue functionJSvoidFunctionLongArg(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call voidFunctionLongArg");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<int32_t >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->VoidFunctionLongArg(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSvoidFunctionNoArgs(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call voidFunctionNoArgs");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  impl->VoidFunctionNoArgs();
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSvoidFunctionObjectArg(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call voidFunctionObjectArg");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<scoped_refptr<ArbitraryInterface> >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->VoidFunctionObjectArg(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue functionJSvoidFunctionStringArg(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call voidFunctionStringArg");
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);
  JSC::JSObject* this_object =
      exec_state->hostThisValue().toThisObject(exec_state);
  OperationsTestInterface* impl =
      GetWrappableOrSetException<OperationsTestInterface>(exec_state, this_object);
  if (!impl) {
    return JSC::JSValue::encode(exec_state->exception());
  }

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<std::string >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      kNoConversionFlags,
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  impl->VoidFunctionStringArg(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue staticFunctionJSoverloadedFunction(
    JSC::ExecState* exec_state) {
  TRACE_EVENT0("JSCOperationsTestInterface", "call overloadedFunction");
  const size_t num_arguments = exec_state->argumentCount();
  switch(num_arguments) {
    case(1): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      if (true) {
        return staticFunctionJSoverloadedFunction1(exec_state);
      }
      break;
    }
    case(2): {
      // Overload resolution algorithm details found here:
      //     http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
      if (true) {
        return staticFunctionJSoverloadedFunction2(exec_state);
      }
      break;
    }
  }
  // Invalid number of args
  // http://heycam.github.io/webidl/#dfn-overload-resolution-algorithm
  // 4. If S is empty, then throw a TypeError.
  return JSC::throwVMTypeError(exec_state);
}

JSC::EncodedJSValue staticFunctionJSoverloadedFunction1(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);

  const size_t kMinArguments = 1;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<double >::ConversionType arg;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      (kConversionFlagRestricted),
      &exception_state, &arg);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  OperationsTestInterface::OverloadedFunction(arg);
  return JSC::JSValue::encode(JSC::jsUndefined());

}

JSC::EncodedJSValue staticFunctionJSoverloadedFunction2(
    JSC::ExecState* exec_state) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSCExceptionState exception_state(global_object);

  const size_t kMinArguments = 2;
  if (exec_state->argumentCount() < kMinArguments) {
    return JSC::throwVMNotEnoughArgumentsError(exec_state);
  }
  // Non-optional arguments
  TypeTraits<double >::ConversionType arg1;
  TypeTraits<double >::ConversionType arg2;

  DCHECK_LT(0, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(0),
      (kConversionFlagRestricted),
      &exception_state, &arg1);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }

  DCHECK_LT(1, exec_state->argumentCount());
  FromJSValue(exec_state,
      exec_state->argument(1),
      (kConversionFlagRestricted),
      &exception_state, &arg2);
  if (exception_state.is_exception_set()) {
    return JSC::throwVMError(exec_state, exception_state.exception_object());
  }
  OperationsTestInterface::OverloadedFunction(arg1, arg2);
  return JSC::JSValue::encode(JSC::jsUndefined());

}
JSC::JSValue NamedPropertyGetter(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  NOTREACHED();
  return JSC::jsUndefined();
}
bool QueryNamedProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  NOTREACHED();
  return false;
}
void NamedPropertySetter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue jsc_value) {
  NOTREACHED();
}

bool NamedPropertyDeleter(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name) {
  return false;
}

#if !defined(COBALT_BUILD_TYPE_GOLD)
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSC::JSValue callable = global_object->get(
      exec_state, JSC::Identifier(exec_state, "__onGetMissingProperty"));
  if (!callable.isUndefined()) {
    JSC::CallData call_data;
    JSC::CallType call_type = JSC::getCallData(callable, call_data);
    if (call_type != JSC::CallTypeNone) {
      // The function called __onGetMissingProperty exists, so call this and
      // return the result as the value for this property.
      JSC::MarkedArgumentBuffer args;
      args.append(slot_base);
      args.append(JSC::JSValue(
              JSC::JSString::create(
                  global_object->globalData(), property_name.publicName())));
      JSC::JSValue retval = JSC::call(
          exec_state, callable, call_type, call_data, global_object, args);
      return retval;
    }
  }
  return JSC::jsUndefined();
}

bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value) {
  JSCGlobalObject* global_object =
      JSC::jsCast<JSCGlobalObject*>(exec_state->lexicalGlobalObject());
  JSC::JSValue callable = global_object->get(
      exec_state, JSC::Identifier(exec_state, "__onSetMissingProperty"));
  if (!callable.isUndefined()) {
    JSC::CallData call_data;
    JSC::CallType call_type = JSC::getCallData(callable, call_data);
    if (call_type != JSC::CallTypeNone) {
      // The function called __onSetMissingProperty exists, so call this with
      // the value to be set. The missing property handler returns true if it
      // has handled the setting of this property.
      JSC::MarkedArgumentBuffer args;
      args.append(cell);
      args.append(JSC::JSValue(
              JSC::JSString::create(
                  global_object->globalData(), property_name.publicName())));
      args.append(value);
      JSC::JSValue retval = JSC::call(
          exec_state, callable, call_type, call_data, global_object, args);
      return retval.toBoolean(exec_state);
    }
  }
  return false;
}
#else
JSC::JSValue OnGetMissingProperty(JSC::ExecState* exec_state,
    JSC::JSValue slot_base, JSC::PropertyName property_name) {
  NOTREACHED();
  return JSC::jsUndefined();
}
bool OnSetMissingProperty(JSC::JSCell* cell, JSC::ExecState* exec_state,
    JSC::PropertyName property_name, JSC::JSValue value) {
  NOTREACHED();
  return false;
}
#endif
}  // namespace

}  // namespace testing
}  // namespace bindings
}  // namespace cobalt
