blob: 3801fb520a432b2acb3479d00c193fef42ef0c4f [file] [log] [blame]
dsinclair08fea802016-07-12 10:37:52 -07001// 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
dsinclair43554682016-09-29 17:29:48 -07007#include "fxjs/cfxjse_class.h"
dsinclair08fea802016-07-12 10:37:52 -07008
Dan Sinclair85c8e7f2016-11-21 13:50:32 -05009#include <memory>
10
dsinclair43554682016-09-29 17:29:48 -070011#include "fxjs/cfxjse_context.h"
12#include "fxjs/cfxjse_value.h"
dsinclair08fea802016-07-12 10:37:52 -070013
14namespace {
15
16void 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()));
Dan Sinclair2fbfb842017-03-22 13:58:45 -040027 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070028 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
35void 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()));
Dan Sinclair2fbfb842017-03-22 13:58:45 -040046 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070047 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
54void 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()));
Dan Sinclair2fbfb842017-03-22 13:58:45 -040067 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070068 lpPropertyInfo->getProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
69 info.GetReturnValue().Set(lpPropValue->DirectGetValue());
70}
71
72void 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()));
Dan Sinclair2fbfb842017-03-22 13:58:45 -040086 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070087 lpPropValue->ForceSetValue(value);
88 lpPropertyInfo->setProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
89}
90
91void 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
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400102 ASSERT(info.Holder()->InternalFieldCount());
103 info.Holder()->SetAlignedPointerInInternalField(0, nullptr);
dsinclair08fea802016-07-12 10:37:52 -0700104}
105
106void 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 =
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400122 info.Holder()
dsinclair08fea802016-07-12 10:37:52 -0700123 ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext())
124 .FromMaybe(v8::Local<v8::String>());
125 info.GetReturnValue().Set(local_str);
126}
127
128void 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()));
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400140 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -0700141 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
148void 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
tsepez304bb912016-11-03 06:10:26 -0700156 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700157 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
184void 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
tsepez304bb912016-11-03 06:10:26 -0700192 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700193 if (nPropType != FXJSE_ClassPropType_Method) {
194 if (lpClass->dynPropSetter)
195 lpClass->dynPropSetter(pObject, szPropName, pValue);
196 }
197}
198
tsepez304bb912016-11-03 06:10:26 -0700199bool DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
200 CFXJSE_Value* pObject,
201 const CFX_ByteStringC& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700202 ASSERT(lpClass);
203 int32_t nPropType =
204 lpClass->dynPropTypeGetter == nullptr
205 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700206 : lpClass->dynPropTypeGetter(pObject, szPropName, true);
dsinclair08fea802016-07-12 10:37:52 -0700207 return nPropType != FXJSE_ClassPropType_None;
208}
209
tsepez304bb912016-11-03 06:10:26 -0700210bool DynPropDeleterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
211 CFXJSE_Value* pObject,
212 const CFX_ByteStringC& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700213 ASSERT(lpClass);
214 int32_t nPropType =
215 lpClass->dynPropTypeGetter == nullptr
216 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700217 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700218 if (nPropType != FXJSE_ClassPropType_Method) {
219 if (lpClass->dynPropDeleter)
220 return lpClass->dynPropDeleter(pObject, szPropName);
tsepez304bb912016-11-03 06:10:26 -0700221 return nPropType != FXJSE_ClassPropType_Property;
dsinclair08fea802016-07-12 10:37:52 -0700222 }
tsepez304bb912016-11-03 06:10:26 -0700223 return false;
dsinclair08fea802016-07-12 10:37:52 -0700224}
225
226void NamedPropertyQueryCallback(
227 v8::Local<v8::Name> property,
228 const v8::PropertyCallbackInfo<v8::Integer>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400229 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700230 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
247void NamedPropertyDeleterCallback(
248 v8::Local<v8::Name> property,
249 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400250 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700251 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
264void NamedPropertyGetterCallback(
265 v8::Local<v8::Name> property,
266 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400267 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700268 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
281void NamedPropertySetterCallback(
282 v8::Local<v8::Name> property,
283 v8::Local<v8::Value> value,
284 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400285 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700286 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
weili1a241992016-09-12 15:10:40 -0700294 std::unique_ptr<CFXJSE_Value> lpNewValue(new CFXJSE_Value(info.GetIsolate()));
dsinclair08fea802016-07-12 10:37:52 -0700295 lpNewValue->ForceSetValue(value);
weili1a241992016-09-12 15:10:40 -0700296 DynPropSetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
297 lpNewValue.get());
dsinclair08fea802016-07-12 10:37:52 -0700298 info.GetReturnValue().Set(value);
299}
300
301void 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
317CFXJSE_Class* CFXJSE_Class::Create(
318 CFXJSE_Context* lpContext,
319 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition,
tsepez304bb912016-11-03 06:10:26 -0700320 bool bIsJSGlobal) {
dsinclair08fea802016-07-12 10:37:52 -0700321 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
407CFXJSE_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
417void 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
433CFXJSE_Class::CFXJSE_Class(CFXJSE_Context* lpContext)
434 : m_lpClassDefinition(nullptr), m_pContext(lpContext) {}
435
436CFXJSE_Class::~CFXJSE_Class() {}