Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(50)

Side by Side Diff: fpdfsdk/src/jsapi/fxjs_v8.cpp

Issue 1799773002: Move fpdfsdk/src up to fpdfsdk/. (Closed) Base URL: https://pdfium.googlesource.com/pdfium.git@master
Patch Set: Rebase to master Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « fpdfsdk/src/javascript/util.cpp ('k') | fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 "fpdfsdk/include/jsapi/fxjs_v8.h"
8
9 #include <vector>
10
11 #include "core/include/fxcrt/fx_basic.h"
12
13 const wchar_t kFXJSValueNameString[] = L"string";
14 const wchar_t kFXJSValueNameNumber[] = L"number";
15 const wchar_t kFXJSValueNameBoolean[] = L"boolean";
16 const wchar_t kFXJSValueNameDate[] = L"date";
17 const wchar_t kFXJSValueNameObject[] = L"object";
18 const wchar_t kFXJSValueNameFxobj[] = L"fxobj";
19 const wchar_t kFXJSValueNameNull[] = L"null";
20 const wchar_t kFXJSValueNameUndefined[] = L"undefined";
21
22 // Keep this consistent with the values defined in gin/public/context_holder.h
23 // (without actually requiring a dependency on gin itself for the standalone
24 // embedders of PDFIum). The value we want to use is:
25 // kPerContextDataStartIndex + kEmbedderPDFium, which is 3.
26 static const unsigned int kPerContextDataIndex = 3u;
27 static unsigned int g_embedderDataSlot = 1u;
28 static v8::Isolate* g_isolate = nullptr;
29 static size_t g_isolate_ref_count = 0;
30 static FXJS_ArrayBufferAllocator* g_arrayBufferAllocator = nullptr;
31 static v8::Global<v8::ObjectTemplate>* g_DefaultGlobalObjectTemplate = nullptr;
32
33 class CFXJS_PerObjectData {
34 public:
35 explicit CFXJS_PerObjectData(int nObjDefID)
36 : m_ObjDefID(nObjDefID), m_pPrivate(nullptr) {}
37
38 const int m_ObjDefID;
39 void* m_pPrivate;
40 };
41
42 class CFXJS_ObjDefinition {
43 public:
44 static int MaxID(v8::Isolate* pIsolate) {
45 return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray.size();
46 }
47
48 static CFXJS_ObjDefinition* ForID(v8::Isolate* pIsolate, int id) {
49 // Note: GetAt() halts if out-of-range even in release builds.
50 return FXJS_PerIsolateData::Get(pIsolate)->m_ObjectDefnArray[id];
51 }
52
53 CFXJS_ObjDefinition(v8::Isolate* isolate,
54 const wchar_t* sObjName,
55 FXJSOBJTYPE eObjType,
56 FXJS_CONSTRUCTOR pConstructor,
57 FXJS_DESTRUCTOR pDestructor)
58 : m_ObjName(sObjName),
59 m_ObjType(eObjType),
60 m_pConstructor(pConstructor),
61 m_pDestructor(pDestructor),
62 m_pIsolate(isolate) {
63 v8::Isolate::Scope isolate_scope(isolate);
64 v8::HandleScope handle_scope(isolate);
65
66 v8::Local<v8::FunctionTemplate> fun = v8::FunctionTemplate::New(isolate);
67 fun->InstanceTemplate()->SetInternalFieldCount(2);
68 m_FunctionTemplate.Reset(isolate, fun);
69
70 v8::Local<v8::Signature> sig = v8::Signature::New(isolate, fun);
71 m_Signature.Reset(isolate, sig);
72 }
73
74 int AssignID() {
75 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(m_pIsolate);
76 pData->m_ObjectDefnArray.push_back(this);
77 return pData->m_ObjectDefnArray.size() - 1;
78 }
79
80 v8::Local<v8::ObjectTemplate> GetInstanceTemplate() {
81 v8::EscapableHandleScope scope(m_pIsolate);
82 v8::Local<v8::FunctionTemplate> function =
83 m_FunctionTemplate.Get(m_pIsolate);
84 return scope.Escape(function->InstanceTemplate());
85 }
86
87 v8::Local<v8::Signature> GetSignature() {
88 v8::EscapableHandleScope scope(m_pIsolate);
89 return scope.Escape(m_Signature.Get(m_pIsolate));
90 }
91
92 const wchar_t* const m_ObjName;
93 const FXJSOBJTYPE m_ObjType;
94 const FXJS_CONSTRUCTOR m_pConstructor;
95 const FXJS_DESTRUCTOR m_pDestructor;
96
97 v8::Isolate* m_pIsolate;
98 v8::Global<v8::FunctionTemplate> m_FunctionTemplate;
99 v8::Global<v8::Signature> m_Signature;
100 };
101
102 static v8::Local<v8::ObjectTemplate> GetGlobalObjectTemplate(
103 v8::Isolate* pIsolate) {
104 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
105 for (int i = 0; i < maxID; ++i) {
106 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
107 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL)
108 return pObjDef->GetInstanceTemplate();
109 }
110 if (!g_DefaultGlobalObjectTemplate) {
111 g_DefaultGlobalObjectTemplate = new v8::Global<v8::ObjectTemplate>;
112 g_DefaultGlobalObjectTemplate->Reset(pIsolate,
113 v8::ObjectTemplate::New(pIsolate));
114 }
115 return g_DefaultGlobalObjectTemplate->Get(pIsolate);
116 }
117
118 void* FXJS_ArrayBufferAllocator::Allocate(size_t length) {
119 return calloc(1, length);
120 }
121
122 void* FXJS_ArrayBufferAllocator::AllocateUninitialized(size_t length) {
123 return malloc(length);
124 }
125
126 void FXJS_ArrayBufferAllocator::Free(void* data, size_t length) {
127 free(data);
128 }
129
130 void V8TemplateMapTraits::Dispose(v8::Isolate* isolate,
131 v8::Global<v8::Object> value,
132 void* key) {
133 v8::Local<v8::Object> obj = value.Get(isolate);
134 if (obj.IsEmpty())
135 return;
136 int id = FXJS_GetObjDefnID(obj);
137 if (id == -1)
138 return;
139
140 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(isolate, id);
141 if (!pObjDef)
142 return;
143 if (pObjDef->m_pDestructor)
144 pObjDef->m_pDestructor(obj);
145 FXJS_FreePrivate(obj);
146 }
147
148 V8TemplateMapTraits::MapType* V8TemplateMapTraits::MapFromWeakCallbackInfo(
149 const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
150 V8TemplateMap* pMap =
151 (FXJS_PerIsolateData::Get(data.GetIsolate()))->m_pDynamicObjsMap;
152 return pMap ? &pMap->m_map : nullptr;
153 }
154
155 void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate) {
156 if (g_isolate) {
157 ASSERT(g_embedderDataSlot == embedderDataSlot);
158 ASSERT(g_isolate == pIsolate);
159 return;
160 }
161 g_embedderDataSlot = embedderDataSlot;
162 g_isolate = pIsolate;
163 }
164
165 void FXJS_Release() {
166 ASSERT(!g_isolate || g_isolate_ref_count == 0);
167 delete g_DefaultGlobalObjectTemplate;
168 g_DefaultGlobalObjectTemplate = nullptr;
169 g_isolate = nullptr;
170
171 delete g_arrayBufferAllocator;
172 g_arrayBufferAllocator = nullptr;
173 }
174
175 bool FXJS_GetIsolate(v8::Isolate** pResultIsolate) {
176 if (g_isolate) {
177 *pResultIsolate = g_isolate;
178 return false;
179 }
180 // Provide backwards compatibility when no external isolate.
181 if (!g_arrayBufferAllocator)
182 g_arrayBufferAllocator = new FXJS_ArrayBufferAllocator();
183 v8::Isolate::CreateParams params;
184 params.array_buffer_allocator = g_arrayBufferAllocator;
185 *pResultIsolate = v8::Isolate::New(params);
186 return true;
187 }
188
189 size_t FXJS_GlobalIsolateRefCount() {
190 return g_isolate_ref_count;
191 }
192
193 // static
194 void FXJS_PerIsolateData::SetUp(v8::Isolate* pIsolate) {
195 if (!pIsolate->GetData(g_embedderDataSlot))
196 pIsolate->SetData(g_embedderDataSlot, new FXJS_PerIsolateData());
197 }
198
199 // static
200 FXJS_PerIsolateData* FXJS_PerIsolateData::Get(v8::Isolate* pIsolate) {
201 return static_cast<FXJS_PerIsolateData*>(
202 pIsolate->GetData(g_embedderDataSlot));
203 }
204
205 int FXJS_DefineObj(v8::Isolate* pIsolate,
206 const wchar_t* sObjName,
207 FXJSOBJTYPE eObjType,
208 FXJS_CONSTRUCTOR pConstructor,
209 FXJS_DESTRUCTOR pDestructor) {
210 v8::Isolate::Scope isolate_scope(pIsolate);
211 v8::HandleScope handle_scope(pIsolate);
212
213 FXJS_PerIsolateData::SetUp(pIsolate);
214 CFXJS_ObjDefinition* pObjDef = new CFXJS_ObjDefinition(
215 pIsolate, sObjName, eObjType, pConstructor, pDestructor);
216 return pObjDef->AssignID();
217 }
218
219 void FXJS_DefineObjMethod(v8::Isolate* pIsolate,
220 int nObjDefnID,
221 const wchar_t* sMethodName,
222 v8::FunctionCallback pMethodCall) {
223 v8::Isolate::Scope isolate_scope(pIsolate);
224 v8::HandleScope handle_scope(pIsolate);
225 CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode();
226 CFXJS_ObjDefinition* pObjDef =
227 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
228 pObjDef->GetInstanceTemplate()->Set(
229 v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
230 v8::NewStringType::kNormal).ToLocalChecked(),
231 v8::FunctionTemplate::New(pIsolate, pMethodCall, v8::Local<v8::Value>(),
232 pObjDef->GetSignature()),
233 v8::ReadOnly);
234 }
235
236 void FXJS_DefineObjProperty(v8::Isolate* pIsolate,
237 int nObjDefnID,
238 const wchar_t* sPropName,
239 v8::AccessorGetterCallback pPropGet,
240 v8::AccessorSetterCallback pPropPut) {
241 v8::Isolate::Scope isolate_scope(pIsolate);
242 v8::HandleScope handle_scope(pIsolate);
243 CFX_ByteString bsPropertyName = CFX_WideString(sPropName).UTF8Encode();
244 CFXJS_ObjDefinition* pObjDef =
245 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
246 pObjDef->GetInstanceTemplate()->SetAccessor(
247 v8::String::NewFromUtf8(pIsolate, bsPropertyName.c_str(),
248 v8::NewStringType::kNormal).ToLocalChecked(),
249 pPropGet, pPropPut);
250 }
251
252 void FXJS_DefineObjAllProperties(v8::Isolate* pIsolate,
253 int nObjDefnID,
254 v8::NamedPropertyQueryCallback pPropQurey,
255 v8::NamedPropertyGetterCallback pPropGet,
256 v8::NamedPropertySetterCallback pPropPut,
257 v8::NamedPropertyDeleterCallback pPropDel) {
258 v8::Isolate::Scope isolate_scope(pIsolate);
259 v8::HandleScope handle_scope(pIsolate);
260 CFXJS_ObjDefinition* pObjDef =
261 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
262 pObjDef->GetInstanceTemplate()->SetNamedPropertyHandler(pPropGet, pPropPut,
263 pPropQurey, pPropDel);
264 }
265
266 void FXJS_DefineObjConst(v8::Isolate* pIsolate,
267 int nObjDefnID,
268 const wchar_t* sConstName,
269 v8::Local<v8::Value> pDefault) {
270 v8::Isolate::Scope isolate_scope(pIsolate);
271 v8::HandleScope handle_scope(pIsolate);
272 CFX_ByteString bsConstName = CFX_WideString(sConstName).UTF8Encode();
273 CFXJS_ObjDefinition* pObjDef =
274 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
275 pObjDef->GetInstanceTemplate()->Set(pIsolate, bsConstName.c_str(), pDefault);
276 }
277
278 void FXJS_DefineGlobalMethod(v8::Isolate* pIsolate,
279 const wchar_t* sMethodName,
280 v8::FunctionCallback pMethodCall) {
281 v8::Isolate::Scope isolate_scope(pIsolate);
282 v8::HandleScope handle_scope(pIsolate);
283 CFX_ByteString bsMethodName = CFX_WideString(sMethodName).UTF8Encode();
284 GetGlobalObjectTemplate(pIsolate)->Set(
285 v8::String::NewFromUtf8(pIsolate, bsMethodName.c_str(),
286 v8::NewStringType::kNormal).ToLocalChecked(),
287 v8::FunctionTemplate::New(pIsolate, pMethodCall), v8::ReadOnly);
288 }
289
290 void FXJS_DefineGlobalConst(v8::Isolate* pIsolate,
291 const wchar_t* sConstName,
292 v8::FunctionCallback pConstGetter) {
293 v8::Isolate::Scope isolate_scope(pIsolate);
294 v8::HandleScope handle_scope(pIsolate);
295 CFX_ByteString bsConst = CFX_WideString(sConstName).UTF8Encode();
296 GetGlobalObjectTemplate(pIsolate)
297 ->SetAccessorProperty(v8::String::NewFromUtf8(pIsolate, bsConst.c_str(),
298 v8::NewStringType::kNormal)
299 .ToLocalChecked(),
300 v8::FunctionTemplate::New(pIsolate, pConstGetter));
301 }
302
303 void FXJS_InitializeRuntime(
304 v8::Isolate* pIsolate,
305 IJS_Runtime* pIRuntime,
306 v8::Global<v8::Context>* pV8PersistentContext,
307 std::vector<v8::Global<v8::Object>*>* pStaticObjects) {
308 if (pIsolate == g_isolate)
309 ++g_isolate_ref_count;
310
311 v8::Isolate::Scope isolate_scope(pIsolate);
312 #ifdef PDF_ENABLE_XFA
313 v8::Locker locker(pIsolate);
314 #endif // PDF_ENABLE_XFA
315 v8::HandleScope handle_scope(pIsolate);
316 v8::Local<v8::Context> v8Context =
317 v8::Context::New(pIsolate, NULL, GetGlobalObjectTemplate(pIsolate));
318 v8::Context::Scope context_scope(v8Context);
319
320 FXJS_PerIsolateData::SetUp(pIsolate);
321 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
322 if (!pData)
323 return;
324 pData->CreateDynamicObjsMap(pIsolate);
325 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pIRuntime);
326
327 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
328 pStaticObjects->resize(maxID + 1);
329 for (int i = 0; i < maxID; ++i) {
330 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
331 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
332 v8Context->Global()
333 ->GetPrototype()
334 ->ToObject(v8Context)
335 .ToLocalChecked()
336 ->SetAlignedPointerInInternalField(0, new CFXJS_PerObjectData(i));
337
338 if (pObjDef->m_pConstructor)
339 pObjDef->m_pConstructor(pIRuntime, v8Context->Global()
340 ->GetPrototype()
341 ->ToObject(v8Context)
342 .ToLocalChecked());
343 } else if (pObjDef->m_ObjType == FXJSOBJTYPE_STATIC) {
344 CFX_ByteString bs = CFX_WideString(pObjDef->m_ObjName).UTF8Encode();
345 v8::Local<v8::String> m_ObjName =
346 v8::String::NewFromUtf8(pIsolate, bs.c_str(),
347 v8::NewStringType::kNormal,
348 bs.GetLength()).ToLocalChecked();
349
350 v8::Local<v8::Object> obj =
351 FXJS_NewFxDynamicObj(pIsolate, pIRuntime, i, true);
352 v8Context->Global()->Set(v8Context, m_ObjName, obj).FromJust();
353 pStaticObjects->at(i) = new v8::Global<v8::Object>(pIsolate, obj);
354 }
355 }
356 pV8PersistentContext->Reset(pIsolate, v8Context);
357 }
358
359 void FXJS_ReleaseRuntime(v8::Isolate* pIsolate,
360 v8::Global<v8::Context>* pV8PersistentContext,
361 std::vector<v8::Global<v8::Object>*>* pStaticObjects) {
362 v8::Isolate::Scope isolate_scope(pIsolate);
363 #ifdef PDF_ENABLE_XFA
364 v8::Locker locker(pIsolate);
365 #endif // PDF_ENABLE_XFA
366 v8::HandleScope handle_scope(pIsolate);
367 v8::Local<v8::Context> context =
368 v8::Local<v8::Context>::New(pIsolate, *pV8PersistentContext);
369 v8::Context::Scope context_scope(context);
370
371 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
372 if (!pData)
373 return;
374 pData->ReleaseDynamicObjsMap();
375
376 int maxID = CFXJS_ObjDefinition::MaxID(pIsolate);
377 for (int i = 0; i < maxID; ++i) {
378 CFXJS_ObjDefinition* pObjDef = CFXJS_ObjDefinition::ForID(pIsolate, i);
379 v8::Local<v8::Object> pObj;
380 if (pObjDef->m_ObjType == FXJSOBJTYPE_GLOBAL) {
381 pObj =
382 context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
383 } else if (pStaticObjects->at(i) && !pStaticObjects->at(i)->IsEmpty()) {
384 pObj = v8::Local<v8::Object>::New(pIsolate, *pStaticObjects->at(i));
385 delete pStaticObjects->at(i);
386 pStaticObjects->at(i) = nullptr;
387 }
388
389 if (!pObj.IsEmpty()) {
390 if (pObjDef->m_pDestructor)
391 pObjDef->m_pDestructor(pObj);
392 FXJS_FreePrivate(pObj);
393 }
394 }
395
396 if (pIsolate == g_isolate && --g_isolate_ref_count > 0)
397 return;
398
399 for (int i = 0; i < maxID; ++i)
400 delete CFXJS_ObjDefinition::ForID(pIsolate, i);
401
402 pIsolate->SetData(g_embedderDataSlot, nullptr);
403 delete pData;
404 }
405
406 IJS_Runtime* FXJS_GetRuntimeFromIsolate(v8::Isolate* pIsolate) {
407 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
408 return static_cast<IJS_Runtime*>(
409 context->GetAlignedPointerFromEmbedderData(kPerContextDataIndex));
410 }
411
412 #ifdef PDF_ENABLE_XFA
413 void FXJS_SetRuntimeForV8Context(v8::Local<v8::Context> v8Context,
414 IJS_Runtime* pIRuntime) {
415 v8Context->SetAlignedPointerInEmbedderData(kPerContextDataIndex, pIRuntime);
416 }
417 #endif // PDF_ENABLE_XFA
418
419 int FXJS_Execute(v8::Isolate* pIsolate,
420 IJS_Context* pJSContext,
421 const wchar_t* script,
422 FXJSErr* pError) {
423 v8::Isolate::Scope isolate_scope(pIsolate);
424 v8::TryCatch try_catch(pIsolate);
425 CFX_ByteString bsScript = CFX_WideString(script).UTF8Encode();
426 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
427 v8::Local<v8::Script> compiled_script;
428 if (!v8::Script::Compile(
429 context, v8::String::NewFromUtf8(
430 pIsolate, bsScript.c_str(), v8::NewStringType::kNormal,
431 bsScript.GetLength()).ToLocalChecked())
432 .ToLocal(&compiled_script)) {
433 v8::String::Utf8Value error(try_catch.Exception());
434 // TODO(tsepez): return error via pError->message.
435 return -1;
436 }
437
438 v8::Local<v8::Value> result;
439 if (!compiled_script->Run(context).ToLocal(&result)) {
440 v8::String::Utf8Value error(try_catch.Exception());
441 // TODO(tsepez): return error via pError->message.
442 return -1;
443 }
444 return 0;
445 }
446
447 v8::Local<v8::Object> FXJS_NewFxDynamicObj(v8::Isolate* pIsolate,
448 IJS_Runtime* pIRuntime,
449 int nObjDefnID,
450 bool bStatic) {
451 v8::Isolate::Scope isolate_scope(pIsolate);
452 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
453 if (nObjDefnID == -1) {
454 v8::Local<v8::ObjectTemplate> objTempl = v8::ObjectTemplate::New(pIsolate);
455 v8::Local<v8::Object> obj;
456 if (!objTempl->NewInstance(context).ToLocal(&obj))
457 return v8::Local<v8::Object>();
458 return obj;
459 }
460
461 FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate);
462 if (!pData)
463 return v8::Local<v8::Object>();
464
465 if (nObjDefnID < 0 || nObjDefnID >= CFXJS_ObjDefinition::MaxID(pIsolate))
466 return v8::Local<v8::Object>();
467
468 CFXJS_ObjDefinition* pObjDef =
469 CFXJS_ObjDefinition::ForID(pIsolate, nObjDefnID);
470 v8::Local<v8::Object> obj;
471 if (!pObjDef->GetInstanceTemplate()->NewInstance(context).ToLocal(&obj))
472 return v8::Local<v8::Object>();
473
474 CFXJS_PerObjectData* pPerObjData = new CFXJS_PerObjectData(nObjDefnID);
475 obj->SetAlignedPointerInInternalField(0, pPerObjData);
476 if (pObjDef->m_pConstructor)
477 pObjDef->m_pConstructor(pIRuntime, obj);
478
479 if (!bStatic && FXJS_PerIsolateData::Get(pIsolate)->m_pDynamicObjsMap) {
480 FXJS_PerIsolateData::Get(pIsolate)
481 ->m_pDynamicObjsMap->set(pPerObjData, obj);
482 }
483 return obj;
484 }
485
486 v8::Local<v8::Object> FXJS_GetThisObj(v8::Isolate* pIsolate) {
487 v8::Isolate::Scope isolate_scope(pIsolate);
488 if (!FXJS_PerIsolateData::Get(pIsolate))
489 return v8::Local<v8::Object>();
490
491 // Return the global object.
492 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
493 return context->Global()->GetPrototype()->ToObject(context).ToLocalChecked();
494 }
495
496 int FXJS_GetObjDefnID(v8::Local<v8::Object> pObj) {
497 if (pObj.IsEmpty() || !pObj->InternalFieldCount())
498 return -1;
499 CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>(
500 pObj->GetAlignedPointerFromInternalField(0));
501 if (pPerObjectData)
502 return pPerObjectData->m_ObjDefID;
503 return -1;
504 }
505
506 void FXJS_Error(v8::Isolate* pIsolate, const CFX_WideString& message) {
507 // Conversion from pdfium's wchar_t wide-strings to v8's uint16_t
508 // wide-strings isn't handled by v8, so use UTF8 as a common
509 // intermediate format.
510 CFX_ByteString utf8_message = message.UTF8Encode();
511 pIsolate->ThrowException(
512 v8::String::NewFromUtf8(pIsolate, utf8_message.c_str(),
513 v8::NewStringType::kNormal).ToLocalChecked());
514 }
515
516 const wchar_t* FXJS_GetTypeof(v8::Local<v8::Value> pObj) {
517 if (pObj.IsEmpty())
518 return NULL;
519 if (pObj->IsString())
520 return kFXJSValueNameString;
521 if (pObj->IsNumber())
522 return kFXJSValueNameNumber;
523 if (pObj->IsBoolean())
524 return kFXJSValueNameBoolean;
525 if (pObj->IsDate())
526 return kFXJSValueNameDate;
527 if (pObj->IsObject())
528 return kFXJSValueNameObject;
529 if (pObj->IsNull())
530 return kFXJSValueNameNull;
531 if (pObj->IsUndefined())
532 return kFXJSValueNameUndefined;
533 return NULL;
534 }
535
536 void FXJS_SetPrivate(v8::Isolate* pIsolate,
537 v8::Local<v8::Object> pObj,
538 void* p) {
539 if (pObj.IsEmpty() || !pObj->InternalFieldCount())
540 return;
541 CFXJS_PerObjectData* pPerObjectData = static_cast<CFXJS_PerObjectData*>(
542 pObj->GetAlignedPointerFromInternalField(0));
543 if (!pPerObjectData)
544 return;
545 pPerObjectData->m_pPrivate = p;
546 }
547
548 void* FXJS_GetPrivate(v8::Isolate* pIsolate, v8::Local<v8::Object> pObj) {
549 if (pObj.IsEmpty())
550 return nullptr;
551 CFXJS_PerObjectData* pPerObjectData = nullptr;
552 if (pObj->InternalFieldCount()) {
553 pPerObjectData = static_cast<CFXJS_PerObjectData*>(
554 pObj->GetAlignedPointerFromInternalField(0));
555 } else {
556 // It could be a global proxy object.
557 v8::Local<v8::Value> v = pObj->GetPrototype();
558 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
559 if (v->IsObject()) {
560 pPerObjectData = static_cast<CFXJS_PerObjectData*>(
561 v->ToObject(context)
562 .ToLocalChecked()
563 ->GetAlignedPointerFromInternalField(0));
564 }
565 }
566 return pPerObjectData ? pPerObjectData->m_pPrivate : nullptr;
567 }
568
569 void FXJS_FreePrivate(void* pPerObjectData) {
570 delete static_cast<CFXJS_PerObjectData*>(pPerObjectData);
571 }
572
573 void FXJS_FreePrivate(v8::Local<v8::Object> pObj) {
574 if (pObj.IsEmpty() || !pObj->InternalFieldCount())
575 return;
576 FXJS_FreePrivate(pObj->GetAlignedPointerFromInternalField(0));
577 pObj->SetAlignedPointerInInternalField(0, NULL);
578 }
579
580 v8::Local<v8::String> FXJS_WSToJSString(v8::Isolate* pIsolate,
581 const wchar_t* PropertyName,
582 int Len) {
583 CFX_WideString ws = CFX_WideString(PropertyName, Len);
584 CFX_ByteString bs = ws.UTF8Encode();
585 if (!pIsolate)
586 pIsolate = v8::Isolate::GetCurrent();
587 return v8::String::NewFromUtf8(pIsolate, bs.c_str(),
588 v8::NewStringType::kNormal).ToLocalChecked();
589 }
590
591 v8::Local<v8::Value> FXJS_GetObjectElement(v8::Isolate* pIsolate,
592 v8::Local<v8::Object> pObj,
593 const wchar_t* PropertyName) {
594 if (pObj.IsEmpty())
595 return v8::Local<v8::Value>();
596 v8::Local<v8::Value> val;
597 if (!pObj->Get(pIsolate->GetCurrentContext(),
598 FXJS_WSToJSString(pIsolate, PropertyName)).ToLocal(&val))
599 return v8::Local<v8::Value>();
600 return val;
601 }
602
603 v8::Local<v8::Array> FXJS_GetObjectElementNames(v8::Isolate* pIsolate,
604 v8::Local<v8::Object> pObj) {
605 if (pObj.IsEmpty())
606 return v8::Local<v8::Array>();
607 v8::Local<v8::Array> val;
608 if (!pObj->GetPropertyNames(pIsolate->GetCurrentContext()).ToLocal(&val))
609 return v8::Local<v8::Array>();
610 return val;
611 }
612
613 void FXJS_PutObjectString(v8::Isolate* pIsolate,
614 v8::Local<v8::Object> pObj,
615 const wchar_t* PropertyName,
616 const wchar_t* sValue) {
617 if (pObj.IsEmpty())
618 return;
619 pObj->Set(pIsolate->GetCurrentContext(),
620 FXJS_WSToJSString(pIsolate, PropertyName),
621 FXJS_WSToJSString(pIsolate, sValue)).FromJust();
622 }
623
624 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
625 v8::Local<v8::Object> pObj,
626 const wchar_t* PropertyName,
627 int nValue) {
628 if (pObj.IsEmpty())
629 return;
630 pObj->Set(pIsolate->GetCurrentContext(),
631 FXJS_WSToJSString(pIsolate, PropertyName),
632 v8::Int32::New(pIsolate, nValue)).FromJust();
633 }
634
635 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
636 v8::Local<v8::Object> pObj,
637 const wchar_t* PropertyName,
638 float fValue) {
639 if (pObj.IsEmpty())
640 return;
641 pObj->Set(pIsolate->GetCurrentContext(),
642 FXJS_WSToJSString(pIsolate, PropertyName),
643 v8::Number::New(pIsolate, (double)fValue)).FromJust();
644 }
645
646 void FXJS_PutObjectNumber(v8::Isolate* pIsolate,
647 v8::Local<v8::Object> pObj,
648 const wchar_t* PropertyName,
649 double dValue) {
650 if (pObj.IsEmpty())
651 return;
652 pObj->Set(pIsolate->GetCurrentContext(),
653 FXJS_WSToJSString(pIsolate, PropertyName),
654 v8::Number::New(pIsolate, (double)dValue)).FromJust();
655 }
656
657 void FXJS_PutObjectBoolean(v8::Isolate* pIsolate,
658 v8::Local<v8::Object> pObj,
659 const wchar_t* PropertyName,
660 bool bValue) {
661 if (pObj.IsEmpty())
662 return;
663 pObj->Set(pIsolate->GetCurrentContext(),
664 FXJS_WSToJSString(pIsolate, PropertyName),
665 v8::Boolean::New(pIsolate, bValue)).FromJust();
666 }
667
668 void FXJS_PutObjectObject(v8::Isolate* pIsolate,
669 v8::Local<v8::Object> pObj,
670 const wchar_t* PropertyName,
671 v8::Local<v8::Object> pPut) {
672 if (pObj.IsEmpty())
673 return;
674 pObj->Set(pIsolate->GetCurrentContext(),
675 FXJS_WSToJSString(pIsolate, PropertyName), pPut).FromJust();
676 }
677
678 void FXJS_PutObjectNull(v8::Isolate* pIsolate,
679 v8::Local<v8::Object> pObj,
680 const wchar_t* PropertyName) {
681 if (pObj.IsEmpty())
682 return;
683 pObj->Set(pIsolate->GetCurrentContext(),
684 FXJS_WSToJSString(pIsolate, PropertyName),
685 v8::Local<v8::Object>()).FromJust();
686 }
687
688 v8::Local<v8::Array> FXJS_NewArray(v8::Isolate* pIsolate) {
689 return v8::Array::New(pIsolate);
690 }
691
692 unsigned FXJS_PutArrayElement(v8::Isolate* pIsolate,
693 v8::Local<v8::Array> pArray,
694 unsigned index,
695 v8::Local<v8::Value> pValue) {
696 if (pArray.IsEmpty())
697 return 0;
698 if (pArray->Set(pIsolate->GetCurrentContext(), index, pValue).IsNothing())
699 return 0;
700 return 1;
701 }
702
703 v8::Local<v8::Value> FXJS_GetArrayElement(v8::Isolate* pIsolate,
704 v8::Local<v8::Array> pArray,
705 unsigned index) {
706 if (pArray.IsEmpty())
707 return v8::Local<v8::Value>();
708 v8::Local<v8::Value> val;
709 if (!pArray->Get(pIsolate->GetCurrentContext(), index).ToLocal(&val))
710 return v8::Local<v8::Value>();
711 return val;
712 }
713
714 unsigned FXJS_GetArrayLength(v8::Local<v8::Array> pArray) {
715 if (pArray.IsEmpty())
716 return 0;
717 return pArray->Length();
718 }
719
720 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, int number) {
721 return v8::Int32::New(pIsolate, number);
722 }
723
724 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, double number) {
725 return v8::Number::New(pIsolate, number);
726 }
727
728 v8::Local<v8::Value> FXJS_NewNumber(v8::Isolate* pIsolate, float number) {
729 return v8::Number::New(pIsolate, (float)number);
730 }
731
732 v8::Local<v8::Value> FXJS_NewBoolean(v8::Isolate* pIsolate, bool b) {
733 return v8::Boolean::New(pIsolate, b);
734 }
735
736 v8::Local<v8::Value> FXJS_NewObject(v8::Isolate* pIsolate,
737 v8::Local<v8::Object> pObj) {
738 if (pObj.IsEmpty())
739 return v8::Local<v8::Value>();
740 return pObj->Clone();
741 }
742
743 v8::Local<v8::Value> FXJS_NewObject2(v8::Isolate* pIsolate,
744 v8::Local<v8::Array> pObj) {
745 if (pObj.IsEmpty())
746 return v8::Local<v8::Value>();
747 return pObj->Clone();
748 }
749
750 v8::Local<v8::Value> FXJS_NewString(v8::Isolate* pIsolate, const wchar_t* str) {
751 return FXJS_WSToJSString(pIsolate, str);
752 }
753
754 v8::Local<v8::Value> FXJS_NewNull() {
755 return v8::Local<v8::Value>();
756 }
757
758 v8::Local<v8::Value> FXJS_NewDate(v8::Isolate* pIsolate, double d) {
759 return v8::Date::New(pIsolate->GetCurrentContext(), d).ToLocalChecked();
760 }
761
762 int FXJS_ToInt32(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
763 if (pValue.IsEmpty())
764 return 0;
765 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
766 return pValue->ToInt32(context).ToLocalChecked()->Value();
767 }
768
769 bool FXJS_ToBoolean(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
770 if (pValue.IsEmpty())
771 return false;
772 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
773 return pValue->ToBoolean(context).ToLocalChecked()->Value();
774 }
775
776 double FXJS_ToNumber(v8::Isolate* pIsolate, v8::Local<v8::Value> pValue) {
777 if (pValue.IsEmpty())
778 return 0.0;
779 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
780 return pValue->ToNumber(context).ToLocalChecked()->Value();
781 }
782
783 v8::Local<v8::Object> FXJS_ToObject(v8::Isolate* pIsolate,
784 v8::Local<v8::Value> pValue) {
785 if (pValue.IsEmpty())
786 return v8::Local<v8::Object>();
787 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
788 return pValue->ToObject(context).ToLocalChecked();
789 }
790
791 CFX_WideString FXJS_ToString(v8::Isolate* pIsolate,
792 v8::Local<v8::Value> pValue) {
793 if (pValue.IsEmpty())
794 return L"";
795 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
796 v8::String::Utf8Value s(pValue->ToString(context).ToLocalChecked());
797 return CFX_WideString::FromUTF8(*s, s.length());
798 }
799
800 v8::Local<v8::Array> FXJS_ToArray(v8::Isolate* pIsolate,
801 v8::Local<v8::Value> pValue) {
802 if (pValue.IsEmpty())
803 return v8::Local<v8::Array>();
804 v8::Local<v8::Context> context = pIsolate->GetCurrentContext();
805 return v8::Local<v8::Array>::Cast(pValue->ToObject(context).ToLocalChecked());
806 }
807
808 void FXJS_ValueCopy(v8::Local<v8::Value>& pTo, v8::Local<v8::Value> pFrom) {
809 pTo = pFrom;
810 }
811
812
OLDNEW
« no previous file with comments | « fpdfsdk/src/javascript/util.cpp ('k') | fpdfsdk/src/jsapi/fxjs_v8_embeddertest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698