blob: 8f4334f89eeff754d8f097b6640796d24ed0a9fe [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>
Tom Sepez80547a12017-04-25 12:43:13 -070010#include <utility>
Dan Sinclair85c8e7f2016-11-21 13:50:32 -050011
Tom Sepez80547a12017-04-25 12:43:13 -070012#include "fxjs/cfxjse_arguments.h"
dsinclair43554682016-09-29 17:29:48 -070013#include "fxjs/cfxjse_context.h"
14#include "fxjs/cfxjse_value.h"
Dan Sinclair0bb13332017-03-30 16:12:02 -040015#include "third_party/base/ptr_util.h"
dsinclair08fea802016-07-12 10:37:52 -070016
17namespace {
18
19void V8FunctionCallback_Wrapper(
20 const v8::FunctionCallbackInfo<v8::Value>& info) {
21 const FXJSE_FUNCTION_DESCRIPTOR* lpFunctionInfo =
22 static_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
23 info.Data().As<v8::External>()->Value());
24 if (!lpFunctionInfo)
25 return;
26
Ryan Harrison275e2602017-09-18 14:23:18 -040027 ByteStringView szFunctionName(lpFunctionInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040028 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040029 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -040030 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -070031 CFXJSE_Arguments impl(&info, lpRetValue.get());
32 lpFunctionInfo->callbackProc(lpThisValue.get(), szFunctionName, impl);
33 if (!lpRetValue->DirectGetValue().IsEmpty())
34 info.GetReturnValue().Set(lpRetValue->DirectGetValue());
35}
36
37void V8ClassGlobalConstructorCallback_Wrapper(
38 const v8::FunctionCallbackInfo<v8::Value>& info) {
39 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition =
40 static_cast<FXJSE_CLASS_DESCRIPTOR*>(
41 info.Data().As<v8::External>()->Value());
42 if (!lpClassDefinition)
43 return;
44
Ryan Harrison275e2602017-09-18 14:23:18 -040045 ByteStringView szFunctionName(lpClassDefinition->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040046 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040047 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -040048 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -070049 CFXJSE_Arguments impl(&info, lpRetValue.get());
50 lpClassDefinition->constructor(lpThisValue.get(), szFunctionName, impl);
51 if (!lpRetValue->DirectGetValue().IsEmpty())
52 info.GetReturnValue().Set(lpRetValue->DirectGetValue());
53}
54
55void V8GetterCallback_Wrapper(v8::Local<v8::String> property,
56 const v8::PropertyCallbackInfo<v8::Value>& info) {
57 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo =
58 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
59 info.Data().As<v8::External>()->Value());
60 if (!lpPropertyInfo)
61 return;
62
Ryan Harrison275e2602017-09-18 14:23:18 -040063 ByteStringView szPropertyName(lpPropertyInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040064 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
65 auto lpPropValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040066 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070067 lpPropertyInfo->getProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
68 info.GetReturnValue().Set(lpPropValue->DirectGetValue());
69}
70
71void V8SetterCallback_Wrapper(v8::Local<v8::String> property,
72 v8::Local<v8::Value> value,
73 const v8::PropertyCallbackInfo<void>& info) {
74 const FXJSE_PROPERTY_DESCRIPTOR* lpPropertyInfo =
75 static_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
76 info.Data().As<v8::External>()->Value());
77 if (!lpPropertyInfo)
78 return;
79
Ryan Harrison275e2602017-09-18 14:23:18 -040080 ByteStringView szPropertyName(lpPropertyInfo->name);
Dan Sinclair0bb13332017-03-30 16:12:02 -040081 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
82 auto lpPropValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -040083 lpThisValue->ForceSetValue(info.Holder());
dsinclair08fea802016-07-12 10:37:52 -070084 lpPropValue->ForceSetValue(value);
85 lpPropertyInfo->setProc(lpThisValue.get(), szPropertyName, lpPropValue.get());
86}
87
88void V8ConstructorCallback_Wrapper(
89 const v8::FunctionCallbackInfo<v8::Value>& info) {
90 if (!info.IsConstructCall())
91 return;
92
93 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition =
94 static_cast<FXJSE_CLASS_DESCRIPTOR*>(
95 info.Data().As<v8::External>()->Value());
96 if (!lpClassDefinition)
97 return;
98
Dan Sinclair2fbfb842017-03-22 13:58:45 -040099 ASSERT(info.Holder()->InternalFieldCount());
100 info.Holder()->SetAlignedPointerInInternalField(0, nullptr);
dsinclair08fea802016-07-12 10:37:52 -0700101}
102
103void Context_GlobalObjToString(
104 const v8::FunctionCallbackInfo<v8::Value>& info) {
105 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
106 info.Data().As<v8::External>()->Value());
107 if (!lpClass)
108 return;
109
110 if (info.This() == info.Holder() && lpClass->name) {
Ryan Harrison275e2602017-09-18 14:23:18 -0400111 ByteString szStringVal;
dsinclair08fea802016-07-12 10:37:52 -0700112 szStringVal.Format("[object %s]", lpClass->name);
113 info.GetReturnValue().Set(v8::String::NewFromUtf8(
114 info.GetIsolate(), szStringVal.c_str(), v8::String::kNormalString,
115 szStringVal.GetLength()));
116 return;
117 }
118 v8::Local<v8::String> local_str =
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400119 info.Holder()
dsinclair08fea802016-07-12 10:37:52 -0700120 ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext())
121 .FromMaybe(v8::Local<v8::String>());
122 info.GetReturnValue().Set(local_str);
123}
124
125void DynPropGetterAdapter_MethodCallback(
126 const v8::FunctionCallbackInfo<v8::Value>& info) {
127 v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
128 FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
129 hCallBackInfo->GetAlignedPointerFromInternalField(0));
130 v8::Local<v8::String> hPropName =
131 hCallBackInfo->GetInternalField(1).As<v8::String>();
132 ASSERT(lpClass && !hPropName.IsEmpty());
133 v8::String::Utf8Value szPropName(hPropName);
Ryan Harrison275e2602017-09-18 14:23:18 -0400134 ByteStringView szFxPropName = *szPropName;
Dan Sinclair0bb13332017-03-30 16:12:02 -0400135 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400136 lpThisValue->ForceSetValue(info.Holder());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400137 auto lpRetValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700138 CFXJSE_Arguments impl(&info, lpRetValue.get());
139 lpClass->dynMethodCall(lpThisValue.get(), szFxPropName, impl);
140 if (!lpRetValue->DirectGetValue().IsEmpty())
141 info.GetReturnValue().Set(lpRetValue->DirectGetValue());
142}
143
144void DynPropGetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
145 CFXJSE_Value* pObject,
Ryan Harrison275e2602017-09-18 14:23:18 -0400146 const ByteStringView& szPropName,
dsinclair08fea802016-07-12 10:37:52 -0700147 CFXJSE_Value* pValue) {
148 ASSERT(lpClass);
149 int32_t nPropType =
150 lpClass->dynPropTypeGetter == nullptr
151 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700152 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700153 if (nPropType == FXJSE_ClassPropType_Property) {
154 if (lpClass->dynPropGetter)
155 lpClass->dynPropGetter(pObject, szPropName, pValue);
156 } else if (nPropType == FXJSE_ClassPropType_Method) {
157 if (lpClass->dynMethodCall && pValue) {
158 v8::Isolate* pIsolate = pValue->GetIsolate();
159 v8::HandleScope hscope(pIsolate);
160 v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
161 v8::ObjectTemplate::New(pIsolate);
162 hCallBackInfoTemplate->SetInternalFieldCount(2);
163 v8::Local<v8::Object> hCallBackInfo =
164 hCallBackInfoTemplate->NewInstance();
165 hCallBackInfo->SetAlignedPointerInInternalField(
166 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClass));
167 hCallBackInfo->SetInternalField(
168 1, v8::String::NewFromUtf8(
169 pIsolate, reinterpret_cast<const char*>(szPropName.raw_str()),
170 v8::String::kNormalString, szPropName.GetLength()));
171 pValue->ForceSetValue(
172 v8::Function::New(pValue->GetIsolate()->GetCurrentContext(),
173 DynPropGetterAdapter_MethodCallback, hCallBackInfo,
174 0, v8::ConstructorBehavior::kThrow)
175 .ToLocalChecked());
176 }
177 }
178}
179
180void DynPropSetterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
181 CFXJSE_Value* pObject,
Ryan Harrison275e2602017-09-18 14:23:18 -0400182 const ByteStringView& szPropName,
dsinclair08fea802016-07-12 10:37:52 -0700183 CFXJSE_Value* pValue) {
184 ASSERT(lpClass);
185 int32_t nPropType =
186 lpClass->dynPropTypeGetter == nullptr
187 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700188 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700189 if (nPropType != FXJSE_ClassPropType_Method) {
190 if (lpClass->dynPropSetter)
191 lpClass->dynPropSetter(pObject, szPropName, pValue);
192 }
193}
194
tsepez304bb912016-11-03 06:10:26 -0700195bool DynPropQueryAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
196 CFXJSE_Value* pObject,
Ryan Harrison275e2602017-09-18 14:23:18 -0400197 const ByteStringView& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700198 ASSERT(lpClass);
199 int32_t nPropType =
200 lpClass->dynPropTypeGetter == nullptr
201 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700202 : lpClass->dynPropTypeGetter(pObject, szPropName, true);
dsinclair08fea802016-07-12 10:37:52 -0700203 return nPropType != FXJSE_ClassPropType_None;
204}
205
tsepez304bb912016-11-03 06:10:26 -0700206bool DynPropDeleterAdapter(const FXJSE_CLASS_DESCRIPTOR* lpClass,
207 CFXJSE_Value* pObject,
Ryan Harrison275e2602017-09-18 14:23:18 -0400208 const ByteStringView& szPropName) {
dsinclair08fea802016-07-12 10:37:52 -0700209 ASSERT(lpClass);
210 int32_t nPropType =
211 lpClass->dynPropTypeGetter == nullptr
212 ? FXJSE_ClassPropType_Property
tsepez304bb912016-11-03 06:10:26 -0700213 : lpClass->dynPropTypeGetter(pObject, szPropName, false);
dsinclair08fea802016-07-12 10:37:52 -0700214 if (nPropType != FXJSE_ClassPropType_Method) {
215 if (lpClass->dynPropDeleter)
216 return lpClass->dynPropDeleter(pObject, szPropName);
tsepez304bb912016-11-03 06:10:26 -0700217 return nPropType != FXJSE_ClassPropType_Property;
dsinclair08fea802016-07-12 10:37:52 -0700218 }
tsepez304bb912016-11-03 06:10:26 -0700219 return false;
dsinclair08fea802016-07-12 10:37:52 -0700220}
221
222void NamedPropertyQueryCallback(
223 v8::Local<v8::Name> property,
224 const v8::PropertyCallbackInfo<v8::Integer>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400225 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700226 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
227 info.Data().As<v8::External>()->Value());
228 v8::Isolate* pIsolate = info.GetIsolate();
229 v8::HandleScope scope(pIsolate);
230 v8::String::Utf8Value szPropName(property);
Ryan Harrison275e2602017-09-18 14:23:18 -0400231 ByteStringView szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400232 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700233 lpThisValue->ForceSetValue(thisObject);
234 if (DynPropQueryAdapter(lpClass, lpThisValue.get(), szFxPropName)) {
235 info.GetReturnValue().Set(v8::DontDelete);
236 return;
237 }
238 const int32_t iV8Absent = 64;
239 info.GetReturnValue().Set(iV8Absent);
240}
241
242void NamedPropertyDeleterCallback(
243 v8::Local<v8::Name> property,
244 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400245 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700246 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
247 info.Data().As<v8::External>()->Value());
248 v8::Isolate* pIsolate = info.GetIsolate();
249 v8::HandleScope scope(pIsolate);
250 v8::String::Utf8Value szPropName(property);
Ryan Harrison275e2602017-09-18 14:23:18 -0400251 ByteStringView szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400252 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700253 lpThisValue->ForceSetValue(thisObject);
254 info.GetReturnValue().Set(
255 !!DynPropDeleterAdapter(lpClass, lpThisValue.get(), szFxPropName));
256}
257
258void NamedPropertyGetterCallback(
259 v8::Local<v8::Name> property,
260 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400261 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700262 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
263 info.Data().As<v8::External>()->Value());
264 v8::String::Utf8Value szPropName(property);
Ryan Harrison275e2602017-09-18 14:23:18 -0400265 ByteStringView szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400266 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700267 lpThisValue->ForceSetValue(thisObject);
Dan Sinclair0bb13332017-03-30 16:12:02 -0400268 auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700269 DynPropGetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
270 lpNewValue.get());
271 info.GetReturnValue().Set(lpNewValue->DirectGetValue());
272}
273
274void NamedPropertySetterCallback(
275 v8::Local<v8::Name> property,
276 v8::Local<v8::Value> value,
277 const v8::PropertyCallbackInfo<v8::Value>& info) {
Dan Sinclair2fbfb842017-03-22 13:58:45 -0400278 v8::Local<v8::Object> thisObject = info.Holder();
dsinclair08fea802016-07-12 10:37:52 -0700279 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
280 info.Data().As<v8::External>()->Value());
281 v8::String::Utf8Value szPropName(property);
Ryan Harrison275e2602017-09-18 14:23:18 -0400282 ByteStringView szFxPropName(*szPropName, szPropName.length());
Dan Sinclair0bb13332017-03-30 16:12:02 -0400283 auto lpThisValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700284 lpThisValue->ForceSetValue(thisObject);
285
Dan Sinclair0bb13332017-03-30 16:12:02 -0400286 auto lpNewValue = pdfium::MakeUnique<CFXJSE_Value>(info.GetIsolate());
dsinclair08fea802016-07-12 10:37:52 -0700287 lpNewValue->ForceSetValue(value);
weili1a241992016-09-12 15:10:40 -0700288 DynPropSetterAdapter(lpClass, lpThisValue.get(), szFxPropName,
289 lpNewValue.get());
dsinclair08fea802016-07-12 10:37:52 -0700290 info.GetReturnValue().Set(value);
291}
292
293void NamedPropertyEnumeratorCallback(
294 const v8::PropertyCallbackInfo<v8::Array>& info) {
295 const FXJSE_CLASS_DESCRIPTOR* lpClass = static_cast<FXJSE_CLASS_DESCRIPTOR*>(
296 info.Data().As<v8::External>()->Value());
297 v8::Isolate* pIsolate = info.GetIsolate();
298 v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum);
299 for (int i = 0; i < lpClass->propNum; i++) {
300 newArray->Set(
301 i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name));
302 }
303 info.GetReturnValue().Set(newArray);
304}
305
306} // namespace
307
308// static
309CFXJSE_Class* CFXJSE_Class::Create(
310 CFXJSE_Context* lpContext,
311 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition,
tsepez304bb912016-11-03 06:10:26 -0700312 bool bIsJSGlobal) {
dsinclair08fea802016-07-12 10:37:52 -0700313 if (!lpContext || !lpClassDefinition)
314 return nullptr;
315
Tom Sepez80547a12017-04-25 12:43:13 -0700316 CFXJSE_Class* pExistingClass =
317 lpContext->GetClassByName(lpClassDefinition->name);
318 if (pExistingClass)
319 return pExistingClass;
dsinclair08fea802016-07-12 10:37:52 -0700320
Tom Sepez80547a12017-04-25 12:43:13 -0700321 v8::Isolate* pIsolate = lpContext->GetIsolate();
322 auto pClass = pdfium::MakeUnique<CFXJSE_Class>(lpContext);
dsinclair08fea802016-07-12 10:37:52 -0700323 pClass->m_szClassName = lpClassDefinition->name;
324 pClass->m_lpClassDefinition = lpClassDefinition;
325 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
326 v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New(
327 pIsolate, bIsJSGlobal ? 0 : V8ConstructorCallback_Wrapper,
328 v8::External::New(
329 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
330 hFunctionTemplate->SetClassName(
331 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name));
Tom Sepez336544a2017-04-24 16:38:51 -0700332 hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(2);
dsinclair08fea802016-07-12 10:37:52 -0700333 v8::Local<v8::ObjectTemplate> hObjectTemplate =
334 hFunctionTemplate->InstanceTemplate();
335 SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition);
336
337 if (lpClassDefinition->propNum) {
338 for (int32_t i = 0; i < lpClassDefinition->propNum; i++) {
339 hObjectTemplate->SetNativeDataProperty(
340 v8::String::NewFromUtf8(pIsolate,
341 lpClassDefinition->properties[i].name),
342 lpClassDefinition->properties[i].getProc ? V8GetterCallback_Wrapper
343 : nullptr,
344 lpClassDefinition->properties[i].setProc ? V8SetterCallback_Wrapper
345 : nullptr,
346 v8::External::New(pIsolate, const_cast<FXJSE_PROPERTY_DESCRIPTOR*>(
347 lpClassDefinition->properties + i)),
348 static_cast<v8::PropertyAttribute>(v8::DontDelete));
349 }
350 }
351 if (lpClassDefinition->methNum) {
352 for (int32_t i = 0; i < lpClassDefinition->methNum; i++) {
353 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
354 pIsolate, V8FunctionCallback_Wrapper,
355 v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
356 lpClassDefinition->methods + i)));
357 fun->RemovePrototype();
358 hObjectTemplate->Set(
359 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name),
360 fun,
361 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
362 }
363 }
364 if (lpClassDefinition->constructor) {
365 if (bIsJSGlobal) {
366 hObjectTemplate->Set(
367 v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
368 v8::FunctionTemplate::New(
369 pIsolate, V8ClassGlobalConstructorCallback_Wrapper,
370 v8::External::New(pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(
371 lpClassDefinition))),
372 static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
373 } else {
Tom Sepez80547a12017-04-25 12:43:13 -0700374 v8::Local<v8::Context> hLocalContext = lpContext->GetContext();
dsinclair08fea802016-07-12 10:37:52 -0700375 FXJSE_GetGlobalObjectFromContext(hLocalContext)
376 ->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name),
377 v8::Function::New(
378 pIsolate, V8ClassGlobalConstructorCallback_Wrapper,
379 v8::External::New(pIsolate,
380 const_cast<FXJSE_CLASS_DESCRIPTOR*>(
381 lpClassDefinition))));
382 }
383 }
384 if (bIsJSGlobal) {
385 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
386 pIsolate, Context_GlobalObjToString,
387 v8::External::New(
388 pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)));
389 fun->RemovePrototype();
390 hObjectTemplate->Set(v8::String::NewFromUtf8(pIsolate, "toString"), fun);
391 }
Tom Sepez80547a12017-04-25 12:43:13 -0700392 pClass->m_hTemplate.Reset(lpContext->GetIsolate(), hFunctionTemplate);
393 CFXJSE_Class* pResult = pClass.get();
394 lpContext->AddClass(std::move(pClass));
395 return pResult;
dsinclair08fea802016-07-12 10:37:52 -0700396}
397
398// static
399void CFXJSE_Class::SetUpNamedPropHandler(
400 v8::Isolate* pIsolate,
401 v8::Local<v8::ObjectTemplate>& hObjectTemplate,
402 const FXJSE_CLASS_DESCRIPTOR* lpClassDefinition) {
403 v8::NamedPropertyHandlerConfiguration configuration(
404 lpClassDefinition->dynPropGetter ? NamedPropertyGetterCallback : 0,
405 lpClassDefinition->dynPropSetter ? NamedPropertySetterCallback : 0,
406 lpClassDefinition->dynPropTypeGetter ? NamedPropertyQueryCallback : 0,
407 lpClassDefinition->dynPropDeleter ? NamedPropertyDeleterCallback : 0,
408 NamedPropertyEnumeratorCallback,
409 v8::External::New(pIsolate,
410 const_cast<FXJSE_CLASS_DESCRIPTOR*>(lpClassDefinition)),
411 v8::PropertyHandlerFlags::kNonMasking);
412 hObjectTemplate->SetHandler(configuration);
413}
414
415CFXJSE_Class::CFXJSE_Class(CFXJSE_Context* lpContext)
416 : m_lpClassDefinition(nullptr), m_pContext(lpContext) {}
417
418CFXJSE_Class::~CFXJSE_Class() {}