1*3ac0a46fSAndroid Build Coastguard Worker // Copyright 2016 The PDFium Authors
2*3ac0a46fSAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*3ac0a46fSAndroid Build Coastguard Worker // found in the LICENSE file.
4*3ac0a46fSAndroid Build Coastguard Worker
5*3ac0a46fSAndroid Build Coastguard Worker // Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
6*3ac0a46fSAndroid Build Coastguard Worker
7*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_class.h"
8*3ac0a46fSAndroid Build Coastguard Worker
9*3ac0a46fSAndroid Build Coastguard Worker #include <memory>
10*3ac0a46fSAndroid Build Coastguard Worker #include <utility>
11*3ac0a46fSAndroid Build Coastguard Worker
12*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/cjs_result.h"
13*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/fxv8.h"
14*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/js_resources.h"
15*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_context.h"
16*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_isolatetracker.h"
17*3ac0a46fSAndroid Build Coastguard Worker #include "fxjs/xfa/cfxjse_value.h"
18*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check.h"
19*3ac0a46fSAndroid Build Coastguard Worker #include "third_party/base/check_op.h"
20*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-container.h"
21*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-external.h"
22*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-function-callback.h"
23*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-function.h"
24*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-isolate.h"
25*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-object.h"
26*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-primitive.h"
27*3ac0a46fSAndroid Build Coastguard Worker #include "v8/include/v8-template.h"
28*3ac0a46fSAndroid Build Coastguard Worker
29*3ac0a46fSAndroid Build Coastguard Worker using pdfium::fxjse::kClassTag;
30*3ac0a46fSAndroid Build Coastguard Worker using pdfium::fxjse::kFuncTag;
31*3ac0a46fSAndroid Build Coastguard Worker
32*3ac0a46fSAndroid Build Coastguard Worker namespace {
33*3ac0a46fSAndroid Build Coastguard Worker
AsFunctionDescriptor(void * ptr)34*3ac0a46fSAndroid Build Coastguard Worker FXJSE_FUNCTION_DESCRIPTOR* AsFunctionDescriptor(void* ptr) {
35*3ac0a46fSAndroid Build Coastguard Worker auto* result = static_cast<FXJSE_FUNCTION_DESCRIPTOR*>(ptr);
36*3ac0a46fSAndroid Build Coastguard Worker return result && result->tag == kFuncTag ? result : nullptr;
37*3ac0a46fSAndroid Build Coastguard Worker }
38*3ac0a46fSAndroid Build Coastguard Worker
AsClassDescriptor(void * ptr)39*3ac0a46fSAndroid Build Coastguard Worker FXJSE_CLASS_DESCRIPTOR* AsClassDescriptor(void* ptr) {
40*3ac0a46fSAndroid Build Coastguard Worker auto* result = static_cast<FXJSE_CLASS_DESCRIPTOR*>(ptr);
41*3ac0a46fSAndroid Build Coastguard Worker return result && result->tag == kClassTag ? result : nullptr;
42*3ac0a46fSAndroid Build Coastguard Worker }
43*3ac0a46fSAndroid Build Coastguard Worker
V8FunctionCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value> & info)44*3ac0a46fSAndroid Build Coastguard Worker void V8FunctionCallback_Wrapper(
45*3ac0a46fSAndroid Build Coastguard Worker const v8::FunctionCallbackInfo<v8::Value>& info) {
46*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_FUNCTION_DESCRIPTOR* pFunctionInfo =
47*3ac0a46fSAndroid Build Coastguard Worker AsFunctionDescriptor(info.Data().As<v8::External>()->Value());
48*3ac0a46fSAndroid Build Coastguard Worker if (!pFunctionInfo)
49*3ac0a46fSAndroid Build Coastguard Worker return;
50*3ac0a46fSAndroid Build Coastguard Worker
51*3ac0a46fSAndroid Build Coastguard Worker pFunctionInfo->callbackProc(CFXJSE_HostObject::FromV8(info.Holder()), info);
52*3ac0a46fSAndroid Build Coastguard Worker }
53*3ac0a46fSAndroid Build Coastguard Worker
V8ConstructorCallback_Wrapper(const v8::FunctionCallbackInfo<v8::Value> & info)54*3ac0a46fSAndroid Build Coastguard Worker void V8ConstructorCallback_Wrapper(
55*3ac0a46fSAndroid Build Coastguard Worker const v8::FunctionCallbackInfo<v8::Value>& info) {
56*3ac0a46fSAndroid Build Coastguard Worker if (!info.IsConstructCall())
57*3ac0a46fSAndroid Build Coastguard Worker return;
58*3ac0a46fSAndroid Build Coastguard Worker
59*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor =
60*3ac0a46fSAndroid Build Coastguard Worker AsClassDescriptor(info.Data().As<v8::External>()->Value());
61*3ac0a46fSAndroid Build Coastguard Worker if (!pClassDescriptor)
62*3ac0a46fSAndroid Build Coastguard Worker return;
63*3ac0a46fSAndroid Build Coastguard Worker
64*3ac0a46fSAndroid Build Coastguard Worker DCHECK_EQ(info.Holder()->InternalFieldCount(), 2);
65*3ac0a46fSAndroid Build Coastguard Worker info.Holder()->SetAlignedPointerInInternalField(0, nullptr);
66*3ac0a46fSAndroid Build Coastguard Worker info.Holder()->SetAlignedPointerInInternalField(1, nullptr);
67*3ac0a46fSAndroid Build Coastguard Worker }
68*3ac0a46fSAndroid Build Coastguard Worker
Context_GlobalObjToString(const v8::FunctionCallbackInfo<v8::Value> & info)69*3ac0a46fSAndroid Build Coastguard Worker void Context_GlobalObjToString(
70*3ac0a46fSAndroid Build Coastguard Worker const v8::FunctionCallbackInfo<v8::Value>& info) {
71*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor =
72*3ac0a46fSAndroid Build Coastguard Worker AsClassDescriptor(info.Data().As<v8::External>()->Value());
73*3ac0a46fSAndroid Build Coastguard Worker if (!pClassDescriptor)
74*3ac0a46fSAndroid Build Coastguard Worker return;
75*3ac0a46fSAndroid Build Coastguard Worker
76*3ac0a46fSAndroid Build Coastguard Worker if (info.This() == info.Holder() && pClassDescriptor->name) {
77*3ac0a46fSAndroid Build Coastguard Worker ByteString szStringVal =
78*3ac0a46fSAndroid Build Coastguard Worker ByteString::Format("[object %s]", pClassDescriptor->name);
79*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(
80*3ac0a46fSAndroid Build Coastguard Worker fxv8::NewStringHelper(info.GetIsolate(), szStringVal.AsStringView()));
81*3ac0a46fSAndroid Build Coastguard Worker return;
82*3ac0a46fSAndroid Build Coastguard Worker }
83*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::String> local_str =
84*3ac0a46fSAndroid Build Coastguard Worker info.Holder()
85*3ac0a46fSAndroid Build Coastguard Worker ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext())
86*3ac0a46fSAndroid Build Coastguard Worker .FromMaybe(v8::Local<v8::String>());
87*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(local_str);
88*3ac0a46fSAndroid Build Coastguard Worker }
89*3ac0a46fSAndroid Build Coastguard Worker
DynPropGetterAdapter_MethodCallback(const v8::FunctionCallbackInfo<v8::Value> & info)90*3ac0a46fSAndroid Build Coastguard Worker void DynPropGetterAdapter_MethodCallback(
91*3ac0a46fSAndroid Build Coastguard Worker const v8::FunctionCallbackInfo<v8::Value>& info) {
92*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
93*3ac0a46fSAndroid Build Coastguard Worker if (hCallBackInfo->InternalFieldCount() != 2)
94*3ac0a46fSAndroid Build Coastguard Worker return;
95*3ac0a46fSAndroid Build Coastguard Worker
96*3ac0a46fSAndroid Build Coastguard Worker auto* pClassDescriptor = static_cast<const FXJSE_CLASS_DESCRIPTOR*>(
97*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfo->GetAlignedPointerFromInternalField(0));
98*3ac0a46fSAndroid Build Coastguard Worker if (pClassDescriptor != &kGlobalClassDescriptor &&
99*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor != &kNormalClassDescriptor &&
100*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor != &kVariablesClassDescriptor &&
101*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor != &kFormCalcDescriptor) {
102*3ac0a46fSAndroid Build Coastguard Worker return;
103*3ac0a46fSAndroid Build Coastguard Worker }
104*3ac0a46fSAndroid Build Coastguard Worker
105*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::String> hPropName =
106*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfo->GetInternalField(1).As<v8::Value>().As<v8::String>();
107*3ac0a46fSAndroid Build Coastguard Worker if (hPropName.IsEmpty())
108*3ac0a46fSAndroid Build Coastguard Worker return;
109*3ac0a46fSAndroid Build Coastguard Worker
110*3ac0a46fSAndroid Build Coastguard Worker v8::String::Utf8Value szPropName(info.GetIsolate(), hPropName);
111*3ac0a46fSAndroid Build Coastguard Worker CJS_Result result =
112*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynMethodCall(info, WideString::FromUTF8(*szPropName));
113*3ac0a46fSAndroid Build Coastguard Worker
114*3ac0a46fSAndroid Build Coastguard Worker if (result.HasError()) {
115*3ac0a46fSAndroid Build Coastguard Worker WideString err = JSFormatErrorString(pClassDescriptor->name, *szPropName,
116*3ac0a46fSAndroid Build Coastguard Worker result.Error());
117*3ac0a46fSAndroid Build Coastguard Worker fxv8::ThrowExceptionHelper(info.GetIsolate(), err.AsStringView());
118*3ac0a46fSAndroid Build Coastguard Worker return;
119*3ac0a46fSAndroid Build Coastguard Worker }
120*3ac0a46fSAndroid Build Coastguard Worker
121*3ac0a46fSAndroid Build Coastguard Worker if (result.HasReturn())
122*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(result.Return());
123*3ac0a46fSAndroid Build Coastguard Worker }
124*3ac0a46fSAndroid Build Coastguard Worker
DynPropGetterAdapter(v8::Isolate * pIsolate,const FXJSE_CLASS_DESCRIPTOR * pClassDescriptor,v8::Local<v8::Object> pObject,ByteStringView szPropName,CFXJSE_Value * pValue)125*3ac0a46fSAndroid Build Coastguard Worker void DynPropGetterAdapter(v8::Isolate* pIsolate,
126*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
127*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject,
128*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName,
129*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Value* pValue) {
130*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pClassDescriptor);
131*3ac0a46fSAndroid Build Coastguard Worker
132*3ac0a46fSAndroid Build Coastguard Worker FXJSE_ClassPropType nPropType =
133*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropTypeGetter
134*3ac0a46fSAndroid Build Coastguard Worker ? pClassDescriptor->dynPropTypeGetter(pIsolate, pObject, szPropName,
135*3ac0a46fSAndroid Build Coastguard Worker false)
136*3ac0a46fSAndroid Build Coastguard Worker : FXJSE_ClassPropType::kProperty;
137*3ac0a46fSAndroid Build Coastguard Worker if (nPropType == FXJSE_ClassPropType::kProperty) {
138*3ac0a46fSAndroid Build Coastguard Worker if (pClassDescriptor->dynPropGetter) {
139*3ac0a46fSAndroid Build Coastguard Worker pValue->ForceSetValue(pIsolate, pClassDescriptor->dynPropGetter(
140*3ac0a46fSAndroid Build Coastguard Worker pIsolate, pObject, szPropName));
141*3ac0a46fSAndroid Build Coastguard Worker }
142*3ac0a46fSAndroid Build Coastguard Worker } else if (nPropType == FXJSE_ClassPropType::kMethod) {
143*3ac0a46fSAndroid Build Coastguard Worker if (pClassDescriptor->dynMethodCall && pValue) {
144*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope hscope(pIsolate);
145*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
146*3ac0a46fSAndroid Build Coastguard Worker v8::ObjectTemplate::New(pIsolate);
147*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfoTemplate->SetInternalFieldCount(2);
148*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> hCallBackInfo =
149*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfoTemplate->NewInstance(pIsolate->GetCurrentContext())
150*3ac0a46fSAndroid Build Coastguard Worker .ToLocalChecked();
151*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfo->SetAlignedPointerInInternalField(
152*3ac0a46fSAndroid Build Coastguard Worker 0, const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor));
153*3ac0a46fSAndroid Build Coastguard Worker hCallBackInfo->SetInternalField(
154*3ac0a46fSAndroid Build Coastguard Worker 1, fxv8::NewStringHelper(pIsolate, szPropName));
155*3ac0a46fSAndroid Build Coastguard Worker pValue->ForceSetValue(
156*3ac0a46fSAndroid Build Coastguard Worker pIsolate,
157*3ac0a46fSAndroid Build Coastguard Worker v8::Function::New(pIsolate->GetCurrentContext(),
158*3ac0a46fSAndroid Build Coastguard Worker DynPropGetterAdapter_MethodCallback, hCallBackInfo,
159*3ac0a46fSAndroid Build Coastguard Worker 0, v8::ConstructorBehavior::kThrow)
160*3ac0a46fSAndroid Build Coastguard Worker .ToLocalChecked());
161*3ac0a46fSAndroid Build Coastguard Worker }
162*3ac0a46fSAndroid Build Coastguard Worker }
163*3ac0a46fSAndroid Build Coastguard Worker }
164*3ac0a46fSAndroid Build Coastguard Worker
DynPropSetterAdapter(v8::Isolate * pIsolate,const FXJSE_CLASS_DESCRIPTOR * pClassDescriptor,v8::Local<v8::Object> pObject,ByteStringView szPropName,CFXJSE_Value * pValue)165*3ac0a46fSAndroid Build Coastguard Worker void DynPropSetterAdapter(v8::Isolate* pIsolate,
166*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
167*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject,
168*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName,
169*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Value* pValue) {
170*3ac0a46fSAndroid Build Coastguard Worker DCHECK(pClassDescriptor);
171*3ac0a46fSAndroid Build Coastguard Worker FXJSE_ClassPropType nPropType =
172*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropTypeGetter
173*3ac0a46fSAndroid Build Coastguard Worker ? pClassDescriptor->dynPropTypeGetter(pIsolate, pObject, szPropName,
174*3ac0a46fSAndroid Build Coastguard Worker false)
175*3ac0a46fSAndroid Build Coastguard Worker : FXJSE_ClassPropType::kProperty;
176*3ac0a46fSAndroid Build Coastguard Worker if (nPropType != FXJSE_ClassPropType::kMethod) {
177*3ac0a46fSAndroid Build Coastguard Worker if (pClassDescriptor->dynPropSetter) {
178*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropSetter(pIsolate, pObject, szPropName,
179*3ac0a46fSAndroid Build Coastguard Worker pValue->GetValue(pIsolate));
180*3ac0a46fSAndroid Build Coastguard Worker }
181*3ac0a46fSAndroid Build Coastguard Worker }
182*3ac0a46fSAndroid Build Coastguard Worker }
183*3ac0a46fSAndroid Build Coastguard Worker
DynPropQueryAdapter(v8::Isolate * pIsolate,const FXJSE_CLASS_DESCRIPTOR * pClassDescriptor,v8::Local<v8::Object> pObject,ByteStringView szPropName)184*3ac0a46fSAndroid Build Coastguard Worker bool DynPropQueryAdapter(v8::Isolate* pIsolate,
185*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
186*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Object> pObject,
187*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szPropName) {
188*3ac0a46fSAndroid Build Coastguard Worker FXJSE_ClassPropType nPropType = pClassDescriptor->dynPropTypeGetter
189*3ac0a46fSAndroid Build Coastguard Worker ? pClassDescriptor->dynPropTypeGetter(
190*3ac0a46fSAndroid Build Coastguard Worker pIsolate, pObject, szPropName, true)
191*3ac0a46fSAndroid Build Coastguard Worker : FXJSE_ClassPropType::kProperty;
192*3ac0a46fSAndroid Build Coastguard Worker return nPropType != FXJSE_ClassPropType::kNone;
193*3ac0a46fSAndroid Build Coastguard Worker }
194*3ac0a46fSAndroid Build Coastguard Worker
NamedPropertyQueryCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Integer> & info)195*3ac0a46fSAndroid Build Coastguard Worker void NamedPropertyQueryCallback(
196*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Name> property,
197*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<v8::Integer>& info) {
198*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClass =
199*3ac0a46fSAndroid Build Coastguard Worker AsClassDescriptor(info.Data().As<v8::External>()->Value());
200*3ac0a46fSAndroid Build Coastguard Worker if (!pClass)
201*3ac0a46fSAndroid Build Coastguard Worker return;
202*3ac0a46fSAndroid Build Coastguard Worker
203*3ac0a46fSAndroid Build Coastguard Worker v8::HandleScope scope(info.GetIsolate());
204*3ac0a46fSAndroid Build Coastguard Worker v8::String::Utf8Value szPropName(info.GetIsolate(), property);
205*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szFxPropName(*szPropName, szPropName.length());
206*3ac0a46fSAndroid Build Coastguard Worker if (DynPropQueryAdapter(info.GetIsolate(), pClass, info.Holder(),
207*3ac0a46fSAndroid Build Coastguard Worker szFxPropName)) {
208*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(v8::DontDelete);
209*3ac0a46fSAndroid Build Coastguard Worker return;
210*3ac0a46fSAndroid Build Coastguard Worker }
211*3ac0a46fSAndroid Build Coastguard Worker const int32_t iV8Absent = 64;
212*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(iV8Absent);
213*3ac0a46fSAndroid Build Coastguard Worker }
214*3ac0a46fSAndroid Build Coastguard Worker
NamedPropertyGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info)215*3ac0a46fSAndroid Build Coastguard Worker void NamedPropertyGetterCallback(
216*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Name> property,
217*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<v8::Value>& info) {
218*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClass =
219*3ac0a46fSAndroid Build Coastguard Worker AsClassDescriptor(info.Data().As<v8::External>()->Value());
220*3ac0a46fSAndroid Build Coastguard Worker if (!pClass)
221*3ac0a46fSAndroid Build Coastguard Worker return;
222*3ac0a46fSAndroid Build Coastguard Worker
223*3ac0a46fSAndroid Build Coastguard Worker v8::String::Utf8Value szPropName(info.GetIsolate(), property);
224*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szFxPropName(*szPropName, szPropName.length());
225*3ac0a46fSAndroid Build Coastguard Worker auto pNewValue = std::make_unique<CFXJSE_Value>();
226*3ac0a46fSAndroid Build Coastguard Worker DynPropGetterAdapter(info.GetIsolate(), pClass, info.Holder(), szFxPropName,
227*3ac0a46fSAndroid Build Coastguard Worker pNewValue.get());
228*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(pNewValue->DirectGetValue());
229*3ac0a46fSAndroid Build Coastguard Worker }
230*3ac0a46fSAndroid Build Coastguard Worker
NamedPropertySetterCallback(v8::Local<v8::Name> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<v8::Value> & info)231*3ac0a46fSAndroid Build Coastguard Worker void NamedPropertySetterCallback(
232*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Name> property,
233*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::Value> value,
234*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<v8::Value>& info) {
235*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClass =
236*3ac0a46fSAndroid Build Coastguard Worker AsClassDescriptor(info.Data().As<v8::External>()->Value());
237*3ac0a46fSAndroid Build Coastguard Worker if (!pClass)
238*3ac0a46fSAndroid Build Coastguard Worker return;
239*3ac0a46fSAndroid Build Coastguard Worker
240*3ac0a46fSAndroid Build Coastguard Worker v8::String::Utf8Value szPropName(info.GetIsolate(), property);
241*3ac0a46fSAndroid Build Coastguard Worker ByteStringView szFxPropName(*szPropName, szPropName.length());
242*3ac0a46fSAndroid Build Coastguard Worker auto pNewValue = std::make_unique<CFXJSE_Value>(info.GetIsolate(), value);
243*3ac0a46fSAndroid Build Coastguard Worker DynPropSetterAdapter(info.GetIsolate(), pClass, info.Holder(), szFxPropName,
244*3ac0a46fSAndroid Build Coastguard Worker pNewValue.get());
245*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(value);
246*3ac0a46fSAndroid Build Coastguard Worker }
247*3ac0a46fSAndroid Build Coastguard Worker
NamedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array> & info)248*3ac0a46fSAndroid Build Coastguard Worker void NamedPropertyEnumeratorCallback(
249*3ac0a46fSAndroid Build Coastguard Worker const v8::PropertyCallbackInfo<v8::Array>& info) {
250*3ac0a46fSAndroid Build Coastguard Worker info.GetReturnValue().Set(v8::Array::New(info.GetIsolate()));
251*3ac0a46fSAndroid Build Coastguard Worker }
252*3ac0a46fSAndroid Build Coastguard Worker
SetUpNamedPropHandler(v8::Isolate * pIsolate,v8::Local<v8::ObjectTemplate> pObjectTemplate,const FXJSE_CLASS_DESCRIPTOR * pClassDescriptor)253*3ac0a46fSAndroid Build Coastguard Worker void SetUpNamedPropHandler(v8::Isolate* pIsolate,
254*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::ObjectTemplate> pObjectTemplate,
255*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor) {
256*3ac0a46fSAndroid Build Coastguard Worker v8::NamedPropertyHandlerConfiguration configuration(
257*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropGetter ? NamedPropertyGetterCallback : nullptr,
258*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropSetter ? NamedPropertySetterCallback : nullptr,
259*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->dynPropTypeGetter ? NamedPropertyQueryCallback
260*3ac0a46fSAndroid Build Coastguard Worker : nullptr,
261*3ac0a46fSAndroid Build Coastguard Worker nullptr, NamedPropertyEnumeratorCallback,
262*3ac0a46fSAndroid Build Coastguard Worker v8::External::New(pIsolate,
263*3ac0a46fSAndroid Build Coastguard Worker const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)),
264*3ac0a46fSAndroid Build Coastguard Worker v8::PropertyHandlerFlags::kNonMasking);
265*3ac0a46fSAndroid Build Coastguard Worker pObjectTemplate->SetHandler(configuration);
266*3ac0a46fSAndroid Build Coastguard Worker }
267*3ac0a46fSAndroid Build Coastguard Worker
268*3ac0a46fSAndroid Build Coastguard Worker } // namespace
269*3ac0a46fSAndroid Build Coastguard Worker
270*3ac0a46fSAndroid Build Coastguard Worker // static
Create(CFXJSE_Context * pContext,const FXJSE_CLASS_DESCRIPTOR * pClassDescriptor,bool bIsJSGlobal)271*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class* CFXJSE_Class::Create(
272*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Context* pContext,
273*3ac0a46fSAndroid Build Coastguard Worker const FXJSE_CLASS_DESCRIPTOR* pClassDescriptor,
274*3ac0a46fSAndroid Build Coastguard Worker bool bIsJSGlobal) {
275*3ac0a46fSAndroid Build Coastguard Worker if (!pContext || !pClassDescriptor)
276*3ac0a46fSAndroid Build Coastguard Worker return nullptr;
277*3ac0a46fSAndroid Build Coastguard Worker
278*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class* pExistingClass =
279*3ac0a46fSAndroid Build Coastguard Worker pContext->GetClassByName(pClassDescriptor->name);
280*3ac0a46fSAndroid Build Coastguard Worker if (pExistingClass)
281*3ac0a46fSAndroid Build Coastguard Worker return pExistingClass;
282*3ac0a46fSAndroid Build Coastguard Worker
283*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate* pIsolate = pContext->GetIsolate();
284*3ac0a46fSAndroid Build Coastguard Worker auto pClass = std::make_unique<CFXJSE_Class>(pContext);
285*3ac0a46fSAndroid Build Coastguard Worker pClass->m_szClassName = pClassDescriptor->name;
286*3ac0a46fSAndroid Build Coastguard Worker pClass->m_pClassDescriptor = pClassDescriptor;
287*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
288*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::FunctionTemplate> hFunctionTemplate = v8::FunctionTemplate::New(
289*3ac0a46fSAndroid Build Coastguard Worker pIsolate, bIsJSGlobal ? 0 : V8ConstructorCallback_Wrapper,
290*3ac0a46fSAndroid Build Coastguard Worker v8::External::New(pIsolate,
291*3ac0a46fSAndroid Build Coastguard Worker const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)));
292*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::String> classname =
293*3ac0a46fSAndroid Build Coastguard Worker fxv8::NewStringHelper(pIsolate, pClassDescriptor->name);
294*3ac0a46fSAndroid Build Coastguard Worker hFunctionTemplate->SetClassName(classname);
295*3ac0a46fSAndroid Build Coastguard Worker hFunctionTemplate->PrototypeTemplate()->Set(
296*3ac0a46fSAndroid Build Coastguard Worker v8::Symbol::GetToStringTag(pIsolate), classname,
297*3ac0a46fSAndroid Build Coastguard Worker static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontEnum));
298*3ac0a46fSAndroid Build Coastguard Worker hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(2);
299*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::ObjectTemplate> hObjectTemplate =
300*3ac0a46fSAndroid Build Coastguard Worker hFunctionTemplate->InstanceTemplate();
301*3ac0a46fSAndroid Build Coastguard Worker SetUpNamedPropHandler(pIsolate, hObjectTemplate, pClassDescriptor);
302*3ac0a46fSAndroid Build Coastguard Worker
303*3ac0a46fSAndroid Build Coastguard Worker if (pClassDescriptor->methNum) {
304*3ac0a46fSAndroid Build Coastguard Worker for (int32_t i = 0; i < pClassDescriptor->methNum; i++) {
305*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(
306*3ac0a46fSAndroid Build Coastguard Worker pIsolate, V8FunctionCallback_Wrapper,
307*3ac0a46fSAndroid Build Coastguard Worker v8::External::New(pIsolate, const_cast<FXJSE_FUNCTION_DESCRIPTOR*>(
308*3ac0a46fSAndroid Build Coastguard Worker pClassDescriptor->methods + i)));
309*3ac0a46fSAndroid Build Coastguard Worker fun->RemovePrototype();
310*3ac0a46fSAndroid Build Coastguard Worker hObjectTemplate->Set(
311*3ac0a46fSAndroid Build Coastguard Worker fxv8::NewStringHelper(pIsolate, pClassDescriptor->methods[i].name),
312*3ac0a46fSAndroid Build Coastguard Worker fun,
313*3ac0a46fSAndroid Build Coastguard Worker static_cast<v8::PropertyAttribute>(v8::ReadOnly | v8::DontDelete));
314*3ac0a46fSAndroid Build Coastguard Worker }
315*3ac0a46fSAndroid Build Coastguard Worker }
316*3ac0a46fSAndroid Build Coastguard Worker
317*3ac0a46fSAndroid Build Coastguard Worker if (bIsJSGlobal) {
318*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::FunctionTemplate> fn = v8::FunctionTemplate::New(
319*3ac0a46fSAndroid Build Coastguard Worker pIsolate, Context_GlobalObjToString,
320*3ac0a46fSAndroid Build Coastguard Worker v8::External::New(
321*3ac0a46fSAndroid Build Coastguard Worker pIsolate, const_cast<FXJSE_CLASS_DESCRIPTOR*>(pClassDescriptor)));
322*3ac0a46fSAndroid Build Coastguard Worker fn->RemovePrototype();
323*3ac0a46fSAndroid Build Coastguard Worker hObjectTemplate->Set(fxv8::NewStringHelper(pIsolate, "toString"), fn);
324*3ac0a46fSAndroid Build Coastguard Worker }
325*3ac0a46fSAndroid Build Coastguard Worker pClass->m_hTemplate.Reset(pContext->GetIsolate(), hFunctionTemplate);
326*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class* pResult = pClass.get();
327*3ac0a46fSAndroid Build Coastguard Worker pContext->AddClass(std::move(pClass));
328*3ac0a46fSAndroid Build Coastguard Worker return pResult;
329*3ac0a46fSAndroid Build Coastguard Worker }
330*3ac0a46fSAndroid Build Coastguard Worker
CFXJSE_Class(const CFXJSE_Context * pContext)331*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class::CFXJSE_Class(const CFXJSE_Context* pContext)
332*3ac0a46fSAndroid Build Coastguard Worker : m_pContext(pContext) {}
333*3ac0a46fSAndroid Build Coastguard Worker
334*3ac0a46fSAndroid Build Coastguard Worker CFXJSE_Class::~CFXJSE_Class() = default;
335*3ac0a46fSAndroid Build Coastguard Worker
GetTemplate(v8::Isolate * pIsolate)336*3ac0a46fSAndroid Build Coastguard Worker v8::Local<v8::FunctionTemplate> CFXJSE_Class::GetTemplate(
337*3ac0a46fSAndroid Build Coastguard Worker v8::Isolate* pIsolate) {
338*3ac0a46fSAndroid Build Coastguard Worker return v8::Local<v8::FunctionTemplate>::New(pIsolate, m_hTemplate);
339*3ac0a46fSAndroid Build Coastguard Worker }
340