From e2a774a4b841829ef089d0cbfd15a08895eecf0e Mon Sep 17 00:00:00 2001 From: Dan Sinclair Date: Tue, 8 Mar 2016 15:03:11 -0500 Subject: Remove xfa/src/fxjse/src and move code up a level. This CL removes the xfa/src/fxjse/src and moves all of the .h and .cpp files up to the, previously empty, xfa/src/fxjse directory. R=tsepez@chromium.org Review URL: https://codereview.chromium.org/1776643002 . --- BUILD.gn | 22 +- fpdfsdk/src/javascript/JS_Runtime.cpp | 2 +- xfa.gyp | 22 +- xfa/src/fxjse/class.cpp | 348 ++++++++++++++++++++ xfa/src/fxjse/class.h | 49 +++ xfa/src/fxjse/context.cpp | 275 ++++++++++++++++ xfa/src/fxjse/context.h | 47 +++ xfa/src/fxjse/dynprop.cpp | 236 ++++++++++++++ xfa/src/fxjse/runtime.cpp | 128 ++++++++ xfa/src/fxjse/runtime.h | 51 +++ xfa/src/fxjse/scope_inline.h | 108 +++++++ xfa/src/fxjse/src/class.cpp | 348 -------------------- xfa/src/fxjse/src/class.h | 49 --- xfa/src/fxjse/src/context.cpp | 275 ---------------- xfa/src/fxjse/src/context.h | 47 --- xfa/src/fxjse/src/dynprop.cpp | 236 -------------- xfa/src/fxjse/src/runtime.cpp | 128 -------- xfa/src/fxjse/src/runtime.h | 51 --- xfa/src/fxjse/src/scope_inline.h | 108 ------- xfa/src/fxjse/src/util_inline.h | 51 --- xfa/src/fxjse/src/value.cpp | 582 ---------------------------------- xfa/src/fxjse/src/value.h | 241 -------------- xfa/src/fxjse/util_inline.h | 51 +++ xfa/src/fxjse/value.cpp | 582 ++++++++++++++++++++++++++++++++++ xfa/src/fxjse/value.h | 241 ++++++++++++++ 25 files changed, 2139 insertions(+), 2139 deletions(-) create mode 100644 xfa/src/fxjse/class.cpp create mode 100644 xfa/src/fxjse/class.h create mode 100644 xfa/src/fxjse/context.cpp create mode 100644 xfa/src/fxjse/context.h create mode 100644 xfa/src/fxjse/dynprop.cpp create mode 100644 xfa/src/fxjse/runtime.cpp create mode 100644 xfa/src/fxjse/runtime.h create mode 100644 xfa/src/fxjse/scope_inline.h delete mode 100644 xfa/src/fxjse/src/class.cpp delete mode 100644 xfa/src/fxjse/src/class.h delete mode 100644 xfa/src/fxjse/src/context.cpp delete mode 100644 xfa/src/fxjse/src/context.h delete mode 100644 xfa/src/fxjse/src/dynprop.cpp delete mode 100644 xfa/src/fxjse/src/runtime.cpp delete mode 100644 xfa/src/fxjse/src/runtime.h delete mode 100644 xfa/src/fxjse/src/scope_inline.h delete mode 100644 xfa/src/fxjse/src/util_inline.h delete mode 100644 xfa/src/fxjse/src/value.cpp delete mode 100644 xfa/src/fxjse/src/value.h create mode 100644 xfa/src/fxjse/util_inline.h create mode 100644 xfa/src/fxjse/value.cpp create mode 100644 xfa/src/fxjse/value.h diff --git a/BUILD.gn b/BUILD.gn index 68a30efaca..4c4f5ded0e 100644 --- a/BUILD.gn +++ b/BUILD.gn @@ -1383,17 +1383,17 @@ if (pdf_enable_xfa) { include_dirs = [ "." ] if (pdf_enable_v8) { sources += [ - "xfa/src/fxjse/src/class.cpp", - "xfa/src/fxjse/src/class.h", - "xfa/src/fxjse/src/context.cpp", - "xfa/src/fxjse/src/context.h", - "xfa/src/fxjse/src/dynprop.cpp", - "xfa/src/fxjse/src/runtime.cpp", - "xfa/src/fxjse/src/runtime.h", - "xfa/src/fxjse/src/scope_inline.h", - "xfa/src/fxjse/src/util_inline.h", - "xfa/src/fxjse/src/value.cpp", - "xfa/src/fxjse/src/value.h", + "xfa/src/fxjse/class.cpp", + "xfa/src/fxjse/class.h", + "xfa/src/fxjse/context.cpp", + "xfa/src/fxjse/context.h", + "xfa/src/fxjse/dynprop.cpp", + "xfa/src/fxjse/runtime.cpp", + "xfa/src/fxjse/runtime.h", + "xfa/src/fxjse/scope_inline.h", + "xfa/src/fxjse/util_inline.h", + "xfa/src/fxjse/value.cpp", + "xfa/src/fxjse/value.h", ] include_dirs += [ "//v8", diff --git a/fpdfsdk/src/javascript/JS_Runtime.cpp b/fpdfsdk/src/javascript/JS_Runtime.cpp index 88696e5110..dd7ef0f09d 100644 --- a/fpdfsdk/src/javascript/JS_Runtime.cpp +++ b/fpdfsdk/src/javascript/JS_Runtime.cpp @@ -30,7 +30,7 @@ #ifdef PDF_ENABLE_XFA #include "fpdfsdk/include/fpdfxfa/fpdfxfa_app.h" -#include "xfa/src/fxjse/src/value.h" +#include "xfa/src/fxjse/value.h" #endif // PDF_ENABLE_XFA // static diff --git a/xfa.gyp b/xfa.gyp index 52fe97ea13..7cbb8b364c 100644 --- a/xfa.gyp +++ b/xfa.gyp @@ -669,17 +669,17 @@ '<(DEPTH)/v8/include', ], 'sources': [ - "xfa/src/fxjse/src/class.cpp", - "xfa/src/fxjse/src/class.h", - "xfa/src/fxjse/src/context.cpp", - "xfa/src/fxjse/src/context.h", - "xfa/src/fxjse/src/dynprop.cpp", - "xfa/src/fxjse/src/runtime.cpp", - "xfa/src/fxjse/src/runtime.h", - "xfa/src/fxjse/src/scope_inline.h", - "xfa/src/fxjse/src/util_inline.h", - "xfa/src/fxjse/src/value.cpp", - "xfa/src/fxjse/src/value.h" + "xfa/src/fxjse/class.cpp", + "xfa/src/fxjse/class.h", + "xfa/src/fxjse/context.cpp", + "xfa/src/fxjse/context.h", + "xfa/src/fxjse/dynprop.cpp", + "xfa/src/fxjse/runtime.cpp", + "xfa/src/fxjse/runtime.h", + "xfa/src/fxjse/scope_inline.h", + "xfa/src/fxjse/util_inline.h", + "xfa/src/fxjse/value.cpp", + "xfa/src/fxjse/value.h" ], }], ["OS == 'win'", { diff --git a/xfa/src/fxjse/class.cpp b/xfa/src/fxjse/class.cpp new file mode 100644 index 0000000000..bccbe2ba20 --- /dev/null +++ b/xfa/src/fxjse/class.cpp @@ -0,0 +1,348 @@ +// 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 + +#include "xfa/src/fxjse/class.h" + +#include "xfa/src/fxjse/context.h" +#include "xfa/src/fxjse/scope_inline.h" +#include "xfa/src/fxjse/util_inline.h" +#include "xfa/src/fxjse/value.h" + +static void FXJSE_V8ConstructorCallback_Wrapper( + const v8::FunctionCallbackInfo& info); +static void FXJSE_V8FunctionCallback_Wrapper( + const v8::FunctionCallbackInfo& info); +static void FXJSE_V8GetterCallback_Wrapper( + v8::Local property, + const v8::PropertyCallbackInfo& info); +static void FXJSE_V8SetterCallback_Wrapper( + v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info); + +void FXJSE_DefineFunctions(FXJSE_HCONTEXT hContext, + const FXJSE_FUNCTION* lpFunctions, + int nNum) { + CFXJSE_Context* lpContext = reinterpret_cast(hContext); + ASSERT(lpContext); + CFXJSE_ScopeUtil_IsolateHandleContext scope(lpContext); + v8::Isolate* pIsolate = lpContext->GetRuntime(); + v8::Local hGlobalObject = + FXJSE_GetGlobalObjectFromContext(scope.GetLocalContext()); + for (int32_t i = 0; i < nNum; i++) { + v8::Maybe maybe_success = hGlobalObject->DefineOwnProperty( + scope.GetLocalContext(), + v8::String::NewFromUtf8(pIsolate, lpFunctions[i].name), + v8::Function::New( + pIsolate, FXJSE_V8FunctionCallback_Wrapper, + v8::External::New(pIsolate, + const_cast(lpFunctions + i))), + static_cast(v8::ReadOnly | v8::DontDelete)); + if (!maybe_success.FromMaybe(false)) + return; + } +} + +FXJSE_HCLASS FXJSE_DefineClass(FXJSE_HCONTEXT hContext, + const FXJSE_CLASS* lpClass) { + CFXJSE_Context* lpContext = reinterpret_cast(hContext); + ASSERT(lpContext); + return reinterpret_cast( + CFXJSE_Class::Create(lpContext, lpClass, FALSE)); +} + +FXJSE_HCLASS FXJSE_GetClass(FXJSE_HCONTEXT hContext, + const CFX_ByteStringC& szName) { + return reinterpret_cast(CFXJSE_Class::GetClassFromContext( + reinterpret_cast(hContext), szName)); +} + +static void FXJSE_V8FunctionCallback_Wrapper( + const v8::FunctionCallbackInfo& info) { + const FXJSE_FUNCTION* lpFunctionInfo = + static_cast(info.Data().As()->Value()); + if (!lpFunctionInfo) { + return; + } + CFX_ByteStringC szFunctionName(lpFunctionInfo->name); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; + lpFunctionInfo->callbackProc(reinterpret_cast(lpThisValue), + szFunctionName, + reinterpret_cast(impl)); + if (!lpRetValue->DirectGetValue().IsEmpty()) { + info.GetReturnValue().Set(lpRetValue->DirectGetValue()); + } + delete lpRetValue; + lpRetValue = NULL; + delete lpThisValue; + lpThisValue = NULL; +} + +static void FXJSE_V8ClassGlobalConstructorCallback_Wrapper( + const v8::FunctionCallbackInfo& info) { + const FXJSE_CLASS* lpClassDefinition = + static_cast(info.Data().As()->Value()); + if (!lpClassDefinition) { + return; + } + CFX_ByteStringC szFunctionName(lpClassDefinition->name); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; + lpClassDefinition->constructor(reinterpret_cast(lpThisValue), + szFunctionName, + reinterpret_cast(impl)); + if (!lpRetValue->DirectGetValue().IsEmpty()) { + info.GetReturnValue().Set(lpRetValue->DirectGetValue()); + } + delete lpRetValue; + lpRetValue = NULL; + delete lpThisValue; + lpThisValue = NULL; +} + +static void FXJSE_V8GetterCallback_Wrapper( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + const FXJSE_PROPERTY* lpPropertyInfo = + static_cast(info.Data().As()->Value()); + if (!lpPropertyInfo) { + return; + } + CFX_ByteStringC szPropertyName(lpPropertyInfo->name); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + lpPropertyInfo->getProc(reinterpret_cast(lpThisValue), + szPropertyName, + reinterpret_cast(lpPropValue)); + info.GetReturnValue().Set(lpPropValue->DirectGetValue()); + delete lpThisValue; + lpThisValue = NULL; + delete lpPropValue; + lpPropValue = NULL; +} + +static void FXJSE_V8SetterCallback_Wrapper( + v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info) { + const FXJSE_PROPERTY* lpPropertyInfo = + static_cast(info.Data().As()->Value()); + if (!lpPropertyInfo) { + return; + } + CFX_ByteStringC szPropertyName(lpPropertyInfo->name); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + lpPropValue->ForceSetValue(value); + lpPropertyInfo->setProc(reinterpret_cast(lpThisValue), + szPropertyName, + reinterpret_cast(lpPropValue)); + delete lpThisValue; + lpThisValue = NULL; + delete lpPropValue; + lpPropValue = NULL; +} + +static void FXJSE_V8ConstructorCallback_Wrapper( + const v8::FunctionCallbackInfo& info) { + const FXJSE_CLASS* lpClassDefinition = + static_cast(info.Data().As()->Value()); + if (!lpClassDefinition) { + return; + } + FXSYS_assert(info.This()->InternalFieldCount()); + info.This()->SetAlignedPointerInInternalField(0, NULL); +} + +FXJSE_HRUNTIME CFXJSE_Arguments::GetRuntime() const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return reinterpret_cast( + lpArguments->m_pRetValue->GetIsolate()); +} + +int32_t CFXJSE_Arguments::GetLength() const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return lpArguments->m_pInfo->Length(); +} + +FXJSE_HVALUE CFXJSE_Arguments::GetValue(int32_t index) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + CFXJSE_Value* lpArgValue = CFXJSE_Value::Create(v8::Isolate::GetCurrent()); + ASSERT(lpArgValue); + lpArgValue->ForceSetValue((*lpArguments->m_pInfo)[index]); + return reinterpret_cast(lpArgValue); +} + +FX_BOOL CFXJSE_Arguments::GetBoolean(int32_t index) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return (*lpArguments->m_pInfo)[index]->BooleanValue(); +} + +int32_t CFXJSE_Arguments::GetInt32(int32_t index) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); +} + +FX_FLOAT CFXJSE_Arguments::GetFloat(int32_t index) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); +} + +CFX_ByteString CFXJSE_Arguments::GetUTF8String(int32_t index) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + v8::Local hString = (*lpArguments->m_pInfo)[index]->ToString(); + v8::String::Utf8Value szStringVal(hString); + return CFX_ByteString(*szStringVal); +} + +void* CFXJSE_Arguments::GetObject(int32_t index, FXJSE_HCLASS hClass) const { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + v8::Local hValue = (*lpArguments->m_pInfo)[index]; + ASSERT(!hValue.IsEmpty()); + if (!hValue->IsObject()) { + return NULL; + } + CFXJSE_Class* lpClass = reinterpret_cast(hClass); + return FXJSE_RetrieveObjectBinding(hValue.As(), lpClass); +} + +FXJSE_HVALUE CFXJSE_Arguments::GetReturnValue() { + const CFXJSE_ArgumentsImpl* lpArguments = + reinterpret_cast(this); + return reinterpret_cast(lpArguments->m_pRetValue); +} +static void FXJSE_Context_GlobalObjToString( + const v8::FunctionCallbackInfo& info) { + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + if (!lpClass) { + return; + } + if (info.This() == info.Holder() && lpClass->name) { + CFX_ByteString szStringVal; + szStringVal.Format("[object %s]", lpClass->name); + info.GetReturnValue().Set(v8::String::NewFromUtf8( + info.GetIsolate(), (const FX_CHAR*)szStringVal, + v8::String::kNormalString, szStringVal.GetLength())); + } else { + v8::Local local_str = + info.This() + ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext()) + .FromMaybe(v8::Local()); + info.GetReturnValue().Set(local_str); + } +} + +CFXJSE_Class* CFXJSE_Class::Create(CFXJSE_Context* lpContext, + const FXJSE_CLASS* lpClassDefinition, + FX_BOOL bIsJSGlobal) { + if (!lpContext || !lpClassDefinition) { + return NULL; + } + CFXJSE_Class* pClass = + GetClassFromContext(lpContext, lpClassDefinition->name); + if (pClass) { + return pClass; + } + v8::Isolate* pIsolate = lpContext->m_pIsolate; + pClass = new CFXJSE_Class(lpContext); + pClass->m_szClassName = lpClassDefinition->name; + pClass->m_lpClassDefinition = lpClassDefinition; + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); + v8::Local hFunctionTemplate = v8::FunctionTemplate::New( + pIsolate, bIsJSGlobal ? 0 : FXJSE_V8ConstructorCallback_Wrapper, + v8::External::New(pIsolate, const_cast(lpClassDefinition))); + hFunctionTemplate->SetClassName( + v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name)); + hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(1); + v8::Local hObjectTemplate = + hFunctionTemplate->InstanceTemplate(); + SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition); + + if (lpClassDefinition->propNum) { + for (int32_t i = 0; i < lpClassDefinition->propNum; i++) { + hObjectTemplate->SetNativeDataProperty( + v8::String::NewFromUtf8(pIsolate, + lpClassDefinition->properties[i].name), + lpClassDefinition->properties[i].getProc + ? FXJSE_V8GetterCallback_Wrapper + : NULL, + lpClassDefinition->properties[i].setProc + ? FXJSE_V8SetterCallback_Wrapper + : NULL, + v8::External::New(pIsolate, const_cast( + lpClassDefinition->properties + i)), + static_cast(v8::DontDelete)); + } + } + if (lpClassDefinition->methNum) { + for (int32_t i = 0; i < lpClassDefinition->methNum; i++) { + hObjectTemplate->Set( + v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name), + v8::FunctionTemplate::New( + pIsolate, FXJSE_V8FunctionCallback_Wrapper, + v8::External::New(pIsolate, const_cast( + lpClassDefinition->methods + i))), + static_cast(v8::ReadOnly | v8::DontDelete)); + } + } + if (lpClassDefinition->constructor) { + if (bIsJSGlobal) { + hObjectTemplate->Set( + v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), + v8::FunctionTemplate::New( + pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper, + v8::External::New(pIsolate, + const_cast(lpClassDefinition))), + static_cast(v8::ReadOnly | v8::DontDelete)); + } else { + v8::Local hLocalContext = + v8::Local::New(pIsolate, lpContext->m_hContext); + FXJSE_GetGlobalObjectFromContext(hLocalContext) + ->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), + v8::Function::New( + pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper, + v8::External::New(pIsolate, const_cast( + lpClassDefinition)))); + } + } + if (bIsJSGlobal) { + hObjectTemplate->Set( + v8::String::NewFromUtf8(pIsolate, "toString"), + v8::FunctionTemplate::New( + pIsolate, FXJSE_Context_GlobalObjToString, + v8::External::New(pIsolate, + const_cast(lpClassDefinition)))); + } + pClass->m_hTemplate.Reset(lpContext->m_pIsolate, hFunctionTemplate); + lpContext->m_rgClasses.Add(pClass); + return pClass; +} +CFXJSE_Class* CFXJSE_Class::GetClassFromContext(CFXJSE_Context* pContext, + const CFX_ByteStringC& szName) { + for (int count = pContext->m_rgClasses.GetSize(), i = 0; i < count; i++) { + CFXJSE_Class* pClass = pContext->m_rgClasses[i]; + if (pClass->m_szClassName == szName) { + return pClass; + } + } + return NULL; +} diff --git a/xfa/src/fxjse/class.h b/xfa/src/fxjse/class.h new file mode 100644 index 0000000000..f5738ebcc6 --- /dev/null +++ b/xfa/src/fxjse/class.h @@ -0,0 +1,49 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_CLASS_H_ +#define XFA_SRC_FXJSE_CLASS_H_ + +#include "v8/include/v8.h" +#include "xfa/include/fxjse/fxjse.h" + +class CFXJSE_Context; +class CFXJSE_Value; + +class CFXJSE_Class { + protected: + CFXJSE_Class(CFXJSE_Context* lpContext) + : m_lpClassDefinition(nullptr), m_pContext(lpContext) {} + + public: + inline CFXJSE_Context* GetContext() { return m_pContext; } + inline v8::Global& GetTemplate() { return m_hTemplate; } + + public: + static CFXJSE_Class* Create(CFXJSE_Context* pContext, + const FXJSE_CLASS* lpClassDefintion, + FX_BOOL bIsJSGlobal = FALSE); + static CFXJSE_Class* GetClassFromContext(CFXJSE_Context* pContext, + const CFX_ByteStringC& szName); + static void SetUpNamedPropHandler( + v8::Isolate* pIsolate, + v8::Local& hObjectTemplate, + const FXJSE_CLASS* lpClassDefinition); + + protected: + CFX_ByteString m_szClassName; + const FXJSE_CLASS* m_lpClassDefinition; + CFXJSE_Context* m_pContext; + v8::Global m_hTemplate; + friend class CFXJSE_Context; + friend class CFXJSE_Value; +}; +struct CFXJSE_ArgumentsImpl { + const v8::FunctionCallbackInfo* m_pInfo; + CFXJSE_Value* m_pRetValue; +}; + +#endif // XFA_SRC_FXJSE_CLASS_H_ diff --git a/xfa/src/fxjse/context.cpp b/xfa/src/fxjse/context.cpp new file mode 100644 index 0000000000..485869d797 --- /dev/null +++ b/xfa/src/fxjse/context.cpp @@ -0,0 +1,275 @@ +// 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 + +#include "xfa/src/fxjse/context.h" + +#include "xfa/src/fxjse/class.h" +#include "xfa/src/fxjse/scope_inline.h" +#include "xfa/src/fxjse/util_inline.h" +#include "xfa/src/fxjse/value.h" + +FXJSE_HCONTEXT FXJSE_Context_Create(FXJSE_HRUNTIME hRuntime, + const FXJSE_CLASS* lpGlobalClass, + void* lpGlobalObject) { + CFXJSE_Context* pContext = CFXJSE_Context::Create( + reinterpret_cast(hRuntime), lpGlobalClass, lpGlobalObject); + return reinterpret_cast(pContext); +} + +void FXJSE_Context_Release(FXJSE_HCONTEXT hContext) { + CFXJSE_Context* pContext = reinterpret_cast(hContext); + if (pContext) { + delete pContext; + } +} + +FXJSE_HVALUE FXJSE_Context_GetGlobalObject(FXJSE_HCONTEXT hContext) { + CFXJSE_Context* pContext = reinterpret_cast(hContext); + if (!pContext) { + return NULL; + } + CFXJSE_Value* lpValue = CFXJSE_Value::Create(pContext->GetRuntime()); + ASSERT(lpValue); + pContext->GetGlobalObject(lpValue); + return reinterpret_cast(lpValue); +} + +FXJSE_HRUNTIME FXJSE_Context_GetRuntime(FXJSE_HCONTEXT hContext) { + CFXJSE_Context* pContext = reinterpret_cast(hContext); + return pContext ? reinterpret_cast(pContext->GetRuntime()) + : NULL; +} + +static const FX_CHAR* szCompatibleModeScripts[] = { + "(function(global, list) {\n" + " 'use strict';\n" + " var objname;\n" + " for (objname in list) {\n" + " var globalobj = global[objname];\n" + " if (globalobj) {\n" + " list[objname].forEach(function(name) {\n" + " if (!globalobj[name]) {\n" + " Object.defineProperty(globalobj, name, {\n" + " writable: true,\n" + " enumerable: false,\n" + " value: (function(obj) {\n" + " if (arguments.length === 0) {\n" + " throw new TypeError('missing argument 0 when calling " + " function ' + objname + '.' + name);\n" + " }\n" + " return globalobj.prototype[name].apply(obj, " + " Array.prototype.slice.call(arguments, 1));\n" + " })\n" + " });\n" + " }\n" + " });\n" + " }\n" + " }\n" + "}(this, {String: ['substr', 'toUpperCase']}));"}; +void FXJSE_Context_EnableCompatibleMode(FXJSE_HCONTEXT hContext, + FX_DWORD dwCompatibleFlags) { + for (uint32_t i = 0; i < (uint32_t)FXJSE_COMPATIBLEMODEFLAGCOUNT; i++) { + if (dwCompatibleFlags & (1 << i)) { + FXJSE_ExecuteScript(hContext, szCompatibleModeScripts[i], NULL, NULL); + } + } +} + +FX_BOOL FXJSE_ExecuteScript(FXJSE_HCONTEXT hContext, + const FX_CHAR* szScript, + FXJSE_HVALUE hRetValue, + FXJSE_HVALUE hNewThisObject) { + CFXJSE_Context* pContext = reinterpret_cast(hContext); + ASSERT(pContext); + return pContext->ExecuteScript( + szScript, reinterpret_cast(hRetValue), + reinterpret_cast(hNewThisObject)); +} + +v8::Local FXJSE_CreateReturnValue(v8::Isolate* pIsolate, + v8::TryCatch& trycatch) { + v8::Local hReturnValue = v8::Object::New(pIsolate); + if (trycatch.HasCaught()) { + v8::Local hException = trycatch.Exception(); + v8::Local hMessage = trycatch.Message(); + if (hException->IsObject()) { + v8::Local hValue; + hValue = hException.As()->Get( + v8::String::NewFromUtf8(pIsolate, "name")); + if (hValue->IsString() || hValue->IsStringObject()) { + hReturnValue->Set(0, hValue); + } else { + hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error")); + } + hValue = hException.As()->Get( + v8::String::NewFromUtf8(pIsolate, "message")); + if (hValue->IsString() || hValue->IsStringObject()) { + hReturnValue->Set(1, hValue); + } else { + hReturnValue->Set(1, hMessage->Get()); + } + } else { + hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error")); + hReturnValue->Set(1, hMessage->Get()); + } + hReturnValue->Set(2, hException); + hReturnValue->Set(3, v8::Integer::New(pIsolate, hMessage->GetLineNumber())); + hReturnValue->Set(4, hMessage->GetSourceLine()); + v8::Maybe maybe_int = + hMessage->GetStartColumn(pIsolate->GetCurrentContext()); + hReturnValue->Set(5, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0))); + maybe_int = hMessage->GetEndColumn(pIsolate->GetCurrentContext()); + hReturnValue->Set(6, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0))); + } + return hReturnValue; +} + +FX_BOOL FXJSE_ReturnValue_GetMessage(FXJSE_HVALUE hRetValue, + CFX_ByteString& utf8Name, + CFX_ByteString& utf8Message) { + CFXJSE_Value* lpValue = reinterpret_cast(hRetValue); + if (!lpValue) { + return FALSE; + } + v8::Isolate* pIsolate = lpValue->GetIsolate(); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); + v8::Local hValue = + v8::Local::New(pIsolate, lpValue->DirectGetValue()); + if (!hValue->IsObject()) { + return FALSE; + } + v8::String::Utf8Value hStringVal0( + hValue.As()->Get(0)->ToString()); + utf8Name = *hStringVal0; + v8::String::Utf8Value hStringVal1( + hValue.As()->Get(1)->ToString()); + utf8Message = *hStringVal1; + return TRUE; +} + +FX_BOOL FXJSE_ReturnValue_GetLineInfo(FXJSE_HVALUE hRetValue, + int32_t& nLine, + int32_t& nCol) { + CFXJSE_Value* lpValue = reinterpret_cast(hRetValue); + if (!lpValue) { + return FALSE; + } + v8::Isolate* pIsolate = lpValue->GetIsolate(); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); + v8::Local hValue = + v8::Local::New(pIsolate, lpValue->DirectGetValue()); + if (!hValue->IsObject()) { + return FALSE; + } + v8::MaybeLocal maybe_int = + hValue.As()->Get(3)->ToInt32(pIsolate->GetCurrentContext()); + nLine = maybe_int.FromMaybe(v8::Local())->Value(); + maybe_int = + hValue.As()->Get(5)->ToInt32(pIsolate->GetCurrentContext()); + nCol = maybe_int.FromMaybe(v8::Local())->Value(); + return TRUE; +} + +CFXJSE_Context* CFXJSE_Context::Create(v8::Isolate* pIsolate, + const FXJSE_CLASS* lpGlobalClass, + void* lpGlobalObject) { + CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); + CFXJSE_Context* pContext = new CFXJSE_Context(pIsolate); + CFXJSE_Class* lpGlobalClassObj = NULL; + v8::Local hObjectTemplate; + if (lpGlobalClass) { + lpGlobalClassObj = CFXJSE_Class::Create(pContext, lpGlobalClass, TRUE); + ASSERT(lpGlobalClassObj); + v8::Local hFunctionTemplate = + v8::Local::New(pIsolate, + lpGlobalClassObj->m_hTemplate); + hObjectTemplate = hFunctionTemplate->InstanceTemplate(); + } else { + hObjectTemplate = v8::ObjectTemplate::New(pIsolate); + hObjectTemplate->SetInternalFieldCount(1); + } + v8::Local hNewContext = + v8::Context::New(pIsolate, NULL, hObjectTemplate); + v8::Local hRootContext = v8::Local::New( + pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext); + hNewContext->SetSecurityToken(hRootContext->GetSecurityToken()); + v8::Local hGlobalObject = + FXJSE_GetGlobalObjectFromContext(hNewContext); + FXJSE_UpdateObjectBinding(hGlobalObject, lpGlobalObject); + pContext->m_hContext.Reset(pIsolate, hNewContext); + return pContext; +} + +CFXJSE_Context::~CFXJSE_Context() { + for (int32_t i = 0, count = m_rgClasses.GetSize(); i < count; i++) { + CFXJSE_Class* pClass = m_rgClasses[i]; + if (pClass) { + delete pClass; + } + } + m_rgClasses.RemoveAll(); +} + +void CFXJSE_Context::GetGlobalObject(CFXJSE_Value* pValue) { + ASSERT(pValue); + CFXJSE_ScopeUtil_IsolateHandleContext scope(this); + v8::Local hContext = + v8::Local::New(m_pIsolate, m_hContext); + v8::Local hGlobalObject = hContext->Global(); + pValue->ForceSetValue(hGlobalObject); +} + +FX_BOOL CFXJSE_Context::ExecuteScript(const FX_CHAR* szScript, + CFXJSE_Value* lpRetValue, + CFXJSE_Value* lpNewThisObject) { + CFXJSE_ScopeUtil_IsolateHandleContext scope(this); + v8::TryCatch trycatch(m_pIsolate); + v8::Local hScriptString = + v8::String::NewFromUtf8(m_pIsolate, szScript); + if (lpNewThisObject == NULL) { + v8::Local hScript = v8::Script::Compile(hScriptString); + if (!trycatch.HasCaught()) { + v8::Local hValue = hScript->Run(); + if (!trycatch.HasCaught()) { + if (lpRetValue) { + lpRetValue->m_hValue.Reset(m_pIsolate, hValue); + } + return TRUE; + } + } + if (lpRetValue) { + lpRetValue->m_hValue.Reset(m_pIsolate, + FXJSE_CreateReturnValue(m_pIsolate, trycatch)); + } + return FALSE; + } else { + v8::Local hNewThis = + v8::Local::New(m_pIsolate, lpNewThisObject->m_hValue); + ASSERT(!hNewThis.IsEmpty()); + v8::Local hWrapper = + v8::Script::Compile(v8::String::NewFromUtf8( + m_pIsolate, "(function () { return eval(arguments[0]); })")); + v8::Local hWrapperValue = hWrapper->Run(); + ASSERT(hWrapperValue->IsFunction()); + v8::Local hWrapperFn = hWrapperValue.As(); + if (!trycatch.HasCaught()) { + v8::Local rgArgs[] = {hScriptString}; + v8::Local hValue = + hWrapperFn->Call(hNewThis.As(), 1, rgArgs); + if (!trycatch.HasCaught()) { + if (lpRetValue) { + lpRetValue->m_hValue.Reset(m_pIsolate, hValue); + } + return TRUE; + } + } + if (lpRetValue) { + lpRetValue->m_hValue.Reset(m_pIsolate, + FXJSE_CreateReturnValue(m_pIsolate, trycatch)); + } + return FALSE; + } +} diff --git a/xfa/src/fxjse/context.h b/xfa/src/fxjse/context.h new file mode 100644 index 0000000000..cedf11cce6 --- /dev/null +++ b/xfa/src/fxjse/context.h @@ -0,0 +1,47 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_CONTEXT_H_ +#define XFA_SRC_FXJSE_CONTEXT_H_ + +#include "v8/include/v8.h" +#include "xfa/include/fxjse/fxjse.h" + +class CFXJSE_Class; +class CFXJSE_Value; + +class CFXJSE_Context { + protected: + CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} + + public: + static CFXJSE_Context* Create(v8::Isolate* pIsolate, + const FXJSE_CLASS* lpGlobalClass = NULL, + void* lpGlobalObject = NULL); + ~CFXJSE_Context(); + V8_INLINE v8::Isolate* GetRuntime(void) { return m_pIsolate; } + void GetGlobalObject(CFXJSE_Value* pValue); + FX_BOOL ExecuteScript(const FX_CHAR* szScript, + CFXJSE_Value* lpRetValue, + CFXJSE_Value* lpNewThisObject = NULL); + + protected: + CFXJSE_Context(); + CFXJSE_Context(const CFXJSE_Context&); + CFXJSE_Context& operator=(const CFXJSE_Context&); + + protected: + v8::Global m_hContext; + v8::Isolate* m_pIsolate; + CFX_ArrayTemplate m_rgClasses; + friend class CFXJSE_Class; + friend class CFXJSE_ScopeUtil_IsolateHandleContext; + friend class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext; +}; +v8::Local FXJSE_CreateReturnValue(v8::Isolate* pIsolate, + v8::TryCatch& trycatch); + +#endif // XFA_SRC_FXJSE_CONTEXT_H_ diff --git a/xfa/src/fxjse/dynprop.cpp b/xfa/src/fxjse/dynprop.cpp new file mode 100644 index 0000000000..55ca6ed8cd --- /dev/null +++ b/xfa/src/fxjse/dynprop.cpp @@ -0,0 +1,236 @@ +// 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 + +#include "xfa/src/fxjse/class.h" +#include "xfa/src/fxjse/value.h" + +static void FXJSE_DynPropGetterAdapter_MethodCallback( + const v8::FunctionCallbackInfo& info) { + v8::Local hCallBackInfo = info.Data().As(); + FXJSE_CLASS* lpClass = static_cast( + hCallBackInfo->GetAlignedPointerFromInternalField(0)); + v8::Local hPropName = + hCallBackInfo->GetInternalField(1).As(); + ASSERT(lpClass && !hPropName.IsEmpty()); + v8::String::Utf8Value szPropName(hPropName); + CFX_ByteStringC szFxPropName = *szPropName; + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; + lpClass->dynMethodCall(reinterpret_cast(lpThisValue), + szFxPropName, + reinterpret_cast(impl)); + if (!lpRetValue->DirectGetValue().IsEmpty()) { + info.GetReturnValue().Set(lpRetValue->DirectGetValue()); + } + delete lpRetValue; + lpRetValue = nullptr; + delete lpThisValue; + lpThisValue = nullptr; +} + +static void FXJSE_DynPropGetterAdapter(const FXJSE_CLASS* lpClass, + FXJSE_HOBJECT hObject, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue) { + ASSERT(lpClass); + int32_t nPropType = + lpClass->dynPropTypeGetter == nullptr + ? FXJSE_ClassPropType_Property + : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); + if (nPropType == FXJSE_ClassPropType_Property) { + if (lpClass->dynPropGetter) { + lpClass->dynPropGetter(hObject, szPropName, hValue); + } + } else if (nPropType == FXJSE_ClassPropType_Method) { + if (lpClass->dynMethodCall && hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + v8::Isolate* pIsolate = lpValue->GetIsolate(); + v8::HandleScope hscope(pIsolate); + v8::Local hCallBackInfoTemplate = + v8::ObjectTemplate::New(pIsolate); + hCallBackInfoTemplate->SetInternalFieldCount(2); + v8::Local hCallBackInfo = + hCallBackInfoTemplate->NewInstance(); + hCallBackInfo->SetAlignedPointerInInternalField( + 0, const_cast(lpClass)); + hCallBackInfo->SetInternalField( + 1, v8::String::NewFromUtf8( + pIsolate, reinterpret_cast(szPropName.GetPtr()), + v8::String::kNormalString, szPropName.GetLength())); + lpValue->ForceSetValue(v8::Function::New( + lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback, + hCallBackInfo)); + } + } +} + +static void FXJSE_DynPropSetterAdapter(const FXJSE_CLASS* lpClass, + FXJSE_HOBJECT hObject, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hValue) { + ASSERT(lpClass); + int32_t nPropType = + lpClass->dynPropTypeGetter == nullptr + ? FXJSE_ClassPropType_Property + : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); + if (nPropType != FXJSE_ClassPropType_Method) { + if (lpClass->dynPropSetter) { + lpClass->dynPropSetter(hObject, szPropName, hValue); + } + } +} + +static FX_BOOL FXJSE_DynPropQueryAdapter(const FXJSE_CLASS* lpClass, + FXJSE_HOBJECT hObject, + const CFX_ByteStringC& szPropName) { + ASSERT(lpClass); + int32_t nPropType = + lpClass->dynPropTypeGetter == nullptr + ? FXJSE_ClassPropType_Property + : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE); + return nPropType != FXJSE_ClassPropType_None; +} + +static FX_BOOL FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS* lpClass, + FXJSE_HOBJECT hObject, + const CFX_ByteStringC& szPropName) { + ASSERT(lpClass); + int32_t nPropType = + lpClass->dynPropTypeGetter == nullptr + ? FXJSE_ClassPropType_Property + : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); + if (nPropType != FXJSE_ClassPropType_Method) { + if (lpClass->dynPropDeleter) { + return lpClass->dynPropDeleter(hObject, szPropName); + } else { + return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE; + } + } + return FALSE; +} + +static void FXJSE_V8_GenericNamedPropertyQueryCallback( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + v8::Local thisObject = info.This(); + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + v8::String::Utf8Value szPropName(property); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(thisObject); + if (FXJSE_DynPropQueryAdapter(lpClass, + reinterpret_cast(lpThisValue), + szFxPropName)) { + info.GetReturnValue().Set(v8::DontDelete); + } else { + const int32_t iV8Absent = 64; + info.GetReturnValue().Set(iV8Absent); + } + delete lpThisValue; + lpThisValue = nullptr; +} + +static void FXJSE_V8_GenericNamedPropertyDeleterCallback( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + v8::Local thisObject = info.This(); + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + v8::String::Utf8Value szPropName(property); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(thisObject); + info.GetReturnValue().Set( + FXJSE_DynPropDeleterAdapter( + lpClass, reinterpret_cast(lpThisValue), szFxPropName) + ? true + : false); + delete lpThisValue; + lpThisValue = nullptr; +} + +static void FXJSE_V8_GenericNamedPropertyGetterCallback( + v8::Local property, + const v8::PropertyCallbackInfo& info) { + v8::Local thisObject = info.This(); + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + v8::String::Utf8Value szPropName(property); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(thisObject); + CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); + FXJSE_DynPropGetterAdapter( + lpClass, reinterpret_cast(lpThisValue), szFxPropName, + reinterpret_cast(lpNewValue)); + info.GetReturnValue().Set(lpNewValue->DirectGetValue()); + delete lpThisValue; + lpThisValue = nullptr; +} + +static void FXJSE_V8_GenericNamedPropertySetterCallback( + v8::Local property, + v8::Local value, + const v8::PropertyCallbackInfo& info) { + v8::Local thisObject = info.This(); + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + v8::String::Utf8Value szPropName(property); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(thisObject); + CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); + lpNewValue->ForceSetValue(value); + FXJSE_DynPropSetterAdapter( + lpClass, reinterpret_cast(lpThisValue), szFxPropName, + reinterpret_cast(lpNewValue)); + info.GetReturnValue().Set(value); + delete lpThisValue; + lpThisValue = nullptr; +} + +static void FXJSE_V8_GenericNamedPropertyEnumeratorCallback( + const v8::PropertyCallbackInfo& info) { + const FXJSE_CLASS* lpClass = + static_cast(info.Data().As()->Value()); + v8::Isolate* pIsolate = info.GetIsolate(); + v8::Local newArray = v8::Array::New(pIsolate, lpClass->propNum); + for (int i = 0; i < lpClass->propNum; i++) { + newArray->Set( + i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name)); + } + info.GetReturnValue().Set(newArray); +} + +void CFXJSE_Class::SetUpNamedPropHandler( + v8::Isolate* pIsolate, + v8::Local& hObjectTemplate, + const FXJSE_CLASS* lpClassDefinition) { + v8::NamedPropertyHandlerConfiguration configuration( + lpClassDefinition->dynPropGetter + ? FXJSE_V8_GenericNamedPropertyGetterCallback + : 0, + lpClassDefinition->dynPropSetter + ? FXJSE_V8_GenericNamedPropertySetterCallback + : 0, + lpClassDefinition->dynPropTypeGetter + ? FXJSE_V8_GenericNamedPropertyQueryCallback + : 0, + lpClassDefinition->dynPropDeleter + ? FXJSE_V8_GenericNamedPropertyDeleterCallback + : 0, + FXJSE_V8_GenericNamedPropertyEnumeratorCallback, + v8::External::New(pIsolate, const_cast(lpClassDefinition)), + v8::PropertyHandlerFlags::kNonMasking); + hObjectTemplate->SetHandler(configuration); +} diff --git a/xfa/src/fxjse/runtime.cpp b/xfa/src/fxjse/runtime.cpp new file mode 100644 index 0000000000..69a0ed1d5e --- /dev/null +++ b/xfa/src/fxjse/runtime.cpp @@ -0,0 +1,128 @@ +// 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 + +#include "xfa/src/fxjse/runtime.h" + +#include "fpdfsdk/include/jsapi/fxjs_v8.h" +#include "xfa/src/fxjse/scope_inline.h" + +// Duplicates fpdfsdk's JS_Runtime.h, but keeps XFA from depending on it. +// TODO(tsepez): make a single version of this. +class FXJSE_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { + void* Allocate(size_t length) override { return calloc(1, length); } + void* AllocateUninitialized(size_t length) override { return malloc(length); } + void Free(void* data, size_t length) override { free(data); } +}; + +static void FXJSE_KillV8() { + v8::V8::Dispose(); +} + +void FXJSE_Initialize() { + if (!CFXJSE_RuntimeData::g_RuntimeList) { + CFXJSE_RuntimeData::g_RuntimeList = new CFXJSE_RuntimeList; + } + static FX_BOOL bV8Initialized = FALSE; + if (bV8Initialized) { + return; + } + bV8Initialized = TRUE; + atexit(FXJSE_KillV8); +} + +static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate) { + { + v8::Locker locker(pIsolate); + if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) { + delete pData->m_pFXJSERuntimeData; + pData->m_pFXJSERuntimeData = nullptr; + } + } + pIsolate->Dispose(); +} + +void FXJSE_Finalize() { + if (CFXJSE_RuntimeData::g_RuntimeList) { + CFXJSE_RuntimeData::g_RuntimeList->RemoveAllRuntimes( + FXJSE_Runtime_DisposeCallback); + delete CFXJSE_RuntimeData::g_RuntimeList; + CFXJSE_RuntimeData::g_RuntimeList = NULL; + } +} + +FXJSE_HRUNTIME FXJSE_Runtime_Create() { + v8::Isolate::CreateParams params; + params.array_buffer_allocator = new FXJSE_ArrayBufferAllocator(); + v8::Isolate* pIsolate = v8::Isolate::New(params); + ASSERT(pIsolate && CFXJSE_RuntimeData::g_RuntimeList); + CFXJSE_RuntimeData::g_RuntimeList->AppendRuntime(pIsolate); + return reinterpret_cast(pIsolate); +} + +void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime, bool bOwnedRuntime) { + v8::Isolate* pIsolate = reinterpret_cast(hRuntime); + if (!pIsolate) + return; + if (bOwnedRuntime) { + ASSERT(CFXJSE_RuntimeData::g_RuntimeList); + CFXJSE_RuntimeData::g_RuntimeList->RemoveRuntime( + pIsolate, FXJSE_Runtime_DisposeCallback); + } else { + if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) { + delete pData->m_pFXJSERuntimeData; + pData->m_pFXJSERuntimeData = nullptr; + } + } +} + +CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) { + CFXJSE_RuntimeData* pRuntimeData = new CFXJSE_RuntimeData(pIsolate); + CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); + v8::Local hFuncTemplate = + v8::FunctionTemplate::New(pIsolate); + v8::Local hContext = + v8::Context::New(pIsolate, 0, hFuncTemplate->InstanceTemplate()); + hContext->SetSecurityToken(v8::External::New(pIsolate, pIsolate)); + pRuntimeData->m_hRootContextGlobalTemplate.Reset(pIsolate, hFuncTemplate); + pRuntimeData->m_hRootContext.Reset(pIsolate, hContext); + return pRuntimeData; +} + +CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate) { + FXJS_PerIsolateData::SetUp(pIsolate); + FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); + if (!pData->m_pFXJSERuntimeData) + pData->m_pFXJSERuntimeData = CFXJSE_RuntimeData::Create(pIsolate); + return pData->m_pFXJSERuntimeData; +} + +CFXJSE_RuntimeList* CFXJSE_RuntimeData::g_RuntimeList = NULL; +void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate) { + m_RuntimeList.Add(pIsolate); +} + +void CFXJSE_RuntimeList::RemoveRuntime( + v8::Isolate* pIsolate, + CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) { + int32_t iIdx = m_RuntimeList.Find(pIsolate, 0); + if (iIdx >= 0) { + m_RuntimeList.RemoveAt(iIdx, 1); + } + if (lpfnDisposeCallback) { + lpfnDisposeCallback(pIsolate); + } +} + +void CFXJSE_RuntimeList::RemoveAllRuntimes( + CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) { + int32_t iSize = m_RuntimeList.GetSize(); + if (lpfnDisposeCallback) { + for (int32_t iIdx = 0; iIdx < iSize; iIdx++) { + lpfnDisposeCallback(m_RuntimeList[iIdx]); + } + } + m_RuntimeList.RemoveAll(); +} diff --git a/xfa/src/fxjse/runtime.h b/xfa/src/fxjse/runtime.h new file mode 100644 index 0000000000..a93a589bb4 --- /dev/null +++ b/xfa/src/fxjse/runtime.h @@ -0,0 +1,51 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_RUNTIME_H_ +#define XFA_SRC_FXJSE_RUNTIME_H_ + +#include "core/include/fxcrt/fx_basic.h" +#include "v8/include/v8.h" + +class CFXJSE_RuntimeList; + +class CFXJSE_RuntimeData { + protected: + CFXJSE_RuntimeData(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} + + public: + static CFXJSE_RuntimeData* Create(v8::Isolate* pIsolate); + static CFXJSE_RuntimeData* Get(v8::Isolate* pIsolate); + + public: + v8::Isolate* m_pIsolate; + v8::Global m_hRootContextGlobalTemplate; + v8::Global m_hRootContext; + + public: + static CFXJSE_RuntimeList* g_RuntimeList; + + protected: + CFXJSE_RuntimeData(); + CFXJSE_RuntimeData(const CFXJSE_RuntimeData&); + CFXJSE_RuntimeData& operator=(const CFXJSE_RuntimeData&); +}; + +class CFXJSE_RuntimeList { + public: + typedef void (*RuntimeDisposeCallback)(v8::Isolate*); + + public: + void AppendRuntime(v8::Isolate* pIsolate); + void RemoveRuntime(v8::Isolate* pIsolate, + RuntimeDisposeCallback lpfnDisposeCallback); + void RemoveAllRuntimes(RuntimeDisposeCallback lpfnDisposeCallback); + + protected: + CFX_ArrayTemplate m_RuntimeList; +}; + +#endif // XFA_SRC_FXJSE_RUNTIME_H_ diff --git a/xfa/src/fxjse/scope_inline.h b/xfa/src/fxjse/scope_inline.h new file mode 100644 index 0000000000..6105590966 --- /dev/null +++ b/xfa/src/fxjse/scope_inline.h @@ -0,0 +1,108 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_SCOPE_INLINE_H_ +#define XFA_SRC_FXJSE_SCOPE_INLINE_H_ + +#include "xfa/src/fxjse/context.h" +#include "xfa/src/fxjse/runtime.h" + +class CFXJSE_ScopeUtil_IsolateHandle { + protected: + v8::Isolate* m_isolate; + v8::Locker m_locker; + v8::Isolate::Scope m_iscope; + v8::HandleScope m_hscope; + + public: + explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate) + : m_isolate(pIsolate), + m_locker(pIsolate), + m_iscope(pIsolate), + m_hscope(pIsolate) {} + v8::Isolate* GetIsolate() { return m_isolate; } + + private: + CFXJSE_ScopeUtil_IsolateHandle(const CFXJSE_ScopeUtil_IsolateHandle&); + void operator=(const CFXJSE_ScopeUtil_IsolateHandle&); + void* operator new(size_t size); + void operator delete(void*, size_t); +}; +class CFXJSE_ScopeUtil_IsolateHandleRootContext { + CFXJSE_ScopeUtil_IsolateHandle m_parent; + v8::Context::Scope m_cscope; + + public: + explicit CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate) + : m_parent(pIsolate), + m_cscope(v8::Local::New( + pIsolate, + CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {} + + private: + CFXJSE_ScopeUtil_IsolateHandleRootContext( + const CFXJSE_ScopeUtil_IsolateHandleRootContext&); + void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootContext&); + void* operator new(size_t size); + void operator delete(void*, size_t); +}; +class CFXJSE_ScopeUtil_IsolateHandleContext { + CFXJSE_Context* m_context; + CFXJSE_ScopeUtil_IsolateHandle m_parent; + v8::Context::Scope m_cscope; + + public: + explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext) + : m_context(pContext), + m_parent(pContext->m_pIsolate), + m_cscope(v8::Local::New(pContext->m_pIsolate, + pContext->m_hContext)) {} + v8::Isolate* GetIsolate() { return m_context->m_pIsolate; } + v8::Local GetLocalContext() { + return v8::Local::New(m_context->m_pIsolate, + m_context->m_hContext); + } + + private: + CFXJSE_ScopeUtil_IsolateHandleContext( + const CFXJSE_ScopeUtil_IsolateHandleContext&); + void operator=(const CFXJSE_ScopeUtil_IsolateHandleContext&); + void* operator new(size_t size); + void operator delete(void*, size_t); +}; +class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext { + CFXJSE_Context* m_context; + CFXJSE_ScopeUtil_IsolateHandle m_parent; + v8::Context::Scope m_cscope; + + public: + explicit CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext( + v8::Isolate* pIsolate, + CFXJSE_Context* pContext) + : m_context(pContext), + m_parent(pIsolate), + m_cscope(v8::Local::New( + pIsolate, + pContext ? pContext->m_hContext + : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {} + v8::Isolate* GetIsolate() { return m_parent.GetIsolate(); } + v8::Local GetLocalContext() { + v8::Isolate* pIsolate = m_parent.GetIsolate(); + return v8::Local::New( + pIsolate, m_context + ? m_context->m_hContext + : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext); + } + + private: + CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext( + const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&); + void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&); + void* operator new(size_t size); + void operator delete(void*, size_t); +}; + +#endif // XFA_SRC_FXJSE_SCOPE_INLINE_H_ diff --git a/xfa/src/fxjse/src/class.cpp b/xfa/src/fxjse/src/class.cpp deleted file mode 100644 index 57e513cc30..0000000000 --- a/xfa/src/fxjse/src/class.cpp +++ /dev/null @@ -1,348 +0,0 @@ -// 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 - -#include "xfa/src/fxjse/src/class.h" - -#include "xfa/src/fxjse/src/context.h" -#include "xfa/src/fxjse/src/scope_inline.h" -#include "xfa/src/fxjse/src/util_inline.h" -#include "xfa/src/fxjse/src/value.h" - -static void FXJSE_V8ConstructorCallback_Wrapper( - const v8::FunctionCallbackInfo& info); -static void FXJSE_V8FunctionCallback_Wrapper( - const v8::FunctionCallbackInfo& info); -static void FXJSE_V8GetterCallback_Wrapper( - v8::Local property, - const v8::PropertyCallbackInfo& info); -static void FXJSE_V8SetterCallback_Wrapper( - v8::Local property, - v8::Local value, - const v8::PropertyCallbackInfo& info); - -void FXJSE_DefineFunctions(FXJSE_HCONTEXT hContext, - const FXJSE_FUNCTION* lpFunctions, - int nNum) { - CFXJSE_Context* lpContext = reinterpret_cast(hContext); - ASSERT(lpContext); - CFXJSE_ScopeUtil_IsolateHandleContext scope(lpContext); - v8::Isolate* pIsolate = lpContext->GetRuntime(); - v8::Local hGlobalObject = - FXJSE_GetGlobalObjectFromContext(scope.GetLocalContext()); - for (int32_t i = 0; i < nNum; i++) { - v8::Maybe maybe_success = hGlobalObject->DefineOwnProperty( - scope.GetLocalContext(), - v8::String::NewFromUtf8(pIsolate, lpFunctions[i].name), - v8::Function::New( - pIsolate, FXJSE_V8FunctionCallback_Wrapper, - v8::External::New(pIsolate, - const_cast(lpFunctions + i))), - static_cast(v8::ReadOnly | v8::DontDelete)); - if (!maybe_success.FromMaybe(false)) - return; - } -} - -FXJSE_HCLASS FXJSE_DefineClass(FXJSE_HCONTEXT hContext, - const FXJSE_CLASS* lpClass) { - CFXJSE_Context* lpContext = reinterpret_cast(hContext); - ASSERT(lpContext); - return reinterpret_cast( - CFXJSE_Class::Create(lpContext, lpClass, FALSE)); -} - -FXJSE_HCLASS FXJSE_GetClass(FXJSE_HCONTEXT hContext, - const CFX_ByteStringC& szName) { - return reinterpret_cast(CFXJSE_Class::GetClassFromContext( - reinterpret_cast(hContext), szName)); -} - -static void FXJSE_V8FunctionCallback_Wrapper( - const v8::FunctionCallbackInfo& info) { - const FXJSE_FUNCTION* lpFunctionInfo = - static_cast(info.Data().As()->Value()); - if (!lpFunctionInfo) { - return; - } - CFX_ByteStringC szFunctionName(lpFunctionInfo->name); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(info.This()); - CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); - CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; - lpFunctionInfo->callbackProc(reinterpret_cast(lpThisValue), - szFunctionName, - reinterpret_cast(impl)); - if (!lpRetValue->DirectGetValue().IsEmpty()) { - info.GetReturnValue().Set(lpRetValue->DirectGetValue()); - } - delete lpRetValue; - lpRetValue = NULL; - delete lpThisValue; - lpThisValue = NULL; -} - -static void FXJSE_V8ClassGlobalConstructorCallback_Wrapper( - const v8::FunctionCallbackInfo& info) { - const FXJSE_CLASS* lpClassDefinition = - static_cast(info.Data().As()->Value()); - if (!lpClassDefinition) { - return; - } - CFX_ByteStringC szFunctionName(lpClassDefinition->name); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(info.This()); - CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); - CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; - lpClassDefinition->constructor(reinterpret_cast(lpThisValue), - szFunctionName, - reinterpret_cast(impl)); - if (!lpRetValue->DirectGetValue().IsEmpty()) { - info.GetReturnValue().Set(lpRetValue->DirectGetValue()); - } - delete lpRetValue; - lpRetValue = NULL; - delete lpThisValue; - lpThisValue = NULL; -} - -static void FXJSE_V8GetterCallback_Wrapper( - v8::Local property, - const v8::PropertyCallbackInfo& info) { - const FXJSE_PROPERTY* lpPropertyInfo = - static_cast(info.Data().As()->Value()); - if (!lpPropertyInfo) { - return; - } - CFX_ByteStringC szPropertyName(lpPropertyInfo->name); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(info.This()); - lpPropertyInfo->getProc(reinterpret_cast(lpThisValue), - szPropertyName, - reinterpret_cast(lpPropValue)); - info.GetReturnValue().Set(lpPropValue->DirectGetValue()); - delete lpThisValue; - lpThisValue = NULL; - delete lpPropValue; - lpPropValue = NULL; -} - -static void FXJSE_V8SetterCallback_Wrapper( - v8::Local property, - v8::Local value, - const v8::PropertyCallbackInfo& info) { - const FXJSE_PROPERTY* lpPropertyInfo = - static_cast(info.Data().As()->Value()); - if (!lpPropertyInfo) { - return; - } - CFX_ByteStringC szPropertyName(lpPropertyInfo->name); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(info.This()); - lpPropValue->ForceSetValue(value); - lpPropertyInfo->setProc(reinterpret_cast(lpThisValue), - szPropertyName, - reinterpret_cast(lpPropValue)); - delete lpThisValue; - lpThisValue = NULL; - delete lpPropValue; - lpPropValue = NULL; -} - -static void FXJSE_V8ConstructorCallback_Wrapper( - const v8::FunctionCallbackInfo& info) { - const FXJSE_CLASS* lpClassDefinition = - static_cast(info.Data().As()->Value()); - if (!lpClassDefinition) { - return; - } - FXSYS_assert(info.This()->InternalFieldCount()); - info.This()->SetAlignedPointerInInternalField(0, NULL); -} - -FXJSE_HRUNTIME CFXJSE_Arguments::GetRuntime() const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return reinterpret_cast( - lpArguments->m_pRetValue->GetIsolate()); -} - -int32_t CFXJSE_Arguments::GetLength() const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return lpArguments->m_pInfo->Length(); -} - -FXJSE_HVALUE CFXJSE_Arguments::GetValue(int32_t index) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - CFXJSE_Value* lpArgValue = CFXJSE_Value::Create(v8::Isolate::GetCurrent()); - ASSERT(lpArgValue); - lpArgValue->ForceSetValue((*lpArguments->m_pInfo)[index]); - return reinterpret_cast(lpArgValue); -} - -FX_BOOL CFXJSE_Arguments::GetBoolean(int32_t index) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return (*lpArguments->m_pInfo)[index]->BooleanValue(); -} - -int32_t CFXJSE_Arguments::GetInt32(int32_t index) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); -} - -FX_FLOAT CFXJSE_Arguments::GetFloat(int32_t index) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); -} - -CFX_ByteString CFXJSE_Arguments::GetUTF8String(int32_t index) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - v8::Local hString = (*lpArguments->m_pInfo)[index]->ToString(); - v8::String::Utf8Value szStringVal(hString); - return CFX_ByteString(*szStringVal); -} - -void* CFXJSE_Arguments::GetObject(int32_t index, FXJSE_HCLASS hClass) const { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - v8::Local hValue = (*lpArguments->m_pInfo)[index]; - ASSERT(!hValue.IsEmpty()); - if (!hValue->IsObject()) { - return NULL; - } - CFXJSE_Class* lpClass = reinterpret_cast(hClass); - return FXJSE_RetrieveObjectBinding(hValue.As(), lpClass); -} - -FXJSE_HVALUE CFXJSE_Arguments::GetReturnValue() { - const CFXJSE_ArgumentsImpl* lpArguments = - reinterpret_cast(this); - return reinterpret_cast(lpArguments->m_pRetValue); -} -static void FXJSE_Context_GlobalObjToString( - const v8::FunctionCallbackInfo& info) { - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - if (!lpClass) { - return; - } - if (info.This() == info.Holder() && lpClass->name) { - CFX_ByteString szStringVal; - szStringVal.Format("[object %s]", lpClass->name); - info.GetReturnValue().Set(v8::String::NewFromUtf8( - info.GetIsolate(), (const FX_CHAR*)szStringVal, - v8::String::kNormalString, szStringVal.GetLength())); - } else { - v8::Local local_str = - info.This() - ->ObjectProtoToString(info.GetIsolate()->GetCurrentContext()) - .FromMaybe(v8::Local()); - info.GetReturnValue().Set(local_str); - } -} - -CFXJSE_Class* CFXJSE_Class::Create(CFXJSE_Context* lpContext, - const FXJSE_CLASS* lpClassDefinition, - FX_BOOL bIsJSGlobal) { - if (!lpContext || !lpClassDefinition) { - return NULL; - } - CFXJSE_Class* pClass = - GetClassFromContext(lpContext, lpClassDefinition->name); - if (pClass) { - return pClass; - } - v8::Isolate* pIsolate = lpContext->m_pIsolate; - pClass = new CFXJSE_Class(lpContext); - pClass->m_szClassName = lpClassDefinition->name; - pClass->m_lpClassDefinition = lpClassDefinition; - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); - v8::Local hFunctionTemplate = v8::FunctionTemplate::New( - pIsolate, bIsJSGlobal ? 0 : FXJSE_V8ConstructorCallback_Wrapper, - v8::External::New(pIsolate, const_cast(lpClassDefinition))); - hFunctionTemplate->SetClassName( - v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name)); - hFunctionTemplate->InstanceTemplate()->SetInternalFieldCount(1); - v8::Local hObjectTemplate = - hFunctionTemplate->InstanceTemplate(); - SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition); - - if (lpClassDefinition->propNum) { - for (int32_t i = 0; i < lpClassDefinition->propNum; i++) { - hObjectTemplate->SetNativeDataProperty( - v8::String::NewFromUtf8(pIsolate, - lpClassDefinition->properties[i].name), - lpClassDefinition->properties[i].getProc - ? FXJSE_V8GetterCallback_Wrapper - : NULL, - lpClassDefinition->properties[i].setProc - ? FXJSE_V8SetterCallback_Wrapper - : NULL, - v8::External::New(pIsolate, const_cast( - lpClassDefinition->properties + i)), - static_cast(v8::DontDelete)); - } - } - if (lpClassDefinition->methNum) { - for (int32_t i = 0; i < lpClassDefinition->methNum; i++) { - hObjectTemplate->Set( - v8::String::NewFromUtf8(pIsolate, lpClassDefinition->methods[i].name), - v8::FunctionTemplate::New( - pIsolate, FXJSE_V8FunctionCallback_Wrapper, - v8::External::New(pIsolate, const_cast( - lpClassDefinition->methods + i))), - static_cast(v8::ReadOnly | v8::DontDelete)); - } - } - if (lpClassDefinition->constructor) { - if (bIsJSGlobal) { - hObjectTemplate->Set( - v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), - v8::FunctionTemplate::New( - pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper, - v8::External::New(pIsolate, - const_cast(lpClassDefinition))), - static_cast(v8::ReadOnly | v8::DontDelete)); - } else { - v8::Local hLocalContext = - v8::Local::New(pIsolate, lpContext->m_hContext); - FXJSE_GetGlobalObjectFromContext(hLocalContext) - ->Set(v8::String::NewFromUtf8(pIsolate, lpClassDefinition->name), - v8::Function::New( - pIsolate, FXJSE_V8ClassGlobalConstructorCallback_Wrapper, - v8::External::New(pIsolate, const_cast( - lpClassDefinition)))); - } - } - if (bIsJSGlobal) { - hObjectTemplate->Set( - v8::String::NewFromUtf8(pIsolate, "toString"), - v8::FunctionTemplate::New( - pIsolate, FXJSE_Context_GlobalObjToString, - v8::External::New(pIsolate, - const_cast(lpClassDefinition)))); - } - pClass->m_hTemplate.Reset(lpContext->m_pIsolate, hFunctionTemplate); - lpContext->m_rgClasses.Add(pClass); - return pClass; -} -CFXJSE_Class* CFXJSE_Class::GetClassFromContext(CFXJSE_Context* pContext, - const CFX_ByteStringC& szName) { - for (int count = pContext->m_rgClasses.GetSize(), i = 0; i < count; i++) { - CFXJSE_Class* pClass = pContext->m_rgClasses[i]; - if (pClass->m_szClassName == szName) { - return pClass; - } - } - return NULL; -} diff --git a/xfa/src/fxjse/src/class.h b/xfa/src/fxjse/src/class.h deleted file mode 100644 index 3c1780fc58..0000000000 --- a/xfa/src/fxjse/src/class.h +++ /dev/null @@ -1,49 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_CLASS_H_ -#define XFA_SRC_FXJSE_SRC_CLASS_H_ - -#include "v8/include/v8.h" -#include "xfa/include/fxjse/fxjse.h" - -class CFXJSE_Context; -class CFXJSE_Value; - -class CFXJSE_Class { - protected: - CFXJSE_Class(CFXJSE_Context* lpContext) - : m_lpClassDefinition(nullptr), m_pContext(lpContext) {} - - public: - inline CFXJSE_Context* GetContext() { return m_pContext; } - inline v8::Global& GetTemplate() { return m_hTemplate; } - - public: - static CFXJSE_Class* Create(CFXJSE_Context* pContext, - const FXJSE_CLASS* lpClassDefintion, - FX_BOOL bIsJSGlobal = FALSE); - static CFXJSE_Class* GetClassFromContext(CFXJSE_Context* pContext, - const CFX_ByteStringC& szName); - static void SetUpNamedPropHandler( - v8::Isolate* pIsolate, - v8::Local& hObjectTemplate, - const FXJSE_CLASS* lpClassDefinition); - - protected: - CFX_ByteString m_szClassName; - const FXJSE_CLASS* m_lpClassDefinition; - CFXJSE_Context* m_pContext; - v8::Global m_hTemplate; - friend class CFXJSE_Context; - friend class CFXJSE_Value; -}; -struct CFXJSE_ArgumentsImpl { - const v8::FunctionCallbackInfo* m_pInfo; - CFXJSE_Value* m_pRetValue; -}; - -#endif // XFA_SRC_FXJSE_SRC_CLASS_H_ diff --git a/xfa/src/fxjse/src/context.cpp b/xfa/src/fxjse/src/context.cpp deleted file mode 100644 index f88fcde2cd..0000000000 --- a/xfa/src/fxjse/src/context.cpp +++ /dev/null @@ -1,275 +0,0 @@ -// 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 - -#include "xfa/src/fxjse/src/context.h" - -#include "xfa/src/fxjse/src/class.h" -#include "xfa/src/fxjse/src/scope_inline.h" -#include "xfa/src/fxjse/src/util_inline.h" -#include "xfa/src/fxjse/src/value.h" - -FXJSE_HCONTEXT FXJSE_Context_Create(FXJSE_HRUNTIME hRuntime, - const FXJSE_CLASS* lpGlobalClass, - void* lpGlobalObject) { - CFXJSE_Context* pContext = CFXJSE_Context::Create( - reinterpret_cast(hRuntime), lpGlobalClass, lpGlobalObject); - return reinterpret_cast(pContext); -} - -void FXJSE_Context_Release(FXJSE_HCONTEXT hContext) { - CFXJSE_Context* pContext = reinterpret_cast(hContext); - if (pContext) { - delete pContext; - } -} - -FXJSE_HVALUE FXJSE_Context_GetGlobalObject(FXJSE_HCONTEXT hContext) { - CFXJSE_Context* pContext = reinterpret_cast(hContext); - if (!pContext) { - return NULL; - } - CFXJSE_Value* lpValue = CFXJSE_Value::Create(pContext->GetRuntime()); - ASSERT(lpValue); - pContext->GetGlobalObject(lpValue); - return reinterpret_cast(lpValue); -} - -FXJSE_HRUNTIME FXJSE_Context_GetRuntime(FXJSE_HCONTEXT hContext) { - CFXJSE_Context* pContext = reinterpret_cast(hContext); - return pContext ? reinterpret_cast(pContext->GetRuntime()) - : NULL; -} - -static const FX_CHAR* szCompatibleModeScripts[] = { - "(function(global, list) {\n" - " 'use strict';\n" - " var objname;\n" - " for (objname in list) {\n" - " var globalobj = global[objname];\n" - " if (globalobj) {\n" - " list[objname].forEach(function(name) {\n" - " if (!globalobj[name]) {\n" - " Object.defineProperty(globalobj, name, {\n" - " writable: true,\n" - " enumerable: false,\n" - " value: (function(obj) {\n" - " if (arguments.length === 0) {\n" - " throw new TypeError('missing argument 0 when calling " - " function ' + objname + '.' + name);\n" - " }\n" - " return globalobj.prototype[name].apply(obj, " - " Array.prototype.slice.call(arguments, 1));\n" - " })\n" - " });\n" - " }\n" - " });\n" - " }\n" - " }\n" - "}(this, {String: ['substr', 'toUpperCase']}));"}; -void FXJSE_Context_EnableCompatibleMode(FXJSE_HCONTEXT hContext, - FX_DWORD dwCompatibleFlags) { - for (uint32_t i = 0; i < (uint32_t)FXJSE_COMPATIBLEMODEFLAGCOUNT; i++) { - if (dwCompatibleFlags & (1 << i)) { - FXJSE_ExecuteScript(hContext, szCompatibleModeScripts[i], NULL, NULL); - } - } -} - -FX_BOOL FXJSE_ExecuteScript(FXJSE_HCONTEXT hContext, - const FX_CHAR* szScript, - FXJSE_HVALUE hRetValue, - FXJSE_HVALUE hNewThisObject) { - CFXJSE_Context* pContext = reinterpret_cast(hContext); - ASSERT(pContext); - return pContext->ExecuteScript( - szScript, reinterpret_cast(hRetValue), - reinterpret_cast(hNewThisObject)); -} - -v8::Local FXJSE_CreateReturnValue(v8::Isolate* pIsolate, - v8::TryCatch& trycatch) { - v8::Local hReturnValue = v8::Object::New(pIsolate); - if (trycatch.HasCaught()) { - v8::Local hException = trycatch.Exception(); - v8::Local hMessage = trycatch.Message(); - if (hException->IsObject()) { - v8::Local hValue; - hValue = hException.As()->Get( - v8::String::NewFromUtf8(pIsolate, "name")); - if (hValue->IsString() || hValue->IsStringObject()) { - hReturnValue->Set(0, hValue); - } else { - hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error")); - } - hValue = hException.As()->Get( - v8::String::NewFromUtf8(pIsolate, "message")); - if (hValue->IsString() || hValue->IsStringObject()) { - hReturnValue->Set(1, hValue); - } else { - hReturnValue->Set(1, hMessage->Get()); - } - } else { - hReturnValue->Set(0, v8::String::NewFromUtf8(pIsolate, "Error")); - hReturnValue->Set(1, hMessage->Get()); - } - hReturnValue->Set(2, hException); - hReturnValue->Set(3, v8::Integer::New(pIsolate, hMessage->GetLineNumber())); - hReturnValue->Set(4, hMessage->GetSourceLine()); - v8::Maybe maybe_int = - hMessage->GetStartColumn(pIsolate->GetCurrentContext()); - hReturnValue->Set(5, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0))); - maybe_int = hMessage->GetEndColumn(pIsolate->GetCurrentContext()); - hReturnValue->Set(6, v8::Integer::New(pIsolate, maybe_int.FromMaybe(0))); - } - return hReturnValue; -} - -FX_BOOL FXJSE_ReturnValue_GetMessage(FXJSE_HVALUE hRetValue, - CFX_ByteString& utf8Name, - CFX_ByteString& utf8Message) { - CFXJSE_Value* lpValue = reinterpret_cast(hRetValue); - if (!lpValue) { - return FALSE; - } - v8::Isolate* pIsolate = lpValue->GetIsolate(); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); - v8::Local hValue = - v8::Local::New(pIsolate, lpValue->DirectGetValue()); - if (!hValue->IsObject()) { - return FALSE; - } - v8::String::Utf8Value hStringVal0( - hValue.As()->Get(0)->ToString()); - utf8Name = *hStringVal0; - v8::String::Utf8Value hStringVal1( - hValue.As()->Get(1)->ToString()); - utf8Message = *hStringVal1; - return TRUE; -} - -FX_BOOL FXJSE_ReturnValue_GetLineInfo(FXJSE_HVALUE hRetValue, - int32_t& nLine, - int32_t& nCol) { - CFXJSE_Value* lpValue = reinterpret_cast(hRetValue); - if (!lpValue) { - return FALSE; - } - v8::Isolate* pIsolate = lpValue->GetIsolate(); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); - v8::Local hValue = - v8::Local::New(pIsolate, lpValue->DirectGetValue()); - if (!hValue->IsObject()) { - return FALSE; - } - v8::MaybeLocal maybe_int = - hValue.As()->Get(3)->ToInt32(pIsolate->GetCurrentContext()); - nLine = maybe_int.FromMaybe(v8::Local())->Value(); - maybe_int = - hValue.As()->Get(5)->ToInt32(pIsolate->GetCurrentContext()); - nCol = maybe_int.FromMaybe(v8::Local())->Value(); - return TRUE; -} - -CFXJSE_Context* CFXJSE_Context::Create(v8::Isolate* pIsolate, - const FXJSE_CLASS* lpGlobalClass, - void* lpGlobalObject) { - CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); - CFXJSE_Context* pContext = new CFXJSE_Context(pIsolate); - CFXJSE_Class* lpGlobalClassObj = NULL; - v8::Local hObjectTemplate; - if (lpGlobalClass) { - lpGlobalClassObj = CFXJSE_Class::Create(pContext, lpGlobalClass, TRUE); - ASSERT(lpGlobalClassObj); - v8::Local hFunctionTemplate = - v8::Local::New(pIsolate, - lpGlobalClassObj->m_hTemplate); - hObjectTemplate = hFunctionTemplate->InstanceTemplate(); - } else { - hObjectTemplate = v8::ObjectTemplate::New(pIsolate); - hObjectTemplate->SetInternalFieldCount(1); - } - v8::Local hNewContext = - v8::Context::New(pIsolate, NULL, hObjectTemplate); - v8::Local hRootContext = v8::Local::New( - pIsolate, CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext); - hNewContext->SetSecurityToken(hRootContext->GetSecurityToken()); - v8::Local hGlobalObject = - FXJSE_GetGlobalObjectFromContext(hNewContext); - FXJSE_UpdateObjectBinding(hGlobalObject, lpGlobalObject); - pContext->m_hContext.Reset(pIsolate, hNewContext); - return pContext; -} - -CFXJSE_Context::~CFXJSE_Context() { - for (int32_t i = 0, count = m_rgClasses.GetSize(); i < count; i++) { - CFXJSE_Class* pClass = m_rgClasses[i]; - if (pClass) { - delete pClass; - } - } - m_rgClasses.RemoveAll(); -} - -void CFXJSE_Context::GetGlobalObject(CFXJSE_Value* pValue) { - ASSERT(pValue); - CFXJSE_ScopeUtil_IsolateHandleContext scope(this); - v8::Local hContext = - v8::Local::New(m_pIsolate, m_hContext); - v8::Local hGlobalObject = hContext->Global(); - pValue->ForceSetValue(hGlobalObject); -} - -FX_BOOL CFXJSE_Context::ExecuteScript(const FX_CHAR* szScript, - CFXJSE_Value* lpRetValue, - CFXJSE_Value* lpNewThisObject) { - CFXJSE_ScopeUtil_IsolateHandleContext scope(this); - v8::TryCatch trycatch(m_pIsolate); - v8::Local hScriptString = - v8::String::NewFromUtf8(m_pIsolate, szScript); - if (lpNewThisObject == NULL) { - v8::Local hScript = v8::Script::Compile(hScriptString); - if (!trycatch.HasCaught()) { - v8::Local hValue = hScript->Run(); - if (!trycatch.HasCaught()) { - if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, hValue); - } - return TRUE; - } - } - if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, - FXJSE_CreateReturnValue(m_pIsolate, trycatch)); - } - return FALSE; - } else { - v8::Local hNewThis = - v8::Local::New(m_pIsolate, lpNewThisObject->m_hValue); - ASSERT(!hNewThis.IsEmpty()); - v8::Local hWrapper = - v8::Script::Compile(v8::String::NewFromUtf8( - m_pIsolate, "(function () { return eval(arguments[0]); })")); - v8::Local hWrapperValue = hWrapper->Run(); - ASSERT(hWrapperValue->IsFunction()); - v8::Local hWrapperFn = hWrapperValue.As(); - if (!trycatch.HasCaught()) { - v8::Local rgArgs[] = {hScriptString}; - v8::Local hValue = - hWrapperFn->Call(hNewThis.As(), 1, rgArgs); - if (!trycatch.HasCaught()) { - if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, hValue); - } - return TRUE; - } - } - if (lpRetValue) { - lpRetValue->m_hValue.Reset(m_pIsolate, - FXJSE_CreateReturnValue(m_pIsolate, trycatch)); - } - return FALSE; - } -} diff --git a/xfa/src/fxjse/src/context.h b/xfa/src/fxjse/src/context.h deleted file mode 100644 index e6c16445cd..0000000000 --- a/xfa/src/fxjse/src/context.h +++ /dev/null @@ -1,47 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_CONTEXT_H_ -#define XFA_SRC_FXJSE_SRC_CONTEXT_H_ - -#include "v8/include/v8.h" -#include "xfa/include/fxjse/fxjse.h" - -class CFXJSE_Class; -class CFXJSE_Value; - -class CFXJSE_Context { - protected: - CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} - - public: - static CFXJSE_Context* Create(v8::Isolate* pIsolate, - const FXJSE_CLASS* lpGlobalClass = NULL, - void* lpGlobalObject = NULL); - ~CFXJSE_Context(); - V8_INLINE v8::Isolate* GetRuntime(void) { return m_pIsolate; } - void GetGlobalObject(CFXJSE_Value* pValue); - FX_BOOL ExecuteScript(const FX_CHAR* szScript, - CFXJSE_Value* lpRetValue, - CFXJSE_Value* lpNewThisObject = NULL); - - protected: - CFXJSE_Context(); - CFXJSE_Context(const CFXJSE_Context&); - CFXJSE_Context& operator=(const CFXJSE_Context&); - - protected: - v8::Global m_hContext; - v8::Isolate* m_pIsolate; - CFX_ArrayTemplate m_rgClasses; - friend class CFXJSE_Class; - friend class CFXJSE_ScopeUtil_IsolateHandleContext; - friend class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext; -}; -v8::Local FXJSE_CreateReturnValue(v8::Isolate* pIsolate, - v8::TryCatch& trycatch); - -#endif // XFA_SRC_FXJSE_SRC_CONTEXT_H_ diff --git a/xfa/src/fxjse/src/dynprop.cpp b/xfa/src/fxjse/src/dynprop.cpp deleted file mode 100644 index bc423c03c0..0000000000 --- a/xfa/src/fxjse/src/dynprop.cpp +++ /dev/null @@ -1,236 +0,0 @@ -// 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 - -#include "xfa/src/fxjse/src/class.h" -#include "xfa/src/fxjse/src/value.h" - -static void FXJSE_DynPropGetterAdapter_MethodCallback( - const v8::FunctionCallbackInfo& info) { - v8::Local hCallBackInfo = info.Data().As(); - FXJSE_CLASS* lpClass = static_cast( - hCallBackInfo->GetAlignedPointerFromInternalField(0)); - v8::Local hPropName = - hCallBackInfo->GetInternalField(1).As(); - ASSERT(lpClass && !hPropName.IsEmpty()); - v8::String::Utf8Value szPropName(hPropName); - CFX_ByteStringC szFxPropName = *szPropName; - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(info.This()); - CFXJSE_Value* lpRetValue = CFXJSE_Value::Create(info.GetIsolate()); - CFXJSE_ArgumentsImpl impl = {&info, lpRetValue}; - lpClass->dynMethodCall(reinterpret_cast(lpThisValue), - szFxPropName, - reinterpret_cast(impl)); - if (!lpRetValue->DirectGetValue().IsEmpty()) { - info.GetReturnValue().Set(lpRetValue->DirectGetValue()); - } - delete lpRetValue; - lpRetValue = nullptr; - delete lpThisValue; - lpThisValue = nullptr; -} - -static void FXJSE_DynPropGetterAdapter(const FXJSE_CLASS* lpClass, - FXJSE_HOBJECT hObject, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue) { - ASSERT(lpClass); - int32_t nPropType = - lpClass->dynPropTypeGetter == nullptr - ? FXJSE_ClassPropType_Property - : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); - if (nPropType == FXJSE_ClassPropType_Property) { - if (lpClass->dynPropGetter) { - lpClass->dynPropGetter(hObject, szPropName, hValue); - } - } else if (nPropType == FXJSE_ClassPropType_Method) { - if (lpClass->dynMethodCall && hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - v8::Isolate* pIsolate = lpValue->GetIsolate(); - v8::HandleScope hscope(pIsolate); - v8::Local hCallBackInfoTemplate = - v8::ObjectTemplate::New(pIsolate); - hCallBackInfoTemplate->SetInternalFieldCount(2); - v8::Local hCallBackInfo = - hCallBackInfoTemplate->NewInstance(); - hCallBackInfo->SetAlignedPointerInInternalField( - 0, const_cast(lpClass)); - hCallBackInfo->SetInternalField( - 1, v8::String::NewFromUtf8( - pIsolate, reinterpret_cast(szPropName.GetPtr()), - v8::String::kNormalString, szPropName.GetLength())); - lpValue->ForceSetValue(v8::Function::New( - lpValue->GetIsolate(), FXJSE_DynPropGetterAdapter_MethodCallback, - hCallBackInfo)); - } - } -} - -static void FXJSE_DynPropSetterAdapter(const FXJSE_CLASS* lpClass, - FXJSE_HOBJECT hObject, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hValue) { - ASSERT(lpClass); - int32_t nPropType = - lpClass->dynPropTypeGetter == nullptr - ? FXJSE_ClassPropType_Property - : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); - if (nPropType != FXJSE_ClassPropType_Method) { - if (lpClass->dynPropSetter) { - lpClass->dynPropSetter(hObject, szPropName, hValue); - } - } -} - -static FX_BOOL FXJSE_DynPropQueryAdapter(const FXJSE_CLASS* lpClass, - FXJSE_HOBJECT hObject, - const CFX_ByteStringC& szPropName) { - ASSERT(lpClass); - int32_t nPropType = - lpClass->dynPropTypeGetter == nullptr - ? FXJSE_ClassPropType_Property - : lpClass->dynPropTypeGetter(hObject, szPropName, TRUE); - return nPropType != FXJSE_ClassPropType_None; -} - -static FX_BOOL FXJSE_DynPropDeleterAdapter(const FXJSE_CLASS* lpClass, - FXJSE_HOBJECT hObject, - const CFX_ByteStringC& szPropName) { - ASSERT(lpClass); - int32_t nPropType = - lpClass->dynPropTypeGetter == nullptr - ? FXJSE_ClassPropType_Property - : lpClass->dynPropTypeGetter(hObject, szPropName, FALSE); - if (nPropType != FXJSE_ClassPropType_Method) { - if (lpClass->dynPropDeleter) { - return lpClass->dynPropDeleter(hObject, szPropName); - } else { - return nPropType == FXJSE_ClassPropType_Property ? FALSE : TRUE; - } - } - return FALSE; -} - -static void FXJSE_V8_GenericNamedPropertyQueryCallback( - v8::Local property, - const v8::PropertyCallbackInfo& info) { - v8::Local thisObject = info.This(); - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - v8::Isolate* pIsolate = info.GetIsolate(); - v8::HandleScope scope(pIsolate); - v8::String::Utf8Value szPropName(property); - CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(thisObject); - if (FXJSE_DynPropQueryAdapter(lpClass, - reinterpret_cast(lpThisValue), - szFxPropName)) { - info.GetReturnValue().Set(v8::DontDelete); - } else { - const int32_t iV8Absent = 64; - info.GetReturnValue().Set(iV8Absent); - } - delete lpThisValue; - lpThisValue = nullptr; -} - -static void FXJSE_V8_GenericNamedPropertyDeleterCallback( - v8::Local property, - const v8::PropertyCallbackInfo& info) { - v8::Local thisObject = info.This(); - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - v8::Isolate* pIsolate = info.GetIsolate(); - v8::HandleScope scope(pIsolate); - v8::String::Utf8Value szPropName(property); - CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(thisObject); - info.GetReturnValue().Set( - FXJSE_DynPropDeleterAdapter( - lpClass, reinterpret_cast(lpThisValue), szFxPropName) - ? true - : false); - delete lpThisValue; - lpThisValue = nullptr; -} - -static void FXJSE_V8_GenericNamedPropertyGetterCallback( - v8::Local property, - const v8::PropertyCallbackInfo& info) { - v8::Local thisObject = info.This(); - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - v8::String::Utf8Value szPropName(property); - CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(thisObject); - CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); - FXJSE_DynPropGetterAdapter( - lpClass, reinterpret_cast(lpThisValue), szFxPropName, - reinterpret_cast(lpNewValue)); - info.GetReturnValue().Set(lpNewValue->DirectGetValue()); - delete lpThisValue; - lpThisValue = nullptr; -} - -static void FXJSE_V8_GenericNamedPropertySetterCallback( - v8::Local property, - v8::Local value, - const v8::PropertyCallbackInfo& info) { - v8::Local thisObject = info.This(); - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - v8::String::Utf8Value szPropName(property); - CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); - CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); - lpThisValue->ForceSetValue(thisObject); - CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); - lpNewValue->ForceSetValue(value); - FXJSE_DynPropSetterAdapter( - lpClass, reinterpret_cast(lpThisValue), szFxPropName, - reinterpret_cast(lpNewValue)); - info.GetReturnValue().Set(value); - delete lpThisValue; - lpThisValue = nullptr; -} - -static void FXJSE_V8_GenericNamedPropertyEnumeratorCallback( - const v8::PropertyCallbackInfo& info) { - const FXJSE_CLASS* lpClass = - static_cast(info.Data().As()->Value()); - v8::Isolate* pIsolate = info.GetIsolate(); - v8::Local newArray = v8::Array::New(pIsolate, lpClass->propNum); - for (int i = 0; i < lpClass->propNum; i++) { - newArray->Set( - i, v8::String::NewFromUtf8(pIsolate, lpClass->properties[i].name)); - } - info.GetReturnValue().Set(newArray); -} - -void CFXJSE_Class::SetUpNamedPropHandler( - v8::Isolate* pIsolate, - v8::Local& hObjectTemplate, - const FXJSE_CLASS* lpClassDefinition) { - v8::NamedPropertyHandlerConfiguration configuration( - lpClassDefinition->dynPropGetter - ? FXJSE_V8_GenericNamedPropertyGetterCallback - : 0, - lpClassDefinition->dynPropSetter - ? FXJSE_V8_GenericNamedPropertySetterCallback - : 0, - lpClassDefinition->dynPropTypeGetter - ? FXJSE_V8_GenericNamedPropertyQueryCallback - : 0, - lpClassDefinition->dynPropDeleter - ? FXJSE_V8_GenericNamedPropertyDeleterCallback - : 0, - FXJSE_V8_GenericNamedPropertyEnumeratorCallback, - v8::External::New(pIsolate, const_cast(lpClassDefinition)), - v8::PropertyHandlerFlags::kNonMasking); - hObjectTemplate->SetHandler(configuration); -} diff --git a/xfa/src/fxjse/src/runtime.cpp b/xfa/src/fxjse/src/runtime.cpp deleted file mode 100644 index 99a29c7da4..0000000000 --- a/xfa/src/fxjse/src/runtime.cpp +++ /dev/null @@ -1,128 +0,0 @@ -// 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 - -#include "xfa/src/fxjse/src/runtime.h" - -#include "fpdfsdk/include/jsapi/fxjs_v8.h" -#include "xfa/src/fxjse/src/scope_inline.h" - -// Duplicates fpdfsdk's JS_Runtime.h, but keeps XFA from depending on it. -// TODO(tsepez): make a single version of this. -class FXJSE_ArrayBufferAllocator : public v8::ArrayBuffer::Allocator { - void* Allocate(size_t length) override { return calloc(1, length); } - void* AllocateUninitialized(size_t length) override { return malloc(length); } - void Free(void* data, size_t length) override { free(data); } -}; - -static void FXJSE_KillV8() { - v8::V8::Dispose(); -} - -void FXJSE_Initialize() { - if (!CFXJSE_RuntimeData::g_RuntimeList) { - CFXJSE_RuntimeData::g_RuntimeList = new CFXJSE_RuntimeList; - } - static FX_BOOL bV8Initialized = FALSE; - if (bV8Initialized) { - return; - } - bV8Initialized = TRUE; - atexit(FXJSE_KillV8); -} - -static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate) { - { - v8::Locker locker(pIsolate); - if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) { - delete pData->m_pFXJSERuntimeData; - pData->m_pFXJSERuntimeData = nullptr; - } - } - pIsolate->Dispose(); -} - -void FXJSE_Finalize() { - if (CFXJSE_RuntimeData::g_RuntimeList) { - CFXJSE_RuntimeData::g_RuntimeList->RemoveAllRuntimes( - FXJSE_Runtime_DisposeCallback); - delete CFXJSE_RuntimeData::g_RuntimeList; - CFXJSE_RuntimeData::g_RuntimeList = NULL; - } -} - -FXJSE_HRUNTIME FXJSE_Runtime_Create() { - v8::Isolate::CreateParams params; - params.array_buffer_allocator = new FXJSE_ArrayBufferAllocator(); - v8::Isolate* pIsolate = v8::Isolate::New(params); - ASSERT(pIsolate && CFXJSE_RuntimeData::g_RuntimeList); - CFXJSE_RuntimeData::g_RuntimeList->AppendRuntime(pIsolate); - return reinterpret_cast(pIsolate); -} - -void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime, bool bOwnedRuntime) { - v8::Isolate* pIsolate = reinterpret_cast(hRuntime); - if (!pIsolate) - return; - if (bOwnedRuntime) { - ASSERT(CFXJSE_RuntimeData::g_RuntimeList); - CFXJSE_RuntimeData::g_RuntimeList->RemoveRuntime( - pIsolate, FXJSE_Runtime_DisposeCallback); - } else { - if (FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate)) { - delete pData->m_pFXJSERuntimeData; - pData->m_pFXJSERuntimeData = nullptr; - } - } -} - -CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) { - CFXJSE_RuntimeData* pRuntimeData = new CFXJSE_RuntimeData(pIsolate); - CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); - v8::Local hFuncTemplate = - v8::FunctionTemplate::New(pIsolate); - v8::Local hContext = - v8::Context::New(pIsolate, 0, hFuncTemplate->InstanceTemplate()); - hContext->SetSecurityToken(v8::External::New(pIsolate, pIsolate)); - pRuntimeData->m_hRootContextGlobalTemplate.Reset(pIsolate, hFuncTemplate); - pRuntimeData->m_hRootContext.Reset(pIsolate, hContext); - return pRuntimeData; -} - -CFXJSE_RuntimeData* CFXJSE_RuntimeData::Get(v8::Isolate* pIsolate) { - FXJS_PerIsolateData::SetUp(pIsolate); - FXJS_PerIsolateData* pData = FXJS_PerIsolateData::Get(pIsolate); - if (!pData->m_pFXJSERuntimeData) - pData->m_pFXJSERuntimeData = CFXJSE_RuntimeData::Create(pIsolate); - return pData->m_pFXJSERuntimeData; -} - -CFXJSE_RuntimeList* CFXJSE_RuntimeData::g_RuntimeList = NULL; -void CFXJSE_RuntimeList::AppendRuntime(v8::Isolate* pIsolate) { - m_RuntimeList.Add(pIsolate); -} - -void CFXJSE_RuntimeList::RemoveRuntime( - v8::Isolate* pIsolate, - CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) { - int32_t iIdx = m_RuntimeList.Find(pIsolate, 0); - if (iIdx >= 0) { - m_RuntimeList.RemoveAt(iIdx, 1); - } - if (lpfnDisposeCallback) { - lpfnDisposeCallback(pIsolate); - } -} - -void CFXJSE_RuntimeList::RemoveAllRuntimes( - CFXJSE_RuntimeList::RuntimeDisposeCallback lpfnDisposeCallback) { - int32_t iSize = m_RuntimeList.GetSize(); - if (lpfnDisposeCallback) { - for (int32_t iIdx = 0; iIdx < iSize; iIdx++) { - lpfnDisposeCallback(m_RuntimeList[iIdx]); - } - } - m_RuntimeList.RemoveAll(); -} diff --git a/xfa/src/fxjse/src/runtime.h b/xfa/src/fxjse/src/runtime.h deleted file mode 100644 index 65b7db06c8..0000000000 --- a/xfa/src/fxjse/src/runtime.h +++ /dev/null @@ -1,51 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_RUNTIME_H_ -#define XFA_SRC_FXJSE_SRC_RUNTIME_H_ - -#include "core/include/fxcrt/fx_basic.h" -#include "v8/include/v8.h" - -class CFXJSE_RuntimeList; - -class CFXJSE_RuntimeData { - protected: - CFXJSE_RuntimeData(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} - - public: - static CFXJSE_RuntimeData* Create(v8::Isolate* pIsolate); - static CFXJSE_RuntimeData* Get(v8::Isolate* pIsolate); - - public: - v8::Isolate* m_pIsolate; - v8::Global m_hRootContextGlobalTemplate; - v8::Global m_hRootContext; - - public: - static CFXJSE_RuntimeList* g_RuntimeList; - - protected: - CFXJSE_RuntimeData(); - CFXJSE_RuntimeData(const CFXJSE_RuntimeData&); - CFXJSE_RuntimeData& operator=(const CFXJSE_RuntimeData&); -}; - -class CFXJSE_RuntimeList { - public: - typedef void (*RuntimeDisposeCallback)(v8::Isolate*); - - public: - void AppendRuntime(v8::Isolate* pIsolate); - void RemoveRuntime(v8::Isolate* pIsolate, - RuntimeDisposeCallback lpfnDisposeCallback); - void RemoveAllRuntimes(RuntimeDisposeCallback lpfnDisposeCallback); - - protected: - CFX_ArrayTemplate m_RuntimeList; -}; - -#endif // XFA_SRC_FXJSE_SRC_RUNTIME_H_ diff --git a/xfa/src/fxjse/src/scope_inline.h b/xfa/src/fxjse/src/scope_inline.h deleted file mode 100644 index 6a7860f93e..0000000000 --- a/xfa/src/fxjse/src/scope_inline.h +++ /dev/null @@ -1,108 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_SCOPE_INLINE_H_ -#define XFA_SRC_FXJSE_SRC_SCOPE_INLINE_H_ - -#include "xfa/src/fxjse/src/context.h" -#include "xfa/src/fxjse/src/runtime.h" - -class CFXJSE_ScopeUtil_IsolateHandle { - protected: - v8::Isolate* m_isolate; - v8::Locker m_locker; - v8::Isolate::Scope m_iscope; - v8::HandleScope m_hscope; - - public: - explicit CFXJSE_ScopeUtil_IsolateHandle(v8::Isolate* pIsolate) - : m_isolate(pIsolate), - m_locker(pIsolate), - m_iscope(pIsolate), - m_hscope(pIsolate) {} - v8::Isolate* GetIsolate() { return m_isolate; } - - private: - CFXJSE_ScopeUtil_IsolateHandle(const CFXJSE_ScopeUtil_IsolateHandle&); - void operator=(const CFXJSE_ScopeUtil_IsolateHandle&); - void* operator new(size_t size); - void operator delete(void*, size_t); -}; -class CFXJSE_ScopeUtil_IsolateHandleRootContext { - CFXJSE_ScopeUtil_IsolateHandle m_parent; - v8::Context::Scope m_cscope; - - public: - explicit CFXJSE_ScopeUtil_IsolateHandleRootContext(v8::Isolate* pIsolate) - : m_parent(pIsolate), - m_cscope(v8::Local::New( - pIsolate, - CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {} - - private: - CFXJSE_ScopeUtil_IsolateHandleRootContext( - const CFXJSE_ScopeUtil_IsolateHandleRootContext&); - void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootContext&); - void* operator new(size_t size); - void operator delete(void*, size_t); -}; -class CFXJSE_ScopeUtil_IsolateHandleContext { - CFXJSE_Context* m_context; - CFXJSE_ScopeUtil_IsolateHandle m_parent; - v8::Context::Scope m_cscope; - - public: - explicit CFXJSE_ScopeUtil_IsolateHandleContext(CFXJSE_Context* pContext) - : m_context(pContext), - m_parent(pContext->m_pIsolate), - m_cscope(v8::Local::New(pContext->m_pIsolate, - pContext->m_hContext)) {} - v8::Isolate* GetIsolate() { return m_context->m_pIsolate; } - v8::Local GetLocalContext() { - return v8::Local::New(m_context->m_pIsolate, - m_context->m_hContext); - } - - private: - CFXJSE_ScopeUtil_IsolateHandleContext( - const CFXJSE_ScopeUtil_IsolateHandleContext&); - void operator=(const CFXJSE_ScopeUtil_IsolateHandleContext&); - void* operator new(size_t size); - void operator delete(void*, size_t); -}; -class CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext { - CFXJSE_Context* m_context; - CFXJSE_ScopeUtil_IsolateHandle m_parent; - v8::Context::Scope m_cscope; - - public: - explicit CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext( - v8::Isolate* pIsolate, - CFXJSE_Context* pContext) - : m_context(pContext), - m_parent(pIsolate), - m_cscope(v8::Local::New( - pIsolate, - pContext ? pContext->m_hContext - : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext)) {} - v8::Isolate* GetIsolate() { return m_parent.GetIsolate(); } - v8::Local GetLocalContext() { - v8::Isolate* pIsolate = m_parent.GetIsolate(); - return v8::Local::New( - pIsolate, m_context - ? m_context->m_hContext - : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext); - } - - private: - CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext( - const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&); - void operator=(const CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext&); - void* operator new(size_t size); - void operator delete(void*, size_t); -}; - -#endif // XFA_SRC_FXJSE_SRC_SCOPE_INLINE_H_ diff --git a/xfa/src/fxjse/src/util_inline.h b/xfa/src/fxjse/src/util_inline.h deleted file mode 100644 index 21520cfbe6..0000000000 --- a/xfa/src/fxjse/src/util_inline.h +++ /dev/null @@ -1,51 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_UTIL_INLINE_H_ -#define XFA_SRC_FXJSE_SRC_UTIL_INLINE_H_ - -#include "xfa/src/fxjse/src/context.h" - -static V8_INLINE v8::Local FXJSE_GetGlobalObjectFromContext( - const v8::Local& hContext) { - return hContext->Global()->GetPrototype().As(); -} -static V8_INLINE void FXJSE_UpdateObjectBinding(v8::Local& hObject, - void* lpNewBinding) { - ASSERT(!hObject.IsEmpty()); - ASSERT(hObject->InternalFieldCount() > 0); - hObject->SetAlignedPointerInInternalField(0, lpNewBinding); -} -static V8_INLINE void* FXJSE_RetrieveObjectBinding( - const v8::Local& hJSObject, - CFXJSE_Class* lpClass = NULL) { - ASSERT(!hJSObject.IsEmpty()); - if (!hJSObject->IsObject()) { - return NULL; - } - v8::Local hObject = hJSObject; - if (hObject->InternalFieldCount() == 0) { - v8::Local hProtoObject = hObject->GetPrototype(); - if (hProtoObject.IsEmpty() || !hProtoObject->IsObject()) { - return NULL; - } - hObject = hProtoObject.As(); - if (hObject->InternalFieldCount() == 0) { - return NULL; - } - } - if (lpClass) { - v8::Local hClass = - v8::Local::New( - lpClass->GetContext()->GetRuntime(), lpClass->GetTemplate()); - if (!hClass->HasInstance(hObject)) { - return NULL; - } - } - return hObject->GetAlignedPointerFromInternalField(0); -} - -#endif // XFA_SRC_FXJSE_SRC_UTIL_INLINE_H_ diff --git a/xfa/src/fxjse/src/value.cpp b/xfa/src/fxjse/src/value.cpp deleted file mode 100644 index 771f757d18..0000000000 --- a/xfa/src/fxjse/src/value.cpp +++ /dev/null @@ -1,582 +0,0 @@ -// 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 - -#include "xfa/src/fxjse/src/value.h" - -#include - -#include "xfa/src/fxjse/src/class.h" -#include "xfa/src/fxjse/src/util_inline.h" - -FX_BOOL FXJSE_Value_IsUndefined(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsUndefined(); -} - -FX_BOOL FXJSE_Value_IsNull(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsNull(); -} - -FX_BOOL FXJSE_Value_IsBoolean(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsBoolean(); -} - -FX_BOOL FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsString(); -} - -FX_BOOL FXJSE_Value_IsNumber(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsNumber(); -} - -FX_BOOL FXJSE_Value_IsInteger(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsInteger(); -} - -FX_BOOL FXJSE_Value_IsObject(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsObject(); -} - -FX_BOOL FXJSE_Value_IsArray(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsArray(); -} - -FX_BOOL FXJSE_Value_IsFunction(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsFunction(); -} - -FX_BOOL FXJSE_Value_IsDate(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - return lpValue && lpValue->IsDate(); -} - -FX_BOOL FXJSE_Value_ToBoolean(FXJSE_HVALUE hValue) { - return reinterpret_cast(hValue)->ToBoolean(); -} - -FX_FLOAT FXJSE_Value_ToFloat(FXJSE_HVALUE hValue) { - return reinterpret_cast(hValue)->ToFloat(); -} - -FXJSE_DOUBLE FXJSE_Value_ToDouble(FXJSE_HVALUE hValue) { - return reinterpret_cast(hValue)->ToDouble(); -} - -void FXJSE_Value_ToUTF8String(FXJSE_HVALUE hValue, - CFX_ByteString& szStrOutput) { - return reinterpret_cast(hValue)->ToString(szStrOutput); -} - -int32_t FXJSE_Value_ToInteger(FXJSE_HVALUE hValue) { - return reinterpret_cast(hValue)->ToInteger(); -} - -void* FXJSE_Value_ToObject(FXJSE_HVALUE hValue, FXJSE_HCLASS hClass) { - CFXJSE_Class* lpClass = reinterpret_cast(hClass); - return reinterpret_cast(hValue)->ToObject(lpClass); -} - -void FXJSE_Value_SetUndefined(FXJSE_HVALUE hValue) { - reinterpret_cast(hValue)->SetUndefined(); -} - -void FXJSE_Value_SetNull(FXJSE_HVALUE hValue) { - reinterpret_cast(hValue)->SetNull(); -} - -void FXJSE_Value_SetBoolean(FXJSE_HVALUE hValue, FX_BOOL bBoolean) { - reinterpret_cast(hValue)->SetBoolean(bBoolean); -} - -void FXJSE_Value_SetUTF8String(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szString) { - reinterpret_cast(hValue)->SetString(szString); -} - -void FXJSE_Value_SetInteger(FXJSE_HVALUE hValue, int32_t nInteger) { - reinterpret_cast(hValue)->SetInteger(nInteger); -} - -void FXJSE_Value_SetFloat(FXJSE_HVALUE hValue, FX_FLOAT fFloat) { - reinterpret_cast(hValue)->SetFloat(fFloat); -} - -void FXJSE_Value_SetDouble(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) { - reinterpret_cast(hValue)->SetDouble(dDouble); -} - -void FXJSE_Value_SetObject(FXJSE_HVALUE hValue, - void* lpObject, - FXJSE_HCLASS hClass) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Class* lpClass = reinterpret_cast(hClass); - if (!lpClass) { - ASSERT(!lpObject); - lpValue->SetJSObject(); - } else { - lpValue->SetHostObject(lpObject, lpClass); - } -} - -void FXJSE_Value_SetArray(FXJSE_HVALUE hValue, - uint32_t uValueCount, - FXJSE_HVALUE* rgValues) { - reinterpret_cast(hValue) - ->SetArray(uValueCount, reinterpret_cast(rgValues)); -} - -void FXJSE_Value_SetDate(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) { - reinterpret_cast(hValue)->SetDate(dDouble); -} - -void FXJSE_Value_Set(FXJSE_HVALUE hValue, FXJSE_HVALUE hOriginalValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpOriginalValue = - reinterpret_cast(hOriginalValue); - ASSERT(lpValue && lpOriginalValue); - lpValue->Assign(lpOriginalValue); -} - -FX_BOOL FXJSE_Value_GetObjectProp(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hPropValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); - ASSERT(lpValue && lpPropValue); - return lpValue->GetObjectProperty(szPropName, lpPropValue); -} - -FX_BOOL FXJSE_Value_SetObjectProp(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hPropValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); - ASSERT(lpValue && lpPropValue); - return lpValue->SetObjectProperty(szPropName, lpPropValue); -} - -FX_BOOL FXJSE_Value_GetObjectPropByIdx(FXJSE_HVALUE hValue, - uint32_t uPropIdx, - FXJSE_HVALUE hPropValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); - ASSERT(lpValue && lpPropValue); - return lpValue->GetObjectProperty(uPropIdx, lpPropValue); -} - -FX_BOOL FXJSE_Value_SetObjectPropByIdx(FXJSE_HVALUE hValue, - uint32_t uPropIdx, - FXJSE_HVALUE hPropValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); - ASSERT(lpValue && lpPropValue); - return lpValue->SetObjectProperty(uPropIdx, lpPropValue); -} - -FX_BOOL FXJSE_Value_DeleteObjectProp(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szPropName) { - return reinterpret_cast(hValue) - ->DeleteObjectProperty(szPropName); -} - -FX_BOOL FXJSE_Value_ObjectHasOwnProp(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szPropName, - FX_BOOL bUseTypeGetter) { - return reinterpret_cast(hValue) - ->HasObjectOwnProperty(szPropName, bUseTypeGetter); -} - -FX_BOOL FXJSE_Value_SetObjectOwnProp(FXJSE_HVALUE hValue, - const CFX_ByteStringC& szPropName, - FXJSE_HVALUE hPropValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); - ASSERT(lpValue && lpPropValue); - return lpValue->SetObjectOwnProperty(szPropName, lpPropValue); -} - -FX_BOOL FXJSE_Value_SetFunctionBind(FXJSE_HVALUE hValue, - FXJSE_HVALUE hOldFunction, - FXJSE_HVALUE hNewThis) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - CFXJSE_Value* lpOldFunction = reinterpret_cast(hOldFunction); - CFXJSE_Value* lpNewThis = reinterpret_cast(hNewThis); - ASSERT(lpValue && lpOldFunction && lpNewThis); - return lpValue->SetFunctionBind(lpOldFunction, lpNewThis); -} - -FX_BOOL FXJSE_Value_CallFunction(FXJSE_HVALUE hFunction, - FXJSE_HVALUE hThis, - FXJSE_HVALUE hRetValue, - uint32_t nArgCount, - FXJSE_HVALUE* lpArgs) { - CFXJSE_Value* lpThis = reinterpret_cast(hThis); - CFXJSE_Value* lpRetValue = reinterpret_cast(hRetValue); - return reinterpret_cast(hFunction) - ->Call(lpThis, lpRetValue, nArgCount, lpArgs); -} - -FXJSE_HVALUE FXJSE_Value_Create(FXJSE_HRUNTIME hRuntime) { - return reinterpret_cast( - CFXJSE_Value::Create(reinterpret_cast(hRuntime))); -} - -void FXJSE_Value_Release(FXJSE_HVALUE hValue) { - CFXJSE_Value* lpValue = reinterpret_cast(hValue); - delete lpValue; -} - -FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue) { - return reinterpret_cast( - reinterpret_cast(hValue)->GetIsolate()); -} - -void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Name, - const CFX_ByteStringC& utf8Message) { - v8::Isolate* pIsolate = v8::Isolate::GetCurrent(); - ASSERT(pIsolate); - - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); - v8::Local hMessage = v8::String::NewFromUtf8( - pIsolate, utf8Message.GetCStr(), v8::String::kNormalString, - utf8Message.GetLength()); - v8::Local hError; - - if (utf8Name == "RangeError") { - hError = v8::Exception::RangeError(hMessage); - } else if (utf8Name == "ReferenceError") { - hError = v8::Exception::ReferenceError(hMessage); - } else if (utf8Name == "SyntaxError") { - hError = v8::Exception::SyntaxError(hMessage); - } else if (utf8Name == "TypeError") { - hError = v8::Exception::TypeError(hMessage); - } else { - hError = v8::Exception::Error(hMessage); - if (utf8Name != "Error" && !utf8Name.IsEmpty()) { - hError.As()->Set( - v8::String::NewFromUtf8(pIsolate, "name"), - v8::String::NewFromUtf8(pIsolate, utf8Name.GetCStr(), - v8::String::kNormalString, - utf8Name.GetLength())); - } - } - pIsolate->ThrowException(hError); -} - -CFXJSE_Value* CFXJSE_Value::Create(v8::Isolate* pIsolate) { - return new CFXJSE_Value(pIsolate); -} - -void* CFXJSE_Value::ToObject(CFXJSE_Class* lpClass) const { - ASSERT(!m_hValue.IsEmpty()); - - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); - ASSERT(!hValue.IsEmpty()); - - if (!hValue->IsObject()) - return nullptr; - - return FXJSE_RetrieveObjectBinding(hValue.As(), lpClass); -} - -V8_INLINE static double FXJSE_ftod(FX_FLOAT fNumber) { - if (sizeof(FX_FLOAT) != 4) { - ASSERT(FALSE); - return fNumber; - } - - uint32_t nFloatBits = (uint32_t&)fNumber; - uint8_t nExponent = (uint8_t)(nFloatBits >> 16 >> 7); - if (nExponent == 0 || nExponent == 255) - return fNumber; - - int8_t nErrExp = nExponent - 127 - 23; - if (nErrExp >= 0) - return fNumber; - - double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2; - double dNumber = fNumber, dNumberAbs = fabs(fNumber); - double dNumberAbsMin = dNumberAbs - dwErrorHalf, - dNumberAbsMax = dNumberAbs + dwErrorHalf; - int32_t iErrPos = 0; - if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) { - dNumberAbsMin = fmod(dNumberAbsMin, 1.0); - dNumberAbsMax = fmod(dNumberAbsMax, 1.0); - int32_t iErrPosMin = 1, iErrPosMax = 38; - do { - int32_t iMid = (iErrPosMin + iErrPosMax) / 2; - double dPow = pow(10.0, iMid); - if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) { - iErrPosMin = iMid + 1; - } else { - iErrPosMax = iMid; - } - } while (iErrPosMin < iErrPosMax); - iErrPos = iErrPosMax; - } - double dPow = pow(10.0, iErrPos); - return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow - : floor(dNumber * dPow + 0.5) / dPow; -} - -void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Number::New(m_pIsolate, FXJSE_ftod(fFloat)); - m_hValue.Reset(m_pIsolate, hValue); -} - -void CFXJSE_Value::SetHostObject(void* lpObject, CFXJSE_Class* lpClass) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - ASSERT(lpClass); - v8::Local hClass = - v8::Local::New(m_pIsolate, lpClass->m_hTemplate); - v8::Local hObject = hClass->InstanceTemplate()->NewInstance(); - FXJSE_UpdateObjectBinding(hObject, lpObject); - m_hValue.Reset(m_pIsolate, hObject); -} - -void CFXJSE_Value::SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hArrayObject = v8::Array::New(m_pIsolate, uValueCount); - if (rgValues) { - for (uint32_t i = 0; i < uValueCount; i++) { - if (rgValues[i]) { - hArrayObject->Set(i, v8::Local::New( - m_pIsolate, rgValues[i]->DirectGetValue())); - } - } - } - m_hValue.Reset(m_pIsolate, hArrayObject); -} - -void CFXJSE_Value::SetDate(FXJSE_DOUBLE dDouble) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hDate = v8::Date::New(m_pIsolate, dDouble); - m_hValue.Reset(m_pIsolate, hDate); -} - -FX_BOOL CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hPropValue = - v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); - return (FX_BOOL)hObject.As()->Set( - v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), - v8::String::kNormalString, - szPropName.GetLength()), - hPropValue); -} - -FX_BOOL CFXJSE_Value::GetObjectProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hPropValue = - hObject.As()->Get(v8::String::NewFromUtf8( - m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, - szPropName.GetLength())); - lpPropValue->ForceSetValue(hPropValue); - return TRUE; -} - -FX_BOOL CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx, - CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hPropValue = - v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); - return (FX_BOOL)hObject.As()->Set(uPropIdx, hPropValue); -} - -FX_BOOL CFXJSE_Value::GetObjectProperty(uint32_t uPropIdx, - CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hPropValue = hObject.As()->Get(uPropIdx); - lpPropValue->ForceSetValue(hPropValue); - return TRUE; -} - -FX_BOOL CFXJSE_Value::DeleteObjectProperty(const CFX_ByteStringC& szPropName) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - hObject.As()->Delete(v8::String::NewFromUtf8( - m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, - szPropName.GetLength())); - return TRUE; -} - -FX_BOOL CFXJSE_Value::HasObjectOwnProperty(const CFX_ByteStringC& szPropName, - FX_BOOL bUseTypeGetter) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hKey = v8::String::NewFromUtf8( - m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, - szPropName.GetLength()); - return hObject.As()->HasRealNamedProperty(hKey) || - (bUseTypeGetter && - hObject.As() - ->HasOwnProperty(m_pIsolate->GetCurrentContext(), hKey) - .FromMaybe(false)); -} - -FX_BOOL CFXJSE_Value::SetObjectOwnProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hObject = - v8::Local::New(m_pIsolate, m_hValue); - if (!hObject->IsObject()) - return FALSE; - - v8::Local hValue = - v8::Local::New(m_pIsolate, lpPropValue->m_hValue); - return hObject.As() - ->DefineOwnProperty( - m_pIsolate->GetCurrentContext(), - v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), - v8::String::kNormalString, - szPropName.GetLength()), - hValue) - .FromMaybe(false); -} - -FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, - CFXJSE_Value* lpNewThis) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local rgArgs[2]; - v8::Local hOldFunction = - v8::Local::New(m_pIsolate, lpOldFunction->DirectGetValue()); - if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction()) - return FALSE; - - rgArgs[0] = hOldFunction; - v8::Local hNewThis = - v8::Local::New(m_pIsolate, lpNewThis->DirectGetValue()); - if (hNewThis.IsEmpty()) - return FALSE; - - rgArgs[1] = hNewThis; - v8::Local hBinderFuncSource = - v8::String::NewFromUtf8(m_pIsolate, - "(function (oldfunction, newthis) { return " - "oldfunction.bind(newthis); })"); - v8::Local hBinderFunc = - v8::Script::Compile(hBinderFuncSource)->Run().As(); - v8::Local hBoundFunction = - hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs); - if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction()) - return FALSE; - - m_hValue.Reset(m_pIsolate, hBoundFunction); - return TRUE; -} - -#define FXJSE_INVALID_PTR ((void*)(intptr_t)-1) -FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver, - CFXJSE_Value* lpRetValue, - uint32_t nArgCount, - FXJSE_HVALUE* lpArgs) { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hFunctionValue = - v8::Local::New(m_pIsolate, DirectGetValue()); - v8::Local hFunctionObject = - !hFunctionValue.IsEmpty() && hFunctionValue->IsObject() - ? hFunctionValue.As() - : v8::Local(); - - v8::TryCatch trycatch(m_pIsolate); - if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) { - if (lpRetValue) - lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch)); - return FALSE; - } - - v8::Local hReturnValue; - v8::Local* lpLocalArgs = NULL; - if (nArgCount) { - lpLocalArgs = FX_Alloc(v8::Local, nArgCount); - for (uint32_t i = 0; i < nArgCount; i++) { - new (lpLocalArgs + i) v8::Local; - CFXJSE_Value* lpArg = (CFXJSE_Value*)lpArgs[i]; - if (lpArg) { - lpLocalArgs[i] = - v8::Local::New(m_pIsolate, lpArg->DirectGetValue()); - } - if (lpLocalArgs[i].IsEmpty()) { - lpLocalArgs[i] = v8::Undefined(m_pIsolate); - } - } - } - - FX_BOOL bRetValue = TRUE; - if (lpReceiver == FXJSE_INVALID_PTR) { - v8::MaybeLocal maybe_retvalue = - hFunctionObject->CallAsConstructor(m_pIsolate->GetCurrentContext(), - nArgCount, lpLocalArgs); - hReturnValue = maybe_retvalue.FromMaybe(v8::Local()); - } else { - v8::Local hReceiver; - if (lpReceiver) { - hReceiver = - v8::Local::New(m_pIsolate, lpReceiver->DirectGetValue()); - } - if (hReceiver.IsEmpty() || !hReceiver->IsObject()) - hReceiver = v8::Object::New(m_pIsolate); - - v8::MaybeLocal maybe_retvalue = hFunctionObject->CallAsFunction( - m_pIsolate->GetCurrentContext(), hReceiver, nArgCount, lpLocalArgs); - hReturnValue = maybe_retvalue.FromMaybe(v8::Local()); - } - - if (trycatch.HasCaught()) { - hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch); - bRetValue = FALSE; - } - - if (lpRetValue) - lpRetValue->ForceSetValue(hReturnValue); - - if (lpLocalArgs) { - for (uint32_t i = 0; i < nArgCount; i++) - lpLocalArgs[i].~Local(); - FX_Free(lpLocalArgs); - } - return bRetValue; -} diff --git a/xfa/src/fxjse/src/value.h b/xfa/src/fxjse/src/value.h deleted file mode 100644 index 4bda30d6df..0000000000 --- a/xfa/src/fxjse/src/value.h +++ /dev/null @@ -1,241 +0,0 @@ -// 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 - -#ifndef XFA_SRC_FXJSE_SRC_VALUE_H_ -#define XFA_SRC_FXJSE_SRC_VALUE_H_ - -#include "xfa/src/fxjse/src/scope_inline.h" - -class CFXJSE_Value { - public: - CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} - - protected: - CFXJSE_Value(); - CFXJSE_Value(const CFXJSE_Value&); - CFXJSE_Value& operator=(const CFXJSE_Value&); - - public: - V8_INLINE FX_BOOL IsUndefined() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsUndefined(); - } - V8_INLINE FX_BOOL IsNull() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsNull(); - } - V8_INLINE FX_BOOL IsBoolean() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsBoolean(); - } - V8_INLINE FX_BOOL IsString() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsString(); - } - V8_INLINE FX_BOOL IsNumber() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsNumber(); - } - V8_INLINE FX_BOOL IsInteger() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsInt32(); - } - V8_INLINE FX_BOOL IsObject() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsObject(); - } - V8_INLINE FX_BOOL IsArray() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsArray(); - } - V8_INLINE FX_BOOL IsFunction() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsFunction(); - } - V8_INLINE FX_BOOL IsDate() const { - if (m_hValue.IsEmpty()) { - return FALSE; - } - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return hValue->IsDate(); - } - - public: - V8_INLINE FX_BOOL ToBoolean() const { - ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return static_cast(hValue->BooleanValue()); - } - V8_INLINE FX_FLOAT ToFloat() const { - ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return static_cast(hValue->NumberValue()); - } - V8_INLINE FXJSE_DOUBLE ToDouble() const { - ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return static_cast(hValue->NumberValue()); - } - V8_INLINE int32_t ToInteger() const { - ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - return static_cast(hValue->NumberValue()); - } - V8_INLINE void ToString(CFX_ByteString& szStrOutput) const { - ASSERT(!m_hValue.IsEmpty()); - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = - v8::Local::New(m_pIsolate, m_hValue); - v8::Local hString = hValue->ToString(); - v8::String::Utf8Value hStringVal(hString); - szStrOutput = *hStringVal; - } - void* ToObject(CFXJSE_Class* lpClass) const; - - public: - V8_INLINE void SetUndefined() { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Undefined(m_pIsolate); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetNull() { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Null(m_pIsolate); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetBoolean(FX_BOOL bBoolean) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = - v8::Boolean::New(m_pIsolate, bBoolean != FALSE); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetInteger(int32_t nInteger) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Integer::New(m_pIsolate, nInteger); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetDouble(FXJSE_DOUBLE dDouble) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::Number::New(m_pIsolate, dDouble); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetString(const CFX_ByteStringC& szString) { - CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); - v8::Local hValue = v8::String::NewFromUtf8( - m_pIsolate, reinterpret_cast(szString.GetPtr()), - v8::String::kNormalString, szString.GetLength()); - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void SetFloat(FX_FLOAT fFloat); - V8_INLINE void SetJSObject() { - CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); - v8::Local hValue = v8::Object::New(m_pIsolate); - m_hValue.Reset(m_pIsolate, hValue); - } - void SetHostObject(void* lpObject, CFXJSE_Class* lpClass); - void SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues); - void SetDate(FXJSE_DOUBLE dDouble); - - public: - FX_BOOL GetObjectProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue); - FX_BOOL SetObjectProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue); - FX_BOOL GetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue); - FX_BOOL SetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue); - FX_BOOL DeleteObjectProperty(const CFX_ByteStringC& szPropName); - FX_BOOL HasObjectOwnProperty(const CFX_ByteStringC& szPropName, - FX_BOOL bUseTypeGetter); - FX_BOOL SetObjectOwnProperty(const CFX_ByteStringC& szPropName, - CFXJSE_Value* lpPropValue); - FX_BOOL SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis); - FX_BOOL Call(CFXJSE_Value* lpReceiver, - CFXJSE_Value* lpRetValue, - uint32_t nArgCount, - FXJSE_HVALUE* lpArgs); - - public: - V8_INLINE v8::Isolate* GetIsolate() const { return m_pIsolate; } - V8_INLINE const v8::Global& DirectGetValue() const { - return m_hValue; - } - V8_INLINE void ForceSetValue(v8::Local hValue) { - m_hValue.Reset(m_pIsolate, hValue); - } - V8_INLINE void Assign(const CFXJSE_Value* lpValue) { - if (lpValue) { - m_hValue.Reset(m_pIsolate, lpValue->m_hValue); - } else { - m_hValue.Reset(); - } - } - - public: - static CFXJSE_Value* Create(v8::Isolate* pIsolate); - - protected: - v8::Isolate* m_pIsolate; - v8::Global m_hValue; - friend class CFXJSE_Context; - friend class CFXJSE_Class; -}; - -#endif // XFA_SRC_FXJSE_SRC_VALUE_H_ diff --git a/xfa/src/fxjse/util_inline.h b/xfa/src/fxjse/util_inline.h new file mode 100644 index 0000000000..c29c22e1f8 --- /dev/null +++ b/xfa/src/fxjse/util_inline.h @@ -0,0 +1,51 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_UTIL_INLINE_H_ +#define XFA_SRC_FXJSE_UTIL_INLINE_H_ + +#include "xfa/src/fxjse/context.h" + +static V8_INLINE v8::Local FXJSE_GetGlobalObjectFromContext( + const v8::Local& hContext) { + return hContext->Global()->GetPrototype().As(); +} +static V8_INLINE void FXJSE_UpdateObjectBinding(v8::Local& hObject, + void* lpNewBinding) { + ASSERT(!hObject.IsEmpty()); + ASSERT(hObject->InternalFieldCount() > 0); + hObject->SetAlignedPointerInInternalField(0, lpNewBinding); +} +static V8_INLINE void* FXJSE_RetrieveObjectBinding( + const v8::Local& hJSObject, + CFXJSE_Class* lpClass = NULL) { + ASSERT(!hJSObject.IsEmpty()); + if (!hJSObject->IsObject()) { + return NULL; + } + v8::Local hObject = hJSObject; + if (hObject->InternalFieldCount() == 0) { + v8::Local hProtoObject = hObject->GetPrototype(); + if (hProtoObject.IsEmpty() || !hProtoObject->IsObject()) { + return NULL; + } + hObject = hProtoObject.As(); + if (hObject->InternalFieldCount() == 0) { + return NULL; + } + } + if (lpClass) { + v8::Local hClass = + v8::Local::New( + lpClass->GetContext()->GetRuntime(), lpClass->GetTemplate()); + if (!hClass->HasInstance(hObject)) { + return NULL; + } + } + return hObject->GetAlignedPointerFromInternalField(0); +} + +#endif // XFA_SRC_FXJSE_UTIL_INLINE_H_ diff --git a/xfa/src/fxjse/value.cpp b/xfa/src/fxjse/value.cpp new file mode 100644 index 0000000000..f7b04092d3 --- /dev/null +++ b/xfa/src/fxjse/value.cpp @@ -0,0 +1,582 @@ +// 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 + +#include "xfa/src/fxjse/value.h" + +#include + +#include "xfa/src/fxjse/class.h" +#include "xfa/src/fxjse/util_inline.h" + +FX_BOOL FXJSE_Value_IsUndefined(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsUndefined(); +} + +FX_BOOL FXJSE_Value_IsNull(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsNull(); +} + +FX_BOOL FXJSE_Value_IsBoolean(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsBoolean(); +} + +FX_BOOL FXJSE_Value_IsUTF8String(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsString(); +} + +FX_BOOL FXJSE_Value_IsNumber(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsNumber(); +} + +FX_BOOL FXJSE_Value_IsInteger(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsInteger(); +} + +FX_BOOL FXJSE_Value_IsObject(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsObject(); +} + +FX_BOOL FXJSE_Value_IsArray(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsArray(); +} + +FX_BOOL FXJSE_Value_IsFunction(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsFunction(); +} + +FX_BOOL FXJSE_Value_IsDate(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue && lpValue->IsDate(); +} + +FX_BOOL FXJSE_Value_ToBoolean(FXJSE_HVALUE hValue) { + return reinterpret_cast(hValue)->ToBoolean(); +} + +FX_FLOAT FXJSE_Value_ToFloat(FXJSE_HVALUE hValue) { + return reinterpret_cast(hValue)->ToFloat(); +} + +FXJSE_DOUBLE FXJSE_Value_ToDouble(FXJSE_HVALUE hValue) { + return reinterpret_cast(hValue)->ToDouble(); +} + +void FXJSE_Value_ToUTF8String(FXJSE_HVALUE hValue, + CFX_ByteString& szStrOutput) { + return reinterpret_cast(hValue)->ToString(szStrOutput); +} + +int32_t FXJSE_Value_ToInteger(FXJSE_HVALUE hValue) { + return reinterpret_cast(hValue)->ToInteger(); +} + +void* FXJSE_Value_ToObject(FXJSE_HVALUE hValue, FXJSE_HCLASS hClass) { + CFXJSE_Class* lpClass = reinterpret_cast(hClass); + return reinterpret_cast(hValue)->ToObject(lpClass); +} + +void FXJSE_Value_SetUndefined(FXJSE_HVALUE hValue) { + reinterpret_cast(hValue)->SetUndefined(); +} + +void FXJSE_Value_SetNull(FXJSE_HVALUE hValue) { + reinterpret_cast(hValue)->SetNull(); +} + +void FXJSE_Value_SetBoolean(FXJSE_HVALUE hValue, FX_BOOL bBoolean) { + reinterpret_cast(hValue)->SetBoolean(bBoolean); +} + +void FXJSE_Value_SetUTF8String(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szString) { + reinterpret_cast(hValue)->SetString(szString); +} + +void FXJSE_Value_SetInteger(FXJSE_HVALUE hValue, int32_t nInteger) { + reinterpret_cast(hValue)->SetInteger(nInteger); +} + +void FXJSE_Value_SetFloat(FXJSE_HVALUE hValue, FX_FLOAT fFloat) { + reinterpret_cast(hValue)->SetFloat(fFloat); +} + +void FXJSE_Value_SetDouble(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) { + reinterpret_cast(hValue)->SetDouble(dDouble); +} + +void FXJSE_Value_SetObject(FXJSE_HVALUE hValue, + void* lpObject, + FXJSE_HCLASS hClass) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Class* lpClass = reinterpret_cast(hClass); + if (!lpClass) { + ASSERT(!lpObject); + lpValue->SetJSObject(); + } else { + lpValue->SetHostObject(lpObject, lpClass); + } +} + +void FXJSE_Value_SetArray(FXJSE_HVALUE hValue, + uint32_t uValueCount, + FXJSE_HVALUE* rgValues) { + reinterpret_cast(hValue) + ->SetArray(uValueCount, reinterpret_cast(rgValues)); +} + +void FXJSE_Value_SetDate(FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) { + reinterpret_cast(hValue)->SetDate(dDouble); +} + +void FXJSE_Value_Set(FXJSE_HVALUE hValue, FXJSE_HVALUE hOriginalValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpOriginalValue = + reinterpret_cast(hOriginalValue); + ASSERT(lpValue && lpOriginalValue); + lpValue->Assign(lpOriginalValue); +} + +FX_BOOL FXJSE_Value_GetObjectProp(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hPropValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); + ASSERT(lpValue && lpPropValue); + return lpValue->GetObjectProperty(szPropName, lpPropValue); +} + +FX_BOOL FXJSE_Value_SetObjectProp(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hPropValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); + ASSERT(lpValue && lpPropValue); + return lpValue->SetObjectProperty(szPropName, lpPropValue); +} + +FX_BOOL FXJSE_Value_GetObjectPropByIdx(FXJSE_HVALUE hValue, + uint32_t uPropIdx, + FXJSE_HVALUE hPropValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); + ASSERT(lpValue && lpPropValue); + return lpValue->GetObjectProperty(uPropIdx, lpPropValue); +} + +FX_BOOL FXJSE_Value_SetObjectPropByIdx(FXJSE_HVALUE hValue, + uint32_t uPropIdx, + FXJSE_HVALUE hPropValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); + ASSERT(lpValue && lpPropValue); + return lpValue->SetObjectProperty(uPropIdx, lpPropValue); +} + +FX_BOOL FXJSE_Value_DeleteObjectProp(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szPropName) { + return reinterpret_cast(hValue) + ->DeleteObjectProperty(szPropName); +} + +FX_BOOL FXJSE_Value_ObjectHasOwnProp(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szPropName, + FX_BOOL bUseTypeGetter) { + return reinterpret_cast(hValue) + ->HasObjectOwnProperty(szPropName, bUseTypeGetter); +} + +FX_BOOL FXJSE_Value_SetObjectOwnProp(FXJSE_HVALUE hValue, + const CFX_ByteStringC& szPropName, + FXJSE_HVALUE hPropValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpPropValue = reinterpret_cast(hPropValue); + ASSERT(lpValue && lpPropValue); + return lpValue->SetObjectOwnProperty(szPropName, lpPropValue); +} + +FX_BOOL FXJSE_Value_SetFunctionBind(FXJSE_HVALUE hValue, + FXJSE_HVALUE hOldFunction, + FXJSE_HVALUE hNewThis) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Value* lpOldFunction = reinterpret_cast(hOldFunction); + CFXJSE_Value* lpNewThis = reinterpret_cast(hNewThis); + ASSERT(lpValue && lpOldFunction && lpNewThis); + return lpValue->SetFunctionBind(lpOldFunction, lpNewThis); +} + +FX_BOOL FXJSE_Value_CallFunction(FXJSE_HVALUE hFunction, + FXJSE_HVALUE hThis, + FXJSE_HVALUE hRetValue, + uint32_t nArgCount, + FXJSE_HVALUE* lpArgs) { + CFXJSE_Value* lpThis = reinterpret_cast(hThis); + CFXJSE_Value* lpRetValue = reinterpret_cast(hRetValue); + return reinterpret_cast(hFunction) + ->Call(lpThis, lpRetValue, nArgCount, lpArgs); +} + +FXJSE_HVALUE FXJSE_Value_Create(FXJSE_HRUNTIME hRuntime) { + return reinterpret_cast( + CFXJSE_Value::Create(reinterpret_cast(hRuntime))); +} + +void FXJSE_Value_Release(FXJSE_HVALUE hValue) { + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + delete lpValue; +} + +FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue) { + return reinterpret_cast( + reinterpret_cast(hValue)->GetIsolate()); +} + +void FXJSE_ThrowMessage(const CFX_ByteStringC& utf8Name, + const CFX_ByteStringC& utf8Message) { + v8::Isolate* pIsolate = v8::Isolate::GetCurrent(); + ASSERT(pIsolate); + + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); + v8::Local hMessage = v8::String::NewFromUtf8( + pIsolate, utf8Message.GetCStr(), v8::String::kNormalString, + utf8Message.GetLength()); + v8::Local hError; + + if (utf8Name == "RangeError") { + hError = v8::Exception::RangeError(hMessage); + } else if (utf8Name == "ReferenceError") { + hError = v8::Exception::ReferenceError(hMessage); + } else if (utf8Name == "SyntaxError") { + hError = v8::Exception::SyntaxError(hMessage); + } else if (utf8Name == "TypeError") { + hError = v8::Exception::TypeError(hMessage); + } else { + hError = v8::Exception::Error(hMessage); + if (utf8Name != "Error" && !utf8Name.IsEmpty()) { + hError.As()->Set( + v8::String::NewFromUtf8(pIsolate, "name"), + v8::String::NewFromUtf8(pIsolate, utf8Name.GetCStr(), + v8::String::kNormalString, + utf8Name.GetLength())); + } + } + pIsolate->ThrowException(hError); +} + +CFXJSE_Value* CFXJSE_Value::Create(v8::Isolate* pIsolate) { + return new CFXJSE_Value(pIsolate); +} + +void* CFXJSE_Value::ToObject(CFXJSE_Class* lpClass) const { + ASSERT(!m_hValue.IsEmpty()); + + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = v8::Local::New(m_pIsolate, m_hValue); + ASSERT(!hValue.IsEmpty()); + + if (!hValue->IsObject()) + return nullptr; + + return FXJSE_RetrieveObjectBinding(hValue.As(), lpClass); +} + +V8_INLINE static double FXJSE_ftod(FX_FLOAT fNumber) { + if (sizeof(FX_FLOAT) != 4) { + ASSERT(FALSE); + return fNumber; + } + + uint32_t nFloatBits = (uint32_t&)fNumber; + uint8_t nExponent = (uint8_t)(nFloatBits >> 16 >> 7); + if (nExponent == 0 || nExponent == 255) + return fNumber; + + int8_t nErrExp = nExponent - 127 - 23; + if (nErrExp >= 0) + return fNumber; + + double dwError = pow(2.0, nErrExp), dwErrorHalf = dwError / 2; + double dNumber = fNumber, dNumberAbs = fabs(fNumber); + double dNumberAbsMin = dNumberAbs - dwErrorHalf, + dNumberAbsMax = dNumberAbs + dwErrorHalf; + int32_t iErrPos = 0; + if (floor(dNumberAbsMin) == floor(dNumberAbsMax)) { + dNumberAbsMin = fmod(dNumberAbsMin, 1.0); + dNumberAbsMax = fmod(dNumberAbsMax, 1.0); + int32_t iErrPosMin = 1, iErrPosMax = 38; + do { + int32_t iMid = (iErrPosMin + iErrPosMax) / 2; + double dPow = pow(10.0, iMid); + if (floor(dNumberAbsMin * dPow) == floor(dNumberAbsMax * dPow)) { + iErrPosMin = iMid + 1; + } else { + iErrPosMax = iMid; + } + } while (iErrPosMin < iErrPosMax); + iErrPos = iErrPosMax; + } + double dPow = pow(10.0, iErrPos); + return fNumber < 0 ? ceil(dNumber * dPow - 0.5) / dPow + : floor(dNumber * dPow + 0.5) / dPow; +} + +void CFXJSE_Value::SetFloat(FX_FLOAT fFloat) { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::Number::New(m_pIsolate, FXJSE_ftod(fFloat)); + m_hValue.Reset(m_pIsolate, hValue); +} + +void CFXJSE_Value::SetHostObject(void* lpObject, CFXJSE_Class* lpClass) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + ASSERT(lpClass); + v8::Local hClass = + v8::Local::New(m_pIsolate, lpClass->m_hTemplate); + v8::Local hObject = hClass->InstanceTemplate()->NewInstance(); + FXJSE_UpdateObjectBinding(hObject, lpObject); + m_hValue.Reset(m_pIsolate, hObject); +} + +void CFXJSE_Value::SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hArrayObject = v8::Array::New(m_pIsolate, uValueCount); + if (rgValues) { + for (uint32_t i = 0; i < uValueCount; i++) { + if (rgValues[i]) { + hArrayObject->Set(i, v8::Local::New( + m_pIsolate, rgValues[i]->DirectGetValue())); + } + } + } + m_hValue.Reset(m_pIsolate, hArrayObject); +} + +void CFXJSE_Value::SetDate(FXJSE_DOUBLE dDouble) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hDate = v8::Date::New(m_pIsolate, dDouble); + m_hValue.Reset(m_pIsolate, hDate); +} + +FX_BOOL CFXJSE_Value::SetObjectProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hPropValue = + v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); + return (FX_BOOL)hObject.As()->Set( + v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), + v8::String::kNormalString, + szPropName.GetLength()), + hPropValue); +} + +FX_BOOL CFXJSE_Value::GetObjectProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hPropValue = + hObject.As()->Get(v8::String::NewFromUtf8( + m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, + szPropName.GetLength())); + lpPropValue->ForceSetValue(hPropValue); + return TRUE; +} + +FX_BOOL CFXJSE_Value::SetObjectProperty(uint32_t uPropIdx, + CFXJSE_Value* lpPropValue) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hPropValue = + v8::Local::New(m_pIsolate, lpPropValue->DirectGetValue()); + return (FX_BOOL)hObject.As()->Set(uPropIdx, hPropValue); +} + +FX_BOOL CFXJSE_Value::GetObjectProperty(uint32_t uPropIdx, + CFXJSE_Value* lpPropValue) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hPropValue = hObject.As()->Get(uPropIdx); + lpPropValue->ForceSetValue(hPropValue); + return TRUE; +} + +FX_BOOL CFXJSE_Value::DeleteObjectProperty(const CFX_ByteStringC& szPropName) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + hObject.As()->Delete(v8::String::NewFromUtf8( + m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, + szPropName.GetLength())); + return TRUE; +} + +FX_BOOL CFXJSE_Value::HasObjectOwnProperty(const CFX_ByteStringC& szPropName, + FX_BOOL bUseTypeGetter) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hKey = v8::String::NewFromUtf8( + m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, + szPropName.GetLength()); + return hObject.As()->HasRealNamedProperty(hKey) || + (bUseTypeGetter && + hObject.As() + ->HasOwnProperty(m_pIsolate->GetCurrentContext(), hKey) + .FromMaybe(false)); +} + +FX_BOOL CFXJSE_Value::SetObjectOwnProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hObject = + v8::Local::New(m_pIsolate, m_hValue); + if (!hObject->IsObject()) + return FALSE; + + v8::Local hValue = + v8::Local::New(m_pIsolate, lpPropValue->m_hValue); + return hObject.As() + ->DefineOwnProperty( + m_pIsolate->GetCurrentContext(), + v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), + v8::String::kNormalString, + szPropName.GetLength()), + hValue) + .FromMaybe(false); +} + +FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, + CFXJSE_Value* lpNewThis) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local rgArgs[2]; + v8::Local hOldFunction = + v8::Local::New(m_pIsolate, lpOldFunction->DirectGetValue()); + if (hOldFunction.IsEmpty() || !hOldFunction->IsFunction()) + return FALSE; + + rgArgs[0] = hOldFunction; + v8::Local hNewThis = + v8::Local::New(m_pIsolate, lpNewThis->DirectGetValue()); + if (hNewThis.IsEmpty()) + return FALSE; + + rgArgs[1] = hNewThis; + v8::Local hBinderFuncSource = + v8::String::NewFromUtf8(m_pIsolate, + "(function (oldfunction, newthis) { return " + "oldfunction.bind(newthis); })"); + v8::Local hBinderFunc = + v8::Script::Compile(hBinderFuncSource)->Run().As(); + v8::Local hBoundFunction = + hBinderFunc->Call(m_pIsolate->GetCurrentContext()->Global(), 2, rgArgs); + if (hBoundFunction.IsEmpty() || !hBoundFunction->IsFunction()) + return FALSE; + + m_hValue.Reset(m_pIsolate, hBoundFunction); + return TRUE; +} + +#define FXJSE_INVALID_PTR ((void*)(intptr_t)-1) +FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver, + CFXJSE_Value* lpRetValue, + uint32_t nArgCount, + FXJSE_HVALUE* lpArgs) { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hFunctionValue = + v8::Local::New(m_pIsolate, DirectGetValue()); + v8::Local hFunctionObject = + !hFunctionValue.IsEmpty() && hFunctionValue->IsObject() + ? hFunctionValue.As() + : v8::Local(); + + v8::TryCatch trycatch(m_pIsolate); + if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) { + if (lpRetValue) + lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch)); + return FALSE; + } + + v8::Local hReturnValue; + v8::Local* lpLocalArgs = NULL; + if (nArgCount) { + lpLocalArgs = FX_Alloc(v8::Local, nArgCount); + for (uint32_t i = 0; i < nArgCount; i++) { + new (lpLocalArgs + i) v8::Local; + CFXJSE_Value* lpArg = (CFXJSE_Value*)lpArgs[i]; + if (lpArg) { + lpLocalArgs[i] = + v8::Local::New(m_pIsolate, lpArg->DirectGetValue()); + } + if (lpLocalArgs[i].IsEmpty()) { + lpLocalArgs[i] = v8::Undefined(m_pIsolate); + } + } + } + + FX_BOOL bRetValue = TRUE; + if (lpReceiver == FXJSE_INVALID_PTR) { + v8::MaybeLocal maybe_retvalue = + hFunctionObject->CallAsConstructor(m_pIsolate->GetCurrentContext(), + nArgCount, lpLocalArgs); + hReturnValue = maybe_retvalue.FromMaybe(v8::Local()); + } else { + v8::Local hReceiver; + if (lpReceiver) { + hReceiver = + v8::Local::New(m_pIsolate, lpReceiver->DirectGetValue()); + } + if (hReceiver.IsEmpty() || !hReceiver->IsObject()) + hReceiver = v8::Object::New(m_pIsolate); + + v8::MaybeLocal maybe_retvalue = hFunctionObject->CallAsFunction( + m_pIsolate->GetCurrentContext(), hReceiver, nArgCount, lpLocalArgs); + hReturnValue = maybe_retvalue.FromMaybe(v8::Local()); + } + + if (trycatch.HasCaught()) { + hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch); + bRetValue = FALSE; + } + + if (lpRetValue) + lpRetValue->ForceSetValue(hReturnValue); + + if (lpLocalArgs) { + for (uint32_t i = 0; i < nArgCount; i++) + lpLocalArgs[i].~Local(); + FX_Free(lpLocalArgs); + } + return bRetValue; +} diff --git a/xfa/src/fxjse/value.h b/xfa/src/fxjse/value.h new file mode 100644 index 0000000000..55c9c72ce2 --- /dev/null +++ b/xfa/src/fxjse/value.h @@ -0,0 +1,241 @@ +// 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 + +#ifndef XFA_SRC_FXJSE_VALUE_H_ +#define XFA_SRC_FXJSE_VALUE_H_ + +#include "xfa/src/fxjse/scope_inline.h" + +class CFXJSE_Value { + public: + CFXJSE_Value(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} + + protected: + CFXJSE_Value(); + CFXJSE_Value(const CFXJSE_Value&); + CFXJSE_Value& operator=(const CFXJSE_Value&); + + public: + V8_INLINE FX_BOOL IsUndefined() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsUndefined(); + } + V8_INLINE FX_BOOL IsNull() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsNull(); + } + V8_INLINE FX_BOOL IsBoolean() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsBoolean(); + } + V8_INLINE FX_BOOL IsString() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsString(); + } + V8_INLINE FX_BOOL IsNumber() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsNumber(); + } + V8_INLINE FX_BOOL IsInteger() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsInt32(); + } + V8_INLINE FX_BOOL IsObject() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsObject(); + } + V8_INLINE FX_BOOL IsArray() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsArray(); + } + V8_INLINE FX_BOOL IsFunction() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsFunction(); + } + V8_INLINE FX_BOOL IsDate() const { + if (m_hValue.IsEmpty()) { + return FALSE; + } + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return hValue->IsDate(); + } + + public: + V8_INLINE FX_BOOL ToBoolean() const { + ASSERT(!m_hValue.IsEmpty()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return static_cast(hValue->BooleanValue()); + } + V8_INLINE FX_FLOAT ToFloat() const { + ASSERT(!m_hValue.IsEmpty()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return static_cast(hValue->NumberValue()); + } + V8_INLINE FXJSE_DOUBLE ToDouble() const { + ASSERT(!m_hValue.IsEmpty()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return static_cast(hValue->NumberValue()); + } + V8_INLINE int32_t ToInteger() const { + ASSERT(!m_hValue.IsEmpty()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + return static_cast(hValue->NumberValue()); + } + V8_INLINE void ToString(CFX_ByteString& szStrOutput) const { + ASSERT(!m_hValue.IsEmpty()); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = + v8::Local::New(m_pIsolate, m_hValue); + v8::Local hString = hValue->ToString(); + v8::String::Utf8Value hStringVal(hString); + szStrOutput = *hStringVal; + } + void* ToObject(CFXJSE_Class* lpClass) const; + + public: + V8_INLINE void SetUndefined() { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::Undefined(m_pIsolate); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetNull() { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::Null(m_pIsolate); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetBoolean(FX_BOOL bBoolean) { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = + v8::Boolean::New(m_pIsolate, bBoolean != FALSE); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetInteger(int32_t nInteger) { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::Integer::New(m_pIsolate, nInteger); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetDouble(FXJSE_DOUBLE dDouble) { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::Number::New(m_pIsolate, dDouble); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetString(const CFX_ByteStringC& szString) { + CFXJSE_ScopeUtil_IsolateHandle scope(m_pIsolate); + v8::Local hValue = v8::String::NewFromUtf8( + m_pIsolate, reinterpret_cast(szString.GetPtr()), + v8::String::kNormalString, szString.GetLength()); + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void SetFloat(FX_FLOAT fFloat); + V8_INLINE void SetJSObject() { + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hValue = v8::Object::New(m_pIsolate); + m_hValue.Reset(m_pIsolate, hValue); + } + void SetHostObject(void* lpObject, CFXJSE_Class* lpClass); + void SetArray(uint32_t uValueCount, CFXJSE_Value** rgValues); + void SetDate(FXJSE_DOUBLE dDouble); + + public: + FX_BOOL GetObjectProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue); + FX_BOOL SetObjectProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue); + FX_BOOL GetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue); + FX_BOOL SetObjectProperty(uint32_t uPropIdx, CFXJSE_Value* lpPropValue); + FX_BOOL DeleteObjectProperty(const CFX_ByteStringC& szPropName); + FX_BOOL HasObjectOwnProperty(const CFX_ByteStringC& szPropName, + FX_BOOL bUseTypeGetter); + FX_BOOL SetObjectOwnProperty(const CFX_ByteStringC& szPropName, + CFXJSE_Value* lpPropValue); + FX_BOOL SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis); + FX_BOOL Call(CFXJSE_Value* lpReceiver, + CFXJSE_Value* lpRetValue, + uint32_t nArgCount, + FXJSE_HVALUE* lpArgs); + + public: + V8_INLINE v8::Isolate* GetIsolate() const { return m_pIsolate; } + V8_INLINE const v8::Global& DirectGetValue() const { + return m_hValue; + } + V8_INLINE void ForceSetValue(v8::Local hValue) { + m_hValue.Reset(m_pIsolate, hValue); + } + V8_INLINE void Assign(const CFXJSE_Value* lpValue) { + if (lpValue) { + m_hValue.Reset(m_pIsolate, lpValue->m_hValue); + } else { + m_hValue.Reset(); + } + } + + public: + static CFXJSE_Value* Create(v8::Isolate* pIsolate); + + protected: + v8::Isolate* m_pIsolate; + v8::Global m_hValue; + friend class CFXJSE_Context; + friend class CFXJSE_Class; +}; + +#endif // XFA_SRC_FXJSE_VALUE_H_ -- cgit v1.2.3