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" 13 FX_BOOL FXJSE_Value_IsUndefined(FXJSE_HVALUE hValue) { 14 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 15 return lpValue && lpValue->IsUndefined(); 16 } 17 FX_BOOL FXJSE_Value_IsNull(FXJSE_HVALUE hValue) { 18 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 19 return lpValue && lpValue->IsNull(); 20 } 21 FX_BOOL FXJSE_Value_IsBoolean(FXJSE_HVALUE hValue) { 22 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 23 return lpValue && lpValue->IsBoolean(); 24 } 25 FX_BOOL FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue) { 26 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 27 return lpValue && lpValue->IsString(); 28 } 29 FX_BOOL FXJSE_Value_IsNumber(FXJSE_HVALUE hValue) { 30 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 31 return lpValue && lpValue->IsNumber(); 32 } 33 FX_BOOL FXJSE_Value_IsInteger(FXJSE_HVALUE hValue) { 34 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 35 return lpValue && lpValue->IsInteger(); 36 } 37 FX_BOOL FXJSE_Value_IsObject(FXJSE_HVALUE hValue) { 38 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 39 return lpValue && lpValue->IsObject(); 40 } 41 FX_BOOL FXJSE_Value_IsArray(FXJSE_HVALUE hValue) { 42 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 43 return lpValue && lpValue->IsArray(); 44 } 45 FX_BOOL FXJSE_Value_IsFunction(FXJSE_HVALUE hValue) { 46 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 47 return lpValue && lpValue->IsFunction(); 48 } 49 FX_BOOL FXJSE_Value_IsDate(FXJSE_HVALUE hValue) { 50 CFXJSE_Value* lpValue = reinterpret_cast<CFXJSE_Value*>(hValue); 51 return lpValue && lpValue->IsDate(); 52 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 270 CFXJSE_Value* CFXJSE_Value::Create(v8::Isolate* pIsolate) { 271 return new CFXJSE_Value(pIsolate); 272 } 273 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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) 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