blob: 8924a48a47e1935be65afec6ec1f79db8d31ea82 [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"
Dan Sinclair0bb13332017-03-30 16:12:02 -040013#include "third_party/base/ptr_util.h"
dsinclair08fea802016-07-12 10:37:52 -070014
15namespace {
16
17void V8FunctionCallback_Wrapper(
18 const v8::FunctionCallbackInfo<v8::Value>& info) {
19 const FXJSE_FUNCTION_DESCRIPTOR* lpFunctionInfo =
20 static_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
21 info.Data().As<v8::External>()->Value());
22 if (!lpFunctionInfo)
23 return;
24
25 CFX_ByteStringC szFunctionName(lpFunctionInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040026 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040027 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -040028 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -070029 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);
Dan Sinclair0bb13332017-03-30 16:12:02 -040044 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040045 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -040046 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -070047 CFXJSE_Arguments impl(&info, lpRetValue.get());
48 lpClassDefinition->constructor(lpThisValue.get(), szFunctionName, impl);
49 if (!lpRetValue->DirectGetValue().IsEmpty())
50 info.GetReturnValue().Set(lpRetValue->DirectGetValue());
51}
52
53void V8GetterCallback_Wrapper(v8::Local<v8::String> property,
54 const v8::PropertyCallbackInfo<v8::Value>& info) {
55 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo =
56 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
57 info.Data().As<v8::External>()->Value());
58 if (!lpPropertyInfo)
59 return;
60
61 CFX_ByteStringC szPropertyName(lpPropertyInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040062 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
63 auto lpPropValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040064 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070065 lpPropertyInfo->getProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
66 info.GetReturnValue().Set(lpPropValue->DirectGetValue());
67}
68
69void V8SetterCallback_Wrapper(v8::Local<v8::String> property,
70 v8::Local<v8::Value> value,
71 const v8::PropertyCallbackInfo<void>& info) {
72 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo =
73 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
74 info.Data().As<v8::External>()->Value());
75 if (!lpPropertyInfo)
76 return;
77
78 CFX_ByteStringC szPropertyName(lpPropertyInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040079 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
80 auto lpPropValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040081 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070082 lpPropValue->ForceSetValue(value);
83 lpPropertyInfo->setProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
84}
85
86void V8ConstructorCallback_Wrapper(
87 const v8::FunctionCallbackInfo<v8::Value>& info) {
88 if (!info.IsConstructCall())
89 return;
90
91 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition =
92 static_cast<FXJSE_CLASS_DESCRIPTOR*>(
93 info.Data().As<v8::External>()->Value());
94 if (!lpClassDefinition)
95 return;
96
Dan Sinclair2fbfb842017-03-22 13:58:45 -040097 ASSERT(info.Holder()->InternalFieldCount());
98 info.Holder()->SetAlignedPointerInInternalField(0, nullptr);
dsinclair08fea802016-07-12 10:37:52 -070099}
100
101void Context_GlobalObjToString(
102 const v8::FunctionCallbackInfo<v8::Value>& info) {
103 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
104 info.Data().As<v8::External>()->Value());
105 if (!lpClass)
106 return;
107
108 if (info.This() == info.Holder() && lpClass->name) {
109 CFX_ByteString szStringVal;
110 szStringVal.Format("[object %s]", lpClass->name);
111 info.GetReturnValue().Set(v8::String::NewFromUtf8(
112 info.GetIsolate(), szStringVal.c_str(), v8::String::kNormalString,
113 szStringVal.GetLength()));
114 return;
115 }
116 v8::Local<v8::String> local_str =
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400117 info.Holder()
dsinclair08fea802016-07-12 10:37:52 -0700118 ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext())
119 .FromMaybe(v8::Local<v8::String>());
120 info.GetReturnValue().Set(local_str);
121}
122
123void DynPropGetterAdapter_MethodCallback(
124 const v8::FunctionCallbackInfo<v8::Value>& info) {
125 v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
126 FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
127 hCallBackInfo->GetAlignedPointerFromInternalField(0));
128 v8::Local<v8::String> hPropName =
129 hCallBackInfo->GetInternalField(1).As<v8::String>();
130 ASSERT(lpClass && !hPropName.IsEmpty());
131 v8::String::Utf8Value szPropName(hPropName);
132 CFX_ByteStringC szFxPropName = *szPropName;
Dan Sinclair0bb13332017-03-30 16:12:02 -0400133 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400134 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400135 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700136 CFXJSE_Arguments impl(&info, lpRetValue.get());
137 lpClass->dynMethodCall(lpThisValue.get(), szFxPropName, impl);
138 if (!lpRetValue->DirectGetValue().IsEmpty())
139 info.GetReturnValue().Set(lpRetValue->DirectGetValue());
140}
141
142void DynPropGetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
143 CFXJSE_Value* pObject,
144 const CFX_ByteStringC& szPropName,
145 CFXJSE_Value* pValue) {
146 ASSERT(lpClass);
147 int32_t nPropType =
148 lpClass->dynPropTypeGetter == nullptr
149 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700150 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700151 if (nPropType == FXJSE_ClassPropType_Property) {
152 if (lpClass->dynPropGetter)
153 lpClass->dynPropGetter(pObject, szPropName, pValue);
154 } else if (nPropType == FXJSE_ClassPropType_Method) {
155 if (lpClass->dynMethodCall && pValue) {
156 v8::Isolate* pIsolate = pValue->GetIsolate();
157 v8::HandleScope hscope(pIsolate);
158 v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
159 v8::ObjectTemplate::New(pIsolate);
160 hCallBackInfoTemplate->SetInternalFieldCount(2);
161 v8::Local<v8::Object> hCallBackInfo =
162 hCallBackInfoTemplate->NewInstance();
163 hCallBackInfo->SetAlignedPointerInInternalField(
164 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClass));
165 hCallBackInfo->SetInternalField(
166 1, v8::String::NewFromUtf8(
167 pIsolate, reinterpret_cast<const char*>(szPropName.raw_str()),
168 v8::String::kNormalString, szPropName.GetLength()));
169 pValue->ForceSetValue(
170 v8::Function::New(pValue->GetIsolate()->GetCurrentContext(),
171 DynPropGetterAdapter_MethodCallback, hCallBackInfo,
172 0, v8::ConstructorBehavior::kThrow)
173 .ToLocalChecked());
174 }
175 }
176}
177
178void DynPropSetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
179 CFXJSE_Value* pObject,
180 const CFX_ByteStringC& szPropName,
181 CFXJSE_Value* pValue) {
182 ASSERT(lpClass);
183 int32_t nPropType =
184 lpClass->dynPropTypeGetter == nullptr
185 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700186 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700187 if (nPropType != FXJSE_ClassPropType_Method) {
188 if (lpClass->dynPropSetter)
189 lpClass->dynPropSetter(pObject, szPropName, pValue);
190 }
191}
192
tsepez304bb912016-11-03 06:10:26 -0700193bool DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
194 CFXJSE_Value* pObject,
195 const CFX_ByteStringC& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700196 ASSERT(lpClass);
197 int32_t nPropType =
198 lpClass->dynPropTypeGetter == nullptr
199 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700200 : lpClass->dynPropTypeGetter(pObject, szPropName, true);
dsinclair08fea802016-07-12 10:37:52 -0700201 return nPropType != FXJSE_ClassPropType_None;
202}
203
tsepez304bb912016-11-03 06:10:26 -0700204bool DynPropDeleterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
205 CFXJSE_Value* pObject,
206 const CFX_ByteStringC& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700207 ASSERT(lpClass);
208 int32_t nPropType =
209 lpClass->dynPropTypeGetter == nullptr
210 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700211 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700212 if (nPropType != FXJSE_ClassPropType_Method) {
213 if (lpClass->dynPropDeleter)
214 return lpClass->dynPropDeleter(pObject, szPropName);
tsepez304bb912016-11-03 06:10:26 -0700215 return nPropType != FXJSE_ClassPropType_Property;
dsinclair08fea802016-07-12 10:37:52 -0700216 }
tsepez304bb912016-11-03 06:10:26 -0700217 return false;
dsinclair08fea802016-07-12 10:37:52 -0700218}
219
220void NamedPropertyQueryCallback(
221 v8::Local<v8::Name> property,
222 const v8::PropertyCallbackInfo<v8::Integer>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400223 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700224 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
225 info.Data().As<v8::External>()->Value());
226 v8::Isolate* pIsolate = info.GetIsolate();
227 v8::HandleScope scope(pIsolate);
228 v8::String::Utf8Value szPropName(property);
229 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400230 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700231 lpThisValue->ForceSetValue(thisObject);
232 if (DynPropQueryAdapter(lpClass, lpThisValue.get(), szFxPropName)) {
233 info.GetReturnValue().Set(v8::DontDelete);
234 return;
235 }
236 const int32_t iV8Absent = 64;
237 info.GetReturnValue().Set(iV8Absent);
238}
239
240void NamedPropertyDeleterCallback(
241 v8::Local<v8::Name> property,
242 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400243 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700244 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
245 info.Data().As<v8::External>()->Value());
246 v8::Isolate* pIsolate = info.GetIsolate();
247 v8::HandleScope scope(pIsolate);
248 v8::String::Utf8Value szPropName(property);
249 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400250 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700251 lpThisValue->ForceSetValue(thisObject);
252 info.GetReturnValue().Set(
253 !!DynPropDeleterAdapter(lpClass, lpThisValue.get(), szFxPropName));
254}
255
256void NamedPropertyGetterCallback(
257 v8::Local<v8::Name> property,
258 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400259 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700260 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
261 info.Data().As<v8::External>()->Value());
262 v8::String::Utf8Value szPropName(property);
263 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400264 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700265 lpThisValue->ForceSetValue(thisObject);
Dan Sinclair0bb13332017-03-30 16:12:02 -0400266 auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700267 DynPropGetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
268 lpNewValue.get());
269 info.GetReturnValue().Set(lpNewValue->DirectGetValue());
270}
271
272void NamedPropertySetterCallback(
273 v8::Local<v8::Name> property,
274 v8::Local<v8::Value> value,
275 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400276 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700277 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
278 info.Data().As<v8::External>()->Value());
279 v8::String::Utf8Value szPropName(property);
280 CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400281 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700282 lpThisValue->ForceSetValue(thisObject);
283
Dan Sinclair0bb13332017-03-30 16:12:02 -0400284 auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700285 lpNewValue->ForceSetValue(value);
weili1a241992016-09-12 15:10:40 -0700286 DynPropSetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
287 lpNewValue.get());
dsinclair08fea802016-07-12 10:37:52 -0700288 info.GetReturnValue().Set(value);
289}
290
291void NamedPropertyEnumeratorCallback(
292 const v8::PropertyCallbackInfo<v8::Array>& info) {
293 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
294 info.Data().As<v8::External>()->Value());
295 v8::Isolate* pIsolate = info.GetIsolate();
296 v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum);
297 for (int i = 0; i < lpClass->propNum; i++) {
298 newArray->Set(
299 i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name));
300 }
301 info.GetReturnValue().Set(newArray);
302}
303
304} // namespace
305
306// static
307CFXJSE_Class* CFXJSE_Class::Create(
308 CFXJSE_Context* lpContext,
309 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition,
tsepez304bb912016-11-03 06:10:26 -0700310 bool bIsJSGlobal) {
dsinclair08fea802016-07-12 10:37:52 -0700311 if (!lpContext || !lpClassDefinition)
312 return nullptr;
313
314 CFXJSE_Class* pClass =
315 GetClassFromContext(lpContext, lpClassDefinition->name);
316 if (pClass)
317 return pClass;
318
319 v8::Isolate* pIsolate = lpContext->m_pIsolate;
320 pClass = new CFXJSE_Class(lpContext);
321 pClass->m_szClassName = lpClassDefinition->name;
322 pClass->m_lpClassDefinition = lpClassDefinition;
323 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
324 v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New(
325 pIsolate, bIsJSGlobal ? 0 : V8ConstructorCallback_Wrapper,
326 v8::External::New(
327 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
328 hFunctionTemplate->SetClassName(
329 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name));
330 hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(1);
331 v8::Local<v8::ObjectTemplate> hObjectTemplate =
332 hFunctionTemplate->InstanceTemplate();
333 SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition);
334
335 if (lpClassDefinition->propNum) {
336 for (int32_t i = 0; i < lpClassDefinition->propNum; i++) {
337 hObjectTemplate->SetNativeDataProperty(
338 v8::String::NewFromUtf8(pIsolate,
339 lpClassDefinition->properties[i].name),
340 lpClassDefinition->properties[i].getProc ? V8GetterCallback_Wrapper
341 : nullptr,
342 lpClassDefinition->properties[i].setProc ? V8SetterCallback_Wrapper
343 : nullptr,
344 v8::External::New(pIsolate, const_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
345 lpClassDefinition->properties + i)),
346 static_cast<v8::PropertyAttribute>(v8::DontDelete));
347 }
348 }
349 if (lpClassDefinition->methNum) {
350 for (int32_t i = 0; i < lpClassDefinition->methNum; i++) {
351 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
352 pIsolate, V8FunctionCallback_Wrapper,
353 v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
354 lpClassDefinition->methods + i)));
355 fun->RemovePrototype();
356 hObjectTemplate->Set(
357 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name),
358 fun,
359 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
360 }
361 }
362 if (lpClassDefinition->constructor) {
363 if (bIsJSGlobal) {
364 hObjectTemplate->Set(
365 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
366 v8::FunctionTemplate::New(
367 pIsolate, V8ClassGlobalConstructorCallback_Wrapper,
368 v8::External::New(pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(
369 lpClassDefinition))),
370 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
371 } else {
372 v8::Local<v8::Context> hLocalContext =
373 v8::Local<v8::Context>::New(pIsolate, lpContext->m_hContext);
374 FXJSE_GetGlobalObjectFromContext(hLocalContext)
375 ->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
376 v8::Function::New(
377 pIsolate, V8ClassGlobalConstructorCallback_Wrapper,
378 v8::External::New(pIsolate,
379 const_cast<FXJSE_CLASS_DESCRIPTOR*>(
380 lpClassDefinition))));
381 }
382 }
383 if (bIsJSGlobal) {
384 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
385 pIsolate, Context_GlobalObjToString,
386 v8::External::New(
387 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
388 fun->RemovePrototype();
389 hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString"), fun);
390 }
391 pClass->m_hTemplate.Reset(lpContext->m_pIsolate, hFunctionTemplate);
392 lpContext->m_rgClasses.push_back(std::unique_ptr<CFXJSE_Class>(pClass));
393 return pClass;
394}
395
396// static
397CFXJSE_Class* CFXJSE_Class::GetClassFromContext(CFXJSE_Context* pContext,
398 const CFX_ByteStringC& szName) {
399 for (const auto& pClass : pContext->m_rgClasses) {
400 if (pClass->m_szClassName == szName)
401 return pClass.get();
402 }
403 return nullptr;
404}
405
406// static
407void CFXJSE_Class::SetUpNamedPropHandler(
408 v8::Isolate* pIsolate,
409 v8::Local<v8::ObjectTemplate>& hObjectTemplate,
410 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition) {
411 v8::NamedPropertyHandlerConfiguration configuration(
412 lpClassDefinition->dynPropGetter ? NamedPropertyGetterCallback : 0,
413 lpClassDefinition->dynPropSetter ? NamedPropertySetterCallback : 0,
414 lpClassDefinition->dynPropTypeGetter ? NamedPropertyQueryCallback : 0,
415 lpClassDefinition->dynPropDeleter ? NamedPropertyDeleterCallback : 0,
416 NamedPropertyEnumeratorCallback,
417 v8::External::New(pIsolate,
418 const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)),
419 v8::PropertyHandlerFlags::kNonMasking);
420 hObjectTemplate->SetHandler(configuration);
421}
422
423CFXJSE_Class::CFXJSE_Class(CFXJSE_Context* lpContext)
424 : m_lpClassDefinition(nullptr), m_pContext(lpContext) {}
425
426CFXJSE_Class::~CFXJSE_Class() {}