// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com

#include "xfa/src/fxjse/src/class.h"
#include "xfa/src/fxjse/src/value.h"

static void FXJSE_DynPropGetterAdapter_MethodCallback(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
  FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
      hCallBackInfo->GetAlignedPointerFromInternalField(0));
  v8::Local<v8::String> hPropName =
      hCallBackInfo->GetInternalField(1).As<v8::String>();
  ASSERT(lpClass && !hPropName.IsEmpty());
  v8::String::Utf8Value szPropName(hPropName);
  CFX_ByteStringC szFxPropName = *szPropName;
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(info.This());
  CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
  CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
  lpClass->dynMethodCall(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
                         szFxPropName,
                         reinterpret_cast<CFXJSE_Arguments&>(impl));
  if (!lpRetValue->DirectGetValue().IsEmpty()) {
    info.GetReturnValue().Set(lpRetValue->DirectGetValue());
  }
  delete lpRetValue;
  lpRetValue = nullptr;
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_DynPropGetterAdapter(const FXJSE_CLASS* lpClass,
                                       FXJSE_HOBJECT hObject,
                                       const CFX_ByteStringC& szPropName,
                                       FXJSE_HVALUE hValue) {
  ASSERT(lpClass);
  int32_t nPropType =
      lpClass->dynPropTypeGetter == nullptr
          ? FXJSE_ClassPropType_Property
          : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
  if (nPropType == FXJSE_ClassPropType_Property) {
    if (lpClass->dynPropGetter) {
      lpClass->dynPropGetter(hObject, szPropName, hValue);
    }
  } else if (nPropType == FXJSE_ClassPropType_Method) {
    if (lpClass->dynMethodCall && hValue) {
      CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
      v8::Isolate* pIsolate = lpValue->GetIsolate();
      v8::HandleScope hscope(pIsolate);
      v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
          v8::ObjectTemplate::New();
      hCallBackInfoTemplate->SetInternalFieldCount(2);
      v8::Local<v8::Object> hCallBackInfo =
          hCallBackInfoTemplate->NewInstance();
      hCallBackInfo->SetAlignedPointerInInternalField(
          0, const_cast<FXJSE_CLASS*>(lpClass));
      hCallBackInfo->SetInternalField(
          1, v8::String::NewFromUtf8(
                 pIsolate, reinterpret_cast<const char*>(szPropName.GetPtr()),
                 v8::String::kNormalString, szPropName.GetLength()));
      lpValue->ForceSetValue(v8::Function::New(
          lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback,
          hCallBackInfo));
    }
  }
}

static void FXJSE_DynPropSetterAdapter(const FXJSE_CLASS* lpClass,
                                       FXJSE_HOBJECT hObject,
                                       const CFX_ByteStringC& szPropName,
                                       FXJSE_HVALUE hValue) {
  ASSERT(lpClass);
  int32_t nPropType =
      lpClass->dynPropTypeGetter == nullptr
          ? FXJSE_ClassPropType_Property
          : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
  if (nPropType != FXJSE_ClassPropType_Method) {
    if (lpClass->dynPropSetter) {
      lpClass->dynPropSetter(hObject, szPropName, hValue);
    }
  }
}

static FX_BOOL FXJSE_DynPropQueryAdapter(const FXJSE_CLASS* lpClass,
                                         FXJSE_HOBJECT hObject,
                                         const CFX_ByteStringC& szPropName) {
  ASSERT(lpClass);
  int32_t nPropType =
      lpClass->dynPropTypeGetter == nullptr
          ? FXJSE_ClassPropType_Property
          : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE);
  return nPropType != FXJSE_ClassPropType_None;
}

static FX_BOOL FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS* lpClass,
                                           FXJSE_HOBJECT hObject,
                                           const CFX_ByteStringC& szPropName) {
  ASSERT(lpClass);
  int32_t nPropType =
      lpClass->dynPropTypeGetter == nullptr
          ? FXJSE_ClassPropType_Property
          : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
  if (nPropType != FXJSE_ClassPropType_Method) {
    if (lpClass->dynPropDeleter) {
      return lpClass->dynPropDeleter(hObject, szPropName);
    } else {
      return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE;
    }
  }
  return FALSE;
}

static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
  FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
      hCallBackInfo->GetAlignedPointerFromInternalField(0));
  v8::Local<v8::String> hPropName =
      hCallBackInfo->GetInternalField(1).As<v8::String>();
  ASSERT(lpClass && !hPropName.IsEmpty());
  v8::String::Utf8Value szPropName(hPropName);
  CFX_ByteStringC szFxPropName = *szPropName;
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(info.This());
  FXJSE_DynPropGetterAdapter(
      lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
      reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
  info.GetReturnValue().Set(lpNewValue->DirectGetValue());
  delete lpThisValue;
  lpThisValue = nullptr;
  delete lpNewValue;
  lpNewValue = nullptr;
}

