From fdc00a7042d912aafaabddae4d9c84199921ef23 Mon Sep 17 00:00:00 2001 From: Bo Xu Date: Tue, 28 Oct 2014 23:03:33 -0700 Subject: Merge XFA to PDFium master at 4dc95e7 on 10/28/2014 --- xfa/src/fxjse/src/class.cpp | 268 ++++++++++++++++++++ xfa/src/fxjse/src/class.h | 40 +++ xfa/src/fxjse/src/context.cpp | 224 +++++++++++++++++ xfa/src/fxjse/src/context.h | 37 +++ xfa/src/fxjse/src/dynprop.cpp | 284 +++++++++++++++++++++ xfa/src/fxjse/src/fxv8.h | 11 + xfa/src/fxjse/src/runtime.cpp | 118 +++++++++ xfa/src/fxjse/src/runtime.h | 39 +++ xfa/src/fxjse/src/scope_inline.h | 86 +++++++ xfa/src/fxjse/src/util_inline.h | 44 ++++ xfa/src/fxjse/src/value.cpp | 524 +++++++++++++++++++++++++++++++++++++++ xfa/src/fxjse/src/value.h | 236 ++++++++++++++++++ 12 files changed, 1911 insertions(+) create mode 100644 xfa/src/fxjse/src/class.cpp create mode 100644 xfa/src/fxjse/src/class.h create mode 100644 xfa/src/fxjse/src/context.cpp create mode 100644 xfa/src/fxjse/src/context.h create mode 100644 xfa/src/fxjse/src/dynprop.cpp create mode 100644 xfa/src/fxjse/src/fxv8.h create mode 100644 xfa/src/fxjse/src/runtime.cpp create mode 100644 xfa/src/fxjse/src/runtime.h create mode 100644 xfa/src/fxjse/src/scope_inline.h create mode 100644 xfa/src/fxjse/src/util_inline.h create mode 100644 xfa/src/fxjse/src/value.cpp create mode 100644 xfa/src/fxjse/src/value.h (limited to 'xfa/src/fxjse') diff --git a/xfa/src/fxjse/src/class.cpp b/xfa/src/fxjse/src/class.cpp new file mode 100644 index 0000000000..326e8d47c2 --- /dev/null +++ b/xfa/src/fxjse/src/class.cpp @@ -0,0 +1,268 @@ +// 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 "../../foxitlib.h" +#include "fxv8.h" +#include "context.h" +#include "class.h" +#include "value.h" +#include "scope_inline.h" +#include "util_inline.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::Handle hGlobalObject = FXJSE_GetGlobalObjectFromContext(scope.GetLocalContext()); + for(FX_INT32 i = 0; i < nNum; i++) { + hGlobalObject->ForceSet(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)); + } +} +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, FX_BSTR 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); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + if(lpClassDefinition->dynMethodCall || lpClassDefinition->dynPropGetter || lpClassDefinition->dynPropSetter || lpClassDefinition->dynPropTypeGetter) { + CFXJSE_Class::SetUpDynPropHandler(NULL, lpThisValue, lpClassDefinition); + } + delete lpThisValue; + lpThisValue = NULL; +} +FXJSE_HRUNTIME CFXJSE_Arguments::GetRuntime() const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + return reinterpret_cast(lpArguments->m_pRetValue->GetIsolate()); +} +FX_INT32 CFXJSE_Arguments::GetLength() const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + return lpArguments->m_pInfo->Length(); +} +FXJSE_HVALUE CFXJSE_Arguments::GetValue(FX_INT32 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(FX_INT32 index) const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + return (*lpArguments->m_pInfo)[index]->BooleanValue() ? TRUE : FALSE; +} +FX_INT32 CFXJSE_Arguments::GetInt32(FX_INT32 index) const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); +} +FX_FLOAT CFXJSE_Arguments::GetFloat(FX_INT32 index) const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + return static_cast((*lpArguments->m_pInfo)[index]->NumberValue()); +} +CFX_ByteString CFXJSE_Arguments::GetUTF8String(FX_INT32 index) const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + v8::Handle hString = (*lpArguments->m_pInfo)[index]->ToString(); + v8::String::Utf8Value szStringVal(hString); + return CFX_ByteString(*szStringVal); +} +FX_LPVOID CFXJSE_Arguments::GetObject(FX_INT32 index, FXJSE_HCLASS hClass ) const +{ + const CFXJSE_ArgumentsImpl* lpArguments = reinterpret_cast(this); + v8::Handle 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(), (FX_LPCSTR)szStringVal, v8::String::kNormalString, szStringVal.GetLength())); + } else { + info.GetReturnValue().Set(info.This()->ObjectProtoToString()); + } +} +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 = FX_NEW CFXJSE_Class(lpContext); + ASSERT(pClass); + pClass->m_szClassName = lpClassDefinition->name; + 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(); + if (lpClassDefinition->dynPropDeleter || lpClassDefinition->dynPropTypeGetter) { + SetUpNamedPropHandler(pIsolate, hObjectTemplate, lpClassDefinition); + } + if(lpClassDefinition->propNum) { + for(FX_INT32 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(FX_INT32 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, FX_BSTR 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 new file mode 100644 index 0000000000..6a0f89fc72 --- /dev/null +++ b/xfa/src/fxjse/src/class.h @@ -0,0 +1,40 @@ +// 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 FXJSE_CLASS_H_ +#define FXJSE_CLASS_H_ +class CFXJSE_Context; +class CFXJSE_Value; +class CFXJSE_Class : public CFX_Object +{ +protected: + CFXJSE_Class(CFXJSE_Context* lpContext) : m_pContext(lpContext) {} +public: + inline CFXJSE_Context* GetContext() + { + return m_pContext; + } + inline v8::Persistent& 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, FX_BSTR szName); + static void SetUpDynPropHandler(CFXJSE_Context* pContext, CFXJSE_Value* pValue, const FXJSE_CLASS* lpClassDefinition); + static void SetUpNamedPropHandler(v8::Isolate* pIsolate, v8::Local& hObjectTemplate, const FXJSE_CLASS* lpClassDefinition); +protected: + CFX_ByteString m_szClassName; + CFXJSE_Context* m_pContext; + v8::Persistent m_hTemplate; + friend class CFXJSE_Context; + friend class CFXJSE_Value; +}; +struct CFXJSE_ArgumentsImpl { + const v8::FunctionCallbackInfo* m_pInfo; + CFXJSE_Value* m_pRetValue; +}; +#endif diff --git a/xfa/src/fxjse/src/context.cpp b/xfa/src/fxjse/src/context.cpp new file mode 100644 index 0000000000..f2d979ee55 --- /dev/null +++ b/xfa/src/fxjse/src/context.cpp @@ -0,0 +1,224 @@ +// 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 "../../foxitlib.h" +#include "fxv8.h" +#include "context.h" +#include "class.h" +#include "value.h" +#include "scope_inline.h" +#include "util_inline.h" +FXJSE_HCONTEXT FXJSE_Context_Create(FXJSE_HRUNTIME hRuntime, const FXJSE_CLASS* lpGlobalClass , FX_LPVOID 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 FX_LPCSTR szCompatibleModeScripts[] = { + "(function (global, list) { 'use strict'; var objname; for (objname in list) { var globalobj = global[objname];\n\ + if (globalobj) { list[objname].forEach( function (name) { if (!globalobj[name]) { Object.defineProperty(globalobj, name, {writable: true, enumerable: false, value: \n\ + (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\ +})});}});}}}(this, {String: ['substr', 'toUpperCase']}));", +}; +void FXJSE_Context_EnableCompatibleMode(FXJSE_HCONTEXT hContext, FX_DWORD dwCompatibleFlags) +{ + for (FX_UINT32 i = 0; i < (FX_UINT32)FXJSE_COMPATIBLEMODEFLAGCOUNT; i++) { + if (dwCompatibleFlags & (1 << i)) { + FXJSE_ExecuteScript(hContext, szCompatibleModeScripts[i], NULL, NULL); + } + } +} +FX_BOOL FXJSE_ExecuteScript(FXJSE_HCONTEXT hContext, FX_LPCSTR 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::Handle FXJSE_CreateReturnValue(v8::Isolate* pIsolate, v8::TryCatch& trycatch) +{ + v8::Handle hReturnValue = v8::Object::New(pIsolate); + if (trycatch.HasCaught()) { + v8::Handle hException = trycatch.Exception(); + v8::Handle 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()); + hReturnValue->Set(5, v8::Integer::New(pIsolate, hMessage->GetStartColumn())); + hReturnValue->Set(6, v8::Integer::New(pIsolate, hMessage->GetEndColumn())); + } + 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, FX_INT32& nLine, FX_INT32& 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; + } + nLine = hValue.As()->Get(3)->ToInt32()->Value(); + nCol = hValue.As()->Get(5)->ToInt32()->Value(); + return TRUE; +} +CFXJSE_Context* CFXJSE_Context::Create(v8::Isolate* pIsolate, const FXJSE_CLASS* lpGlobalClass , FX_LPVOID lpGlobalObject ) +{ + CFXJSE_ScopeUtil_IsolateHandle scope(pIsolate); + CFXJSE_Context* pContext = FX_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(); + 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); + if (lpGlobalClass) { + if(lpGlobalClass->dynMethodCall || lpGlobalClass->dynPropGetter || lpGlobalClass->dynPropSetter || lpGlobalClass->dynPropTypeGetter) { + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(pIsolate); + lpThisValue->ForceSetValue(hGlobalObject); + CFXJSE_Class::SetUpDynPropHandler(pContext, lpThisValue, lpGlobalClass); + delete lpThisValue; + lpThisValue = NULL; + } + } + return pContext; +} +CFXJSE_Context::~CFXJSE_Context() +{ + for(FX_INT32 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(FX_LPCSTR szScript, CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject ) +{ + CFXJSE_ScopeUtil_IsolateHandleContext scope(this); + v8::TryCatch trycatch; + 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::Handle 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 new file mode 100644 index 0000000000..6579cd973a --- /dev/null +++ b/xfa/src/fxjse/src/context.h @@ -0,0 +1,37 @@ +// 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 FXJSE_CONTEXT_H_ +#define FXJSE_CONTEXT_H_ +class CFXJSE_Class; +class CFXJSE_Value; +class CFXJSE_Context : public CFX_Object +{ +protected: + CFXJSE_Context(v8::Isolate* pIsolate) : m_pIsolate(pIsolate) {} +public: + static CFXJSE_Context* Create(v8::Isolate* pIsolate, const FXJSE_CLASS* lpGlobalClass = NULL, FX_LPVOID lpGlobalObject = NULL); + ~CFXJSE_Context(); + V8_INLINE v8::Isolate* GetRuntime(void) + { + return m_pIsolate; + } + void GetGlobalObject(CFXJSE_Value* pValue); + FX_BOOL ExecuteScript(FX_LPCSTR szScript, CFXJSE_Value* lpRetValue, CFXJSE_Value* lpNewThisObject = NULL); +protected: + CFXJSE_Context(); + CFXJSE_Context(const CFXJSE_Context&); + CFXJSE_Context& operator = (const CFXJSE_Context&); +protected: + v8::Persistent 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::Handle FXJSE_CreateReturnValue(v8::Isolate* pIsolate, v8::TryCatch& trycatch); +#endif diff --git a/xfa/src/fxjse/src/dynprop.cpp b/xfa/src/fxjse/src/dynprop.cpp new file mode 100644 index 0000000000..fd03dcf6fd --- /dev/null +++ b/xfa/src/fxjse/src/dynprop.cpp @@ -0,0 +1,284 @@ +// 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 "../../foxitlib.h" +#include "fxv8.h" +#include "class.h" +#include "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 = NULL; + delete lpThisValue; + lpThisValue = NULL; +} +static void FXJSE_DynPropGetterAdapter (const FXJSE_CLASS* lpClass, FXJSE_HOBJECT hObject, FX_BSTR szPropName, FXJSE_HVALUE hValue) +{ + ASSERT(lpClass); + FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? 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(); + 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, FX_BSTR szPropName, FXJSE_HVALUE hValue) +{ + ASSERT(lpClass); + FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? 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, FX_BSTR szPropName) +{ + ASSERT(lpClass); + FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? 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, FX_BSTR szPropName) +{ + ASSERT(lpClass); + FX_INT32 nPropType = lpClass->dynPropTypeGetter == NULL ? 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_V8ProxyCallback_getOwnPropertyDescriptor_getter(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()); + CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + FXJSE_DynPropGetterAdapter(lpClass, reinterpret_cast(lpThisValue), szFxPropName, reinterpret_cast(lpNewValue)); + info.GetReturnValue().Set(lpNewValue->DirectGetValue()); + delete lpThisValue; + lpThisValue = NULL; + delete lpNewValue; + lpNewValue = NULL; +} +static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter(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()); + CFXJSE_Value* lpNewValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + lpNewValue->ForceSetValue(info[0]); + FXJSE_DynPropSetterAdapter(lpClass, reinterpret_cast(lpThisValue), szFxPropName, reinterpret_cast(lpNewValue)); + delete lpThisValue; + lpThisValue = NULL; + delete lpNewValue; + lpNewValue = NULL; +} +static void FXJSE_V8ProxyCallback_getOwnPropertyDescriptor (const v8::FunctionCallbackInfo& info) +{ + const FXJSE_CLASS* lpClass = static_cast(info.Data().As()->Value()); + if (!lpClass) { + return; + } + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + v8::Local hPropName = info[0]->ToString(); + v8::String::Utf8Value szPropName(hPropName); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + v8::Local hCallBackInfoTemplate = v8::ObjectTemplate::New(); + hCallBackInfoTemplate->SetInternalFieldCount(2); + v8::Local hCallBackInfo = hCallBackInfoTemplate->NewInstance(); + hCallBackInfo->SetAlignedPointerInInternalField(0, const_cast(lpClass)); + hCallBackInfo->SetInternalField(1, hPropName); + v8::Local hPropDescriptor = v8::Object::New(pIsolate); + hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "get"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_getter, hCallBackInfo)); + hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "set"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor_setter, hCallBackInfo)); + hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "enumerable"), v8::Boolean::New(pIsolate, false)); + hPropDescriptor->ForceSet(v8::String::NewFromUtf8(pIsolate, "configurable"), v8::Boolean::New(pIsolate, true)); + info.GetReturnValue().Set(hPropDescriptor); +} +static void FXJSE_V8ProxyCallback_getPropertyDescriptor (const v8::FunctionCallbackInfo& info) +{ + v8::Isolate* pIsolate = info.GetIsolate(); + v8::Local hChainObj = info.This()->GetPrototype().As(); + v8::Local fnSource = v8::Script::Compile(v8::String::NewFromUtf8(pIsolate, + "(function (o, name) { var fn, x, d; fn = Object.getOwnPropertyDescriptor; x = o; while(x && !(d = fn(x, name))){x = x.__proto__;} return d; })")); + v8::Local fn = fnSource->Run().As(); + v8::Handle rgArgs[] = {hChainObj, info[0]}; + v8::Local hChainDescriptor = fn->Call(info.This(), 2, rgArgs); + if(!hChainDescriptor.IsEmpty() && hChainDescriptor->IsObject()) { + info.GetReturnValue().Set(hChainDescriptor); + } else { + FXJSE_V8ProxyCallback_getOwnPropertyDescriptor(info); + } +} +static void FXJSE_V8ProxyCallback_getOwnPropertyNames (const v8::FunctionCallbackInfo& info) +{ + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + info.GetReturnValue().Set(v8::Array::New(pIsolate)); +} +static void FXJSE_V8ProxyCallback_getPropertyNames (const v8::FunctionCallbackInfo& info) +{ + v8::Local hChainObj = info.This()->GetPrototype().As(); + v8::Local hChainPropertyNames = hChainObj->GetPropertyNames(); + info.GetReturnValue().Set(hChainPropertyNames); +} +static void FXJSE_V8ProxyCallback_defineProperty (const v8::FunctionCallbackInfo& info) +{ + const FXJSE_CLASS* lpClass = static_cast(info.Data().As()->Value()); + if (!lpClass) { + return; + } + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + v8::Local hPropName = info[0]->ToString(); + v8::Local hPropDescriptor = info[1]->ToObject(); + v8::String::Utf8Value szPropName(hPropName); + if(!hPropDescriptor->Has(v8::String::NewFromUtf8(pIsolate, "value"))) { + return; + } + v8::Local hPropValue = hPropDescriptor->Get(v8::String::NewFromUtf8(pIsolate, "value")); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + CFXJSE_Value* lpPropValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + lpPropValue->ForceSetValue(hPropValue); + FXJSE_DynPropSetterAdapter(lpClass, reinterpret_cast(lpThisValue), szFxPropName, reinterpret_cast(lpPropValue)); + delete lpThisValue; + lpThisValue = NULL; + delete lpPropValue; + lpPropValue = NULL; +} +static void FXJSE_V8ProxyCallback_delete (const v8::FunctionCallbackInfo& info) +{ + info.GetReturnValue().Set(true); + const FXJSE_CLASS* lpClass = static_cast(info.Data().As()->Value()); + if (!lpClass) { + return; + } + v8::Isolate* pIsolate = info.GetIsolate(); + v8::HandleScope scope(pIsolate); + v8::Local hPropName = info[0]->ToString(); + v8::String::Utf8Value szPropName(hPropName); + CFX_ByteStringC szFxPropName(*szPropName, szPropName.length()); + CFXJSE_Value* lpThisValue = CFXJSE_Value::Create(info.GetIsolate()); + lpThisValue->ForceSetValue(info.This()); + info.GetReturnValue().Set(FXJSE_DynPropDeleterAdapter(lpClass, reinterpret_cast(lpThisValue), szFxPropName) ? true : false); + delete lpThisValue; + lpThisValue = NULL; +} +static void FXJSE_V8ProxyCallback_fix (const v8::FunctionCallbackInfo& info) +{ + info.GetReturnValue().SetUndefined(); +} +static void FXJSE_V8_NamedPropertyQueryCallback(v8::Local property, const v8::PropertyCallbackInfo& info) +{ + v8::Local thisObject = info.This(); + if (thisObject->HasRealNamedProperty(property)) { + return; + } + 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 FX_INT32 iV8Absent = 64; + info.GetReturnValue().Set(iV8Absent); + } + delete lpThisValue; + lpThisValue = NULL; +} +static void FXJSE_V8_NamedPropertyDeleterCallback(v8::Local property, const v8::PropertyCallbackInfo& info) +{ + v8::Local thisObject = info.This(); + if (thisObject->HasRealNamedProperty(property)) { + return; + } + 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 = NULL; +} +void CFXJSE_Class::SetUpDynPropHandler(CFXJSE_Context* pContext, CFXJSE_Value* pValue, const FXJSE_CLASS* lpClassDefinition) +{ + v8::Isolate* pIsolate = pValue->GetIsolate(); + CFXJSE_ScopeUtil_IsolateHandleRootOrNormalContext scope(pIsolate, pContext); + v8::Local hContext = v8::Local::New(pIsolate, pContext ? pContext->m_hContext : CFXJSE_RuntimeData::Get(pIsolate)->m_hRootContext); + v8::Local hObject = v8::Local::New(pIsolate, pValue->m_hValue.As()); + v8::Local hHarmonyProxyObj = hContext->Global()->Get(v8::String::NewFromUtf8(pIsolate, "Proxy")).As(); + v8::Local hHarmonyProxyCreateFn = hHarmonyProxyObj->Get(v8::String::NewFromUtf8(pIsolate, "create")).As(); + v8::Local hOldPrototype = hObject->GetPrototype(); + v8::Local hTrapper = v8::Object::New(pIsolate); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getOwnPropertyDescriptor"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyDescriptor, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getPropertyDescriptor"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyDescriptor, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getOwnPropertyNames"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getOwnPropertyNames, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "getPropertyNames"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_getPropertyNames, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "delete"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_delete, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "defineProperty"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_defineProperty, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + hTrapper->ForceSet(v8::String::NewFromUtf8(pIsolate, "fix"), v8::Function::New(pIsolate, FXJSE_V8ProxyCallback_fix, v8::External::New(pIsolate, const_cast(lpClassDefinition)))); + v8::Handle rgArgs[] = {hTrapper, hOldPrototype}; + v8::Local hNewPrototype = hHarmonyProxyCreateFn->Call(hHarmonyProxyObj, 2, rgArgs); + hObject->SetPrototype(hNewPrototype); +} +void CFXJSE_Class::SetUpNamedPropHandler(v8::Isolate* pIsolate, v8::Local& hObjectTemplate, const FXJSE_CLASS* lpClassDefinition) +{ + hObjectTemplate->SetNamedPropertyHandler(0, 0, + lpClassDefinition->dynPropTypeGetter ? FXJSE_V8_NamedPropertyQueryCallback : 0, + lpClassDefinition->dynPropDeleter ? FXJSE_V8_NamedPropertyDeleterCallback : 0, + 0, + v8::External::New(pIsolate, const_cast(lpClassDefinition))); +} diff --git a/xfa/src/fxjse/src/fxv8.h b/xfa/src/fxjse/src/fxv8.h new file mode 100644 index 0000000000..4cc7b3f406 --- /dev/null +++ b/xfa/src/fxjse/src/fxv8.h @@ -0,0 +1,11 @@ +// 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 _FX_V8_H_ +#define _FX_V8_H_ +#include +#include +#endif diff --git a/xfa/src/fxjse/src/runtime.cpp b/xfa/src/fxjse/src/runtime.cpp new file mode 100644 index 0000000000..e406f6a233 --- /dev/null +++ b/xfa/src/fxjse/src/runtime.cpp @@ -0,0 +1,118 @@ +// 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 "../../foxitlib.h" +#include "fxv8.h" +#include "runtime.h" +#include "scope_inline.h" +static void FXJSE_KillV8() +{ + v8::V8::Dispose(); +} +void FXJSE_Initialize() +{ + static FX_BOOL bV8Initialized = FALSE; + if (bV8Initialized) { + return; + } + bV8Initialized = TRUE; + atexit(FXJSE_KillV8); + FX_LPCSTR szCmdFlags = + "--harmony_proxies " + "--block_concurrent_recompilation " + ; + v8::V8::SetFlagsFromString(szCmdFlags, FXSYS_strlen(szCmdFlags)); + v8::V8::InitializeICU(); + v8::Platform* platform = v8::platform::CreateDefaultPlatform(); + v8::V8::InitializePlatform(platform); + v8::V8::Initialize(); + if(!CFXJSE_RuntimeData::g_RuntimeList) { + CFXJSE_RuntimeData::g_RuntimeList = FX_NEW CFXJSE_RuntimeList; + } +} +static void FXJSE_Runtime_DisposeCallback(v8::Isolate* pIsolate) +{ + { + v8::Locker locker(pIsolate); + CFXJSE_RuntimeData *pRuntimeData = reinterpret_cast(pIsolate->GetData(0)); + if(pRuntimeData) { + pIsolate->SetData(0, NULL); + delete pRuntimeData; + } + } + 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* pIsolate = v8::Isolate::New(); + ASSERT(pIsolate && CFXJSE_RuntimeData::g_RuntimeList); + CFXJSE_RuntimeData::g_RuntimeList->AppendRuntime(pIsolate); + return reinterpret_cast(pIsolate); +} +void FXJSE_Runtime_Release(FXJSE_HRUNTIME hRuntime) +{ + v8::Isolate* pIsolate = reinterpret_cast(hRuntime); + if(pIsolate) { + ASSERT(CFXJSE_RuntimeData::g_RuntimeList); + CFXJSE_RuntimeData::g_RuntimeList->RemoveRuntime(pIsolate, FXJSE_Runtime_DisposeCallback); + } +} +CFXJSE_RuntimeData* CFXJSE_RuntimeData::Create(v8::Isolate* pIsolate) +{ + CFXJSE_RuntimeData* pRuntimeData = FX_NEW CFXJSE_RuntimeData(pIsolate); + ASSERT(pRuntimeData); + 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) +{ + ASSERT(pIsolate); + CFXJSE_RuntimeData* pRuntimeData = static_cast(pIsolate->GetData(0)); + if(!pRuntimeData) { + pRuntimeData = CFXJSE_RuntimeData::Create(pIsolate); + ASSERT(pRuntimeData); + pIsolate->SetData(0, pRuntimeData); + } + return pRuntimeData; +} +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) +{ + FX_INT32 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) +{ + FX_INT32 iSize = m_RuntimeList.GetSize(); + if(lpfnDisposeCallback) { + for(FX_INT32 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 new file mode 100644 index 0000000000..78e891bfe4 --- /dev/null +++ b/xfa/src/fxjse/src/runtime.h @@ -0,0 +1,39 @@ +// 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 FXJSE_RUNTIME_H_ +#define FXJSE_RUNTIME_H_ +class CFXJSE_RuntimeList; +class CFXJSE_RuntimeData : public CFX_Object +{ +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::Persistent m_hRootContextGlobalTemplate; + v8::Persistent 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 CFX_Object +{ +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 diff --git a/xfa/src/fxjse/src/scope_inline.h b/xfa/src/fxjse/src/scope_inline.h new file mode 100644 index 0000000000..8a590f3fb8 --- /dev/null +++ b/xfa/src/fxjse/src/scope_inline.h @@ -0,0 +1,86 @@ +// 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 FXJSE_SCOPE_INLINE_H_ +#define FXJSE_SCOPE_INLINE_H_ +#include "runtime.h" +#include "context.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 diff --git a/xfa/src/fxjse/src/util_inline.h b/xfa/src/fxjse/src/util_inline.h new file mode 100644 index 0000000000..dddcab3053 --- /dev/null +++ b/xfa/src/fxjse/src/util_inline.h @@ -0,0 +1,44 @@ +// 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 FXJSE_UTIL_INLINE_H_ +#define FXJSE_UTIL_INLINE_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, FX_LPVOID lpNewBinding) +{ + ASSERT(!hObject.IsEmpty()); + ASSERT(hObject->InternalFieldCount() > 0); + hObject->SetAlignedPointerInInternalField(0, lpNewBinding); +} +static V8_INLINE FX_LPVOID 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::Handle 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 diff --git a/xfa/src/fxjse/src/value.cpp b/xfa/src/fxjse/src/value.cpp new file mode 100644 index 0000000000..cd2fff1595 --- /dev/null +++ b/xfa/src/fxjse/src/value.cpp @@ -0,0 +1,524 @@ +// 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 "../../foxitlib.h" +#include "fxv8.h" +#include "value.h" +#include "class.h" +#include +#include "util_inline.h" +#if !defined(__PLACEMENT_NEW_INLINE) && !defined(_MFC_VER) && !defined(_NEW) +#define __PLACEMENT_NEW_INLINE +inline void* operator new(size_t size, void* pos) +{ + return pos; +} +inline void operator delete(void* ptr, void* pos) +{ +} +#endif +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) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->ToBoolean(); +} +FX_FLOAT FXJSE_Value_ToFloat (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->ToFloat(); +} +FXJSE_DOUBLE FXJSE_Value_ToDouble (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->ToDouble(); +} +void FXJSE_Value_ToUTF8String (FXJSE_HVALUE hValue, CFX_ByteString& szStrOutput) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->ToString(szStrOutput); +} +FX_INT32 FXJSE_Value_ToInteger (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->ToInteger(); +} +FX_LPVOID FXJSE_Value_ToObject (FXJSE_HVALUE hValue, FXJSE_HCLASS hClass) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Class* lpClass = reinterpret_cast(hClass); + ASSERT(lpValue); + return lpValue->ToObject(lpClass); +} +void FXJSE_Value_SetUndefined (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetUndefined(); +} +void FXJSE_Value_SetNull (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetNull(); +} +void FXJSE_Value_SetBoolean (FXJSE_HVALUE hValue, FX_BOOL bBoolean) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetBoolean(bBoolean); +} +void FXJSE_Value_SetUTF8String (FXJSE_HVALUE hValue, FX_BSTR szString) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetString(szString); +} +void FXJSE_Value_SetInteger (FXJSE_HVALUE hValue, FX_INT32 nInteger) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetInteger(nInteger); +} +void FXJSE_Value_SetFloat (FXJSE_HVALUE hValue, FX_FLOAT fFloat) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetFloat(fFloat); +} +void FXJSE_Value_SetDouble (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->SetDouble(dDouble); +} +void FXJSE_Value_SetObject (FXJSE_HVALUE hValue, FX_LPVOID lpObject, FXJSE_HCLASS hClass) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + CFXJSE_Class* lpClass = reinterpret_cast(hClass); + if(lpClass == NULL) { + ASSERT(lpObject == NULL); + lpValue->SetJSObject(); + } else if(lpClass != NULL) { + lpValue->SetHostObject(lpObject, lpClass); + } +} +void FXJSE_Value_SetArray (FXJSE_HVALUE hValue, FX_UINT32 uValueCount, FXJSE_HVALUE* rgValues) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue->SetArray(uValueCount, reinterpret_cast(rgValues)); +} +void FXJSE_Value_SetDate (FXJSE_HVALUE hValue, FXJSE_DOUBLE dDouble) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + return lpValue->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); + return lpValue->Assign(lpOriginalValue); +} +FX_BOOL FXJSE_Value_GetObjectProp (FXJSE_HVALUE hValue, FX_BSTR 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, FX_BSTR 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, FX_UINT32 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, FX_UINT32 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, FX_BSTR szPropName) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->DeleteObjectProperty(szPropName); +} +FX_BOOL FXJSE_Value_ObjectHasOwnProp (FXJSE_HVALUE hValue, FX_BSTR szPropName, FX_BOOL bUseTypeGetter) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return lpValue->HasObjectOwnProperty(szPropName, bUseTypeGetter); +} +FX_BOOL FXJSE_Value_SetObjectOwnProp (FXJSE_HVALUE hValue, FX_BSTR 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, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs) +{ + CFXJSE_Value* lpFunction = reinterpret_cast(hFunction); + CFXJSE_Value* lpThis = reinterpret_cast(hThis); + CFXJSE_Value* lpRetValue = reinterpret_cast(hRetValue); + ASSERT(lpFunction); + return lpFunction->Call(lpThis, lpRetValue, nArgCount, lpArgs); +} +FXJSE_HVALUE FXJSE_Value_Create (FXJSE_HRUNTIME hRuntime) +{ + CFXJSE_Value* lpValue = CFXJSE_Value::Create(reinterpret_cast(hRuntime)); + ASSERT(lpValue); + return reinterpret_cast(lpValue); +} +void FXJSE_Value_Release (FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + if(lpValue) { + delete lpValue; + } +} +FXJSE_HRUNTIME FXJSE_Value_GetRuntime(FXJSE_HVALUE hValue) +{ + CFXJSE_Value* lpValue = reinterpret_cast(hValue); + ASSERT(lpValue); + return reinterpret_cast(lpValue->GetIsolate()); +} +void FXJSE_ThrowMessage(FX_BSTR utf8Name, FX_BSTR utf8Message) +{ + v8::Isolate* pIsolate = v8::Isolate::GetCurrent(); + ASSERT(pIsolate); + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(pIsolate); + v8::Handle hMessage = v8::String::NewFromUtf8(pIsolate, utf8Message.GetCStr(), v8::String::kNormalString, utf8Message.GetLength()); + v8::Handle 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 FX_NEW CFXJSE_Value(pIsolate); +} +FX_LPVOID 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 NULL; + } + return FXJSE_RetrieveObjectBinding(hValue.As(), lpClass); +} +V8_INLINE static double FXJSE_ftod(FX_FLOAT fNumber) +{ + if(sizeof(FX_FLOAT) != 4) { + ASSERT(FALSE); + return fNumber; + } + FX_UINT32 nFloatBits = (FX_UINT32&)fNumber; + FX_UINT8 nExponent = (FX_UINT8)(nFloatBits >> 16 >> 7 ); + if(nExponent == 0 || nExponent == 255) { + return fNumber; + } + FX_INT8 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; + FX_INT32 iErrPos = 0; + if(floor(dNumberAbsMin) == floor(dNumberAbsMax)) { + dNumberAbsMin = fmod(dNumberAbsMin, 1.0); + dNumberAbsMax = fmod(dNumberAbsMax, 1.0); + FX_INT32 iErrPosMin = 1, iErrPosMax = 38; + do { + FX_INT32 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(FX_LPVOID 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(FX_UINT32 uValueCount, CFXJSE_Value** rgValues) +{ + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Local hArrayObject = v8::Array::New(m_pIsolate, uValueCount); + if (rgValues) { + for(FX_UINT32 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(FX_BSTR 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(FX_BSTR 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(FX_UINT32 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(FX_UINT32 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(FX_BSTR 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(FX_BSTR 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(hKey)); +} +FX_BOOL CFXJSE_Value::SetObjectOwnProperty(FX_BSTR 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()->ForceSet(v8::String::NewFromUtf8(m_pIsolate, szPropName.GetCStr(), v8::String::kNormalString, szPropName.GetLength()), hValue); +} +FX_BOOL CFXJSE_Value::SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis) +{ + CFXJSE_ScopeUtil_IsolateHandleRootContext scope(m_pIsolate); + v8::Handle 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 ((FX_LPVOID)(FX_INTPTR)-1) +FX_BOOL CFXJSE_Value::Call(CFXJSE_Value* lpReceiver, CFXJSE_Value* lpRetValue, FX_UINT32 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; + if (hFunctionObject.IsEmpty() || !hFunctionObject->IsCallable()) { + if(lpRetValue) { + lpRetValue->ForceSetValue(FXJSE_CreateReturnValue(m_pIsolate, trycatch)); + } + return FALSE; + } + v8::Local hReturnValue; + v8::Handle* lpLocalArgs = NULL; + if(nArgCount) { + lpLocalArgs = FX_Alloc(v8::Handle, nArgCount); + if (!lpLocalArgs) { + return FALSE; + } + for (FX_UINT32 i = 0; i < nArgCount; i++) { + new (lpLocalArgs + i) v8::Handle; + 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) { + hReturnValue = hFunctionObject->CallAsConstructor(nArgCount, lpLocalArgs); + } 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); + } + hReturnValue = hFunctionObject->CallAsFunction(hReceiver, nArgCount, lpLocalArgs); + } + if(trycatch.HasCaught()) { + hReturnValue = FXJSE_CreateReturnValue(m_pIsolate, trycatch); + bRetValue = FALSE; + } + if(lpRetValue) { + lpRetValue->ForceSetValue(hReturnValue); + } + if(lpLocalArgs) { + for (FX_UINT32 i = 0; i < nArgCount; i++) { + lpLocalArgs[i].~Handle(); + } + FX_Free(lpLocalArgs); + } + return bRetValue; +} diff --git a/xfa/src/fxjse/src/value.h b/xfa/src/fxjse/src/value.h new file mode 100644 index 0000000000..aca23bf310 --- /dev/null +++ b/xfa/src/fxjse/src/value.h @@ -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 + +#ifndef FXJSE_VALUE_H_ +#define FXJSE_VALUE_H_ +#include "scope_inline.h" +class CFXJSE_Value : public CFX_Object +{ +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 FX_INT32 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; + } + FX_LPVOID 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(FX_INT32 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(FX_BSTR 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(FX_LPVOID lpObject, CFXJSE_Class* lpClass); + void SetArray(FX_UINT32 uValueCount, CFXJSE_Value** rgValues); + void SetDate(FXJSE_DOUBLE dDouble); +public: + FX_BOOL GetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue); + FX_BOOL SetObjectProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue); + FX_BOOL GetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue); + FX_BOOL SetObjectProperty(FX_UINT32 uPropIdx, CFXJSE_Value* lpPropValue); + FX_BOOL DeleteObjectProperty(FX_BSTR szPropName); + FX_BOOL HasObjectOwnProperty(FX_BSTR szPropName, FX_BOOL bUseTypeGetter); + FX_BOOL SetObjectOwnProperty(FX_BSTR szPropName, CFXJSE_Value* lpPropValue); + FX_BOOL SetFunctionBind(CFXJSE_Value* lpOldFunction, CFXJSE_Value* lpNewThis); + FX_BOOL Call(CFXJSE_Value* lpReceiver, CFXJSE_Value* lpRetValue, FX_UINT32 nArgCount, FXJSE_HVALUE* lpArgs); +public: + V8_INLINE v8::Isolate* GetIsolate() const + { + return m_pIsolate; + } + V8_INLINE const v8::Persistent& 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::Persistent m_hValue; + friend class CFXJSE_Context; + friend class CFXJSE_Class; +}; +#endif -- cgit v1.2.3