blob: 906c73705ca4dbf9956561de2752cbe9d7c0ed36 [file] [log] [blame]
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -07001// 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 "../../include/javascript/JavaScript.h"
8#include "../../include/javascript/IJavaScript.h"
9#include "../../include/javascript/JS_Define.h"
10#include "../../include/javascript/JS_Object.h"
11#include "../../include/javascript/JS_Value.h"
12#include "../../include/javascript/JS_GlobalData.h"
13#include "../../include/javascript/global.h"
14#include "../../include/javascript/JS_EventHandler.h"
15#include "../../include/javascript/JS_Context.h"
Bo Xufdc00a72014-10-28 23:03:33 -070016#include "../../include/fpdfxfa/fpdfxfa_app.h"
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070017
18/* ---------------------------- global ---------------------------- */
19
Bruce Dawsone68d6242015-01-05 15:18:21 -080020// Helper class for compile-time calculation of hash values in order to
21// avoid having global object initializers.
22template <unsigned ACC, wchar_t... Ns>
23struct CHash;
24
25// Only needed to hash single-character strings.
26template <wchar_t N>
27struct CHash<N> {
28 static const unsigned value = N;
29};
30
31template <unsigned ACC, wchar_t N>
32struct CHash<ACC, N> {
33 static const unsigned value = (ACC * 1313LLU + N) & 0xFFFFFFFF;
34};
35
36template <unsigned ACC, wchar_t N, wchar_t... Ns>
37struct CHash<ACC, N, Ns...> {
38 static const unsigned value = CHash<CHash<ACC, N>::value, Ns...>::value;
39};
40
41extern const unsigned int JSCONST_nStringHash =
42 CHash<'s','t','r','i','n','g'>::value;
43extern const unsigned int JSCONST_nNumberHash =
44 CHash<'n','u','m','b','e','r'>::value;
45extern const unsigned int JSCONST_nBoolHash =
46 CHash<'b','o','o','l','e','a','n'>::value;
47extern const unsigned int JSCONST_nDateHash =
48 CHash<'d','a','t','e'>::value;
49extern const unsigned int JSCONST_nObjectHash =
50 CHash<'o','b','j','e','c','t'>::value;
51extern const unsigned int JSCONST_nFXobjHash =
52 CHash<'f','x','o','b','j'>::value;
53extern const unsigned int JSCONST_nNullHash =
54 CHash<'n','u','l','l'>::value;
55extern const unsigned int JSCONST_nUndefHash =
56 CHash<'u','n','d','e','f','i','n','e','d'>::value;
57
58#ifdef _DEBUG
59class HashVerify
60{
61public:
62 HashVerify();
63} g_hashVerify;
64
65HashVerify::HashVerify()
66{
67 ASSERT(JSCONST_nStringHash ==
68 JS_CalcHash(VALUE_NAME_STRING,wcslen(VALUE_NAME_STRING)));
69 ASSERT(JSCONST_nNumberHash ==
70 JS_CalcHash(VALUE_NAME_NUMBER,wcslen(VALUE_NAME_NUMBER)));
71 ASSERT(JSCONST_nBoolHash ==
72 JS_CalcHash(VALUE_NAME_BOOLEAN,wcslen(VALUE_NAME_BOOLEAN)));
73 ASSERT(JSCONST_nDateHash ==
74 JS_CalcHash(VALUE_NAME_DATE,wcslen(VALUE_NAME_DATE)));
75 ASSERT(JSCONST_nObjectHash ==
76 JS_CalcHash(VALUE_NAME_OBJECT,wcslen(VALUE_NAME_OBJECT)));
77 ASSERT(JSCONST_nFXobjHash ==
78 JS_CalcHash(VALUE_NAME_FXOBJ,wcslen(VALUE_NAME_FXOBJ)));
79 ASSERT(JSCONST_nNullHash ==
80 JS_CalcHash(VALUE_NAME_NULL,wcslen(VALUE_NAME_NULL)));
81 ASSERT(JSCONST_nUndefHash ==
82 JS_CalcHash(VALUE_NAME_UNDEFINED,wcslen(VALUE_NAME_UNDEFINED)));
83}
84#endif
85
Bruce Dawsonc674af42014-12-12 21:30:37 -080086
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -070087BEGIN_JS_STATIC_CONST(CJS_Global)
88END_JS_STATIC_CONST()
89
90BEGIN_JS_STATIC_PROP(CJS_Global)
91END_JS_STATIC_PROP()
92
93BEGIN_JS_STATIC_METHOD(CJS_Global)
94 JS_STATIC_METHOD_ENTRY(setPersistent, 2)
95END_JS_STATIC_METHOD()
96
97IMPLEMENT_SPECIAL_JS_CLASS(CJS_Global, global_alternate, global);
98
99FX_BOOL CJS_Global::InitInstance(IFXJS_Context* cc)
100{
101 CJS_Context* pContext = (CJS_Context*)cc;
102 ASSERT(pContext != NULL);
103
104 global_alternate* pGlobal = (global_alternate*)GetEmbedObject();
105 ASSERT(pGlobal != NULL);
106
107 pGlobal->Initial(pContext->GetReaderApp());
108
109 return TRUE;
110};
111
112global_alternate::global_alternate(CJS_Object* pJSObject)
113 : CJS_EmbedObj(pJSObject),
114 m_pApp(NULL)
115{
116}
117
118global_alternate::~global_alternate(void)
119{
120 ASSERT(m_pApp != NULL);
121
122// CommitGlobalPersisitentVariables();
123 DestroyGlobalPersisitentVariables();
124
Bo Xufdc00a72014-10-28 23:03:33 -0700125 CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700126 ASSERT(pFactory);
127
128 pFactory->ReleaseGlobalData();
129}
130
131void global_alternate::Initial(CPDFDoc_Environment* pApp)
132{
133 m_pApp = pApp;
134
Bo Xufdc00a72014-10-28 23:03:33 -0700135 CJS_RuntimeFactory* pFactory = FPDFXFA_GetApp()->GetRuntimeFactory();
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700136 ASSERT(pFactory);
137 m_pGlobalData = pFactory->NewGlobalData(pApp);
138 UpdateGlobalPersistentVariables();
139}
140
141FX_BOOL global_alternate::QueryProperty(FX_LPCWSTR propname)
142{
143 return CFX_WideString(propname) != L"setPersistent";
144}
145
146FX_BOOL global_alternate::DelProperty(IFXJS_Context* cc, FX_LPCWSTR propname, JS_ErrorString& sError)
147{
148 js_global_data* pData = NULL;
149 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
150
151 if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
152 {
153 pData->bDeleted = TRUE;
154 return TRUE;
155 }
156
157 return FALSE;
158}
159
160FX_BOOL global_alternate::DoProperty(IFXJS_Context* cc, FX_LPCWSTR propname, CJS_PropValue& vp, JS_ErrorString& sError)
161{
162 if (vp.IsSetting())
163 {
164 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
165 switch (vp.GetType())
166 {
167 case VT_number:
168 {
169 double dData;
170 vp >> dData;
171 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NUMBER, dData, false, "", v8::Handle<v8::Object>(), FALSE);
172 }
173 case VT_boolean:
174 {
175 bool bData;
176 vp >> bData;
177 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)vp, "", v8::Handle<v8::Object>(), FALSE);
178 }
179 case VT_string:
180 {
181 CFX_ByteString sData;
182 vp >> sData;
183 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_STRING, 0, false, sData, v8::Handle<v8::Object>(), FALSE);
184 }
185 case VT_object:
186 {
187 JSObject pData = (JSObject)vp;
188 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "", pData, FALSE);
189// else
190// {
191// if (vp.IsArrayObject())
192// {
193// CJS_Array array;
194// vp.ConvertToArray(array);
195// return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "",
196// (Dobject*)(Darray*)array, FALSE);
197// }
198// else
199// return FALSE;
200// }
201 }
202 case VT_null:
203 {
204 return SetGlobalVariables(sPropName, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Handle<v8::Object>(), FALSE);
205 }
206 case VT_undefined:
207 {
208 DelProperty(cc, propname, sError);
209 return TRUE;
210 }
211 default:
212 return FALSE;
213 }
214 }
215 else
216 {
217 js_global_data* pData = NULL;
218 CFX_ByteString sPropName = CFX_ByteString::FromUnicode(propname);
219
220 if (m_mapGlobal.Lookup(sPropName, (FX_LPVOID&)pData))
221 {
222 if (pData)
223 {
224 if (!pData->bDeleted)
225 {
226 switch (pData->nType)
227 {
228 case JS_GLOBALDATA_TYPE_NUMBER:
229 vp << pData->dData;
230 break;
231 case JS_GLOBALDATA_TYPE_BOOLEAN:
232 vp << pData->bData;
233 break;
234 case JS_GLOBALDATA_TYPE_STRING:
235 vp << pData->sData;
236 break;
237 case JS_GLOBALDATA_TYPE_OBJECT:
238 {
239 v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(vp.GetIsolate(),pData->pData);
240 vp << obj;
241 break;
242 }
243 case JS_GLOBALDATA_TYPE_NULL:
244 vp.SetNull();
245 break;
246 default:
247 return FALSE;
248 }
249 return TRUE;
250 }
251 else
252 {
253 return TRUE;
254 }
255 }
256 else
257 {
258 vp.SetNull();
259 return TRUE;
260 }
261 }
262 else
263 {
264 vp.SetNull();
265 return TRUE;
266 }
267 }
268
269 return FALSE;
270}
271
Tom Sepezccc94832015-02-17 13:30:23 -0800272FX_BOOL global_alternate::setPersistent(IFXJS_Context* cc, const CJS_Parameters& params, CJS_Value& vRet, JS_ErrorString& sError)
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700273{
274 if (params.size() != 2)
275 {
276 //sError = JSGetStringFromID(IDS_STRING_JSPARAMERROR);
277 return FALSE;
278 }
279
280 CFX_ByteString sName = params[0];
281
282 js_global_data* pData = NULL;
283 if (m_mapGlobal.Lookup(sName, (FX_LPVOID&)pData))
284 {
285 if (pData && !pData->bDeleted)
286 {
287 pData->bPersistent = (bool)params[1];
288 return TRUE;
289 }
290 }
291
292 //sError = JSGetStringFromID(IDS_JSPARAM_INCORRECT);
293 return FALSE;
294}
295
296void global_alternate::UpdateGlobalPersistentVariables()
297{
298 ASSERT(m_pGlobalData != NULL);
299
300 for (int i=0,sz=m_pGlobalData->GetSize(); i<sz; i++)
301 {
302 CJS_GlobalData_Element* pData = m_pGlobalData->GetAt(i);
303 ASSERT(pData != NULL);
304
305 switch (pData->data.nType)
306 {
307 case JS_GLOBALDATA_TYPE_NUMBER:
308 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NUMBER, pData->data.dData, false, "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
309 JS_PutObjectNumber(NULL,(JSFXObject)(*m_pJSObject),
310 pData->data.sKey.UTF8Decode(), pData->data.dData);
311 break;
312 case JS_GLOBALDATA_TYPE_BOOLEAN:
313 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_BOOLEAN, 0, (bool)(pData->data.bData == 1), "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
314 JS_PutObjectBoolean(NULL,(JSFXObject)(*m_pJSObject),
315 pData->data.sKey.UTF8Decode(), (bool)(pData->data.bData == 1));
316 break;
317 case JS_GLOBALDATA_TYPE_STRING:
318 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_STRING, 0, false, pData->data.sData, v8::Handle<v8::Object>(), pData->bPersistent == 1);
319 JS_PutObjectString(NULL,(JSFXObject)(*m_pJSObject),
320 pData->data.sKey.UTF8Decode(),
321 pData->data.sData.UTF8Decode());
322 break;
323 case JS_GLOBALDATA_TYPE_OBJECT:
324 {
325 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
326 v8::Handle<v8::Object> pObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
327
328 PutObjectProperty(pObj, &pData->data);
329
330 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_OBJECT, 0, false, "",
331 (JSObject)pObj, pData->bPersistent == 1);
332 JS_PutObjectObject(NULL,(JSFXObject)(*m_pJSObject),
333 pData->data.sKey.UTF8Decode(), (JSObject)pObj);
334 }
335 break;
336 case JS_GLOBALDATA_TYPE_NULL:
337 this->SetGlobalVariables(pData->data.sKey, JS_GLOBALDATA_TYPE_NULL, 0, false, "", v8::Handle<v8::Object>(), pData->bPersistent == 1);
338 JS_PutObjectNull(NULL,(JSFXObject)(*m_pJSObject),
339 pData->data.sKey.UTF8Decode());
340 break;
341 }
342 }
343}
344
345void global_alternate::CommitGlobalPersisitentVariables()
346{
347 ASSERT(m_pGlobalData != NULL);
348
349 FX_POSITION pos = m_mapGlobal.GetStartPosition();
350 while (pos)
351 {
352 CFX_ByteString name;
353 js_global_data* pData = NULL;
354 m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
355
356 if (pData)
357 {
358 if (pData->bDeleted)
359 {
360 m_pGlobalData->DeleteGlobalVariable(name);
361 }
362 else
363 {
364 switch (pData->nType)
365 {
366 case JS_GLOBALDATA_TYPE_NUMBER:
367 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
368 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
369 break;
370 case JS_GLOBALDATA_TYPE_BOOLEAN:
371 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
372 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
373 break;
374 case JS_GLOBALDATA_TYPE_STRING:
375 m_pGlobalData->SetGlobalVariableString(name, pData->sData);
376 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
377 break;
378 case JS_GLOBALDATA_TYPE_OBJECT:
379 //if (pData->pData)
380 {
381 CJS_GlobalVariableArray array;
382 v8::Handle<v8::Object> obj = v8::Local<v8::Object>::New(GetJSObject()->GetIsolate(),pData->pData);
383 ObjectToArray(obj, array);
384 m_pGlobalData->SetGlobalVariableObject(name, array);
385 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
386 }
387 break;
388 case JS_GLOBALDATA_TYPE_NULL:
389 m_pGlobalData->SetGlobalVariableNull(name);
390 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
391 break;
392 }
393 }
394 }
395 }
396}
397
398void global_alternate::ObjectToArray(v8::Handle<v8::Object> pObj, CJS_GlobalVariableArray& array)
399{
400 v8::Handle<v8::Array> pKeyList = JS_GetObjectElementNames(pObj);
401 int nObjElements = pKeyList->Length();
402
403 v8::Local<v8::Context> context = pObj->CreationContext();
404 v8::Isolate* isolate = context->GetIsolate();
405
406 for (int i=0; i<nObjElements; i++)
407 {
408
409 CFX_WideString ws = JS_ToString(JS_GetArrayElemnet(pKeyList, i));
410 CFX_ByteString sKey = ws.UTF8Encode();
411
Bruce Dawson0a476d22014-12-23 12:21:02 -0800412 v8::Handle<v8::Value> v = JS_GetObjectElement(isolate, pObj, ws.c_str());
John Abd-El-Malek3f3b45c2014-05-23 17:28:10 -0700413 FXJSVALUETYPE vt = GET_VALUE_TYPE(v);
414 switch (vt)
415 {
416 case VT_number:
417 {
418 CJS_KeyValue* pObjElement = new CJS_KeyValue;
419 pObjElement->nType = JS_GLOBALDATA_TYPE_NUMBER;
420 pObjElement->sKey = sKey;
421 pObjElement->dData = JS_ToNumber(v);
422 array.Add(pObjElement);
423 }
424 break;
425 case VT_boolean:
426 {
427 CJS_KeyValue* pObjElement = new CJS_KeyValue;
428 pObjElement->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
429 pObjElement->sKey = sKey;
430 pObjElement->dData = JS_ToBoolean(v);
431 array.Add(pObjElement);
432 }
433 break;
434 case VT_string:
435 {
436 CFX_ByteString sValue = CJS_Value(isolate, v, VT_string);
437 CJS_KeyValue* pObjElement = new CJS_KeyValue;
438 pObjElement->nType = JS_GLOBALDATA_TYPE_STRING;
439 pObjElement->sKey = sKey;
440 pObjElement->sData = sValue;
441 array.Add(pObjElement);
442 }
443 break;
444 case VT_object:
445 {
446 CJS_KeyValue* pObjElement = new CJS_KeyValue;
447 pObjElement->nType = JS_GLOBALDATA_TYPE_OBJECT;
448 pObjElement->sKey = sKey;
449 ObjectToArray(JS_ToObject(v), pObjElement->objData);
450 array.Add(pObjElement);
451 }
452 break;
453 case VT_null:
454 {
455 CJS_KeyValue* pObjElement = new CJS_KeyValue;
456 pObjElement->nType = JS_GLOBALDATA_TYPE_NULL;
457 pObjElement->sKey = sKey;
458 array.Add(pObjElement);
459 }
460 break;
461 default:
462 break;
463 }
464 }
465}
466
467void global_alternate::PutObjectProperty(v8::Handle<v8::Object> pObj, CJS_KeyValue* pData)
468{
469 ASSERT(pData != NULL);
470
471 for (int i=0,sz=pData->objData.Count(); i<sz; i++)
472 {
473 CJS_KeyValue* pObjData = pData->objData.GetAt(i);
474 ASSERT(pObjData != NULL);
475
476 switch (pObjData->nType)
477 {
478 case JS_GLOBALDATA_TYPE_NUMBER:
479 JS_PutObjectNumber(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), pObjData->dData);
480 break;
481 case JS_GLOBALDATA_TYPE_BOOLEAN:
482 JS_PutObjectBoolean(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), (bool)(pObjData->bData == 1));
483 break;
484 case JS_GLOBALDATA_TYPE_STRING:
485 JS_PutObjectString(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode(), pObjData->sData.UTF8Decode());
486 break;
487 case JS_GLOBALDATA_TYPE_OBJECT:
488 {
489 IJS_Runtime* pRuntime = JS_GetRuntime((JSFXObject)(*m_pJSObject));
490 v8::Handle<v8::Object> pNewObj = JS_NewFxDynamicObj(pRuntime, NULL, -1);
491 PutObjectProperty(pNewObj, pObjData);
492 JS_PutObjectObject(NULL, (JSObject)pObj, pObjData->sKey.UTF8Decode(), (JSObject)pNewObj);
493 }
494 break;
495 case JS_GLOBALDATA_TYPE_NULL:
496 JS_PutObjectNull(NULL,(JSObject)pObj, pObjData->sKey.UTF8Decode());
497 break;
498 }
499 }
500}
501
502void global_alternate::DestroyGlobalPersisitentVariables()
503{
504 FX_POSITION pos = m_mapGlobal.GetStartPosition();
505 while (pos)
506 {
507 CFX_ByteString name;
508 js_global_data* pData = NULL;
509 m_mapGlobal.GetNextAssoc(pos, name, (FX_LPVOID&)pData);
510 delete pData;
511 }
512
513 m_mapGlobal.RemoveAll();
514}
515
516
517FX_BOOL global_alternate::SetGlobalVariables(FX_LPCSTR propname, int nType,
518 double dData, bool bData, const CFX_ByteString& sData, JSObject pData, bool bDefaultPersistent)
519{
520 if (propname == NULL) return FALSE;
521
522 js_global_data* pTemp = NULL;
523 m_mapGlobal.Lookup(propname, (FX_LPVOID&)pTemp);
524
525 if (pTemp)
526 {
527 if (pTemp->bDeleted || pTemp->nType != nType)
528 {
529 pTemp->dData = 0;
530 pTemp->bData = 0;
531 pTemp->sData = "";
532 pTemp->nType = nType;
533 }
534
535 pTemp->bDeleted = FALSE;
536
537 switch (nType)
538 {
539 case JS_GLOBALDATA_TYPE_NUMBER:
540 {
541 pTemp->dData = dData;
542 }
543 break;
544 case JS_GLOBALDATA_TYPE_BOOLEAN:
545 {
546 pTemp->bData = bData;
547 }
548 break;
549 case JS_GLOBALDATA_TYPE_STRING:
550 {
551 pTemp->sData = sData;
552 }
553 break;
554 case JS_GLOBALDATA_TYPE_OBJECT:
555 {
556 pTemp->pData.Reset(JS_GetRuntime(pData), pData);
557 }
558 break;
559 case JS_GLOBALDATA_TYPE_NULL:
560 break;
561 default:
562 return FALSE;
563 }
564
565 return TRUE;
566 }
567
568 js_global_data* pNewData = NULL;
569
570 switch (nType)
571 {
572 case JS_GLOBALDATA_TYPE_NUMBER:
573 {
574 pNewData = new js_global_data;
575 pNewData->nType = JS_GLOBALDATA_TYPE_NUMBER;
576 pNewData->dData = dData;
577 pNewData->bPersistent = bDefaultPersistent;
578 }
579 break;
580 case JS_GLOBALDATA_TYPE_BOOLEAN:
581 {
582 pNewData = new js_global_data;
583 pNewData->nType = JS_GLOBALDATA_TYPE_BOOLEAN;
584 pNewData->bData = bData;
585 pNewData->bPersistent = bDefaultPersistent;
586 }
587 break;
588 case JS_GLOBALDATA_TYPE_STRING:
589 {
590 pNewData = new js_global_data;
591 pNewData->nType = JS_GLOBALDATA_TYPE_STRING;
592 pNewData->sData = sData;
593 pNewData->bPersistent = bDefaultPersistent;
594 }
595 break;
596 case JS_GLOBALDATA_TYPE_OBJECT:
597 {
598 pNewData = new js_global_data;
599 pNewData->nType = JS_GLOBALDATA_TYPE_OBJECT;
600 pNewData->pData.Reset(JS_GetRuntime(pData), pData);
601 pNewData->bPersistent = bDefaultPersistent;
602 }
603 break;
604 case JS_GLOBALDATA_TYPE_NULL:
605 {
606 pNewData = new js_global_data;
607 pNewData->nType = JS_GLOBALDATA_TYPE_NULL;
608 pNewData->bPersistent = bDefaultPersistent;
609 }
610 break;
611 default:
612 return FALSE;
613 }
614
615 m_mapGlobal.SetAt(propname, (FX_LPVOID)pNewData);
616
617 return TRUE;
618}
Tom Sepezccc94832015-02-17 13:30:23 -0800619
620FXJSVALUETYPE GET_VALUE_TYPE(v8::Handle<v8::Value> p)
621{
622 const unsigned int nHash = JS_CalcHash(JS_GetTypeof(p));
623
624 if (nHash == JSCONST_nUndefHash)
625 return VT_undefined;
626 if (nHash == JSCONST_nNullHash)
627 return VT_null;
628 if (nHash == JSCONST_nStringHash)
629 return VT_string;
630 if (nHash == JSCONST_nNumberHash)
631 return VT_number;
632 if (nHash == JSCONST_nBoolHash)
633 return VT_boolean;
634 if (nHash == JSCONST_nDateHash)
635 return VT_date;
636 if (nHash == JSCONST_nObjectHash)
637 return VT_object;
638 if (nHash == JSCONST_nFXobjHash)
639 return VT_fxobject;
640
641 return VT_unknown;
642}
643