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 "xfa/src/foxitlib.h"
8 #include "fxv8.h"
9 #include "value.h"
10 #include "class.h"
11 #include <math.h>
12 #include "util_inline.h"
FXJSE_Value_IsUndefined(FXJSE_HVALUE hValue)13 FX_BOOL FXJSE_Value_IsUndefined(FXJSE_HVALUE hValue) {
14 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
15 return lpValue && lpValue->IsUndefined();
16 }
FXJSE_Value_IsNull(FXJSE_HVALUE hValue)17 FX_BOOL FXJSE_Value_IsNull(FXJSE_HVALUE hValue) {
18 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
19 return lpValue && lpValue->IsNull();
20 }
FXJSE_Value_IsBoolean(FXJSE_HVALUE hValue)21 FX_BOOL FXJSE_Value_IsBoolean(FXJSE_HVALUE hValue) {
22 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
23 return lpValue && lpValue->IsBoolean();
24 }
FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue)25 FX_BOOL FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue) {
26 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
27 return lpValue && lpValue->IsString();
28 }
FXJSE_Value_IsNumber(FXJSE_HVALUE hValue)29 FX_BOOL FXJSE_Value_IsNumber(FXJSE_HVALUE hValue) {
30 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
31 return lpValue && lpValue->IsNumber();
32 }
FXJSE_Value_IsInteger(FXJSE_HVALUE hValue)33 FX_BOOL FXJSE_Value_IsInteger(FXJSE_HVALUE hValue) {
34 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
35 return lpValue && lpValue->IsInteger();
36 }
FXJSE_Value_IsObject(FXJSE_HVALUE hValue)37 FX_BOOL FXJSE_Value_IsObject(FXJSE_HVALUE hValue) {
38 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
39 return lpValue && lpValue->IsObject();
40 }
FXJSE_Value_IsArray(FXJSE_HVALUE hValue)41 FX_BOOL FXJSE_Value_IsArray(FXJSE_HVALUE hValue) {
42 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
43 return lpValue && lpValue->IsArray();
44 }
FXJSE_Value_IsFunction(FXJSE_HVALUE hValue)45 FX_BOOL FXJSE_Value_IsFunction(FXJSE_HVALUE hValue) {
46 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
47 return lpValue && lpValue->IsFunction();
48 }
FXJSE_Value_IsDate(FXJSE_HVALUE hValue)49 FX_BOOL FXJSE_Value_IsDate(FXJSE_HVALUE hValue) {
50 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
51 return lpValue && lpValue->IsDate();
52 }
FXJSE_Value_ToBoolean(FXJSE_HVALUE hValue)53 FX_BOOL FXJSE_Value_ToBoolean(FXJSE_HVALUE hValue) {
54 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
55 ASSERT(lpValue);
56 return lpValue->ToBoolean();
57 }
FXJSE_Value_ToFloat(FXJSE_HVALUE hValue)58 FX_FLOAT FXJSE_Value_ToFloat(FXJSE_HVALUE hValue) {
59 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
60 ASSERT(lpValue);
61 return lpValue->ToFloat();
62 }
FXJSE_Value_ToDouble(FXJSE_HVALUE hValue)63 FXJSE_DOUBLE FXJSE_Value_ToDouble(FXJSE_HVALUE hValue) {
64 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
65 ASSERT(lpValue);
66 return lpValue->ToDouble();
67 }
FXJSE_Value_ToUTF8String(FXJSE_HVALUE hValue,CFX_ByteString & szStrOutput)68 void FXJSE_Value_ToUTF8String(FXJSE_HVALUE hValue,
69 CFX_ByteString& szStrOutput) {
70 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
71 ASSERT(lpValue);
72 return lpValue->ToString(szStrOutput);
73 }
FXJSE_Value_ToInteger(FXJSE_HVALUE hValue)74 int32_t FXJSE_Value_ToInteger(FXJSE_HVALUE hValue) {
75 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
76 ASSERT(lpValue);
77 return lpValue->ToInteger();
78 }
FXJSE_Value_ToObject(FXJSE_HVALUE hValue,FXJSE_HCLASS hClass)79 void* FXJSE_Value_ToObject(FXJSE_HVALUE hValue, FXJSE_HCLASS hClass) {
80 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
81 CFXJSE_Class* lpClass = reinterpret_cast<CFXJSE_Class*>(hClass);
82 ASSERT(lpValue);
83 return lpValue->ToObject(lpClass);
84 }
FXJSE_Value_SetUndefined(FXJSE_HVALUE hValue)85 void FXJSE_Value_SetUndefined(FXJSE_HVALUE hValue) {
86 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
87 ASSERT(lpValue);
88 return lpValue->SetUndefined();
89 }
FXJSE_Value_SetNull(FXJSE_HVALUE hValue)90 void FXJSE_Value_SetNull(FXJSE_HVALUE hValue) {
91 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
92 ASSERT(lpValue);
93 return lpValue->SetNull();
94 }
FXJSE_Value_SetBoolean(FXJSE_HVALUE hValue,FX_BOOL bBoolean)95 void FXJSE_Value_SetBoolean(FXJSE_HVALUE hValue, FX_BOOL bBoolean) {
96 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
97 ASSERT(lpValue);
98 return lpValue->SetBoolean(bBoolean);
99 }
FXJSE_Value_SetUTF8String(FXJSE_HVALUE hValue,const CFX_ByteStringC & szString)100 void FXJSE_Value_SetUTF8String(FXJSE_HVALUE hValue,
101 const CFX_ByteStringC& szString) {
102 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
103 ASSERT(lpValue);
104 return lpValue->SetString(szString);
105 }
FXJSE_Value_SetInteger(FXJSE_HVALUE hValue,int32_t nInteger)106 void FXJSE_Value_SetInteger(FXJSE_HVALUE hValue, int32_t nInteger) {
107 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
108 ASSERT(lpValue);
109 return lpValue->SetInteger(nInteger);
110 }
FXJSE_Value_SetFloat(FXJSE_HVALUE hValue,FX_FLOAT fFloat)111 void FXJSE_Value_SetFloat(FXJSE_HVALUE hValue, FX_FLOAT fFloat) {
112 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
113 ASSERT(lpValue);
114 return lpValue->SetFloat(fFloat);
115 }
FXJSE_Value_SetDouble(FXJSE_HVALUE hValue,FXJSE_DOUBLE dDouble)116 void FXJSE_Value_SetDouble(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) {
117 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
118 ASSERT(lpValue);
119 return lpValue->SetDouble(dDouble);
120 }
FXJSE_Value_SetObject(FXJSE_HVALUE hValue,void * lpObject,FXJSE_HCLASS hClass)121 void FXJSE_Value_SetObject(FXJSE_HVALUE hValue,
122 void* lpObject,
123 FXJSE_HCLASS hClass) {
124 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
125 CFXJSE_Class* lpClass = reinterpret_cast<CFXJSE_Class*>(hClass);
126 if (lpClass == NULL) {
127 ASSERT(lpObject == NULL);
128 lpValue->SetJSObject();
129 } else if (lpClass != NULL) {
130 lpValue->SetHostObject(lpObject, lpClass);
131 }
132 }
FXJSE_Value_SetArray(FXJSE_HVALUE hValue,uint32_t uValueCount,FXJSE_HVALUE * rgValues)133 void FXJSE_Value_SetArray(FXJSE_HVALUE hValue,
134 uint32_t uValueCount,
135 FXJSE_HVALUE* rgValues) {
136 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
137 return lpValue->SetArray(uValueCount,
138 reinterpret_cast<CFXJSE_Value**>(rgValues));
139 }
FXJSE_Value_SetDate(FXJSE_HVALUE hValue,FXJSE_DOUBLE dDouble)140 void FXJSE_Value_SetDate(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) {
141 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
142 return lpValue->SetDate(dDouble);
143 }
FXJSE_Value_Set(FXJSE_HVALUE hValue,FXJSE_HVALUE hOriginalValue)144 void FXJSE_Value_Set(FXJSE_HVALUE hValue, FXJSE_HVALUE hOriginalValue) {
145 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
146 CFXJSE_Value* lpOriginalValue =
147 reinterpret_cast<CFXJSE_Value*>(hOriginalValue);
148 ASSERT(lpValue && lpOriginalValue);
149 return lpValue->Assign(lpOriginalValue);
150 }
FXJSE_Value_GetObjectProp(FXJSE_HVALUE hValue,const CFX_ByteStringC & szPropName,FXJSE_HVALUE hPropValue)151 FX_BOOL FXJSE_Value_GetObjectProp(FXJSE_HVALUE hValue,
152 const CFX_ByteStringC& szPropName,
153 FXJSE_HVALUE hPropValue) {
154 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
155 CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
156 ASSERT(lpValue && lpPropValue);
157 return lpValue->GetObjectProperty(szPropName, lpPropValue);
158 }
FXJSE_Value_SetObjectProp(FXJSE_HVALUE hValue,const CFX_ByteStringC & szPropName,FXJSE_HVALUE hPropValue)159 FX_BOOL FXJSE_Value_SetObjectProp(FXJSE_HVALUE hValue,
160 const CFX_ByteStringC& szPropName,
161 FXJSE_HVALUE hPropValue) {
162 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
163 CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
164 ASSERT(lpValue && lpPropValue);
165 return lpValue->SetObjectProperty(szPropName, lpPropValue);
166 }
FXJSE_Value_GetObjectPropByIdx(FXJSE_HVALUE hValue,uint32_t uPropIdx,FXJSE_HVALUE hPropValue)167 FX_BOOL FXJSE_Value_GetObjectPropByIdx(FXJSE_HVALUE hValue,
168 uint32_t uPropIdx,
169 FXJSE_HVALUE hPropValue) {
170 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
171 CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
172 ASSERT(lpValue && lpPropValue);
173 return lpValue->GetObjectProperty(uPropIdx, lpPropValue);
174 }
FXJSE_Value_SetObjectPropByIdx(FXJSE_HVALUE hValue,uint32_t uPropIdx,FXJSE_HVALUE hPropValue)175 FX_BOOL FXJSE_Value_SetObjectPropByIdx(FXJSE_HVALUE hValue,
176 uint32_t uPropIdx,
177 FXJSE_HVALUE hPropValue) {
178 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
179 CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
180 ASSERT(lpValue && lpPropValue);
181 return lpValue->SetObjectProperty(uPropIdx, lpPropValue);
182 }
FXJSE_Value_DeleteObjectProp(FXJSE_HVALUE hValue,const CFX_ByteStringC & szPropName)183 FX_BOOL FXJSE_Value_DeleteObjectProp(FXJSE_HVALUE hValue,
184 const CFX_ByteStringC& szPropName) {
185 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
186 ASSERT(lpValue);
187 return lpValue->DeleteObjectProperty(szPropName);
188 }
FXJSE_Value_ObjectHasOwnProp(FXJSE_HVALUE hValue,const CFX_ByteStringC & szPropName,FX_BOOL bUseTypeGetter)189 FX_BOOL FXJSE_Value_ObjectHasOwnProp(FXJSE_HVALUE hValue,
190 const CFX_ByteStringC& szPropName,
191 FX_BOOL bUseTypeGetter) {
192 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
193 ASSERT(lpValue);
194 return lpValue->HasObjectOwnProperty(szPropName, bUseTypeGetter);
195 }
FXJSE_Value_SetObjectOwnProp(FXJSE_HVALUE hValue,const CFX_ByteStringC & szPropName,FXJSE_HVALUE hPropValue)196 FX_BOOL FXJSE_Value_SetObjectOwnProp(FXJSE_HVALUE hValue,
197 const CFX_ByteStringC& szPropName,
198 FXJSE_HVALUE hPropValue) {
199 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
200 CFXJSE_Value* lpPropValue = reinterpret_cast<CFXJSE_Value*>(hPropValue);
201 ASSERT(lpValue && lpPropValue);
202 return lpValue->SetObjectOwnProperty(szPropName, lpPropValue);
203 }
FXJSE_Value_SetFunctionBind(FXJSE_HVALUE hValue,FXJSE_HVALUE hOldFunction,FXJSE_HVALUE hNewThis)204 FX_BOOL FXJSE_Value_SetFunctionBind(FXJSE_HVALUE hValue,
205 FXJSE_HVALUE hOldFunction,
206 FXJSE_HVALUE hNewThis) {
207 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
208 CFXJSE_Value* lpOldFunction = reinterpret_cast<CFXJSE_Value*>(hOldFunction);
209 CFXJSE_Value* lpNewThis = reinterpret_cast<CFXJSE_Value*>(hNewThis);
210 ASSERT(lpValue && lpOldFunction && lpNewThis);
211 return lpValue->SetFunctionBind(lpOldFunction, lpNewThis);
212 }
FXJSE_Value_CallFunction(FXJSE_HVALUE hFunction,FXJSE_HVALUE hThis,FXJSE_HVALUE hRetValue,uint32_t nArgCount,FXJSE_HVALUE * lpArgs)213 FX_BOOL FXJSE_Value_CallFunction(FXJSE_HVALUE hFunction,
214 FXJSE_HVALUE hThis,
215 FXJSE_HVALUE hRetValue,
216 uint32_t nArgCount,
217 FXJSE_HVALUE* lpArgs) {
218 CFXJSE_Value* lpFunction = reinterpret_cast<CFXJSE_Value*>(hFunction);
219 CFXJSE_Value* lpThis = reinterpret_cast<CFXJSE_Value*>(hThis);
220 CFXJSE_Value* lpRetValue = reinterpret_cast<CFXJSE_Value*>(hRetValue);
221 ASSERT(lpFunction);
222 return lpFunction->Call(lpThis, lpRetValue, nArgCount, lpArgs);
223 }
FXJSE_Value_Create(FXJSE_HRUNTIME hRuntime)224 FXJSE_HVALUE FXJSE_Value_Create(FXJSE_HRUNTIME hRuntime) {
225 CFXJSE_Value* lpValue =
226 CFXJSE_Value::Create(reinterpret_cast<v8::Isolate*>(hRuntime));
227 ASSERT(lpValue);
228 return reinterpret_cast<FXJSE_HVALUE>(lpValue);
229 }
FXJSE_Value_Release(FXJSE_HVALUE hValue)230 void FXJSE_Value_Release(FXJSE_HVALUE hValue) {
231 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
232 if (lpValue) {
233 delete lpValue;
234 }
235 }
FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue)236 FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue) {
237 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue);
238 ASSERT(lpValue);
239 return reinterpret_cast<FXJSE_HRUNTIME>(lpValue->GetIsolate());
240 }
FXJSE_ThrowMessage(const CFX_ByteStringC & utf8Name,const CFX_ByteStringC & utf8Message)241 void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Name,
242 const CFX_ByteStringC& utf8Message) {
243 v8::Isolate* pIsolate = v8::Isolate::GetCurrent();
244 ASSERT(pIsolate);
245 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate);
246 v8::Local<v8::String> hMessage = v8::String::NewFromUtf8(
247 pIsolate, utf8Message.GetCStr(), v8::String::kNormalString,
248 utf8Message.GetLength());
249 v8::Local<v8::Value> hError;
250 if (utf8Name == "RangeError") {
251 hError = v8::Exception::RangeError(hMessage);
252 } else if (utf8Name == "ReferenceError") {
253 hError = v8::Exception::ReferenceError(hMessage);
254 } else if (utf8Name == "SyntaxError") {
255 hError = v8::Exception::SyntaxError(hMessage);
256 } else if (utf8Name == "TypeError") {
257 hError = v8::Exception::TypeError(hMessage);
258 } else {
259 hError = v8::Exception::Error(hMessage);
260 if (utf8Name != "Error" && !utf8Name.IsEmpty()) {
261 hError.As<v8::Object>()->Set(
262 v8::String::NewFromUtf8(pIsolate, "name"),
263 v8::String::NewFromUtf8(pIsolate, utf8Name.GetCStr(),
264 v8::String::kNormalString,
265 utf8Name.GetLength()));
266 }
267 }
268 pIsolate->ThrowException(hError);
269 }
Create(v8::Isolate * pIsolate)270 CFXJSE_Value* CFXJSE_Value::Create(v8::Isolate* pIsolate) {
271 return new CFXJSE_Value(pIsolate);
272 }
ToObject(CFXJSE_Class * lpClass) const273 void* CFXJSE_Value::ToObject(CFXJSE_Class* lpClass) const {
274 ASSERT(!m_hValue.IsEmpty());
275 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
276 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
277 ASSERT(!hValue.IsEmpty());
278 if (!hValue->IsObject()) {
279 return NULL;
280 }
281 return FXJSE_RetrieveObjectBinding(hValue.As<v8::Object>(), lpClass);
282 }
FXJSE_ftod(FX_FLOAT fNumber)283 V8_INLINE static double FXJSE_ftod(FX_FLOAT fNumber) {
284 if (sizeof(FX_FLOAT) != 4) {
285 ASSERT(FALSE);
286 return fNumber;
287 }
288 uint32_t nFloatBits = (uint32_t&)fNumber;
289 uint8_t nExponent = (uint8_t)(nFloatBits >> 16 >> 7);
290 if (nExponent == 0 || nExponent == 255) {
291 return fNumber;
292 }
293 int8_t nErrExp = nExponent - 127 - 23;
294 if (nErrExp >= 0) {
295 return fNumber;
296 }
297 double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2;
298 double dNumber = fNumber, dNumberAbs = fabs(fNumber);
299 double dNumberAbsMin = dNumberAbs - dwErrorHalf,
300 dNumberAbsMax = dNumberAbs + dwErrorHalf;
301 int32_t iErrPos = 0;
302 if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
303 dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
304 dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
305 int32_t iErrPosMin = 1, iErrPosMax = 38;
306 do {
307 int32_t iMid = (iErrPosMin + iErrPosMax) / 2;
308 double dPow = pow(10.0, iMid);
309 if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) {
310 iErrPosMin = iMid + 1;
311 } else {
312 iErrPosMax = iMid;
313 }
314 } while (iErrPosMin < iErrPosMax);
315 iErrPos = iErrPosMax;
316 }
317 double dPow = pow(10.0, iErrPos);
318 return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow
319 : floor(dNumber * dPow + 0.5) / dPow;
320 }
SetFloat(FX_FLOAT fFloat)321 void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) {
322 CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate);
323 v8::Local<v8::Value> hValue = v8::Number::New(m_pIsolate, FXJSE_ftod(fFloat));
324 m_hValue.Reset(m_pIsolate, hValue);
325 }
SetHostObject(void * lpObject,CFXJSE_Class * lpClass)326 void CFXJSE_Value::SetHostObject(void* lpObject, CFXJSE_Class* lpClass) {
327 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
328 ASSERT(lpClass);
329 v8::Local<v8::FunctionTemplate> hClass =
330 v8::Local<v8::FunctionTemplate>::New(m_pIsolate, lpClass->m_hTemplate);
331 v8::Local<v8::Object> hObject = hClass->InstanceTemplate()->NewInstance();
332 FXJSE_UpdateObjectBinding(hObject, lpObject);
333 m_hValue.Reset(m_pIsolate, hObject);
334 }
SetArray(uint32_t uValueCount,CFXJSE_Value ** rgValues)335 void CFXJSE_Value::SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues) {
336 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
337 v8::Local<v8::Array> hArrayObject = v8::Array::New(m_pIsolate, uValueCount);
338 if (rgValues) {
339 for (uint32_t i = 0; i < uValueCount; i++) {
340 if (rgValues[i]) {
341 hArrayObject->Set(i, v8::Local<v8::Value>::New(
342 m_pIsolate, rgValues[i]->DirectGetValue()));
343 }
344 }
345 }
346 m_hValue.Reset(m_pIsolate, hArrayObject);
347 }
SetDate(FXJSE_DOUBLE dDouble)348 void CFXJSE_Value::SetDate(FXJSE_DOUBLE dDouble) {
349 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
350 v8::Local<v8::Value> hDate = v8::Date::New(m_pIsolate, dDouble);
351 m_hValue.Reset(m_pIsolate, hDate);
352 }
SetObjectProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)353 FX_BOOL CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName,
354 CFXJSE_Value* lpPropValue) {
355 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
356 v8::Local<v8::Value> hObject =
357 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
358 if (!hObject->IsObject()) {
359 return FALSE;
360 }
361 v8::Local<v8::Value> hPropValue =
362 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
363 return (FX_BOOL)hObject.As<v8::Object>()->Set(
364 v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(),
365 v8::String::kNormalString,
366 szPropName.GetLength()),
367 hPropValue);
368 }
GetObjectProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)369 FX_BOOL CFXJSE_Value::GetObjectProperty(const CFX_ByteStringC& szPropName,
370 CFXJSE_Value* lpPropValue) {
371 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
372 v8::Local<v8::Value> hObject =
373 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
374 if (!hObject->IsObject()) {
375 return FALSE;
376 }
377 v8::Local<v8::Value> hPropValue =
378 hObject.As<v8::Object>()->Get(v8::String::NewFromUtf8(
379 m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString,
380 szPropName.GetLength()));
381 lpPropValue->ForceSetValue(hPropValue);
382 return TRUE;
383 }
SetObjectProperty(uint32_t uPropIdx,CFXJSE_Value * lpPropValue)384 FX_BOOL CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx,
385 CFXJSE_Value* lpPropValue) {
386 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
387 v8::Local<v8::Value> hObject =
388 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
389 if (!hObject->IsObject()) {
390 return FALSE;
391 }
392 v8::Local<v8::Value> hPropValue =
393 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->DirectGetValue());
394 return (FX_BOOL)hObject.As<v8::Object>()->Set(uPropIdx, hPropValue);
395 }
GetObjectProperty(uint32_t uPropIdx,CFXJSE_Value * lpPropValue)396 FX_BOOL CFXJSE_Value::GetObjectProperty(uint32_t uPropIdx,
397 CFXJSE_Value* lpPropValue) {
398 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
399 v8::Local<v8::Value> hObject =
400 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
401 if (!hObject->IsObject()) {
402 return FALSE;
403 }
404 v8::Local<v8::Value> hPropValue = hObject.As<v8::Object>()->Get(uPropIdx);
405 lpPropValue->ForceSetValue(hPropValue);
406 return TRUE;
407 }
DeleteObjectProperty(const CFX_ByteStringC & szPropName)408 FX_BOOL CFXJSE_Value::DeleteObjectProperty(const CFX_ByteStringC& szPropName) {
409 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
410 v8::Local<v8::Value> hObject =
411 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
412 if (!hObject->IsObject()) {
413 return FALSE;
414 }
415 hObject.As<v8::Object>()->Delete(v8::String::NewFromUtf8(
416 m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString,
417 szPropName.GetLength()));
418 return TRUE;
419 }
HasObjectOwnProperty(const CFX_ByteStringC & szPropName,FX_BOOL bUseTypeGetter)420 FX_BOOL CFXJSE_Value::HasObjectOwnProperty(const CFX_ByteStringC& szPropName,
421 FX_BOOL bUseTypeGetter) {
422 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
423 v8::Local<v8::Value> hObject =
424 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
425 if (!hObject->IsObject()) {
426 return FALSE;
427 }
428 v8::Local<v8::String> hKey = v8::String::NewFromUtf8(
429 m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString,
430 szPropName.GetLength());
431 return hObject.As<v8::Object>()->HasRealNamedProperty(hKey) ||
432 (bUseTypeGetter && hObject.As<v8::Object>()->HasOwnProperty(hKey));
433 }
SetObjectOwnProperty(const CFX_ByteStringC & szPropName,CFXJSE_Value * lpPropValue)434 FX_BOOL CFXJSE_Value::SetObjectOwnProperty(const CFX_ByteStringC& szPropName,
435 CFXJSE_Value* lpPropValue) {
436 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
437 v8::Local<v8::Value> hObject =
438 v8::Local<v8::Value>::New(m_pIsolate, m_hValue);
439 if (!hObject->IsObject()) {
440 return FALSE;
441 }
442 v8::Local<v8::Value> hValue =
443 v8::Local<v8::Value>::New(m_pIsolate, lpPropValue->m_hValue);
444 return hObject.As<v8::Object>()->ForceSet(
445 v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(),
446 v8::String::kNormalString,
447 szPropName.GetLength()),
448 hValue);
449 }
SetFunctionBind(CFXJSE_Value * lpOldFunction,CFXJSE_Value * lpNewThis)450 FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction,
451 CFXJSE_Value* lpNewThis) {
452 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
453 v8::Local<v8::Value> rgArgs[2];
454 v8::Local<v8::Value> hOldFunction =
455 v8::Local<v8::Value>::New(m_pIsolate, lpOldFunction->DirectGetValue());
456 if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction()) {
457 return FALSE;
458 }
459 rgArgs[0] = hOldFunction;
460 v8::Local<v8::Value> hNewThis =
461 v8::Local<v8::Value>::New(m_pIsolate, lpNewThis->DirectGetValue());
462 if (hNewThis.IsEmpty()) {
463 return FALSE;
464 }
465 rgArgs[1] = hNewThis;
466 v8::Local<v8::String> hBinderFuncSource =
467 v8::String::NewFromUtf8(m_pIsolate,
468 "(function (oldfunction, newthis) { return "
469 "oldfunction.bind(newthis); })");
470 v8::Local<v8::Function> hBinderFunc =
471 v8::Script::Compile(hBinderFuncSource)->Run().As<v8::Function>();
472 v8::Local<v8::Value> hBoundFunction =
473 hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs);
474 if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction()) {
475 return FALSE;
476 }
477 m_hValue.Reset(m_pIsolate, hBoundFunction);
478 return TRUE;
479 }
480 #define FXJSE_INVALID_PTR ((void*)(intptr_t)-1)
Call(CFXJSE_Value * lpReceiver,CFXJSE_Value * lpRetValue,uint32_t nArgCount,FXJSE_HVALUE * lpArgs)481 FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver,
482 CFXJSE_Value* lpRetValue,
483 uint32_t nArgCount,
484 FXJSE_HVALUE* lpArgs) {
485 CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate);
486 v8::Local<v8::Value> hFunctionValue =
487 v8::Local<v8::Value>::New(m_pIsolate, DirectGetValue());
488 v8::Local<v8::Object> hFunctionObject =
489 !hFunctionValue.IsEmpty() && hFunctionValue->IsObject()
490 ? hFunctionValue.As<v8::Object>()
491 : v8::Local<v8::Object>();
492 v8::TryCatch trycatch;
493 if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) {
494 if (lpRetValue) {
495 lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch));
496 }
497 return FALSE;
498 }
499 v8::Local<v8::Value> hReturnValue;
500 v8::Local<v8::Value>* lpLocalArgs = NULL;
501 if (nArgCount) {
502 lpLocalArgs = FX_Alloc(v8::Local<v8::Value>, nArgCount);
503 for (uint32_t i = 0; i < nArgCount; i++) {
504 new (lpLocalArgs + i) v8::Local<v8::Value>;
505 CFXJSE_Value* lpArg = (CFXJSE_Value*)lpArgs[i];
506 if (lpArg) {
507 lpLocalArgs[i] =
508 v8::Local<v8::Value>::New(m_pIsolate, lpArg->DirectGetValue());
509 }
510 if (lpLocalArgs[i].IsEmpty()) {
511 lpLocalArgs[i] = v8::Undefined(m_pIsolate);
512 }
513 }
514 }
515 FX_BOOL bRetValue = TRUE;
516 if (lpReceiver == FXJSE_INVALID_PTR) {
517 hReturnValue = hFunctionObject->CallAsConstructor(nArgCount, lpLocalArgs);
518 } else {
519 v8::Local<v8::Value> hReceiver;
520 if (lpReceiver) {
521 hReceiver =
522 v8::Local<v8::Value>::New(m_pIsolate, lpReceiver->DirectGetValue());
523 }
524 if (hReceiver.IsEmpty() || !hReceiver->IsObject()) {
525 hReceiver = v8::Object::New(m_pIsolate);
526 }
527 hReturnValue =
528 hFunctionObject->CallAsFunction(hReceiver, nArgCount, lpLocalArgs);
529 }
530 if (trycatch.HasCaught()) {
531 hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch);
532 bRetValue = FALSE;
533 }
534 if (lpRetValue) {
535 lpRetValue->ForceSetValue(hReturnValue);
536 }
537 if (lpLocalArgs) {
538 for (uint32_t i = 0; i < nArgCount; i++) {
539 lpLocalArgs[i].~Local();
540 }
541 FX_Free(lpLocalArgs);
542 }
543 return bRetValue;
544 }
545