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 #ifndef FXJSE_VALUE_H_
8 #define FXJSE_VALUE_H_
9 #include "scope_inline.h"
10 class CFXJSE_Value {
11  public:
CFXJSE_Value(v8::Isolate * pIsolate)12   CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {}
13 
14  protected:
15   CFXJSE_Value();
16   CFXJSE_Value(const CFXJSE_Value&);
17   CFXJSE_Value& operator=(const CFXJSE_Value&);
18 
19  public:
IsUndefined()20   V8_INLINE FX_BOOL IsUndefined() const {
21     if (m_hValue.IsEmpty()) {
22       return FALSE;
23     }
24     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
25     v8::Local<v8::Value> hValue =
26         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
27     return hValue->IsUndefined();
28   }
IsNull()29   V8_INLINE FX_BOOL IsNull() const {
30     if (m_hValue.IsEmpty()) {
31       return FALSE;
32     }
33     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
34     v8::Local<v8::Value> hValue =
35         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
36     return hValue->IsNull();
37   }
IsBoolean()38   V8_INLINE FX_BOOL IsBoolean() const {
39     if (m_hValue.IsEmpty()) {
40       return FALSE;
41     }
42     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
43     v8::Local<v8::Value> hValue =
44         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
45     return hValue->IsBoolean();
46   }
IsString()47   V8_INLINE FX_BOOL IsString() const {
48     if (m_hValue.IsEmpty()) {
49       return FALSE;
50     }
51     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
52     v8::Local<v8::Value> hValue =
53         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
54     return hValue->IsString();
55   }
IsNumber()56   V8_INLINE FX_BOOL IsNumber() const {
57     if (m_hValue.IsEmpty()) {
58       return FALSE;
59     }
60     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
61     v8::Local<v8::Value> hValue =
62         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
63     return hValue->IsNumber();
64   }
IsInteger()65   V8_INLINE FX_BOOL IsInteger() const {
66     if (m_hValue.IsEmpty()) {
67       return FALSE;
68     }
69     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
70     v8::Local<v8::Value> hValue =
71         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
72     return hValue->IsInt32();
73   }
IsObject()74   V8_INLINE FX_BOOL IsObject() const {
75     if (m_hValue.IsEmpty()) {
76       return FALSE;
77     }
78     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
79     v8::Local<v8::Value> hValue =
80         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
81     return hValue->IsObject();
82   }
IsArray()83   V8_INLINE FX_BOOL IsArray() const {
84     if (m_hValue.IsEmpty()) {
85       return FALSE;
86     }
87     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
88     v8::Local<v8::Value> hValue =
89         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
90     return hValue->IsArray();
91   }
IsFunction()92   V8_INLINE FX_BOOL IsFunction() const {
93     if (m_hValue.IsEmpty()) {
94       return FALSE;
95     }
96     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
97     v8::Local<v8::Value> hValue =
98         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
99     return hValue->IsFunction();
100   }
IsDate()101   V8_INLINE FX_BOOL IsDate() const {
102     if (m_hValue.IsEmpty()) {
103       return FALSE;
104     }
105     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
106     v8::Local<v8::Value> hValue =
107         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
108     return hValue->IsDate();
109   }
110 
111  public:
ToBoolean()112   V8_INLINE FX_BOOL ToBoolean() const {
113     ASSERT(!m_hValue.IsEmpty());
114     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
115     v8::Local<v8::Value> hValue =
116         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
117     return static_cast<FX_BOOL>(hValue->BooleanValue());
118   }
ToFloat()119   V8_INLINE FX_FLOAT ToFloat() const {
120     ASSERT(!m_hValue.IsEmpty());
121     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
122     v8::Local<v8::Value> hValue =
123         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
124     return static_cast<FX_FLOAT>(hValue->NumberValue());
125   }
ToDouble()126   V8_INLINE FXJSE_DOUBLE ToDouble() const {
127     ASSERT(!m_hValue.IsEmpty());
128     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
129     v8::Local<v8::Value> hValue =
130         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
131     return static_cast<FXJSE_DOUBLE>(hValue->NumberValue());
132   }
ToInteger()133   V8_INLINE int32_t ToInteger() const {
134     ASSERT(!m_hValue.IsEmpty());
135     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
136     v8::Local<v8::Value> hValue =
137         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
138     return static_cast<int32_t>(hValue->NumberValue());
139   }
ToString(CFX_ByteString & szStrOutput)140   V8_INLINE void ToString(CFX_ByteString& szStrOutput) const {
141     ASSERT(!m_hValue.IsEmpty());
142     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
143     v8::Local<v8::Value> hValue =
144         v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
145     v8::Local<v8::String> hString = hValue->ToString();
146     v8::String::Utf8Value hStringVal(hString);
147     szStrOutput = *hStringVal;
148   }
149   void* ToObject(CFXJSE_Class* lpClass) const;
150 
151  public:
SetUndefined()152   V8_INLINE void SetUndefined() {
153     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
154     v8::Local<v8::Value> hValue = v8::Undefined(m_pIsolate);
155     m_hValue.Reset(m_pIsolate, hValue);
156   }
SetNull()157   V8_INLINE void SetNull() {
158     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
159     v8::Local<v8::Value> hValue = v8::Null(m_pIsolate);
160     m_hValue.Reset(m_pIsolate, hValue);
161   }
SetBoolean(FX_BOOL bBoolean)162   V8_INLINE void SetBoolean(FX_BOOL bBoolean) {
163     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
164     v8::Local<v8::Value> hValue =
165         v8::Boolean::New(m_pIsolate, bBoolean != FALSE);
166     m_hValue.Reset(m_pIsolate, hValue);
167   }
SetInteger(int32_t nInteger)168   V8_INLINE void SetInteger(int32_t nInteger) {
169     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
170     v8::Local<v8::Value> hValue = v8::Integer::New(m_pIsolate, nInteger);
171     m_hValue.Reset(m_pIsolate, hValue);
172   }
SetDouble(FXJSE_DOUBLE dDouble)173   V8_INLINE void SetDouble(FXJSE_DOUBLE dDouble) {
174     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
175     v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, dDouble);
176     m_hValue.Reset(m_pIsolate, hValue);
177   }
SetString(const CFX_ByteStringC & szString)178   V8_INLINE void SetString(const CFX_ByteStringC& szString) {
179     CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
180     v8::Local<v8::Value> hValue = v8::String::NewFromUtf8(
181         m_pIsolate, reinterpret_cast<const char*>(szString.GetPtr()),
182         v8::String::kNormalString, szString.GetLength());
183     m_hValue.Reset(m_pIsolate, hValue);
184   }
185   V8_INLINE void SetFloat(FX_FLOAT fFloat);
SetJSObject()186   V8_INLINE void SetJSObject() {
187     CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
188     v8::Local<v8::Value> hValue = v8::Object::New(m_pIsolate);
189     m_hValue.Reset(m_pIsolate, hValue);
190   }
191   void SetHostObject(void* lpObject, CFXJSE_Class* lpClass);
192   void SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues);
193   void SetDate(FXJSE_DOUBLE dDouble);
194 
195  public:
196   FX_BOOL GetObjectProperty(const CFX_ByteStringC& szPropName,
197                             CFXJSE_Value* lpPropValue);
198   FX_BOOL SetObjectProperty(const CFX_ByteStringC& szPropName,
199                             CFXJSE_Value* lpPropValue);
200   FX_BOOL GetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue);
201   FX_BOOL SetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue);
202   FX_BOOL DeleteObjectProperty(const CFX_ByteStringC& szPropName);
203   FX_BOOL HasObjectOwnProperty(const CFX_ByteStringC& szPropName,
204                                FX_BOOL bUseTypeGetter);
205   FX_BOOL SetObjectOwnProperty(const CFX_ByteStringC& szPropName,
206                                CFXJSE_Value* lpPropValue);
207   FX_BOOL SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis);
208   FX_BOOL Call(CFXJSE_Value* lpReceiver,
209                CFXJSE_Value* lpRetValue,
210                uint32_t nArgCount,
211                FXJSE_HVALUE* lpArgs);
212 
213  public:
GetIsolate()214   V8_INLINE v8::Isolate* GetIsolate() const { return m_pIsolate; }
DirectGetValue()215   V8_INLINE const v8::Global<v8::Value>& DirectGetValue() const {
216     return m_hValue;
217   }
ForceSetValue(v8::Local<v8::Value> hValue)218   V8_INLINE void ForceSetValue(v8::Local<v8::Value> hValue) {
219     m_hValue.Reset(m_pIsolate, hValue);
220   }
Assign(const CFXJSE_Value * lpValue)221   V8_INLINE void Assign(const CFXJSE_Value* lpValue) {
222     if (lpValue) {
223       m_hValue.Reset(m_pIsolate, lpValue->m_hValue);
224     } else {
225       m_hValue.Reset();
226     }
227   }
228 
229  public:
230   static CFXJSE_Value* Create(v8::Isolate* pIsolate);
231 
232  protected:
233   v8::Isolate* m_pIsolate;
234   v8::Global<v8::Value> m_hValue;
235   friend class CFXJSE_Context;
236   friend class CFXJSE_Class;
237 };
238 #endif
239