blob: 4e25ac961b1b83b0fef336954edad9e89cf57563 [file]
//-------------------------------------------------------------------------------------------------------
// Copyright (C) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information.
//-------------------------------------------------------------------------------------------------------
// Forward declaration to avoid including scriptdirect.h
typedef HRESULT(__cdecl *InitializeMethod)(Js::Var instance);
namespace Js
{
struct StdCallJavascriptMethodInfo
{
Var thisArg;
Var newTargetArg;
bool isConstructCall;
};
typedef Var (__stdcall *StdCallJavascriptMethod)(Var callee, Var *args, USHORT cargs, StdCallJavascriptMethodInfo *info, void *callbackState);
typedef int JavascriptTypeId;
class JavascriptExternalFunction : public RuntimeFunction
{
private:
DEFINE_MARSHAL_OBJECT_TO_SCRIPT_CONTEXT(JavascriptExternalFunction);
protected:
DEFINE_VTABLE_CTOR(JavascriptExternalFunction, RuntimeFunction);
JavascriptExternalFunction(DynamicType * type);
public:
JavascriptExternalFunction(ExternalMethod nativeMethod, DynamicType* type);
JavascriptExternalFunction(ExternalMethod entryPoint, DynamicType* type, InitializeMethod method, unsigned short deferredSlotCount, bool accessors);
// this is default external function for DOM constructor that cannot be new'ed.
JavascriptExternalFunction(DynamicType* type, InitializeMethod method, unsigned short deferredSlotCount, bool accessors);
JavascriptExternalFunction(JavascriptExternalFunction* wrappedMethod, DynamicType* type);
JavascriptExternalFunction(StdCallJavascriptMethod nativeMethod, DynamicType* type);
virtual BOOL IsExternalFunction() override { return TRUE; }
inline void SetSignature(Var signature) { this->signature = signature; }
Var GetSignature() { return signature; }
inline void SetCallbackState(void *callbackState) { this->callbackState = callbackState; }
void *GetCallbackState() { return callbackState; }
static const int ETW_MIN_COUNT_FOR_CALLER = 0x100; // power of 2
class EntryInfo
{
public:
static FunctionInfo ExternalFunctionThunk;
static FunctionInfo WrappedFunctionThunk;
static FunctionInfo StdCallExternalFunctionThunk;
static FunctionInfo DefaultExternalFunctionThunk;
};
ExternalMethod GetNativeMethod() { return nativeMethod; }
BOOL SetLengthProperty(Var length);
void SetExternalFlags(UINT64 flags) { this->flags = flags; }
unsigned char GetDeferredLength() const { return deferredLength; }
void SetDeferredLength(unsigned char deferredLength)
{
AssertOrFailFastMsg(this->deferredLength == 0, "Deferred length is already pending");
this->deferredLength = deferredLength;
}
void UndeferLength(ScriptContext *scriptContext);
private:
Field(UINT64) flags;
Field(Var) signature;
Field(void *) callbackState;
union
{
FieldNoBarrier(ExternalMethod) nativeMethod;
Field(JavascriptExternalFunction*) wrappedMethod;
FieldNoBarrier(StdCallJavascriptMethod) stdCallNativeMethod;
};
Field(InitializeMethod) initMethod;
// Ensure GC doesn't pin
Field(unsigned int) oneBit:1;
// Count of type slots for
Field(unsigned int) typeSlots:15;
// Determines if we need are a dictionary type
Field(unsigned int) hasAccessors:1;
Field(unsigned int) unused:7;
// DOM Direct functions need to be able to set the length at construction time without undeferring the function.
// We can store the length here so it can be set at the time of undeferral.
Field(unsigned int) deferredLength:8;
static Var ExternalFunctionThunk(RecyclableObject* function, CallInfo callInfo, ...);
static Var WrappedFunctionThunk(RecyclableObject* function, CallInfo callInfo, ...);
static Var StdCallExternalFunctionThunk(RecyclableObject* function, CallInfo callInfo, ...);
static Var DefaultExternalFunctionThunk(RecyclableObject* function, CallInfo callInfo, ...);
static bool __cdecl DeferredLengthInitializer(DynamicObject* instance, DeferredTypeHandlerBase* typeHandler, DeferredInitializeMode mode);
static bool __cdecl DeferredConstructorInitializer(DynamicObject* instance, DeferredTypeHandlerBase* typeHandler, DeferredInitializeMode mode);
void PrepareExternalCall(Arguments * args);
#if ENABLE_TTD
public:
virtual TTD::NSSnapObjects::SnapObjectType GetSnapTag_TTD() const override;
virtual void ExtractSnapObjectDataInto(TTD::NSSnapObjects::SnapObject* objData, TTD::SlabAllocator& alloc) override;
static Var HandleRecordReplayExternalFunction_Thunk(Js::JavascriptFunction* function, CallInfo& callInfo, Arguments& args, ScriptContext* scriptContext);
static Var HandleRecordReplayExternalFunction_StdThunk(Js::RecyclableObject* function, CallInfo& callInfo, Arguments& args, ScriptContext* scriptContext);
static Var __stdcall TTDReplayDummyExternalMethod(Var callee, Var *args, USHORT cargs, StdCallJavascriptMethodInfo *info, void *callbackState);
#endif
friend class JavascriptLibrary;
};
}