1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255
|
// Copyright 2014 PDFium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
// Original code copyright 2014 Foxit Software Inc. http://www.foxitsoftware.com
// FXJS_V8 is a layer that makes it easier to define native objects in V8, but
// has no knowledge of PDF-specific native objects. It could in theory be used
// to implement other sets of native objects.
// PDFium code should include this file rather than including V8 headers
// directly.
#ifndef FXJS_FXJS_V8_H_
#define FXJS_FXJS_V8_H_
#include <v8-util.h>
#include <v8.h>
#include <map>
#include <memory>
#include <vector>
#include "core/fxcrt/fx_string.h"
#ifdef PDF_ENABLE_XFA
// Header for CFXJSE_RuntimeData. FXJS_V8 doesn't interpret this class,
// it is just passed along to XFA.
#include "fxjs/cfxjse_runtimedata.h"
#endif // PDF_ENABLE_XFA
class CFXJS_Engine;
class CFXJS_ObjDefinition;
// FXJS_V8 places no restrictions on this class; it merely passes it
// on to caller-provided methods.
class IJS_Context; // A description of the event that caused JS execution.
enum FXJSOBJTYPE {
FXJSOBJTYPE_DYNAMIC = 0, // Created by native method and returned to JS.
FXJSOBJTYPE_STATIC, // Created by init and hung off of global object.
FXJSOBJTYPE_GLOBAL, // The global object itself (may only appear once).
};
struct FXJSErr {
const wchar_t* message;
const wchar_t* srcline;
unsigned linnum;
};
// Global weak map to save dynamic objects.
class V8TemplateMapTraits : public v8::StdMapTraits<void*, v8::Object> {
public:
typedef v8::GlobalValueMap<void*, v8::Object, V8TemplateMapTraits> MapType;
typedef void WeakCallbackDataType;
static WeakCallbackDataType* WeakCallbackParameter(
MapType* map,
void* key,
const v8::Local<v8::Object>& value) {
return key;
}
static MapType* MapFromWeakCallbackInfo(
const v8::WeakCallbackInfo<WeakCallbackDataType>&);
static void* KeyFromWeakCallbackInfo(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {
return data.GetParameter();
}
static const v8::PersistentContainerCallbackType kCallbackType =
v8::kWeakWithInternalFields;
static void DisposeWeak(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void OnWeakCallback(
const v8::WeakCallbackInfo<WeakCallbackDataType>& data) {}
static void Dispose(v8::Isolate* isolate,
v8::Global<v8::Object> value,
void* key);
static void DisposeCallbackData(WeakCallbackDataType* callbackData) {}
};
class V8TemplateMap {
public:
typedef v8::GlobalValueMap<void*, v8::Object, V8TemplateMapTraits> MapType;
explicit V8TemplateMap(v8::Isolate* isolate);
~V8TemplateMap();
void set(void* key, v8::Local<v8::Object> handle);
friend class V8TemplateMapTraits;
private:
MapType m_map;
};
class FXJS_PerIsolateData {
public:
~FXJS_PerIsolateData();
static void SetUp(v8::Isolate* pIsolate);
static FXJS_PerIsolateData* Get(v8::Isolate* pIsolate);
std::vector<std::unique_ptr<CFXJS_ObjDefinition>> m_ObjectDefnArray;
#ifdef PDF_ENABLE_XFA
std::unique_ptr<CFXJSE_RuntimeData> m_pFXJSERuntimeData;
#endif // PDF_ENABLE_XFA
std::unique_ptr<V8TemplateMap> m_pDynamicObjsMap;
protected:
explicit FXJS_PerIsolateData(v8::Isolate* pIsolate);
};
class FXJS_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator {
void* Allocate(size_t length) override;
void* AllocateUninitialized(size_t length) override;
void Free(void* data, size_t length) override;
};
void FXJS_Initialize(unsigned int embedderDataSlot, v8::Isolate* pIsolate);
void FXJS_Release();
// Gets the global isolate set by FXJS_Initialize(), or makes a new one each
// time if there is no such isolate. Returns true if a new isolate had to be
// created.
bool FXJS_GetIsolate(v8::Isolate** pResultIsolate);
// Get the global isolate's ref count.
size_t FXJS_GlobalIsolateRefCount();
class CFXJS_Engine {
public:
explicit CFXJS_Engine(v8::Isolate* pIsolate);
~CFXJS_Engine();
using Constructor = void (*)(CFXJS_Engine* pEngine,
v8::Local<v8::Object> obj);
using Destructor = void (*)(CFXJS_Engine* pEngine, v8::Local<v8::Object> obj);
static CFXJS_Engine* CurrentEngineFromIsolate(v8::Isolate* pIsolate);
static int GetObjDefnID(v8::Local<v8::Object> pObj);
v8::Isolate* GetIsolate() const { return m_isolate; }
// Always returns a valid, newly-created objDefnID.
int DefineObj(const wchar_t* sObjName,
FXJSOBJTYPE eObjType,
Constructor pConstructor,
Destructor pDestructor);
void DefineObjMethod(int nObjDefnID,
const wchar_t* sMethodName,
v8::FunctionCallback pMethodCall);
void DefineObjProperty(int nObjDefnID,
const wchar_t* sPropName,
v8::AccessorGetterCallback pPropGet,
v8::AccessorSetterCallback pPropPut);
void DefineObjAllProperties(int nObjDefnID,
v8::NamedPropertyQueryCallback pPropQurey,
v8::NamedPropertyGetterCallback pPropGet,
v8::NamedPropertySetterCallback pPropPut,
v8::NamedPropertyDeleterCallback pPropDel);
void DefineObjConst(int nObjDefnID,
const wchar_t* sConstName,
v8::Local<v8::Value> pDefault);
void DefineGlobalMethod(const wchar_t* sMethodName,
v8::FunctionCallback pMethodCall);
void DefineGlobalConst(const wchar_t* sConstName,
v8::FunctionCallback pConstGetter);
// Called after FXJS_Define* calls made.
void InitializeEngine();
void ReleaseEngine();
// Called after FXJS_InitializeEngine call made.
int Execute(const CFX_WideString& script, FXJSErr* perror);
v8::Local<v8::Context> NewLocalContext();
v8::Local<v8::Context> GetPersistentContext();
v8::Local<v8::Value> NewNull();
v8::Local<v8::Array> NewArray();
v8::Local<v8::Value> NewNumber(int number);
v8::Local<v8::Value> NewNumber(double number);
v8::Local<v8::Value> NewNumber(float number);
v8::Local<v8::Value> NewBoolean(bool b);
v8::Local<v8::Value> NewString(const wchar_t* str);
v8::Local<v8::Date> NewDate(double d);
v8::Local<v8::Object> NewFxDynamicObj(int nObjDefnID, bool bStatic = false);
v8::Local<v8::Object> GetThisObj();
int ToInt32(v8::Local<v8::Value> pValue);
bool ToBoolean(v8::Local<v8::Value> pValue);
double ToNumber(v8::Local<v8::Value> pValue);
CFX_WideString ToString(v8::Local<v8::Value> pValue);
v8::Local<v8::Object> ToObject(v8::Local<v8::Value> pValue);
v8::Local<v8::Array> ToArray(v8::Local<v8::Value> pValue);
unsigned GetArrayLength(v8::Local<v8::Array> pArray);
v8::Local<v8::Value> GetArrayElement(v8::Local<v8::Array> pArray,
unsigned index);
unsigned PutArrayElement(v8::Local<v8::Array> pArray,
unsigned index,
v8::Local<v8::Value> pValue);
std::vector<CFX_WideString> GetObjectPropertyNames(
v8::Local<v8::Object> pObj);
v8::Local<v8::Value> GetObjectProperty(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName);
void PutObjectString(v8::Local<v8::Object> pObj,
const CFX_WideString& wsPropertyName,
const CFX_WideString& wsValue);
void PutObjectNumber(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName,
int nValue);
void PutObjectNumber(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName,
float fValue);
void PutObjectNumber(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName,
double dValue);
void PutObjectBoolean(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName,
bool bValue);
void PutObjectObject(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName,
v8::Local<v8::Object> pPut);
void PutObjectNull(v8::Local<v8::Object> pObj,
const CFX_WideString& PropertyName);
// Native object binding.
void SetObjectPrivate(v8::Local<v8::Object> pObj, void* p);
void* GetObjectPrivate(v8::Local<v8::Object> pObj);
static void FreeObjectPrivate(void* p);
static void FreeObjectPrivate(v8::Local<v8::Object> pObj);
void SetConstArray(const CFX_WideString& name, v8::Local<v8::Array> array);
v8::Local<v8::Array> GetConstArray(const CFX_WideString& name);
v8::Local<v8::String> WSToJSString(const CFX_WideString& wsPropertyName);
void Error(const CFX_WideString& message);
protected:
CFXJS_Engine();
void SetIsolate(v8::Isolate* pIsolate) { m_isolate = pIsolate; }
private:
v8::Isolate* m_isolate;
v8::Global<v8::Context> m_V8PersistentContext;
std::vector<v8::Global<v8::Object>*> m_StaticObjects;
std::map<CFX_WideString, v8::Global<v8::Array>> m_ConstArrays;
};
#endif // FXJS_FXJS_V8_H_
|