X-Git-Url: https://git.saurik.com/apple/javascriptcore.git/blobdiff_plain/14957cd040308e3eeec43d26bae5d76da13fcd85..6fe7ccc865dc7d7541b93c5bcaf6368d2c98a174:/dfg/DFGOperations.h?ds=inline diff --git a/dfg/DFGOperations.h b/dfg/DFGOperations.h index d4c7c0f..5da754a 100644 --- a/dfg/DFGOperations.h +++ b/dfg/DFGOperations.h @@ -28,62 +28,191 @@ #if ENABLE(DFG_JIT) -#include +#include "DFGJITCompiler.h" +#include "PutKind.h" namespace JSC { -class Identifier; +struct GlobalResolveInfo; namespace DFG { +extern "C" { + +#if CALLING_CONVENTION_IS_STDCALL +#define DFG_OPERATION CDECL +#else +#define DFG_OPERATION +#endif + // These typedefs provide typechecking when generating calls out to helper routines; // this helps prevent calling a helper routine with the wrong arguments! -typedef EncodedJSValue (*J_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); -typedef EncodedJSValue (*J_DFGOperation_EJ)(ExecState*, EncodedJSValue); -typedef EncodedJSValue (*J_DFGOperation_EJP)(ExecState*, EncodedJSValue, void*); -typedef EncodedJSValue (*J_DFGOperation_EJI)(ExecState*, EncodedJSValue, Identifier*); -typedef bool (*Z_DFGOperation_EJ)(ExecState*, EncodedJSValue); -typedef bool (*Z_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); -typedef void (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue); -typedef void (*V_DFGOperation_EJJP)(ExecState*, EncodedJSValue, EncodedJSValue, void*); -typedef void (*V_DFGOperation_EJJI)(ExecState*, EncodedJSValue, EncodedJSValue, Identifier*); -typedef double (*D_DFGOperation_DD)(double, double); +/* + Key: + V: void + J: JSValue + P: pointer (void*) + C: JSCell* + A: JSArray* + S: size_t + Z: int32_t + D: double + I: Identifier* + G: GlobalResolveInfo* +*/ +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EA)(ExecState*, JSArray*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECI)(ExecState*, JSCell*, Identifier*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ECJ)(ExecState*, JSCell*, EncodedJSValue); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EGI)(ExecState*, GlobalResolveInfo*, Identifier*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EI)(ExecState*, Identifier*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJ)(ExecState*, EncodedJSValue); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJA)(ExecState*, EncodedJSValue, JSArray*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJI)(ExecState*, EncodedJSValue, Identifier*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EJP)(ExecState*, EncodedJSValue, void*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EP)(ExecState*, void*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPP)(ExecState*, void*, void*); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_EPS)(ExecState*, void*, size_t); +typedef EncodedJSValue DFG_OPERATION (*J_DFGOperation_ESS)(ExecState*, size_t, size_t); +typedef JSCell* DFG_OPERATION (*C_DFGOperation_E)(ExecState*); +typedef JSCell* DFG_OPERATION (*C_DFGOperation_EC)(ExecState*, JSCell*); +typedef JSCell* DFG_OPERATION (*C_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*); +typedef double DFG_OPERATION (*D_DFGOperation_DD)(double, double); +typedef double DFG_OPERATION (*D_DFGOperation_ZZ)(int32_t, int32_t); +typedef double DFG_OPERATION (*D_DFGOperation_EJ)(ExecState*, EncodedJSValue); +typedef int32_t DFG_OPERATION (*Z_DFGOperation_D)(double); +typedef size_t DFG_OPERATION (*S_DFGOperation_ECC)(ExecState*, JSCell*, JSCell*); +typedef size_t DFG_OPERATION (*S_DFGOperation_EJ)(ExecState*, EncodedJSValue); +typedef size_t DFG_OPERATION (*S_DFGOperation_EJJ)(ExecState*, EncodedJSValue, EncodedJSValue); +typedef size_t DFG_OPERATION (*S_DFGOperation_J)(EncodedJSValue); +typedef void DFG_OPERATION (*V_DFGOperation_EAZJ)(ExecState*, JSArray*, int32_t, EncodedJSValue); +typedef void DFG_OPERATION (*V_DFGOperation_ECJJ)(ExecState*, JSCell*, EncodedJSValue, EncodedJSValue); +typedef void DFG_OPERATION (*V_DFGOperation_EJCI)(ExecState*, EncodedJSValue, JSCell*, Identifier*); +typedef void DFG_OPERATION (*V_DFGOperation_EJJJ)(ExecState*, EncodedJSValue, EncodedJSValue, EncodedJSValue); +typedef void DFG_OPERATION (*V_DFGOperation_EJPP)(ExecState*, EncodedJSValue, EncodedJSValue, void*); +typedef void DFG_OPERATION (*V_DFGOperation_EPZJ)(ExecState*, void*, int32_t, EncodedJSValue); +typedef void DFG_OPERATION (V_DFGOperation_EC)(ExecState*, JSCell*); +typedef void* DFG_OPERATION (*P_DFGOperation_E)(ExecState*); // These routines are provide callbacks out to C++ implementations of operations too complex to JIT. -EncodedJSValue operationConvertThis(ExecState*, EncodedJSValue encodedOp1); -EncodedJSValue operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -EncodedJSValue operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty); -EncodedJSValue operationGetById(ExecState*, EncodedJSValue encodedBase, Identifier*); -void operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); -void operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); -void operationPutByIdStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*); -void operationPutByIdNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*); -void operationPutByIdDirectStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*); -void operationPutByIdDirectNonStrict(ExecState*, EncodedJSValue encodedValue, EncodedJSValue encodedBase, Identifier*); -bool operationCompareLess(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -bool operationCompareLessEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -bool operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); -bool operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +JSCell* DFG_OPERATION operationNewObject(ExecState*); +JSCell* DFG_OPERATION operationCreateThis(ExecState*, JSCell* encodedOp1); +JSCell* DFG_OPERATION operationCreateThisInlined(ExecState*, JSCell* encodedOp1, JSCell* constructor); +EncodedJSValue DFG_OPERATION operationConvertThis(ExecState*, EncodedJSValue encodedOp1); +EncodedJSValue DFG_OPERATION operationValueAdd(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +EncodedJSValue DFG_OPERATION operationValueAddNotNumber(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +EncodedJSValue DFG_OPERATION operationGetByVal(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty); +EncodedJSValue DFG_OPERATION operationGetByValCell(ExecState*, JSCell*, EncodedJSValue encodedProperty); +EncodedJSValue DFG_OPERATION operationGetById(ExecState*, EncodedJSValue, Identifier*); +EncodedJSValue DFG_OPERATION operationGetByIdBuildList(ExecState*, EncodedJSValue, Identifier*); +EncodedJSValue DFG_OPERATION operationGetByIdProtoBuildList(ExecState*, EncodedJSValue, Identifier*); +EncodedJSValue DFG_OPERATION operationGetByIdOptimize(ExecState*, EncodedJSValue, Identifier*); +EncodedJSValue DFG_OPERATION operationCallCustomGetter(ExecState*, JSCell*, PropertySlot::GetValueFunc, Identifier*); +EncodedJSValue DFG_OPERATION operationCallGetter(ExecState*, JSCell*, JSCell*); +EncodedJSValue DFG_OPERATION operationResolve(ExecState*, Identifier*); +EncodedJSValue DFG_OPERATION operationResolveBase(ExecState*, Identifier*); +EncodedJSValue DFG_OPERATION operationResolveBaseStrictPut(ExecState*, Identifier*); +EncodedJSValue DFG_OPERATION operationResolveGlobal(ExecState*, GlobalResolveInfo*, Identifier*); +EncodedJSValue DFG_OPERATION operationToPrimitive(ExecState*, EncodedJSValue); +EncodedJSValue DFG_OPERATION operationStrCat(ExecState*, void*, size_t); +EncodedJSValue DFG_OPERATION operationNewArray(ExecState*, void*, size_t); +EncodedJSValue DFG_OPERATION operationNewArrayBuffer(ExecState*, size_t, size_t); +EncodedJSValue DFG_OPERATION operationNewRegexp(ExecState*, void*); +void DFG_OPERATION operationPutByValStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); +void DFG_OPERATION operationPutByValNonStrict(ExecState*, EncodedJSValue encodedBase, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); +void DFG_OPERATION operationPutByValCellStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); +void DFG_OPERATION operationPutByValCellNonStrict(ExecState*, JSCell*, EncodedJSValue encodedProperty, EncodedJSValue encodedValue); +void DFG_OPERATION operationPutByValBeyondArrayBoundsStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue); +void DFG_OPERATION operationPutByValBeyondArrayBoundsNonStrict(ExecState*, JSArray*, int32_t index, EncodedJSValue encodedValue); +EncodedJSValue DFG_OPERATION operationArrayPush(ExecState*, EncodedJSValue encodedValue, JSArray*); +EncodedJSValue DFG_OPERATION operationArrayPop(ExecState*, JSArray*); +EncodedJSValue DFG_OPERATION operationRegExpExec(ExecState*, JSCell*, JSCell*); +void DFG_OPERATION operationPutByIdStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdNonStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectNonStrict(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdStrictOptimize(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdNonStrictOptimize(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectStrictOptimize(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectNonStrictOptimize(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdNonStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +void DFG_OPERATION operationPutByIdDirectNonStrictBuildList(ExecState*, EncodedJSValue encodedValue, JSCell* base, Identifier*); +// These comparisons return a boolean within a size_t such that the value is zero extended to fill the register. +size_t DFG_OPERATION operationRegExpTest(ExecState*, JSCell*, JSCell*); +size_t DFG_OPERATION operationCompareLess(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareLessEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareGreater(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareGreaterEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareStrictEqCell(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +size_t DFG_OPERATION operationCompareStrictEq(ExecState*, EncodedJSValue encodedOp1, EncodedJSValue encodedOp2); +void* DFG_OPERATION operationVirtualCall(ExecState*); +void* DFG_OPERATION operationLinkCall(ExecState*); +void* DFG_OPERATION operationVirtualConstruct(ExecState*); +void* DFG_OPERATION operationLinkConstruct(ExecState*); +JSCell* DFG_OPERATION operationCreateActivation(ExecState*); +void DFG_OPERATION operationTearOffActivation(ExecState*, JSCell*); +JSCell* DFG_OPERATION operationNewFunction(ExecState*, JSCell*); +JSCell* DFG_OPERATION operationNewFunctionExpression(ExecState*, JSCell*); +double DFG_OPERATION operationFModOnInts(int32_t, int32_t); +size_t DFG_OPERATION operationIsObject(EncodedJSValue); +size_t DFG_OPERATION operationIsFunction(EncodedJSValue); // This method is used to lookup an exception hander, keyed by faultLocation, which is // the return location from one of the calls out to one of the helper operations above. + +// According to C++ rules, a type used for the return signature of function with C linkage (i.e. +// 'extern "C"') needs to be POD; hence putting any constructors into it could cause either compiler +// warnings, or worse, a change in the ABI used to return these types. struct DFGHandler { - DFGHandler(ExecState* exec, void* handler) - : exec(exec) - , handler(handler) - { - } - - ExecState* exec; - void* handler; + union Union { + struct Struct { + ExecState* exec; + void* handler; + } s; + uint64_t encoded; + } u; }; -DFGHandler lookupExceptionHandler(ExecState*, ReturnAddressPtr faultLocation); + +inline DFGHandler createDFGHandler(ExecState* exec, void* handler) +{ + DFGHandler result; + result.u.s.exec = exec; + result.u.s.handler = handler; + return result; +} + +#if CPU(X86_64) +typedef DFGHandler DFGHandlerEncoded; +inline DFGHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler) +{ + return createDFGHandler(exec, handler); +} +#else +typedef uint64_t DFGHandlerEncoded; +inline DFGHandlerEncoded dfgHandlerEncoded(ExecState* exec, void* handler) +{ + COMPILE_ASSERT(sizeof(DFGHandler::Union) == sizeof(uint64_t), DFGHandler_Union_is_64bit); + return createDFGHandler(exec, handler).u.encoded; +} +#endif +DFGHandlerEncoded DFG_OPERATION lookupExceptionHandler(ExecState*, uint32_t); +DFGHandlerEncoded DFG_OPERATION lookupExceptionHandlerInStub(ExecState*, StructureStubInfo*); // These operations implement the implicitly called ToInt32, ToNumber, and ToBoolean conversions from ES5. -double dfgConvertJSValueToNumber(ExecState*, EncodedJSValue); -int32_t dfgConvertJSValueToInt32(ExecState*, EncodedJSValue); -bool dfgConvertJSValueToBoolean(ExecState*, EncodedJSValue); +double DFG_OPERATION dfgConvertJSValueToNumber(ExecState*, EncodedJSValue); +// This conversion returns an int32_t within a size_t such that the value is zero extended to fill the register. +size_t DFG_OPERATION dfgConvertJSValueToInt32(ExecState*, EncodedJSValue); +size_t DFG_OPERATION dfgConvertJSValueToBoolean(ExecState*, EncodedJSValue); + +#if DFG_ENABLE(VERBOSE_SPECULATION_FAILURE) +void DFG_OPERATION debugOperationPrintSpeculationFailure(ExecState*, void*); +#endif +} // extern "C" } } // namespace JSC::DFG #endif