static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
  FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
      hCallBackInfo->GetAlignedPointerFromInternalField(0));
  v8::Local<v8::String> hPropName =
      hCallBackInfo->GetInternalField(1).As<v8::String>();
  ASSERT(lpClass && !hPropName.IsEmpty());
  v8::String::Utf8Value szPropName(hPropName);
  CFX_ByteStringC szFxPropName = *szPropName;
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(info.This());
  lpNewValue->ForceSetValue(info[0]);
  FXJSE_DynPropSetterAdapter(
      lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
      reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
  delete lpThisValue;
  lpThisValue = nullptr;
  delete lpNewValue;
  lpNewValue = nullptr;
}

static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  if (!lpClass) {
    return;
  }
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  v8::Local<v8::String> hPropName = info[0]->ToString();
  v8::String::Utf8Value szPropName(hPropName);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
      v8::ObjectTemplate::New();
  hCallBackInfoTemplate->SetInternalFieldCount(2);
  v8::Local<v8::Object> hCallBackInfo = hCallBackInfoTemplate->NewInstance();
  hCallBackInfo->SetAlignedPointerInInternalField(
      0, const_cast<FXJSE_CLASS*>(lpClass));
  hCallBackInfo->SetInternalField(1, hPropName);
  v8::Local<v8::Object> hPropDescriptor = v8::Object::New(pIsolate);
  hPropDescriptor->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "get"),
      v8::Function::New(pIsolate,
                        FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter,
                        hCallBackInfo));
  hPropDescriptor->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "set"),
      v8::Function::New(pIsolate,
                        FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter,
                        hCallBackInfo));
  hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "enumerable"),
                            v8::Boolean::New(pIsolate, false));
  hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "configurable"),
                            v8::Boolean::New(pIsolate, true));
  info.GetReturnValue().Set(hPropDescriptor);
}

static void FXJSE_V8ProxyCallback_getPropertyDescriptor(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::Local<v8::Object> hChainObj =
      info.This()->GetPrototype().As<v8::Object>();
  v8::Local<v8::Script> fnSource = v8::Script::Compile(v8::String::NewFromUtf8(
      pIsolate,
      "(function (o, name) { var fn, x, d; fn = "
      "Object.getOwnPropertyDescriptor; x = o; while(x && !(d = fn(x, "
      "name))){x = x.__proto__;} return d; })"));
  v8::Local<v8::Function> fn = fnSource->Run().As<v8::Function>();
  v8::Local<v8::Value> rgArgs[] = {hChainObj, info[0]};
  v8::Local<v8::Value> hChainDescriptor = fn->Call(info.This(), 2, rgArgs);
  if (!hChainDescriptor.IsEmpty() && hChainDescriptor->IsObject()) {
    info.GetReturnValue().Set(hChainDescriptor);
  } else {
    FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(info);
  }
}

static void FXJSE_V8ProxyCallback_getOwnPropertyNames(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  info.GetReturnValue().Set(v8::Array::New(pIsolate));
}

static void FXJSE_V8ProxyCallback_getPropertyNames(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> hChainObj =
      info.This()->GetPrototype().As<v8::Object>();
  v8::Local<v8::Value> hChainPropertyNames = hChainObj->GetPropertyNames();
  info.GetReturnValue().Set(hChainPropertyNames);
}

