Home | History | Annotate | Download | only in src
      1 // Copyright 2014 PDFium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
      6 
      7 #include "xfa/src/foxitlib.h"
      8 #include "fxv8.h"
      9 #include "class.h"
     10 #include "value.h"
     11 static void FXJSE_DynPropGetterAdapter_MethodCallback(
     12     const v8::FunctionCallbackInfo<v8::Value>& info) {
     13   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
     14   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
     15       hCallBackInfo->GetAlignedPointerFromInternalField(0));
     16   v8::Local<v8::String> hPropName =
     17       hCallBackInfo->GetInternalField(1).As<v8::String>();
     18   ASSERT(lpClass && !hPropName.IsEmpty());
     19   v8::String::Utf8Value szPropName(hPropName);
     20   CFX_ByteStringC szFxPropName = *szPropName;
     21   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
     22   lpThisValue->ForceSetValue(info.This());
     23   CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
     24   CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
     25   lpClass->dynMethodCall(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
     26                          szFxPropName,
     27                          reinterpret_cast<CFXJSE_Arguments&>(impl));
     28   if (!lpRetValue->DirectGetValue().IsEmpty()) {
     29     info.GetReturnValue().Set(lpRetValue->DirectGetValue());
     30   }
     31   delete lpRetValue;
     32   lpRetValue = nullptr;
     33   delete lpThisValue;
     34   lpThisValue = nullptr;
     35 }
     36 static void FXJSE_DynPropGetterAdapter(const FXJSE_CLASS* lpClass,
     37                                        FXJSE_HOBJECT hObject,
     38                                        const CFX_ByteStringC& szPropName,
     39                                        FXJSE_HVALUE hValue) {
     40   ASSERT(lpClass);
     41   int32_t nPropType =
     42       lpClass->dynPropTypeGetter == nullptr
     43           ? FXJSE_ClassPropType_Property
     44           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
     45   if (nPropType == FXJSE_ClassPropType_Property) {
     46     if (lpClass->dynPropGetter) {
     47       lpClass->dynPropGetter(hObject, szPropName, hValue);
     48     }
     49   } else if (nPropType == FXJSE_ClassPropType_Method) {
     50     if (lpClass->dynMethodCall && hValue) {
     51       CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
     52       v8::Isolate* pIsolate = lpValue->GetIsolate();
     53       v8::HandleScope hscope(pIsolate);
     54       v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
     55           v8::ObjectTemplate::New();
     56       hCallBackInfoTemplate->SetInternalFieldCount(2);
     57       v8::Local<v8::Object> hCallBackInfo =
     58           hCallBackInfoTemplate->NewInstance();
     59       hCallBackInfo->SetAlignedPointerInInternalField(
     60           0, const_cast<FXJSE_CLASS*>(lpClass));
     61       hCallBackInfo->SetInternalField(
     62           1, v8::String::NewFromUtf8(
     63                  pIsolate, reinterpret_cast<const char*>(szPropName.GetPtr()),
     64                  v8::String::kNormalString, szPropName.GetLength()));
     65       lpValue->ForceSetValue(v8::Function::New(
     66           lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback,
     67           hCallBackInfo));
     68     }
     69   }
     70 }
     71 static void FXJSE_DynPropSetterAdapter(const FXJSE_CLASS* lpClass,
     72                                        FXJSE_HOBJECT hObject,
     73                                        const CFX_ByteStringC& szPropName,
     74                                        FXJSE_HVALUE hValue) {
     75   ASSERT(lpClass);
     76   int32_t nPropType =
     77       lpClass->dynPropTypeGetter == nullptr
     78           ? FXJSE_ClassPropType_Property
     79           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
     80   if (nPropType != FXJSE_ClassPropType_Method) {
     81     if (lpClass->dynPropSetter) {
     82       lpClass->dynPropSetter(hObject, szPropName, hValue);
     83     }
     84   }
     85 }
     86 static FX_BOOL FXJSE_DynPropQueryAdapter(const FXJSE_CLASS* lpClass,
     87                                          FXJSE_HOBJECT hObject,
     88                                          const CFX_ByteStringC& szPropName) {
     89   ASSERT(lpClass);
     90   int32_t nPropType =
     91       lpClass->dynPropTypeGetter == nullptr
     92           ? FXJSE_ClassPropType_Property
     93           : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE);
     94   return nPropType != FXJSE_ClassPropType_None;
     95 }
     96 static FX_BOOL FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS* lpClass,
     97                                            FXJSE_HOBJECT hObject,
     98                                            const CFX_ByteStringC& szPropName) {
     99   ASSERT(lpClass);
    100   int32_t nPropType =
    101       lpClass->dynPropTypeGetter == nullptr
    102           ? FXJSE_ClassPropType_Property
    103           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
    104   if (nPropType != FXJSE_ClassPropType_Method) {
    105     if (lpClass->dynPropDeleter) {
    106       return lpClass->dynPropDeleter(hObject, szPropName);
    107     } else {
    108       return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE;
    109     }
    110   }
    111   return FALSE;
    112 }
    113 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter(
    114     const v8::FunctionCallbackInfo<v8::Value>& info) {
    115   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
    116   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
    117       hCallBackInfo->GetAlignedPointerFromInternalField(0));
    118   v8::Local<v8::String> hPropName =
    119       hCallBackInfo->GetInternalField(1).As<v8::String>();
    120   ASSERT(lpClass && !hPropName.IsEmpty());
    121   v8::String::Utf8Value szPropName(hPropName);
    122   CFX_ByteStringC szFxPropName = *szPropName;
    123   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    124   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
    125   lpThisValue->ForceSetValue(info.This());
    126   FXJSE_DynPropGetterAdapter(
    127       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
    128       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
    129   info.GetReturnValue().Set(lpNewValue->DirectGetValue());
    130   delete lpThisValue;
    131   lpThisValue = nullptr;
    132   delete lpNewValue;
    133   lpNewValue = nullptr;
    134 }
    135 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(
    136     const v8::FunctionCallbackInfo<v8::Value>& info) {
    137   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
    138   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
    139       hCallBackInfo->GetAlignedPointerFromInternalField(0));
    140   v8::Local<v8::String> hPropName =
    141       hCallBackInfo->GetInternalField(1).As<v8::String>();
    142   ASSERT(lpClass && !hPropName.IsEmpty());
    143   v8::String::Utf8Value szPropName(hPropName);
    144   CFX_ByteStringC szFxPropName = *szPropName;
    145   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    146   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
    147   lpThisValue->ForceSetValue(info.This());
    148   lpNewValue->ForceSetValue(info[0]);
    149   FXJSE_DynPropSetterAdapter(
    150       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
    151       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
    152   delete lpThisValue;
    153   lpThisValue = nullptr;
    154   delete lpNewValue;
    155   lpNewValue = nullptr;
    156 }
    157 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(
    158     const v8::FunctionCallbackInfo<v8::Value>& info) {
    159   const FXJSE_CLASS* lpClass =
    160       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    161   if (!lpClass) {
    162     return;
    163   }
    164   v8::Isolate* pIsolate = info.GetIsolate();
    165   v8::HandleScope scope(pIsolate);
    166   v8::Local<v8::String> hPropName = info[0]->ToString();
    167   v8::String::Utf8Value szPropName(hPropName);
    168   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    169   v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
    170       v8::ObjectTemplate::New();
    171   hCallBackInfoTemplate->SetInternalFieldCount(2);
    172   v8::Local<v8::Object> hCallBackInfo = hCallBackInfoTemplate->NewInstance();
    173   hCallBackInfo->SetAlignedPointerInInternalField(
    174       0, const_cast<FXJSE_CLASS*>(lpClass));
    175   hCallBackInfo->SetInternalField(1, hPropName);
    176   v8::Local<v8::Object> hPropDescriptor = v8::Object::New(pIsolate);
    177   hPropDescriptor->ForceSet(
    178       v8::String::NewFromUtf8(pIsolate, "get"),
    179       v8::Function::New(pIsolate,
    180                         FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter,
    181                         hCallBackInfo));
    182   hPropDescriptor->ForceSet(
    183       v8::String::NewFromUtf8(pIsolate, "set"),
    184       v8::Function::New(pIsolate,
    185                         FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter,
    186                         hCallBackInfo));
    187   hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "enumerable"),
    188                             v8::Boolean::New(pIsolate, false));
    189   hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "configurable"),
    190                             v8::Boolean::New(pIsolate, true));
    191   info.GetReturnValue().Set(hPropDescriptor);
    192 }
    193 static void FXJSE_V8ProxyCallback_getPropertyDescriptor(
    194     const v8::FunctionCallbackInfo<v8::Value>& info) {
    195   v8::Isolate* pIsolate = info.GetIsolate();
    196   v8::Local<v8::Object> hChainObj =
    197       info.This()->GetPrototype().As<v8::Object>();
    198   v8::Local<v8::Script> fnSource = v8::Script::Compile(v8::String::NewFromUtf8(
    199       pIsolate,
    200       "(function (o, name) { var fn, x, d; fn = "
    201       "Object.getOwnPropertyDescriptor; x = o; while(x && !(d = fn(x, "
    202       "name))){x = x.__proto__;} return d; })"));
    203   v8::Local<v8::Function> fn = fnSource->Run().As<v8::Function>();
    204   v8::Local<v8::Value> rgArgs[] = {hChainObj, info[0]};
    205   v8::Local<v8::Value> hChainDescriptor = fn->Call(info.This(), 2, rgArgs);
    206   if (!hChainDescriptor.IsEmpty() && hChainDescriptor->IsObject()) {
    207     info.GetReturnValue().Set(hChainDescriptor);
    208   } else {
    209     FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(info);
    210   }
    211 }
    212 static void FXJSE_V8ProxyCallback_getOwnPropertyNames(
    213     const v8::FunctionCallbackInfo<v8::Value>& info) {
    214   v8::Isolate* pIsolate = info.GetIsolate();
    215   v8::HandleScope scope(pIsolate);
    216   info.GetReturnValue().Set(v8::Array::New(pIsolate));
    217 }
    218 static void FXJSE_V8ProxyCallback_getPropertyNames(
    219     const v8::FunctionCallbackInfo<v8::Value>& info) {
    220   v8::Local<v8::Object> hChainObj =
    221       info.This()->GetPrototype().As<v8::Object>();
    222   v8::Local<v8::Value> hChainPropertyNames = hChainObj->GetPropertyNames();
    223   info.GetReturnValue().Set(hChainPropertyNames);
    224 }
    225 static void FXJSE_V8ProxyCallback_defineProperty(
    226     const v8::FunctionCallbackInfo<v8::Value>& info) {
    227   const FXJSE_CLASS* lpClass =
    228       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    229   if (!lpClass) {
    230     return;
    231   }
    232   v8::Isolate* pIsolate = info.GetIsolate();
    233   v8::HandleScope scope(pIsolate);
    234   v8::Local<v8::String> hPropName = info[0]->ToString();
    235   v8::Local<v8::Object> hPropDescriptor = info[1]->ToObject();
    236   v8::String::Utf8Value szPropName(hPropName);
    237   if (!hPropDescriptor->Has(v8::String::NewFromUtf8(pIsolate, "value"))) {
    238     return;
    239   }
    240   v8::Local<v8::Value> hPropValue =
    241       hPropDescriptor->Get(v8::String::NewFromUtf8(pIsolate, "value"));
    242   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    243   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    244   CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
    245   lpThisValue->ForceSetValue(info.This());
    246   lpPropValue->ForceSetValue(hPropValue);
    247   FXJSE_DynPropSetterAdapter(
    248       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
    249       reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
    250   delete lpThisValue;
    251   lpThisValue = nullptr;
    252   delete lpPropValue;
    253   lpPropValue = nullptr;
    254 }
    255 static void FXJSE_V8ProxyCallback_delete(
    256     const v8::FunctionCallbackInfo<v8::Value>& info) {
    257   info.GetReturnValue().Set(true);
    258   const FXJSE_CLASS* lpClass =
    259       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    260   if (!lpClass) {
    261     return;
    262   }
    263   v8::Isolate* pIsolate = info.GetIsolate();
    264   v8::HandleScope scope(pIsolate);
    265   v8::Local<v8::String> hPropName = info[0]->ToString();
    266   v8::String::Utf8Value szPropName(hPropName);
    267   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    268   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    269   lpThisValue->ForceSetValue(info.This());
    270   info.GetReturnValue().Set(
    271       FXJSE_DynPropDeleterAdapter(
    272           lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
    273           ? true
    274           : false);
    275   delete lpThisValue;
    276   lpThisValue = nullptr;
    277 }
    278 static void FXJSE_V8ProxyCallback_fix(
    279     const v8::FunctionCallbackInfo<v8::Value>& info) {
    280   info.GetReturnValue().SetUndefined();
    281 }
    282 static void FXJSE_V8_GenericNamedPropertyQueryCallback(
    283     v8::Local<v8::Name> property,
    284     const v8::PropertyCallbackInfo<v8::Integer>& info) {
    285   v8::Local<v8::Object> thisObject = info.This();
    286   const FXJSE_CLASS* lpClass =
    287       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    288   v8::Isolate* pIsolate = info.GetIsolate();
    289   v8::HandleScope scope(pIsolate);
    290   v8::String::Utf8Value szPropName(property);
    291   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    292   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    293   lpThisValue->ForceSetValue(thisObject);
    294   if (FXJSE_DynPropQueryAdapter(lpClass,
    295                                 reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
    296                                 szFxPropName)) {
    297     info.GetReturnValue().Set(v8::DontDelete);
    298   } else {
    299     const int32_t iV8Absent = 64;
    300     info.GetReturnValue().Set(iV8Absent);
    301   }
    302   delete lpThisValue;
    303   lpThisValue = nullptr;
    304 }
    305 static void FXJSE_V8_GenericNamedPropertyDeleterCallback(
    306     v8::Local<v8::Name> property,
    307     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
    308   v8::Local<v8::Object> thisObject = info.This();
    309   const FXJSE_CLASS* lpClass =
    310       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    311   v8::Isolate* pIsolate = info.GetIsolate();
    312   v8::HandleScope scope(pIsolate);
    313   v8::String::Utf8Value szPropName(property);
    314   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    315   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    316   lpThisValue->ForceSetValue(thisObject);
    317   info.GetReturnValue().Set(
    318       FXJSE_DynPropDeleterAdapter(
    319           lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
    320           ? true
    321           : false);
    322   delete lpThisValue;
    323   lpThisValue = nullptr;
    324 }
    325 static void FXJSE_V8_GenericNamedPropertyGetterCallback(
    326     v8::Local<v8::Name> property,
    327     const v8::PropertyCallbackInfo<v8::Value>& info) {
    328   v8::Local<v8::Object> thisObject = info.This();
    329   const FXJSE_CLASS* lpClass =
    330       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    331   v8::String::Utf8Value szPropName(property);
    332   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    333   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    334   lpThisValue->ForceSetValue(thisObject);
    335   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
    336   FXJSE_DynPropGetterAdapter(
    337       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
    338       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
    339   info.GetReturnValue().Set(lpNewValue->DirectGetValue());
    340   delete lpThisValue;
    341   lpThisValue = nullptr;
    342 }
    343 static void FXJSE_V8_GenericNamedPropertySetterCallback(
    344     v8::Local<v8::Name> property,
    345     v8::Local<v8::Value> value,
    346     const v8::PropertyCallbackInfo<v8::Value>& info) {
    347   v8::Local<v8::Object> thisObject = info.This();
    348   const FXJSE_CLASS* lpClass =
    349       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    350   v8::String::Utf8Value szPropName(property);
    351   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
    352   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
    353   lpThisValue->ForceSetValue(thisObject);
    354   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
    355   lpNewValue->ForceSetValue(value);
    356   FXJSE_DynPropSetterAdapter(
    357       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
    358       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
    359   info.GetReturnValue().Set(value);
    360   delete lpThisValue;
    361   lpThisValue = nullptr;
    362 }
    363 static void FXJSE_V8_GenericNamedPropertyEnumeratorCallback(
    364     const v8::PropertyCallbackInfo<v8::Array>& info) {
    365   const FXJSE_CLASS* lpClass =
    366       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
    367   v8::Isolate* pIsolate = info.GetIsolate();
    368   v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum);
    369   for (int i = 0; i < lpClass->propNum; i++) {
    370     newArray->Set(
    371         i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name));
    372   }
    373   info.GetReturnValue().Set(newArray);
    374 }
    375 
    376 void CFXJSE_Class::SetUpDynPropHandler(CFXJSE_Context* pContext,
    377                                        CFXJSE_Value* pValue,
    378                                        const FXJSE_CLASS* lpClassDefinition) {
    379   v8::Isolate* pIsolate = pValue->GetIsolate();
    380   CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext scope(pIsolate, pContext);
    381   v8::Local<v8::Context> hContext = v8::Local<v8::Context>::New(
    382       pIsolate, pContext ? pContext->m_hContext
    383                          : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
    384   v8::Local<v8::Object> hObject =
    385       v8::Local<v8::Value>::New(pIsolate, pValue->m_hValue).As<v8::Object>();
    386   v8::Local<v8::Object> hHarmonyProxyObj =
    387       hContext->Global()
    388           ->Get(v8::String::NewFromUtf8(pIsolate, "Proxy"))
    389           .As<v8::Object>();
    390   v8::Local<v8::Function> hHarmonyProxyCreateFn =
    391       hHarmonyProxyObj->Get(v8::String::NewFromUtf8(pIsolate, "create"))
    392           .As<v8::Function>();
    393   v8::Local<v8::Value> hOldPrototype = hObject->GetPrototype();
    394   v8::Local<v8::Object> hTrapper = v8::Object::New(pIsolate);
    395   hTrapper->ForceSet(
    396       v8::String::NewFromUtf8(pIsolate, "getOwnPropertyDescriptor"),
    397       v8::Function::New(
    398           pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor,
    399           v8::External::New(pIsolate,
    400                             const_cast<FXJSE_CLASS*>(lpClassDefinition))));
    401   hTrapper->ForceSet(
    402       v8::String::NewFromUtf8(pIsolate, "getPropertyDescriptor"),
    403       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyDescriptor,
    404                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    405                                                         lpClassDefinition))));
    406   hTrapper->ForceSet(
    407       v8::String::NewFromUtf8(pIsolate, "getOwnPropertyNames"),
    408       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyNames,
    409                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    410                                                         lpClassDefinition))));
    411   hTrapper->ForceSet(
    412       v8::String::NewFromUtf8(pIsolate, "getPropertyNames"),
    413       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyNames,
    414                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    415                                                         lpClassDefinition))));
    416   hTrapper->ForceSet(
    417       v8::String::NewFromUtf8(pIsolate, "delete"),
    418       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_delete,
    419                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    420                                                         lpClassDefinition))));
    421   hTrapper->ForceSet(
    422       v8::String::NewFromUtf8(pIsolate, "defineProperty"),
    423       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_defineProperty,
    424                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    425                                                         lpClassDefinition))));
    426   hTrapper->ForceSet(
    427       v8::String::NewFromUtf8(pIsolate, "fix"),
    428       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_fix,
    429                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
    430                                                         lpClassDefinition))));
    431   v8::Local<v8::Value> rgArgs[] = {hTrapper, hOldPrototype};
    432   v8::Local<v8::Value> hNewPrototype =
    433       hHarmonyProxyCreateFn->Call(hHarmonyProxyObj, 2, rgArgs);
    434   hObject->SetPrototype(hNewPrototype);
    435 }
    436 void CFXJSE_Class::SetUpNamedPropHandler(
    437     v8::Isolate* pIsolate,
    438     v8::Local<v8::ObjectTemplate>& hObjectTemplate,
    439     const FXJSE_CLASS* lpClassDefinition) {
    440   v8::NamedPropertyHandlerConfiguration configuration(
    441       lpClassDefinition->dynPropGetter
    442           ? FXJSE_V8_GenericNamedPropertyGetterCallback
    443           : 0,
    444       lpClassDefinition->dynPropSetter
    445           ? FXJSE_V8_GenericNamedPropertySetterCallback
    446           : 0,
    447       lpClassDefinition->dynPropTypeGetter
    448           ? FXJSE_V8_GenericNamedPropertyQueryCallback
    449           : 0,
    450       lpClassDefinition->dynPropDeleter
    451           ? FXJSE_V8_GenericNamedPropertyDeleterCallback
    452           : 0,
    453       FXJSE_V8_GenericNamedPropertyEnumeratorCallback,
    454       v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition)),
    455       v8::PropertyHandlerFlags::kNonMasking);
    456   hObjectTemplate->SetHandler(configuration);
    457 }
    458