1 // Copyright 2016 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 "fxjs/cfxjse_class.h" 8 9 #include <memory> 10 11 #include "fxjs/cfxjse_context.h" 12 #include "fxjs/cfxjse_value.h" 13 14 namespace { 15 V8FunctionCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value> & info)16 void V8FunctionCallback_Wrapper( 17 const v8::FunctionCallbackInfo<v8::Value>& info) { 18 const FXJSE_FUNCTION_DESCRIPTOR* lpFunctionInfo = 19 static_cast<FXJSE_FUNCTION_DESCRIPTOR*>( 20 info.Data().As<v8::External>()->Value()); 21 if (!lpFunctionInfo) 22 return; 23 24 CFX_ByteStringC szFunctionName(lpFunctionInfo->name); 25 std::unique_ptr<CFXJSE_Value> lpThisValue( 26 new CFXJSE_Value(info.GetIsolate())); 27 lpThisValue->ForceSetValue(info.This()); 28 std::unique_ptr<CFXJSE_Value> lpRetValue(new CFXJSE_Value(info.GetIsolate())); 29 CFXJSE_Arguments impl(&info, lpRetValue.get()); 30 lpFunctionInfo->callbackProc(lpThisValue.get(), szFunctionName, impl); 31 if (!lpRetValue->DirectGetValue().IsEmpty()) 32 info.GetReturnValue().Set(lpRetValue->DirectGetValue()); 33 } 34 V8ClassGlobalConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value> & info)35 void V8ClassGlobalConstructorCallback_Wrapper( 36 const v8::FunctionCallbackInfo<v8::Value>& info) { 37 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition = 38 static_cast<FXJSE_CLASS_DESCRIPTOR*>( 39 info.Data().As<v8::External>()->Value()); 40 if (!lpClassDefinition) 41 return; 42 43 CFX_ByteStringC szFunctionName(lpClassDefinition->name); 44 std::unique_ptr<CFXJSE_Value> lpThisValue( 45 new CFXJSE_Value(info.GetIsolate())); 46 lpThisValue->ForceSetValue(info.This()); 47 std::unique_ptr<CFXJSE_Value> lpRetValue(new CFXJSE_Value(info.GetIsolate())); 48 CFXJSE_Arguments impl(&info, lpRetValue.get()); 49 lpClassDefinition->constructor(lpThisValue.get(), szFunctionName, impl); 50 if (!lpRetValue->DirectGetValue().IsEmpty()) 51 info.GetReturnValue().Set(lpRetValue->DirectGetValue()); 52 } 53 V8GetterCallback_Wrapper(v8::Local<v8::String> property,const v8::PropertyCallbackInfo<v8::Value> & info)54 void V8GetterCallback_Wrapper(v8::Local<v8::String> property, 55 const v8::PropertyCallbackInfo<v8::Value>& info) { 56 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo = 57 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>( 58 info.Data().As<v8::External>()->Value()); 59 if (!lpPropertyInfo) 60 return; 61 62 CFX_ByteStringC szPropertyName(lpPropertyInfo->name); 63 std::unique_ptr<CFXJSE_Value> lpThisValue( 64 new CFXJSE_Value(info.GetIsolate())); 65 std::unique_ptr<CFXJSE_Value> lpPropValue( 66 new CFXJSE_Value(info.GetIsolate())); 67 lpThisValue->ForceSetValue(info.This()); 68 lpPropertyInfo->getProc(lpThisValue.get(), szPropertyName, lpPropValue.get()); 69 info.GetReturnValue().Set(lpPropValue->DirectGetValue()); 70 } 71 V8SetterCallback_Wrapper(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<void> & info)72 void V8SetterCallback_Wrapper(v8::Local<v8::String> property, 73 v8::Local<v8::Value> value, 74 const v8::PropertyCallbackInfo<void>& info) { 75 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo = 76 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>( 77 info.Data().As<v8::External>()->Value()); 78 if (!lpPropertyInfo) 79 return; 80 81 CFX_ByteStringC szPropertyName(lpPropertyInfo->name); 82 std::unique_ptr<CFXJSE_Value> lpThisValue( 83 new CFXJSE_Value(info.GetIsolate())); 84 std::unique_ptr<CFXJSE_Value> lpPropValue( 85 new CFXJSE_Value(info.GetIsolate())); 86 lpThisValue->ForceSetValue(info.This()); 87 lpPropValue->ForceSetValue(value); 88 lpPropertyInfo->setProc(lpThisValue.get(), szPropertyName, lpPropValue.get()); 89 } 90 V8ConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value> & info)91 void V8ConstructorCallback_Wrapper( 92 const v8::FunctionCallbackInfo<v8::Value>& info) { 93 if (!info.IsConstructCall()) 94 return; 95 96 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition = 97 static_cast<FXJSE_CLASS_DESCRIPTOR*>( 98 info.Data().As<v8::External>()->Value()); 99 if (!lpClassDefinition) 100 return; 101 102 ASSERT(info.This()->InternalFieldCount()); 103 info.This()->SetAlignedPointerInInternalField(0, nullptr); 104 } 105 Context_GlobalObjToString(const v8::FunctionCallbackInfo<v8::Value> & info)106 void Context_GlobalObjToString( 107 const v8::FunctionCallbackInfo<v8::Value>& info) { 108 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 109 info.Data().As<v8::External>()->Value()); 110 if (!lpClass) 111 return; 112 113 if (info.This() == info.Holder() && lpClass->name) { 114 CFX_ByteString szStringVal; 115 szStringVal.Format("[object %s]", lpClass->name); 116 info.GetReturnValue().Set(v8::String::NewFromUtf8( 117 info.GetIsolate(), szStringVal.c_str(), v8::String::kNormalString, 118 szStringVal.GetLength())); 119 return; 120 } 121 v8::Local<v8::String> local_str = 122 info.This() 123 ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext()) 124 .FromMaybe(v8::Local<v8::String>()); 125 info.GetReturnValue().Set(local_str); 126 } 127 DynPropGetterAdapter_MethodCallback(const v8::FunctionCallbackInfo<v8::Value> & info)128 void DynPropGetterAdapter_MethodCallback( 129 const v8::FunctionCallbackInfo<v8::Value>& info) { 130 v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>(); 131 FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 132 hCallBackInfo->GetAlignedPointerFromInternalField(0)); 133 v8::Local<v8::String> hPropName = 134 hCallBackInfo->GetInternalField(1).As<v8::String>(); 135 ASSERT(lpClass && !hPropName.IsEmpty()); 136 v8::String::Utf8Value szPropName(hPropName); 137 CFX_ByteStringC szFxPropName = *szPropName; 138 std::unique_ptr<CFXJSE_Value> lpThisValue( 139 new CFXJSE_Value(info.GetIsolate())); 140 lpThisValue->ForceSetValue(info.This()); 141 std::unique_ptr<CFXJSE_Value> lpRetValue(new CFXJSE_Value(info.GetIsolate())); 142 CFXJSE_Arguments impl(&info, lpRetValue.get()); 143 lpClass->dynMethodCall(lpThisValue.get(), szFxPropName, impl); 144 if (!lpRetValue->DirectGetValue().IsEmpty()) 145 info.GetReturnValue().Set(lpRetValue->DirectGetValue()); 146 } 147 DynPropGetterAdapter(const FXJSE_CLASS_DESCRIPTOR * lpClass,CFXJSE_Value * pObject,const CFX_ByteStringC & szPropName,CFXJSE_Value * pValue)148 void DynPropGetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass, 149 CFXJSE_Value* pObject, 150 const CFX_ByteStringC& szPropName, 151 CFXJSE_Value* pValue) { 152 ASSERT(lpClass); 153 int32_t nPropType = 154 lpClass->dynPropTypeGetter == nullptr 155 ? FXJSE_ClassPropType_Property 156 : lpClass->dynPropTypeGetter(pObject, szPropName, false); 157 if (nPropType == FXJSE_ClassPropType_Property) { 158 if (lpClass->dynPropGetter) 159 lpClass->dynPropGetter(pObject, szPropName, pValue); 160 } else if (nPropType == FXJSE_ClassPropType_Method) { 161 if (lpClass->dynMethodCall && pValue) { 162 v8::Isolate* pIsolate = pValue->GetIsolate(); 163 v8::HandleScope hscope(pIsolate); 164 v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate = 165 v8::ObjectTemplate::New(pIsolate); 166 hCallBackInfoTemplate->SetInternalFieldCount(2); 167 v8::Local<v8::Object> hCallBackInfo = 168 hCallBackInfoTemplate->NewInstance(); 169 hCallBackInfo->SetAlignedPointerInInternalField( 170 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClass)); 171 hCallBackInfo->SetInternalField( 172 1, v8::String::NewFromUtf8( 173 pIsolate, reinterpret_cast<const char*>(szPropName.raw_str()), 174 v8::String::kNormalString, szPropName.GetLength())); 175 pValue->ForceSetValue( 176 v8::Function::New(pValue->GetIsolate()->GetCurrentContext(), 177 DynPropGetterAdapter_MethodCallback, hCallBackInfo, 178 0, v8::ConstructorBehavior::kThrow) 179 .ToLocalChecked()); 180 } 181 } 182 } 183 DynPropSetterAdapter(const FXJSE_CLASS_DESCRIPTOR * lpClass,CFXJSE_Value * pObject,const CFX_ByteStringC & szPropName,CFXJSE_Value * pValue)184 void DynPropSetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass, 185 CFXJSE_Value* pObject, 186 const CFX_ByteStringC& szPropName, 187 CFXJSE_Value* pValue) { 188 ASSERT(lpClass); 189 int32_t nPropType = 190 lpClass->dynPropTypeGetter == nullptr 191 ? FXJSE_ClassPropType_Property 192 : lpClass->dynPropTypeGetter(pObject, szPropName, false); 193 if (nPropType != FXJSE_ClassPropType_Method) { 194 if (lpClass->dynPropSetter) 195 lpClass->dynPropSetter(pObject, szPropName, pValue); 196 } 197 } 198 DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR * lpClass,CFXJSE_Value * pObject,const CFX_ByteStringC & szPropName)199 bool DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass, 200 CFXJSE_Value* pObject, 201 const CFX_ByteStringC& szPropName) { 202 ASSERT(lpClass); 203 int32_t nPropType = 204 lpClass->dynPropTypeGetter == nullptr 205 ? FXJSE_ClassPropType_Property 206 : lpClass->dynPropTypeGetter(pObject, szPropName, true); 207 return nPropType != FXJSE_ClassPropType_None; 208 } 209 DynPropDeleterAdapter(const FXJSE_CLASS_DESCRIPTOR * lpClass,CFXJSE_Value * pObject,const CFX_ByteStringC & szPropName)210 bool DynPropDeleterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass, 211 CFXJSE_Value* pObject, 212 const CFX_ByteStringC& szPropName) { 213 ASSERT(lpClass); 214 int32_t nPropType = 215 lpClass->dynPropTypeGetter == nullptr 216 ? FXJSE_ClassPropType_Property 217 : lpClass->dynPropTypeGetter(pObject, szPropName, false); 218 if (nPropType != FXJSE_ClassPropType_Method) { 219 if (lpClass->dynPropDeleter) 220 return lpClass->dynPropDeleter(pObject, szPropName); 221 return nPropType != FXJSE_ClassPropType_Property; 222 } 223 return false; 224 } 225 NamedPropertyQueryCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Integer> & info)226 void NamedPropertyQueryCallback( 227 v8::Local<v8::Name> property, 228 const v8::PropertyCallbackInfo<v8::Integer>& info) { 229 v8::Local<v8::Object> thisObject = info.This(); 230 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 231 info.Data().As<v8::External>()->Value()); 232 v8::Isolate* pIsolate = info.GetIsolate(); 233 v8::HandleScope scope(pIsolate); 234 v8::String::Utf8Value szPropName(property); 235 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); 236 std::unique_ptr<CFXJSE_Value> lpThisValue( 237 new CFXJSE_Value(info.GetIsolate())); 238 lpThisValue->ForceSetValue(thisObject); 239 if (DynPropQueryAdapter(lpClass, lpThisValue.get(), szFxPropName)) { 240 info.GetReturnValue().Set(v8::DontDelete); 241 return; 242 } 243 const int32_t iV8Absent = 64; 244 info.GetReturnValue().Set(iV8Absent); 245 } 246 NamedPropertyDeleterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Boolean> & info)247 void NamedPropertyDeleterCallback( 248 v8::Local<v8::Name> property, 249 const v8::PropertyCallbackInfo<v8::Boolean>& info) { 250 v8::Local<v8::Object> thisObject = info.This(); 251 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 252 info.Data().As<v8::External>()->Value()); 253 v8::Isolate* pIsolate = info.GetIsolate(); 254 v8::HandleScope scope(pIsolate); 255 v8::String::Utf8Value szPropName(property); 256 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); 257 std::unique_ptr<CFXJSE_Value> lpThisValue( 258 new CFXJSE_Value(info.GetIsolate())); 259 lpThisValue->ForceSetValue(thisObject); 260 info.GetReturnValue().Set( 261 !!DynPropDeleterAdapter(lpClass, lpThisValue.get(), szFxPropName)); 262 } 263 NamedPropertyGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info)264 void NamedPropertyGetterCallback( 265 v8::Local<v8::Name> property, 266 const v8::PropertyCallbackInfo<v8::Value>& info) { 267 v8::Local<v8::Object> thisObject = info.This(); 268 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 269 info.Data().As<v8::External>()->Value()); 270 v8::String::Utf8Value szPropName(property); 271 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); 272 std::unique_ptr<CFXJSE_Value> lpThisValue( 273 new CFXJSE_Value(info.GetIsolate())); 274 lpThisValue->ForceSetValue(thisObject); 275 std::unique_ptr<CFXJSE_Value> lpNewValue(new CFXJSE_Value(info.GetIsolate())); 276 DynPropGetterAdapter(lpClass, lpThisValue.get(), szFxPropName, 277 lpNewValue.get()); 278 info.GetReturnValue().Set(lpNewValue->DirectGetValue()); 279 } 280 NamedPropertySetterCallback(v8::Local<v8::Name> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<v8::Value> & info)281 void NamedPropertySetterCallback( 282 v8::Local<v8::Name> property, 283 v8::Local<v8::Value> value, 284 const v8::PropertyCallbackInfo<v8::Value>& info) { 285 v8::Local<v8::Object> thisObject = info.This(); 286 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 287 info.Data().As<v8::External>()->Value()); 288 v8::String::Utf8Value szPropName(property); 289 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); 290 std::unique_ptr<CFXJSE_Value> lpThisValue( 291 new CFXJSE_Value(info.GetIsolate())); 292 lpThisValue->ForceSetValue(thisObject); 293 294 std::unique_ptr<CFXJSE_Value> lpNewValue(new CFXJSE_Value(info.GetIsolate())); 295 lpNewValue->ForceSetValue(value); 296 DynPropSetterAdapter(lpClass, lpThisValue.get(), szFxPropName, 297 lpNewValue.get()); 298 info.GetReturnValue().Set(value); 299 } 300 NamedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array> & info)301 void NamedPropertyEnumeratorCallback( 302 const v8::PropertyCallbackInfo<v8::Array>& info) { 303 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>( 304 info.Data().As<v8::External>()->Value()); 305 v8::Isolate* pIsolate = info.GetIsolate(); 306 v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum); 307 for (int i = 0; i < lpClass->propNum; i++) { 308 newArray->Set( 309 i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name)); 310 } 311 info.GetReturnValue().Set(newArray); 312 } 313 314 } // namespace 315 316 // static Create(CFXJSE_Context * lpContext,const FXJSE_CLASS_DESCRIPTOR * lpClassDefinition,bool bIsJSGlobal)317 CFXJSE_Class* CFXJSE_Class::Create( 318 CFXJSE_Context* lpContext, 319 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition, 320 bool bIsJSGlobal) { 321 if (!lpContext || !lpClassDefinition) 322 return nullptr; 323 324 CFXJSE_Class* pClass = 325 GetClassFromContext(lpContext, lpClassDefinition->name); 326 if (pClass) 327 return pClass; 328 329 v8::Isolate* pIsolate = lpContext->m_pIsolate; 330 pClass = new CFXJSE_Class(lpContext); 331 pClass->m_szClassName = lpClassDefinition->name; 332 pClass->m_lpClassDefinition = lpClassDefinition; 333 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); 334 v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New( 335 pIsolate, bIsJSGlobal ? 0 : V8ConstructorCallback_Wrapper, 336 v8::External::New( 337 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition))); 338 hFunctionTemplate->SetClassName( 339 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name)); 340 hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(1); 341 v8::Local<v8::ObjectTemplate> hObjectTemplate = 342 hFunctionTemplate->InstanceTemplate(); 343 SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition); 344 345 if (lpClassDefinition->propNum) { 346 for (int32_t i = 0; i < lpClassDefinition->propNum; i++) { 347 hObjectTemplate->SetNativeDataProperty( 348 v8::String::NewFromUtf8(pIsolate, 349 lpClassDefinition->properties[i].name), 350 lpClassDefinition->properties[i].getProc ? V8GetterCallback_Wrapper 351 : nullptr, 352 lpClassDefinition->properties[i].setProc ? V8SetterCallback_Wrapper 353 : nullptr, 354 v8::External::New(pIsolate, const_cast<FXJSE_PROPERTY_DESCRIPTOR*>( 355 lpClassDefinition->properties + i)), 356 static_cast<v8::PropertyAttribute>(v8::DontDelete)); 357 } 358 } 359 if (lpClassDefinition->methNum) { 360 for (int32_t i = 0; i < lpClassDefinition->methNum; i++) { 361 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New( 362 pIsolate, V8FunctionCallback_Wrapper, 363 v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION_DESCRIPTOR*>( 364 lpClassDefinition->methods + i))); 365 fun->RemovePrototype(); 366 hObjectTemplate->Set( 367 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name), 368 fun, 369 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); 370 } 371 } 372 if (lpClassDefinition->constructor) { 373 if (bIsJSGlobal) { 374 hObjectTemplate->Set( 375 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), 376 v8::FunctionTemplate::New( 377 pIsolate, V8ClassGlobalConstructorCallback_Wrapper, 378 v8::External::New(pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>( 379 lpClassDefinition))), 380 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete)); 381 } else { 382 v8::Local<v8::Context> hLocalContext = 383 v8::Local<v8::Context>::New(pIsolate, lpContext->m_hContext); 384 FXJSE_GetGlobalObjectFromContext(hLocalContext) 385 ->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), 386 v8::Function::New( 387 pIsolate, V8ClassGlobalConstructorCallback_Wrapper, 388 v8::External::New(pIsolate, 389 const_cast<FXJSE_CLASS_DESCRIPTOR*>( 390 lpClassDefinition)))); 391 } 392 } 393 if (bIsJSGlobal) { 394 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New( 395 pIsolate, Context_GlobalObjToString, 396 v8::External::New( 397 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition))); 398 fun->RemovePrototype(); 399 hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString"), fun); 400 } 401 pClass->m_hTemplate.Reset(lpContext->m_pIsolate, hFunctionTemplate); 402 lpContext->m_rgClasses.push_back(std::unique_ptr<CFXJSE_Class>(pClass)); 403 return pClass; 404 } 405 406 // static GetClassFromContext(CFXJSE_Context * pContext,const CFX_ByteStringC & szName)407 CFXJSE_Class* CFXJSE_Class::GetClassFromContext(CFXJSE_Context* pContext, 408 const CFX_ByteStringC& szName) { 409 for (const auto& pClass : pContext->m_rgClasses) { 410 if (pClass->m_szClassName == szName) 411 return pClass.get(); 412 } 413 return nullptr; 414 } 415 416 // static SetUpNamedPropHandler(v8::Isolate * pIsolate,v8::Local<v8::ObjectTemplate> & hObjectTemplate,const FXJSE_CLASS_DESCRIPTOR * lpClassDefinition)417 void CFXJSE_Class::SetUpNamedPropHandler( 418 v8::Isolate* pIsolate, 419 v8::Local<v8::ObjectTemplate>& hObjectTemplate, 420 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition) { 421 v8::NamedPropertyHandlerConfiguration configuration( 422 lpClassDefinition->dynPropGetter ? NamedPropertyGetterCallback : 0, 423 lpClassDefinition->dynPropSetter ? NamedPropertySetterCallback : 0, 424 lpClassDefinition->dynPropTypeGetter ? NamedPropertyQueryCallback : 0, 425 lpClassDefinition->dynPropDeleter ? NamedPropertyDeleterCallback : 0, 426 NamedPropertyEnumeratorCallback, 427 v8::External::New(pIsolate, 428 const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)), 429 v8::PropertyHandlerFlags::kNonMasking); 430 hObjectTemplate->SetHandler(configuration); 431 } 432 CFXJSE_Class(CFXJSE_Context * lpContext)433 CFXJSE_Class::CFXJSE_Class(CFXJSE_Context* lpContext) 434 : m_lpClassDefinition(nullptr), m_pContext(lpContext) {} 435 ~CFXJSE_Class()436 CFXJSE_Class::~CFXJSE_Class() {} 437