static void FXJSE_V8ProxyCallback_defineProperty(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  if (!lpClass) {
    return;
  }
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  v8::Local<v8::String> hPropName = info[0]->ToString();
  v8::Local<v8::Object> hPropDescriptor = info[1]->ToObject();
  v8::String::Utf8Value szPropName(hPropName);
  if (!hPropDescriptor->Has(v8::String::NewFromUtf8(pIsolate, "value"))) {
    return;
  }
  v8::Local<v8::Value> hPropValue =
      hPropDescriptor->Get(v8::String::NewFromUtf8(pIsolate, "value"));
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(info.This());
  lpPropValue->ForceSetValue(hPropValue);
  FXJSE_DynPropSetterAdapter(
      lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
      reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
  delete lpThisValue;
  lpThisValue = nullptr;
  delete lpPropValue;
  lpPropValue = nullptr;
}

static void FXJSE_V8ProxyCallback_delete(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  info.GetReturnValue().Set(true);
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  if (!lpClass) {
    return;
  }
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  v8::Local<v8::String> hPropName = info[0]->ToString();
  v8::String::Utf8Value szPropName(hPropName);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(info.This());
  info.GetReturnValue().Set(
      FXJSE_DynPropDeleterAdapter(
          lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
          ? true
          : false);
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_V8ProxyCallback_fix(
    const v8::FunctionCallbackInfo<v8::Value>& info) {
  info.GetReturnValue().SetUndefined();
}

static void FXJSE_V8_GenericNamedPropertyQueryCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Integer>& info) {
  v8::Local<v8::Object> thisObject = info.This();
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  v8::String::Utf8Value szPropName(property);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(thisObject);
  if (FXJSE_DynPropQueryAdapter(lpClass,
                                reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
                                szFxPropName)) {
    info.GetReturnValue().Set(v8::DontDelete);
  } else {
    const int32_t iV8Absent = 64;
    info.GetReturnValue().Set(iV8Absent);
  }
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_V8_GenericNamedPropertyDeleterCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Boolean>& info) {
  v8::Local<v8::Object> thisObject = info.This();
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::HandleScope scope(pIsolate);
  v8::String::Utf8Value szPropName(property);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(thisObject);
  info.GetReturnValue().Set(
      FXJSE_DynPropDeleterAdapter(
          lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
          ? true
          : false);
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_V8_GenericNamedPropertyGetterCallback(
    v8::Local<v8::Name> property,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> thisObject = info.This();
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  v8::String::Utf8Value szPropName(property);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(thisObject);
  CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
  FXJSE_DynPropGetterAdapter(
      lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
      reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
  info.GetReturnValue().Set(lpNewValue->DirectGetValue());
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_V8_GenericNamedPropertySetterCallback(
    v8::Local<v8::Name> property,
    v8::Local<v8::Value> value,
    const v8::PropertyCallbackInfo<v8::Value>& info) {
  v8::Local<v8::Object> thisObject = info.This();
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  v8::String::Utf8Value szPropName(property);
  CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
  CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
  lpThisValue->ForceSetValue(thisObject);
  CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
  lpNewValue->ForceSetValue(value);
  FXJSE_DynPropSetterAdapter(
      lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
      reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
  info.GetReturnValue().Set(value);
  delete lpThisValue;
  lpThisValue = nullptr;
}

static void FXJSE_V8_GenericNamedPropertyEnumeratorCallback(
    const v8::PropertyCallbackInfo<v8::Array>& info) {
  const FXJSE_CLASS* lpClass =
      static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
  v8::Isolate* pIsolate = info.GetIsolate();
  v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum);
  for (int i = 0; i < lpClass->propNum; i++) {
    newArray->Set(
        i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name));
  }
  info.GetReturnValue().Set(newArray);
}

void CFXJSE_Class::SetUpDynPropHandler(CFXJSE_Context* pContext,
                                       CFXJSE_Value* pValue,
                                       const FXJSE_CLASS* lpClassDefinition) {
  v8::Isolate* pIsolate = pValue->GetIsolate();
  CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext scope(pIsolate, pContext);
  v8::Local<v8::Context> hContext = v8::Local<v8::Context>::New(
      pIsolate, pContext ? pContext->m_hContext
                         : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
  v8::Local<v8::Object> hObject =
      v8::Local<v8::Value>::New(pIsolate, pValue->m_hValue).As<v8::Object>();
  v8::Local<v8::Object> hHarmonyProxyObj =
      hContext->Global()
          ->Get(v8::String::NewFromUtf8(pIsolate, "Proxy"))
          .As<v8::Object>();
  v8::Local<v8::Function> hHarmonyProxyCreateFn =
      hHarmonyProxyObj->Get(v8::String::NewFromUtf8(pIsolate, "create"))
          .As<v8::Function>();
  v8::Local<v8::Value> hOldPrototype = hObject->GetPrototype();
  v8::Local<v8::Object> hTrapper = v8::Object::New(pIsolate);
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "getOwnPropertyDescriptor"),
      v8::Function::New(
          pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor,
          v8::External::New(pIsolate,
                            const_cast<FXJSE_CLASS*>(lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "getPropertyDescriptor"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyDescriptor,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "getOwnPropertyNames"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyNames,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "getPropertyNames"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyNames,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "delete"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_delete,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "defineProperty"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_defineProperty,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  hTrapper->ForceSet(
      v8::String::NewFromUtf8(pIsolate, "fix"),
      v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_fix,
                        v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
                                                        lpClassDefinition))));
  v8::Local<v8::Value> rgArgs[] = {hTrapper, hOldPrototype};
  v8::Local<v8::Value> hNewPrototype =
      hHarmonyProxyCreateFn->Call(hHarmonyProxyObj, 2, rgArgs);
  hObject->SetPrototype(hNewPrototype);
}

void CFXJSE_Class::SetUpNamedPropHandler(
    v8::Isolate* pIsolate,
    v8::Local<v8::ObjectTemplate>& hObjectTemplate,
    const FXJSE_CLASS* lpClassDefinition) {
  v8::NamedPropertyHandlerConfiguration configuration(
      lpClassDefinition->dynPropGetter
          ? FXJSE_V8_GenericNamedPropertyGetterCallback
          : 0,
      lpClassDefinition->dynPropSetter
          ? FXJSE_V8_GenericNamedPropertySetterCallback
          : 0,
      lpClassDefinition->dynPropTypeGetter
          ? FXJSE_V8_GenericNamedPropertyQueryCallback
          : 0,
      lpClassDefinition->dynPropDeleter
          ? FXJSE_V8_GenericNamedPropertyDeleterCallback
          : 0,
      FXJSE_V8_GenericNamedPropertyEnumeratorCallback,
      v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition)),
      v8::PropertyHandlerFlags::kNonMasking);
  hObjectTemplate->SetHandler(configuration);
}
