7#include "fxjs/xfa/cfxjse_value.h"
12#include "fxjs/xfa/cfxjse_class.h"
13#include "fxjs/xfa/cfxjse_context.h"
14#include "fxjs/xfa/cfxjse_isolatetracker.h"
15#include "third_party/base/check.h"
16#include "v8/include/v8-container.h"
17#include "v8/include/v8-exception.h"
18#include "v8/include/v8-function.h"
19#include "v8/include/v8-local-handle.h"
20#include "v8/include/v8-primitive.h"
21#include "v8/include/v8-script.h"
25double ftod(
float fNumber) {
26 static_assert(
sizeof(
float) == 4,
"float of incorrect size");
28 uint32_t nFloatBits = (uint32_t&)fNumber;
29 uint8_t nExponent = (uint8_t)(nFloatBits >> 23);
30 if (nExponent == 0 || nExponent == 255)
33 int8_t nErrExp = nExponent - 150;
37 double dwError = pow(2.0, nErrExp);
38 double dwErrorHalf = dwError / 2;
39 double dNumber = fNumber;
40 double dNumberAbs = fabs(fNumber);
41 double dNumberAbsMin = dNumberAbs - dwErrorHalf;
42 double dNumberAbsMax = dNumberAbs + dwErrorHalf;
44 if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) {
45 dNumberAbsMin = fmod(dNumberAbsMin, 1.0);
46 dNumberAbsMax = fmod(dNumberAbsMax, 1.0);
47 int32_t iErrPosMin = 1;
48 int32_t iErrPosMax = 38;
50 int32_t iMid = (iErrPosMin + iErrPosMax) / 2;
51 double dPow = pow(10.0, iMid);
52 if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) {
53 iErrPosMin = iMid + 1;
57 }
while (iErrPosMin < iErrPosMax);
60 double dPow = pow(10.0, iErrPos);
61 return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow
62 : floor(dNumber * dPow + 0.5) / dPow;
70 v8::Local<v8::String> hMessage = fxv8::NewStringHelper(pIsolate, utf8Message);
71 v8::Local<v8::Value> hError = v8::Exception::Error(hMessage);
72 pIsolate->ThrowException(hError);
78 ForceSetValue(pIsolate, value);
85 return CFXJSE_HostObject::FromV8(
86 v8::Local<v8::Value>::New(pIsolate, m_hValue));
93 m_hValue.Reset(pIsolate, pObject->NewBoundV8Object(
94 pIsolate, pClass->GetTemplate(pIsolate)));
98 v8::Isolate* pIsolate,
99 const std::vector<std::unique_ptr<CFXJSE_Value>>& values) {
101 v8::LocalVector<v8::Value> local_values(pIsolate);
102 local_values.reserve(values.size());
103 for (
auto& v : values) {
105 local_values.push_back(fxv8::NewUndefinedHelper(pIsolate));
107 local_values.push_back(v->GetValue(pIsolate));
109 v8::Local<v8::Array> hArrayObject =
110 v8::Array::New(pIsolate, local_values.data(), local_values.size());
111 m_hValue.Reset(pIsolate, hArrayObject);
116 m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, ftod(fFloat)));
120 ByteStringView szPropName,
126 v8::Local<v8::Value> hObject = GetValue(pIsolate);
127 if (!hObject->IsObject())
130 return fxv8::ReentrantPutObjectPropertyHelper(
131 pIsolate, hObject.As<v8::Object>(), szPropName,
132 pPropValue->GetValue(pIsolate));
136 ByteStringView szPropName,
139 v8::Local<v8::Value> hObject = GetValue(pIsolate);
140 if (!hObject->IsObject())
143 pPropValue->ForceSetValue(
144 pIsolate, fxv8::ReentrantGetObjectPropertyHelper(
145 pIsolate, hObject.As<v8::Object>(), szPropName));
153 v8::Local<v8::Value> hObject = GetValue(pIsolate);
154 if (!hObject->IsArray())
157 pPropValue->ForceSetValue(pIsolate,
158 fxv8::ReentrantGetArrayElementHelper(
159 pIsolate, hObject.As<v8::Array>(), uPropIdx));
164 ByteStringView szPropName) {
166 v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(pIsolate, m_hValue);
167 if (hObject->IsObject()) {
168 fxv8::ReentrantDeleteObjectPropertyHelper(
169 pIsolate, hObject.As<v8::Object>(), szPropName);
174 ByteStringView szPropName,
177 v8::Local<v8::Value> hObject = v8::Local<v8::Value>::New(pIsolate, m_hValue);
178 if (!hObject->IsObject())
181 v8::Local<v8::Value> pValue =
182 v8::Local<v8::Value>::New(pIsolate, pPropValue->m_hValue);
183 return fxv8::ReentrantSetObjectOwnPropertyHelper(
184 pIsolate, hObject.As<v8::Object>(), szPropName, pValue);
188 v8::Isolate* pIsolate,
189 v8::Local<v8::Function> hOldFunction,
190 v8::Local<v8::Object> hNewThis) {
191 DCHECK(!hOldFunction.IsEmpty());
192 DCHECK(!hNewThis.IsEmpty());
194 CFXJSE_ScopeUtil_RootContext scope(pIsolate);
195 v8::Local<v8::Value> rgArgs[2];
196 rgArgs[0] = hOldFunction;
197 rgArgs[1] = hNewThis;
198 v8::Local<v8::String> hBinderFuncSource = fxv8::NewStringHelper(
199 pIsolate,
"(function (fn, obj) { return fn.bind(obj); })");
200 v8::Local<v8::Context> hContext = pIsolate->GetCurrentContext();
201 v8::Local<v8::Function> hBinderFunc =
202 v8::Script::Compile(hContext, hBinderFuncSource)
207 v8::Local<v8::Value> hBoundFunction =
208 hBinderFunc->Call(hContext, hContext->Global(), 2, rgArgs)
210 if (!fxv8::IsFunction(hBoundFunction))
211 return v8::Local<v8::Function>();
213 return hBoundFunction.As<v8::Function>();
217 return v8::Local<v8::Value>::New(pIsolate, m_hValue);
221 return m_hValue.IsEmpty();
229 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
230 return hValue->IsUndefined();
238 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
239 return hValue->IsNull();
247 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
248 return hValue->IsBoolean();
256 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
257 return hValue->IsString();
265 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
266 return hValue->IsNumber();
274 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
275 return hValue->IsInt32();
283 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
284 return hValue->IsObject();
292 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
293 return hValue->IsArray();
301 v8::Local<v8::Value> hValue = v8::Local<v8::Value>::New(pIsolate, m_hValue);
302 return hValue->IsFunction();
308 return fxv8::ReentrantToBooleanHelper(
309 pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
313 return static_cast<
float>(ToDouble(pIsolate));
319 return fxv8::ReentrantToDoubleHelper(
320 pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
326 return fxv8::ReentrantToInt32Helper(
327 pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
333 return fxv8::ReentrantToByteStringHelper(
334 pIsolate, v8::Local<v8::Value>::New(pIsolate, m_hValue));
339 m_hValue.Reset(pIsolate, fxv8::NewUndefinedHelper(pIsolate));
344 m_hValue.Reset(pIsolate, fxv8::NewNullHelper(pIsolate));
349 m_hValue.Reset(pIsolate, fxv8::NewBooleanHelper(pIsolate, bBoolean));
354 m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, nInteger));
359 m_hValue.Reset(pIsolate, fxv8::NewNumberHelper(pIsolate, dDouble));
364 m_hValue.Reset(pIsolate, fxv8::NewStringHelper(pIsolate, szString));
void FXJSE_ThrowMessage(v8::Isolate *pIsolate, ByteStringView utf8Message)
bool IsBoolean(v8::Isolate *pIsolate) const
CFXJSE_Value(v8::Isolate *pIsolate, v8::Local< v8::Value > value)
void SetArray(v8::Isolate *pIsolate, const std::vector< std::unique_ptr< CFXJSE_Value > > &values)
CFXJSE_HostObject * ToHostObject(v8::Isolate *pIsolate) const
bool GetObjectProperty(v8::Isolate *pIsolate, ByteStringView szPropName, CFXJSE_Value *pPropValue)
bool SetObjectOwnProperty(v8::Isolate *pIsolate, ByteStringView szPropName, CFXJSE_Value *pPropValue)
bool IsString(v8::Isolate *pIsolate) const
bool IsArray(v8::Isolate *pIsolate) const
void SetInteger(v8::Isolate *pIsolate, int32_t nInteger)
bool GetObjectPropertyByIdx(v8::Isolate *pIsolate, uint32_t uPropIdx, CFXJSE_Value *pPropValue)
int32_t ToInteger(v8::Isolate *pIsolate) const
bool SetObjectProperty(v8::Isolate *pIsolate, ByteStringView szPropName, CFXJSE_Value *pPropValue)
bool IsFunction(v8::Isolate *pIsolate) const
bool IsUndefined(v8::Isolate *pIsolate) const
double ToDouble(v8::Isolate *pIsolate) const
bool IsObject(v8::Isolate *pIsolate) const
void SetDouble(v8::Isolate *pIsolate, double dDouble)
bool IsNull(v8::Isolate *pIsolate) const
void SetFloat(v8::Isolate *pIsolate, float fFloat)
void SetString(v8::Isolate *pIsolate, ByteStringView szString)
ByteString ToString(v8::Isolate *pIsolate) const
void SetNull(v8::Isolate *pIsolate)
void DeleteObjectProperty(v8::Isolate *pIsolate, ByteStringView szPropName)
void SetHostObject(v8::Isolate *pIsolate, CFXJSE_HostObject *pObject, CFXJSE_Class *pClass)
float ToFloat(v8::Isolate *pIsolate) const
bool ToBoolean(v8::Isolate *pIsolate) const
void SetUndefined(v8::Isolate *pIsolate)
v8::Local< v8::Value > GetValue(v8::Isolate *pIsolate) const
bool IsInteger(v8::Isolate *pIsolate) const
void SetBoolean(v8::Isolate *pIsolate, bool bBoolean)
bool IsNumber(v8::Isolate *pIsolate) const