/*
 * 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_object_proxy.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_object.h"
#include "cobalt/script/javascriptcore/jsc_global_object_proxy.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::GlobalObjectProxy;
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::JSCObjectHandle;
using cobalt::script::javascriptcore::JSCObjectHandleHolder;
using cobalt::script::javascriptcore::JSCGlobalObject;
using cobalt::script::javascriptcore::JSCGlobalObjectProxy;
using cobalt::script::javascriptcore::JSObjectToWrappable;
using cobalt::script::javascriptcore::ScriptObjectRegistry;
using cobalt::script::javascriptcore::ToJSValue;
using cobalt::script::javascriptcore::ToWTFString;
using cobalt::script::javascriptcore::TypeTraits;
using cobalt::script::javascriptcore::PrototypeBase;
using cobalt::script::javascriptcore::ThreadLocalHashTable;
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
