1 // Copyright 2014 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 "xfa/src/foxitlib.h"
8 #include "fxv8.h"
9 #include "class.h"
10 #include "value.h"
FXJSE_DynPropGetterAdapter_MethodCallback(const v8::FunctionCallbackInfo<v8::Value> & info)11 static void FXJSE_DynPropGetterAdapter_MethodCallback(
12     const v8::FunctionCallbackInfo<v8::Value>& info) {
13   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
14   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
15       hCallBackInfo->GetAlignedPointerFromInternalField(0));
16   v8::Local<v8::String> hPropName =
17       hCallBackInfo->GetInternalField(1).As<v8::String>();
18   ASSERT(lpClass && !hPropName.IsEmpty());
19   v8::String::Utf8Value szPropName(hPropName);
20   CFX_ByteStringC szFxPropName = *szPropName;
21   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
22   lpThisValue->ForceSetValue(info.This());
23   CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate());
24   CFXJSE_ArgumentsImpl impl = {&info, lpRetValue};
25   lpClass->dynMethodCall(reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
26                          szFxPropName,
27                          reinterpret_cast<CFXJSE_Arguments&>(impl));
28   if (!lpRetValue->DirectGetValue().IsEmpty()) {
29     info.GetReturnValue().Set(lpRetValue->DirectGetValue());
30   }
31   delete lpRetValue;
32   lpRetValue = nullptr;
33   delete lpThisValue;
34   lpThisValue = nullptr;
35 }
FXJSE_DynPropGetterAdapter(const FXJSE_CLASS * lpClass,FXJSE_HOBJECT hObject,const CFX_ByteStringC & szPropName,FXJSE_HVALUE hValue)36 static void FXJSE_DynPropGetterAdapter(const FXJSE_CLASS* lpClass,
37                                        FXJSE_HOBJECT hObject,
38                                        const CFX_ByteStringC& szPropName,
39                                        FXJSE_HVALUE hValue) {
40   ASSERT(lpClass);
41   int32_t nPropType =
42       lpClass->dynPropTypeGetter == nullptr
43           ? FXJSE_ClassPropType_Property
44           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
45   if (nPropType == FXJSE_ClassPropType_Property) {
46     if (lpClass->dynPropGetter) {
47       lpClass->dynPropGetter(hObject, szPropName, hValue);
48     }
49   } else if (nPropType == FXJSE_ClassPropType_Method) {
50     if (lpClass->dynMethodCall && hValue) {
51       CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
52       v8::Isolate* pIsolate = lpValue->GetIsolate();
53       v8::HandleScope hscope(pIsolate);
54       v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
55           v8::ObjectTemplate::New();
56       hCallBackInfoTemplate->SetInternalFieldCount(2);
57       v8::Local<v8::Object> hCallBackInfo =
58           hCallBackInfoTemplate->NewInstance();
59       hCallBackInfo->SetAlignedPointerInInternalField(
60           0, const_cast<FXJSE_CLASS*>(lpClass));
61       hCallBackInfo->SetInternalField(
62           1, v8::String::NewFromUtf8(
63                  pIsolate, reinterpret_cast<const char*>(szPropName.GetPtr()),
64                  v8::String::kNormalString, szPropName.GetLength()));
65       lpValue->ForceSetValue(v8::Function::New(
66           lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback,
67           hCallBackInfo));
68     }
69   }
70 }
FXJSE_DynPropSetterAdapter(const FXJSE_CLASS * lpClass,FXJSE_HOBJECT hObject,const CFX_ByteStringC & szPropName,FXJSE_HVALUE hValue)71 static void FXJSE_DynPropSetterAdapter(const FXJSE_CLASS* lpClass,
72                                        FXJSE_HOBJECT hObject,
73                                        const CFX_ByteStringC& szPropName,
74                                        FXJSE_HVALUE hValue) {
75   ASSERT(lpClass);
76   int32_t nPropType =
77       lpClass->dynPropTypeGetter == nullptr
78           ? FXJSE_ClassPropType_Property
79           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
80   if (nPropType != FXJSE_ClassPropType_Method) {
81     if (lpClass->dynPropSetter) {
82       lpClass->dynPropSetter(hObject, szPropName, hValue);
83     }
84   }
85 }
FXJSE_DynPropQueryAdapter(const FXJSE_CLASS * lpClass,FXJSE_HOBJECT hObject,const CFX_ByteStringC & szPropName)86 static FX_BOOL FXJSE_DynPropQueryAdapter(const FXJSE_CLASS* lpClass,
87                                          FXJSE_HOBJECT hObject,
88                                          const CFX_ByteStringC& szPropName) {
89   ASSERT(lpClass);
90   int32_t nPropType =
91       lpClass->dynPropTypeGetter == nullptr
92           ? FXJSE_ClassPropType_Property
93           : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE);
94   return nPropType != FXJSE_ClassPropType_None;
95 }
FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS * lpClass,FXJSE_HOBJECT hObject,const CFX_ByteStringC & szPropName)96 static FX_BOOL FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS* lpClass,
97                                            FXJSE_HOBJECT hObject,
98                                            const CFX_ByteStringC& szPropName) {
99   ASSERT(lpClass);
100   int32_t nPropType =
101       lpClass->dynPropTypeGetter == nullptr
102           ? FXJSE_ClassPropType_Property
103           : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE);
104   if (nPropType != FXJSE_ClassPropType_Method) {
105     if (lpClass->dynPropDeleter) {
106       return lpClass->dynPropDeleter(hObject, szPropName);
107     } else {
108       return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE;
109     }
110   }
111   return FALSE;
112 }
FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter(const v8::FunctionCallbackInfo<v8::Value> & info)113 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter(
114     const v8::FunctionCallbackInfo<v8::Value>& info) {
115   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
116   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
117       hCallBackInfo->GetAlignedPointerFromInternalField(0));
118   v8::Local<v8::String> hPropName =
119       hCallBackInfo->GetInternalField(1).As<v8::String>();
120   ASSERT(lpClass && !hPropName.IsEmpty());
121   v8::String::Utf8Value szPropName(hPropName);
122   CFX_ByteStringC szFxPropName = *szPropName;
123   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
124   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
125   lpThisValue->ForceSetValue(info.This());
126   FXJSE_DynPropGetterAdapter(
127       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
128       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
129   info.GetReturnValue().Set(lpNewValue->DirectGetValue());
130   delete lpThisValue;
131   lpThisValue = nullptr;
132   delete lpNewValue;
133   lpNewValue = nullptr;
134 }
FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(const v8::FunctionCallbackInfo<v8::Value> & info)135 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(
136     const v8::FunctionCallbackInfo<v8::Value>& info) {
137   v8::Local<v8::Object> hCallBackInfo = info.Data().As<v8::Object>();
138   FXJSE_CLASS* lpClass = static_cast<FXJSE_CLASS*>(
139       hCallBackInfo->GetAlignedPointerFromInternalField(0));
140   v8::Local<v8::String> hPropName =
141       hCallBackInfo->GetInternalField(1).As<v8::String>();
142   ASSERT(lpClass && !hPropName.IsEmpty());
143   v8::String::Utf8Value szPropName(hPropName);
144   CFX_ByteStringC szFxPropName = *szPropName;
145   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
146   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
147   lpThisValue->ForceSetValue(info.This());
148   lpNewValue->ForceSetValue(info[0]);
149   FXJSE_DynPropSetterAdapter(
150       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
151       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
152   delete lpThisValue;
153   lpThisValue = nullptr;
154   delete lpNewValue;
155   lpNewValue = nullptr;
156 }
FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(const v8::FunctionCallbackInfo<v8::Value> & info)157 static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(
158     const v8::FunctionCallbackInfo<v8::Value>& info) {
159   const FXJSE_CLASS* lpClass =
160       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
161   if (!lpClass) {
162     return;
163   }
164   v8::Isolate* pIsolate = info.GetIsolate();
165   v8::HandleScope scope(pIsolate);
166   v8::Local<v8::String> hPropName = info[0]->ToString();
167   v8::String::Utf8Value szPropName(hPropName);
168   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
169   v8::Local<v8::ObjectTemplate> hCallBackInfoTemplate =
170       v8::ObjectTemplate::New();
171   hCallBackInfoTemplate->SetInternalFieldCount(2);
172   v8::Local<v8::Object> hCallBackInfo = hCallBackInfoTemplate->NewInstance();
173   hCallBackInfo->SetAlignedPointerInInternalField(
174       0, const_cast<FXJSE_CLASS*>(lpClass));
175   hCallBackInfo->SetInternalField(1, hPropName);
176   v8::Local<v8::Object> hPropDescriptor = v8::Object::New(pIsolate);
177   hPropDescriptor->ForceSet(
178       v8::String::NewFromUtf8(pIsolate, "get"),
179       v8::Function::New(pIsolate,
180                         FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter,
181                         hCallBackInfo));
182   hPropDescriptor->ForceSet(
183       v8::String::NewFromUtf8(pIsolate, "set"),
184       v8::Function::New(pIsolate,
185                         FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter,
186                         hCallBackInfo));
187   hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "enumerable"),
188                             v8::Boolean::New(pIsolate, false));
189   hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "configurable"),
190                             v8::Boolean::New(pIsolate, true));
191   info.GetReturnValue().Set(hPropDescriptor);
192 }
FXJSE_V8ProxyCallback_getPropertyDescriptor(const v8::FunctionCallbackInfo<v8::Value> & info)193 static void FXJSE_V8ProxyCallback_getPropertyDescriptor(
194     const v8::FunctionCallbackInfo<v8::Value>& info) {
195   v8::Isolate* pIsolate = info.GetIsolate();
196   v8::Local<v8::Object> hChainObj =
197       info.This()->GetPrototype().As<v8::Object>();
198   v8::Local<v8::Script> fnSource = v8::Script::Compile(v8::String::NewFromUtf8(
199       pIsolate,
200       "(function (o, name) { var fn, x, d; fn = "
201       "Object.getOwnPropertyDescriptor; x = o; while(x && !(d = fn(x, "
202       "name))){x = x.__proto__;} return d; })"));
203   v8::Local<v8::Function> fn = fnSource->Run().As<v8::Function>();
204   v8::Local<v8::Value> rgArgs[] = {hChainObj, info[0]};
205   v8::Local<v8::Value> hChainDescriptor = fn->Call(info.This(), 2, rgArgs);
206   if (!hChainDescriptor.IsEmpty() && hChainDescriptor->IsObject()) {
207     info.GetReturnValue().Set(hChainDescriptor);
208   } else {
209     FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(info);
210   }
211 }
FXJSE_V8ProxyCallback_getOwnPropertyNames(const v8::FunctionCallbackInfo<v8::Value> & info)212 static void FXJSE_V8ProxyCallback_getOwnPropertyNames(
213     const v8::FunctionCallbackInfo<v8::Value>& info) {
214   v8::Isolate* pIsolate = info.GetIsolate();
215   v8::HandleScope scope(pIsolate);
216   info.GetReturnValue().Set(v8::Array::New(pIsolate));
217 }
FXJSE_V8ProxyCallback_getPropertyNames(const v8::FunctionCallbackInfo<v8::Value> & info)218 static void FXJSE_V8ProxyCallback_getPropertyNames(
219     const v8::FunctionCallbackInfo<v8::Value>& info) {
220   v8::Local<v8::Object> hChainObj =
221       info.This()->GetPrototype().As<v8::Object>();
222   v8::Local<v8::Value> hChainPropertyNames = hChainObj->GetPropertyNames();
223   info.GetReturnValue().Set(hChainPropertyNames);
224 }
FXJSE_V8ProxyCallback_defineProperty(const v8::FunctionCallbackInfo<v8::Value> & info)225 static void FXJSE_V8ProxyCallback_defineProperty(
226     const v8::FunctionCallbackInfo<v8::Value>& info) {
227   const FXJSE_CLASS* lpClass =
228       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
229   if (!lpClass) {
230     return;
231   }
232   v8::Isolate* pIsolate = info.GetIsolate();
233   v8::HandleScope scope(pIsolate);
234   v8::Local<v8::String> hPropName = info[0]->ToString();
235   v8::Local<v8::Object> hPropDescriptor = info[1]->ToObject();
236   v8::String::Utf8Value szPropName(hPropName);
237   if (!hPropDescriptor->Has(v8::String::NewFromUtf8(pIsolate, "value"))) {
238     return;
239   }
240   v8::Local<v8::Value> hPropValue =
241       hPropDescriptor->Get(v8::String::NewFromUtf8(pIsolate, "value"));
242   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
243   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
244   CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate());
245   lpThisValue->ForceSetValue(info.This());
246   lpPropValue->ForceSetValue(hPropValue);
247   FXJSE_DynPropSetterAdapter(
248       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
249       reinterpret_cast<FXJSE_HVALUE>(lpPropValue));
250   delete lpThisValue;
251   lpThisValue = nullptr;
252   delete lpPropValue;
253   lpPropValue = nullptr;
254 }
FXJSE_V8ProxyCallback_delete(const v8::FunctionCallbackInfo<v8::Value> & info)255 static void FXJSE_V8ProxyCallback_delete(
256     const v8::FunctionCallbackInfo<v8::Value>& info) {
257   info.GetReturnValue().Set(true);
258   const FXJSE_CLASS* lpClass =
259       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
260   if (!lpClass) {
261     return;
262   }
263   v8::Isolate* pIsolate = info.GetIsolate();
264   v8::HandleScope scope(pIsolate);
265   v8::Local<v8::String> hPropName = info[0]->ToString();
266   v8::String::Utf8Value szPropName(hPropName);
267   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
268   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
269   lpThisValue->ForceSetValue(info.This());
270   info.GetReturnValue().Set(
271       FXJSE_DynPropDeleterAdapter(
272           lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
273           ? true
274           : false);
275   delete lpThisValue;
276   lpThisValue = nullptr;
277 }
FXJSE_V8ProxyCallback_fix(const v8::FunctionCallbackInfo<v8::Value> & info)278 static void FXJSE_V8ProxyCallback_fix(
279     const v8::FunctionCallbackInfo<v8::Value>& info) {
280   info.GetReturnValue().SetUndefined();
281 }
FXJSE_V8_GenericNamedPropertyQueryCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Integer> & info)282 static void FXJSE_V8_GenericNamedPropertyQueryCallback(
283     v8::Local<v8::Name> property,
284     const v8::PropertyCallbackInfo<v8::Integer>& info) {
285   v8::Local<v8::Object> thisObject = info.This();
286   const FXJSE_CLASS* lpClass =
287       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
288   v8::Isolate* pIsolate = info.GetIsolate();
289   v8::HandleScope scope(pIsolate);
290   v8::String::Utf8Value szPropName(property);
291   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
292   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
293   lpThisValue->ForceSetValue(thisObject);
294   if (FXJSE_DynPropQueryAdapter(lpClass,
295                                 reinterpret_cast<FXJSE_HOBJECT>(lpThisValue),
296                                 szFxPropName)) {
297     info.GetReturnValue().Set(v8::DontDelete);
298   } else {
299     const int32_t iV8Absent = 64;
300     info.GetReturnValue().Set(iV8Absent);
301   }
302   delete lpThisValue;
303   lpThisValue = nullptr;
304 }
FXJSE_V8_GenericNamedPropertyDeleterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Boolean> & info)305 static void FXJSE_V8_GenericNamedPropertyDeleterCallback(
306     v8::Local<v8::Name> property,
307     const v8::PropertyCallbackInfo<v8::Boolean>& info) {
308   v8::Local<v8::Object> thisObject = info.This();
309   const FXJSE_CLASS* lpClass =
310       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
311   v8::Isolate* pIsolate = info.GetIsolate();
312   v8::HandleScope scope(pIsolate);
313   v8::String::Utf8Value szPropName(property);
314   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
315   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
316   lpThisValue->ForceSetValue(thisObject);
317   info.GetReturnValue().Set(
318       FXJSE_DynPropDeleterAdapter(
319           lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName)
320           ? true
321           : false);
322   delete lpThisValue;
323   lpThisValue = nullptr;
324 }
FXJSE_V8_GenericNamedPropertyGetterCallback(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info)325 static void FXJSE_V8_GenericNamedPropertyGetterCallback(
326     v8::Local<v8::Name> property,
327     const v8::PropertyCallbackInfo<v8::Value>& info) {
328   v8::Local<v8::Object> thisObject = info.This();
329   const FXJSE_CLASS* lpClass =
330       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
331   v8::String::Utf8Value szPropName(property);
332   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
333   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
334   lpThisValue->ForceSetValue(thisObject);
335   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
336   FXJSE_DynPropGetterAdapter(
337       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
338       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
339   info.GetReturnValue().Set(lpNewValue->DirectGetValue());
340   delete lpThisValue;
341   lpThisValue = nullptr;
342 }
FXJSE_V8_GenericNamedPropertySetterCallback(v8::Local<v8::Name> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<v8::Value> & info)343 static void FXJSE_V8_GenericNamedPropertySetterCallback(
344     v8::Local<v8::Name> property,
345     v8::Local<v8::Value> value,
346     const v8::PropertyCallbackInfo<v8::Value>& info) {
347   v8::Local<v8::Object> thisObject = info.This();
348   const FXJSE_CLASS* lpClass =
349       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
350   v8::String::Utf8Value szPropName(property);
351   CFX_ByteStringC szFxPropName(*szPropName, szPropName.length());
352   CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate());
353   lpThisValue->ForceSetValue(thisObject);
354   CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate());
355   lpNewValue->ForceSetValue(value);
356   FXJSE_DynPropSetterAdapter(
357       lpClass, reinterpret_cast<FXJSE_HOBJECT>(lpThisValue), szFxPropName,
358       reinterpret_cast<FXJSE_HVALUE>(lpNewValue));
359   info.GetReturnValue().Set(value);
360   delete lpThisValue;
361   lpThisValue = nullptr;
362 }
FXJSE_V8_GenericNamedPropertyEnumeratorCallback(const v8::PropertyCallbackInfo<v8::Array> & info)363 static void FXJSE_V8_GenericNamedPropertyEnumeratorCallback(
364     const v8::PropertyCallbackInfo<v8::Array>& info) {
365   const FXJSE_CLASS* lpClass =
366       static_cast<FXJSE_CLASS*>(info.Data().As<v8::External>()->Value());
367   v8::Isolate* pIsolate = info.GetIsolate();
368   v8::Local<v8::Array> newArray = v8::Array::New(pIsolate, lpClass->propNum);
369   for (int i = 0; i < lpClass->propNum; i++) {
370     newArray->Set(
371         i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name));
372   }
373   info.GetReturnValue().Set(newArray);
374 }
375 
SetUpDynPropHandler(CFXJSE_Context * pContext,CFXJSE_Value * pValue,const FXJSE_CLASS * lpClassDefinition)376 void CFXJSE_Class::SetUpDynPropHandler(CFXJSE_Context* pContext,
377                                        CFXJSE_Value* pValue,
378                                        const FXJSE_CLASS* lpClassDefinition) {
379   v8::Isolate* pIsolate = pValue->GetIsolate();
380   CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext scope(pIsolate, pContext);
381   v8::Local<v8::Context> hContext = v8::Local<v8::Context>::New(
382       pIsolate, pContext ? pContext->m_hContext
383                          : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext);
384   v8::Local<v8::Object> hObject =
385       v8::Local<v8::Value>::New(pIsolate, pValue->m_hValue).As<v8::Object>();
386   v8::Local<v8::Object> hHarmonyProxyObj =
387       hContext->Global()
388           ->Get(v8::String::NewFromUtf8(pIsolate, "Proxy"))
389           .As<v8::Object>();
390   v8::Local<v8::Function> hHarmonyProxyCreateFn =
391       hHarmonyProxyObj->Get(v8::String::NewFromUtf8(pIsolate, "create"))
392           .As<v8::Function>();
393   v8::Local<v8::Value> hOldPrototype = hObject->GetPrototype();
394   v8::Local<v8::Object> hTrapper = v8::Object::New(pIsolate);
395   hTrapper->ForceSet(
396       v8::String::NewFromUtf8(pIsolate, "getOwnPropertyDescriptor"),
397       v8::Function::New(
398           pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor,
399           v8::External::New(pIsolate,
400                             const_cast<FXJSE_CLASS*>(lpClassDefinition))));
401   hTrapper->ForceSet(
402       v8::String::NewFromUtf8(pIsolate, "getPropertyDescriptor"),
403       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyDescriptor,
404                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
405                                                         lpClassDefinition))));
406   hTrapper->ForceSet(
407       v8::String::NewFromUtf8(pIsolate, "getOwnPropertyNames"),
408       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyNames,
409                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
410                                                         lpClassDefinition))));
411   hTrapper->ForceSet(
412       v8::String::NewFromUtf8(pIsolate, "getPropertyNames"),
413       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyNames,
414                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
415                                                         lpClassDefinition))));
416   hTrapper->ForceSet(
417       v8::String::NewFromUtf8(pIsolate, "delete"),
418       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_delete,
419                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
420                                                         lpClassDefinition))));
421   hTrapper->ForceSet(
422       v8::String::NewFromUtf8(pIsolate, "defineProperty"),
423       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_defineProperty,
424                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
425                                                         lpClassDefinition))));
426   hTrapper->ForceSet(
427       v8::String::NewFromUtf8(pIsolate, "fix"),
428       v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_fix,
429                         v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(
430                                                         lpClassDefinition))));
431   v8::Local<v8::Value> rgArgs[] = {hTrapper, hOldPrototype};
432   v8::Local<v8::Value> hNewPrototype =
433       hHarmonyProxyCreateFn->Call(hHarmonyProxyObj, 2, rgArgs);
434   hObject->SetPrototype(hNewPrototype);
435 }
SetUpNamedPropHandler(v8::Isolate * pIsolate,v8::Local<v8::ObjectTemplate> & hObjectTemplate,const FXJSE_CLASS * lpClassDefinition)436 void CFXJSE_Class::SetUpNamedPropHandler(
437     v8::Isolate* pIsolate,
438     v8::Local<v8::ObjectTemplate>& hObjectTemplate,
439     const FXJSE_CLASS* lpClassDefinition) {
440   v8::NamedPropertyHandlerConfiguration configuration(
441       lpClassDefinition->dynPropGetter
442           ? FXJSE_V8_GenericNamedPropertyGetterCallback
443           : 0,
444       lpClassDefinition->dynPropSetter
445           ? FXJSE_V8_GenericNamedPropertySetterCallback
446           : 0,
447       lpClassDefinition->dynPropTypeGetter
448           ? FXJSE_V8_GenericNamedPropertyQueryCallback
449           : 0,
450       lpClassDefinition->dynPropDeleter
451           ? FXJSE_V8_GenericNamedPropertyDeleterCallback
452           : 0,
453       FXJSE_V8_GenericNamedPropertyEnumeratorCallback,
454       v8::External::New(pIsolate, const_cast<FXJSE_CLASS*>(lpClassDefinition)),
455       v8::PropertyHandlerFlags::kNonMasking);
456   hObjectTemplate->SetHandler(configuration);
457 }
458