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