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 "fxjs/cjs_global.h"
8
9 #include <memory>
10 #include <utility>
11 #include <vector>
12
13 #include "core/fxcrt/fx_extension.h"
14 #include "fxjs/cfx_globaldata.h"
15 #include "fxjs/cfx_keyvalue.h"
16 #include "fxjs/cjs_event_context.h"
17 #include "fxjs/cjs_eventrecorder.h"
18 #include "fxjs/cjs_object.h"
19 #include "fxjs/js_define.h"
20 #include "fxjs/js_resources.h"
21
22 namespace {
23
PropFromV8Prop(v8::Isolate * pIsolate,v8::Local<v8::String> property)24 WideString PropFromV8Prop(v8::Isolate* pIsolate,
25 v8::Local<v8::String> property) {
26 v8::String::Utf8Value utf8_value(pIsolate, property);
27 return WideString::FromUTF8(ByteStringView(*utf8_value, utf8_value.length()));
28 }
29
JSSpecialPropQuery(v8::Local<v8::String> property,const v8::PropertyCallbackInfo<v8::Integer> & info)30 void JSSpecialPropQuery(v8::Local<v8::String> property,
31 const v8::PropertyCallbackInfo<v8::Integer>& info) {
32 auto pObj = JSGetObject<CJS_Global>(info.Holder());
33 if (!pObj)
34 return;
35
36 CJS_Runtime* pRuntime = pObj->GetRuntime();
37 if (!pRuntime)
38 return;
39
40 CJS_Result result =
41 pObj->QueryProperty(PropFromV8Prop(info.GetIsolate(), property).c_str());
42
43 info.GetReturnValue().Set(!result.HasError() ? 4 : 0);
44 }
45
JSSpecialPropGet(v8::Local<v8::String> property,const v8::PropertyCallbackInfo<v8::Value> & info)46 void JSSpecialPropGet(v8::Local<v8::String> property,
47 const v8::PropertyCallbackInfo<v8::Value>& info) {
48 auto pObj = JSGetObject<CJS_Global>(info.Holder());
49 if (!pObj)
50 return;
51
52 CJS_Runtime* pRuntime = pObj->GetRuntime();
53 if (!pRuntime)
54 return;
55
56 CJS_Result result = pObj->GetProperty(
57 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str());
58
59 if (result.HasError()) {
60 pRuntime->Error(
61 JSFormatErrorString("global", "GetProperty", result.Error()));
62 return;
63 }
64 if (result.HasReturn())
65 info.GetReturnValue().Set(result.Return());
66 }
67
JSSpecialPropPut(v8::Local<v8::String> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<v8::Value> & info)68 void JSSpecialPropPut(v8::Local<v8::String> property,
69 v8::Local<v8::Value> value,
70 const v8::PropertyCallbackInfo<v8::Value>& info) {
71 auto pObj = JSGetObject<CJS_Global>(info.Holder());
72 if (!pObj)
73 return;
74
75 CJS_Runtime* pRuntime = pObj->GetRuntime();
76 if (!pRuntime)
77 return;
78
79 CJS_Result result = pObj->SetProperty(
80 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str(), value);
81
82 if (result.HasError()) {
83 pRuntime->Error(
84 JSFormatErrorString("global", "PutProperty", result.Error()));
85 }
86 }
87
JSSpecialPropDel(v8::Local<v8::String> property,const v8::PropertyCallbackInfo<v8::Boolean> & info)88 void JSSpecialPropDel(v8::Local<v8::String> property,
89 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
90 auto pObj = JSGetObject<CJS_Global>(info.Holder());
91 if (!pObj)
92 return;
93
94 CJS_Runtime* pRuntime = pObj->GetRuntime();
95 if (!pRuntime)
96 return;
97
98 CJS_Result result = pObj->DelProperty(
99 pRuntime, PropFromV8Prop(info.GetIsolate(), property).c_str());
100
101 if (result.HasError()) {
102 // TODO(dsinclair): Should this set the pRuntime->Error result?
103 // pRuntime->Error(
104 // JSFormatErrorString("global", "DelProperty", result.Error());
105 }
106 }
107
108 template <typename T>
GetV8StringFromProperty(v8::Local<v8::Name> property,const T & info)109 v8::Local<v8::String> GetV8StringFromProperty(v8::Local<v8::Name> property,
110 const T& info) {
111 return property->ToString(info.GetIsolate()->GetCurrentContext())
112 .ToLocalChecked();
113 }
114
115 } // namespace
116
117 CJS_Global::JSGlobalData::JSGlobalData() = default;
118
119 CJS_Global::JSGlobalData::~JSGlobalData() = default;
120
121 const JSMethodSpec CJS_Global::MethodSpecs[] = {
122 {"setPersistent", setPersistent_static}};
123
124 uint32_t CJS_Global::ObjDefnID = 0;
125
126 // static
setPersistent_static(const v8::FunctionCallbackInfo<v8::Value> & info)127 void CJS_Global::setPersistent_static(
128 const v8::FunctionCallbackInfo<v8::Value>& info) {
129 JSMethod<CJS_Global, &CJS_Global::setPersistent>("setPersistent", "global",
130 info);
131 }
132
133 // static
queryprop_static(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Integer> & info)134 void CJS_Global::queryprop_static(
135 v8::Local<v8::Name> property,
136 const v8::PropertyCallbackInfo<v8::Integer>& info) {
137 ASSERT(property->IsString());
138 JSSpecialPropQuery(
139 v8::Local<v8::String>::New(info.GetIsolate(),
140 GetV8StringFromProperty(property, info)),
141 info);
142 }
143
144 // static
getprop_static(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Value> & info)145 void CJS_Global::getprop_static(
146 v8::Local<v8::Name> property,
147 const v8::PropertyCallbackInfo<v8::Value>& info) {
148 ASSERT(property->IsString());
149 JSSpecialPropGet(
150 v8::Local<v8::String>::New(info.GetIsolate(),
151 GetV8StringFromProperty(property, info)),
152 info);
153 }
154
155 // static
putprop_static(v8::Local<v8::Name> property,v8::Local<v8::Value> value,const v8::PropertyCallbackInfo<v8::Value> & info)156 void CJS_Global::putprop_static(
157 v8::Local<v8::Name> property,
158 v8::Local<v8::Value> value,
159 const v8::PropertyCallbackInfo<v8::Value>& info) {
160 ASSERT(property->IsString());
161 JSSpecialPropPut(
162 v8::Local<v8::String>::New(info.GetIsolate(),
163 GetV8StringFromProperty(property, info)),
164 value, info);
165 }
166
167 // static
delprop_static(v8::Local<v8::Name> property,const v8::PropertyCallbackInfo<v8::Boolean> & info)168 void CJS_Global::delprop_static(
169 v8::Local<v8::Name> property,
170 const v8::PropertyCallbackInfo<v8::Boolean>& info) {
171 ASSERT(property->IsString());
172 JSSpecialPropDel(
173 v8::Local<v8::String>::New(info.GetIsolate(),
174 GetV8StringFromProperty(property, info)),
175 info);
176 }
177
178 // static
DefineAllProperties(CFXJS_Engine * pEngine)179 void CJS_Global::DefineAllProperties(CFXJS_Engine* pEngine) {
180 pEngine->DefineObjAllProperties(
181 ObjDefnID, CJS_Global::queryprop_static, CJS_Global::getprop_static,
182 CJS_Global::putprop_static, CJS_Global::delprop_static);
183 }
184
185 // static
GetObjDefnID()186 uint32_t CJS_Global::GetObjDefnID() {
187 return ObjDefnID;
188 }
189
190 // static
DefineJSObjects(CFXJS_Engine * pEngine)191 void CJS_Global::DefineJSObjects(CFXJS_Engine* pEngine) {
192 ObjDefnID = pEngine->DefineObj("global", FXJSOBJTYPE_STATIC,
193 JSConstructor<CJS_Global>, JSDestructor);
194 DefineMethods(pEngine, ObjDefnID, MethodSpecs);
195 DefineAllProperties(pEngine);
196 }
197
CJS_Global(v8::Local<v8::Object> pObject,CJS_Runtime * pRuntime)198 CJS_Global::CJS_Global(v8::Local<v8::Object> pObject, CJS_Runtime* pRuntime)
199 : CJS_Object(pObject, pRuntime) {
200 CPDFSDK_FormFillEnvironment* pFormFillEnv = GetRuntime()->GetFormFillEnv();
201 m_pFormFillEnv.Reset(pFormFillEnv);
202 m_pGlobalData = CFX_GlobalData::GetRetainedInstance(nullptr);
203 UpdateGlobalPersistentVariables();
204 }
205
~CJS_Global()206 CJS_Global::~CJS_Global() {
207 DestroyGlobalPersisitentVariables();
208 m_pGlobalData->Release();
209 }
210
QueryProperty(const wchar_t * propname)211 CJS_Result CJS_Global::QueryProperty(const wchar_t* propname) {
212 if (WideString(propname).EqualsASCII("setPersistent"))
213 return CJS_Result::Success();
214
215 return CJS_Result::Failure(JSMessage::kUnknownProperty);
216 }
217
DelProperty(CJS_Runtime * pRuntime,const wchar_t * propname)218 CJS_Result CJS_Global::DelProperty(CJS_Runtime* pRuntime,
219 const wchar_t* propname) {
220 auto it = m_MapGlobal.find(WideString(propname).ToDefANSI());
221 if (it == m_MapGlobal.end())
222 return CJS_Result::Failure(JSMessage::kUnknownProperty);
223
224 it->second->bDeleted = true;
225 return CJS_Result::Success();
226 }
227
GetProperty(CJS_Runtime * pRuntime,const wchar_t * propname)228 CJS_Result CJS_Global::GetProperty(CJS_Runtime* pRuntime,
229 const wchar_t* propname) {
230 auto it = m_MapGlobal.find(WideString(propname).ToDefANSI());
231 if (it == m_MapGlobal.end())
232 return CJS_Result::Success();
233
234 JSGlobalData* pData = it->second.get();
235 if (pData->bDeleted)
236 return CJS_Result::Success();
237
238 switch (pData->nType) {
239 case CFX_Value::DataType::kNumber:
240 return CJS_Result::Success(pRuntime->NewNumber(pData->dData));
241 case CFX_Value::DataType::kBoolean:
242 return CJS_Result::Success(pRuntime->NewBoolean(pData->bData));
243 case CFX_Value::DataType::kString:
244 return CJS_Result::Success(pRuntime->NewString(
245 WideString::FromDefANSI(pData->sData.AsStringView()).AsStringView()));
246 case CFX_Value::DataType::kObject:
247 return CJS_Result::Success(
248 v8::Local<v8::Object>::New(pRuntime->GetIsolate(), pData->pData));
249 case CFX_Value::DataType::kNull:
250 return CJS_Result::Success(pRuntime->NewNull());
251 default:
252 break;
253 }
254 return CJS_Result::Failure(JSMessage::kObjectTypeError);
255 }
256
SetProperty(CJS_Runtime * pRuntime,const wchar_t * propname,v8::Local<v8::Value> vp)257 CJS_Result CJS_Global::SetProperty(CJS_Runtime* pRuntime,
258 const wchar_t* propname,
259 v8::Local<v8::Value> vp) {
260 ByteString sPropName = WideString(propname).ToDefANSI();
261 if (vp->IsNumber()) {
262 return SetGlobalVariables(sPropName, CFX_Value::DataType::kNumber,
263 pRuntime->ToDouble(vp), false, ByteString(),
264 v8::Local<v8::Object>(), false);
265 }
266 if (vp->IsBoolean()) {
267 return SetGlobalVariables(sPropName, CFX_Value::DataType::kBoolean, 0,
268 pRuntime->ToBoolean(vp), ByteString(),
269 v8::Local<v8::Object>(), false);
270 }
271 if (vp->IsString()) {
272 return SetGlobalVariables(sPropName, CFX_Value::DataType::kString, 0, false,
273 pRuntime->ToWideString(vp).ToDefANSI(),
274 v8::Local<v8::Object>(), false);
275 }
276 if (vp->IsObject()) {
277 return SetGlobalVariables(sPropName, CFX_Value::DataType::kObject, 0, false,
278 ByteString(), pRuntime->ToObject(vp), false);
279 }
280 if (vp->IsNull()) {
281 return SetGlobalVariables(sPropName, CFX_Value::DataType::kNull, 0, false,
282 ByteString(), v8::Local<v8::Object>(), false);
283 }
284 if (vp->IsUndefined()) {
285 DelProperty(pRuntime, propname);
286 return CJS_Result::Success();
287 }
288 return CJS_Result::Failure(JSMessage::kObjectTypeError);
289 }
290
setPersistent(CJS_Runtime * pRuntime,const std::vector<v8::Local<v8::Value>> & params)291 CJS_Result CJS_Global::setPersistent(
292 CJS_Runtime* pRuntime,
293 const std::vector<v8::Local<v8::Value>>& params) {
294 if (params.size() != 2)
295 return CJS_Result::Failure(JSMessage::kParamError);
296
297 auto it = m_MapGlobal.find(pRuntime->ToWideString(params[0]).ToDefANSI());
298 if (it == m_MapGlobal.end() || it->second->bDeleted)
299 return CJS_Result::Failure(JSMessage::kGlobalNotFoundError);
300
301 it->second->bPersistent = pRuntime->ToBoolean(params[1]);
302 return CJS_Result::Success();
303 }
304
UpdateGlobalPersistentVariables()305 void CJS_Global::UpdateGlobalPersistentVariables() {
306 CJS_Runtime* pRuntime = GetRuntime();
307 if (!pRuntime)
308 return;
309
310 for (int i = 0, sz = m_pGlobalData->GetSize(); i < sz; i++) {
311 CFX_GlobalData::Element* pData = m_pGlobalData->GetAt(i);
312 switch (pData->data.nType) {
313 case CFX_Value::DataType::kNumber:
314 SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kNumber,
315 pData->data.dData, false, ByteString(),
316 v8::Local<v8::Object>(), pData->bPersistent == 1);
317 pRuntime->PutObjectProperty(ToV8Object(),
318 pData->data.sKey.AsStringView(),
319 pRuntime->NewNumber(pData->data.dData));
320 break;
321 case CFX_Value::DataType::kBoolean:
322 SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kBoolean, 0,
323 pData->data.bData == 1, ByteString(),
324 v8::Local<v8::Object>(), pData->bPersistent == 1);
325 pRuntime->PutObjectProperty(
326 ToV8Object(), pData->data.sKey.AsStringView(),
327 pRuntime->NewBoolean(pData->data.bData == 1));
328 break;
329 case CFX_Value::DataType::kString:
330 SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kString, 0,
331 false, pData->data.sData, v8::Local<v8::Object>(),
332 pData->bPersistent == 1);
333 pRuntime->PutObjectProperty(
334 ToV8Object(), pData->data.sKey.AsStringView(),
335 pRuntime->NewString(
336 WideString::FromUTF8(pData->data.sData.AsStringView())
337 .AsStringView()));
338 break;
339 case CFX_Value::DataType::kObject: {
340 v8::Local<v8::Object> pObj = pRuntime->NewObject();
341 if (!pObj.IsEmpty()) {
342 PutObjectProperty(pObj, &pData->data);
343 SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kObject, 0,
344 false, ByteString(), pObj,
345 pData->bPersistent == 1);
346 pRuntime->PutObjectProperty(ToV8Object(),
347 pData->data.sKey.AsStringView(), pObj);
348 }
349 } break;
350 case CFX_Value::DataType::kNull:
351 SetGlobalVariables(pData->data.sKey, CFX_Value::DataType::kNull, 0,
352 false, ByteString(), v8::Local<v8::Object>(),
353 pData->bPersistent == 1);
354 pRuntime->PutObjectProperty(
355 ToV8Object(), pData->data.sKey.AsStringView(), pRuntime->NewNull());
356 break;
357 }
358 }
359 }
360
CommitGlobalPersisitentVariables(CJS_Runtime * pRuntime)361 void CJS_Global::CommitGlobalPersisitentVariables(CJS_Runtime* pRuntime) {
362 for (const auto& iter : m_MapGlobal) {
363 ByteString name = iter.first;
364 JSGlobalData* pData = iter.second.get();
365 if (pData->bDeleted) {
366 m_pGlobalData->DeleteGlobalVariable(name);
367 continue;
368 }
369 switch (pData->nType) {
370 case CFX_Value::DataType::kNumber:
371 m_pGlobalData->SetGlobalVariableNumber(name, pData->dData);
372 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
373 break;
374 case CFX_Value::DataType::kBoolean:
375 m_pGlobalData->SetGlobalVariableBoolean(name, pData->bData);
376 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
377 break;
378 case CFX_Value::DataType::kString:
379 m_pGlobalData->SetGlobalVariableString(name, pData->sData);
380 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
381 break;
382 case CFX_Value::DataType::kObject: {
383 std::vector<std::unique_ptr<CFX_KeyValue>> array;
384 v8::Local<v8::Object> obj =
385 v8::Local<v8::Object>::New(GetIsolate(), pData->pData);
386 ObjectToArray(pRuntime, obj, &array);
387 m_pGlobalData->SetGlobalVariableObject(name, std::move(array));
388 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
389 } break;
390 case CFX_Value::DataType::kNull:
391 m_pGlobalData->SetGlobalVariableNull(name);
392 m_pGlobalData->SetGlobalVariablePersistent(name, pData->bPersistent);
393 break;
394 }
395 }
396 }
397
ObjectToArray(CJS_Runtime * pRuntime,v8::Local<v8::Object> pObj,std::vector<std::unique_ptr<CFX_KeyValue>> * pArray)398 void CJS_Global::ObjectToArray(
399 CJS_Runtime* pRuntime,
400 v8::Local<v8::Object> pObj,
401 std::vector<std::unique_ptr<CFX_KeyValue>>* pArray) {
402 std::vector<WideString> pKeyList = pRuntime->GetObjectPropertyNames(pObj);
403 for (const auto& ws : pKeyList) {
404 ByteString sKey = ws.ToUTF8();
405 v8::Local<v8::Value> v =
406 pRuntime->GetObjectProperty(pObj, sKey.AsStringView());
407 if (v->IsNumber()) {
408 auto pObjElement = std::make_unique<CFX_KeyValue>();
409 pObjElement->nType = CFX_Value::DataType::kNumber;
410 pObjElement->sKey = sKey;
411 pObjElement->dData = pRuntime->ToDouble(v);
412 pArray->push_back(std::move(pObjElement));
413 continue;
414 }
415 if (v->IsBoolean()) {
416 auto pObjElement = std::make_unique<CFX_KeyValue>();
417 pObjElement->nType = CFX_Value::DataType::kBoolean;
418 pObjElement->sKey = sKey;
419 pObjElement->dData = pRuntime->ToBoolean(v);
420 pArray->push_back(std::move(pObjElement));
421 continue;
422 }
423 if (v->IsString()) {
424 ByteString sValue = pRuntime->ToWideString(v).ToDefANSI();
425 auto pObjElement = std::make_unique<CFX_KeyValue>();
426 pObjElement->nType = CFX_Value::DataType::kString;
427 pObjElement->sKey = sKey;
428 pObjElement->sData = sValue;
429 pArray->push_back(std::move(pObjElement));
430 continue;
431 }
432 if (v->IsObject()) {
433 auto pObjElement = std::make_unique<CFX_KeyValue>();
434 pObjElement->nType = CFX_Value::DataType::kObject;
435 pObjElement->sKey = sKey;
436 ObjectToArray(pRuntime, pRuntime->ToObject(v), &pObjElement->objData);
437 pArray->push_back(std::move(pObjElement));
438 continue;
439 }
440 if (v->IsNull()) {
441 auto pObjElement = std::make_unique<CFX_KeyValue>();
442 pObjElement->nType = CFX_Value::DataType::kNull;
443 pObjElement->sKey = sKey;
444 pArray->push_back(std::move(pObjElement));
445 }
446 }
447 }
448
PutObjectProperty(v8::Local<v8::Object> pObj,CFX_KeyValue * pData)449 void CJS_Global::PutObjectProperty(v8::Local<v8::Object> pObj,
450 CFX_KeyValue* pData) {
451 CJS_Runtime* pRuntime = GetRuntime();
452 if (pRuntime)
453 return;
454
455 for (size_t i = 0; i < pData->objData.size(); ++i) {
456 CFX_KeyValue* pObjData = pData->objData.at(i).get();
457 switch (pObjData->nType) {
458 case CFX_Value::DataType::kNumber:
459 pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
460 pRuntime->NewNumber(pObjData->dData));
461 break;
462 case CFX_Value::DataType::kBoolean:
463 pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
464 pRuntime->NewBoolean(pObjData->bData == 1));
465 break;
466 case CFX_Value::DataType::kString:
467 pRuntime->PutObjectProperty(
468 pObj, pObjData->sKey.AsStringView(),
469 pRuntime->NewString(
470 WideString::FromUTF8(pObjData->sData.AsStringView())
471 .AsStringView()));
472 break;
473 case CFX_Value::DataType::kObject: {
474 v8::Local<v8::Object> pNewObj = pRuntime->NewObject();
475 if (!pNewObj.IsEmpty()) {
476 PutObjectProperty(pNewObj, pObjData);
477 pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
478 pNewObj);
479 }
480 } break;
481 case CFX_Value::DataType::kNull:
482 pRuntime->PutObjectProperty(pObj, pObjData->sKey.AsStringView(),
483 pRuntime->NewNull());
484 break;
485 }
486 }
487 }
488
DestroyGlobalPersisitentVariables()489 void CJS_Global::DestroyGlobalPersisitentVariables() {
490 m_MapGlobal.clear();
491 }
492
SetGlobalVariables(const ByteString & propname,CFX_Value::DataType nType,double dData,bool bData,const ByteString & sData,v8::Local<v8::Object> pData,bool bDefaultPersistent)493 CJS_Result CJS_Global::SetGlobalVariables(const ByteString& propname,
494 CFX_Value::DataType nType,
495 double dData,
496 bool bData,
497 const ByteString& sData,
498 v8::Local<v8::Object> pData,
499 bool bDefaultPersistent) {
500 if (propname.IsEmpty())
501 return CJS_Result::Failure(JSMessage::kUnknownProperty);
502
503 auto it = m_MapGlobal.find(propname);
504 if (it != m_MapGlobal.end()) {
505 JSGlobalData* pTemp = it->second.get();
506 if (pTemp->bDeleted || pTemp->nType != nType) {
507 pTemp->dData = 0;
508 pTemp->bData = 0;
509 pTemp->sData.clear();
510 pTemp->nType = nType;
511 }
512 pTemp->bDeleted = false;
513 switch (nType) {
514 case CFX_Value::DataType::kNumber:
515 pTemp->dData = dData;
516 break;
517 case CFX_Value::DataType::kBoolean:
518 pTemp->bData = bData;
519 break;
520 case CFX_Value::DataType::kString:
521 pTemp->sData = sData;
522 break;
523 case CFX_Value::DataType::kObject:
524 pTemp->pData.Reset(pData->GetIsolate(), pData);
525 break;
526 case CFX_Value::DataType::kNull:
527 break;
528 default:
529 return CJS_Result::Failure(JSMessage::kObjectTypeError);
530 }
531 return CJS_Result::Success();
532 }
533
534 auto pNewData = std::make_unique<JSGlobalData>();
535 switch (nType) {
536 case CFX_Value::DataType::kNumber:
537 pNewData->nType = CFX_Value::DataType::kNumber;
538 pNewData->dData = dData;
539 pNewData->bPersistent = bDefaultPersistent;
540 break;
541 case CFX_Value::DataType::kBoolean:
542 pNewData->nType = CFX_Value::DataType::kBoolean;
543 pNewData->bData = bData;
544 pNewData->bPersistent = bDefaultPersistent;
545 break;
546 case CFX_Value::DataType::kString:
547 pNewData->nType = CFX_Value::DataType::kString;
548 pNewData->sData = sData;
549 pNewData->bPersistent = bDefaultPersistent;
550 break;
551 case CFX_Value::DataType::kObject:
552 pNewData->nType = CFX_Value::DataType::kObject;
553 pNewData->pData.Reset(pData->GetIsolate(), pData);
554 pNewData->bPersistent = bDefaultPersistent;
555 break;
556 case CFX_Value::DataType::kNull:
557 pNewData->nType = CFX_Value::DataType::kNull;
558 pNewData->bPersistent = bDefaultPersistent;
559 break;
560 default:
561 return CJS_Result::Failure(JSMessage::kObjectTypeError);
562 }
563 m_MapGlobal[propname] = std::move(pNewData);
564 return CJS_Result::Success();
565 }
566