Skip to content

Commit 48dfd00

Browse files
committed
jsrt: JsObject Delete/Get/Has/OwnP../Set Property
AcmeAIR LTO gain (3%) New JSRT property interface that API user can use without going through convert-to-property-id process. See # 3790 for details. Also added a TODO note; ``` TODO: Can we make PropertyString && LiteralStringWithPropertyStringPtr share the string buffer? ``` Once this PR is merged, there will be an additional PR on node-chakracore end to benefit this new interface.
1 parent cb6e6d9 commit 48dfd00

22 files changed

+989
-248
lines changed

lib/Common/Codex/Utf8Helper.h

Lines changed: 51 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -86,30 +86,28 @@ namespace utf8
8686
return WideStringToNarrow(Allocator::allocate, sourceString, sourceCount, destStringPtr, destCount, allocateCount);
8787
}
8888

89-
///
90-
/// Use the codex library to encode a UTF8 string to UTF16.
91-
/// The caller is responsible for freeing the memory, which is allocated
92-
/// using Allocator.
93-
/// The returned string is null terminated.
94-
///
95-
template <typename AllocatorFunction>
96-
HRESULT NarrowStringToWide(_In_ AllocatorFunction allocator,_In_ LPCSTR sourceString, size_t sourceCount, _Out_ LPWSTR* destStringPtr, _Out_ size_t* destCount, size_t* allocateCount = nullptr)
89+
inline HRESULT NarrowStringToWideNoAlloc(_In_ LPCSTR sourceString, size_t sourceCount,
90+
__out_ecount(destBufferCount) LPWSTR destString, size_t destBufferCount, _Out_ size_t* destCount)
9791
{
98-
size_t cbSourceString = sourceCount;
9992
size_t sourceStart = 0;
100-
size_t cbDestString = (sourceCount + 1) * sizeof(WCHAR);
101-
if (cbDestString < sourceCount) // overflow ?
93+
size_t cbSourceString = sourceCount;
94+
95+
if (sourceCount >= MAXUINT32)
10296
{
97+
destString[0] = WCHAR(0);
10398
return E_OUTOFMEMORY;
10499
}
105100

106-
WCHAR* destString = (WCHAR*)allocator(cbDestString);
107101
if (destString == nullptr)
108102
{
109-
return E_OUTOFMEMORY;
103+
return E_INVALIDARG;
110104
}
111105

112-
if (allocateCount != nullptr) *allocateCount = cbDestString;
106+
if (sourceCount >= destBufferCount)
107+
{
108+
destString[0] = WCHAR(0);
109+
return E_INVALIDARG;
110+
}
113111

114112
for (; sourceStart < sourceCount; sourceStart++)
115113
{
@@ -127,7 +125,6 @@ namespace utf8
127125
{
128126
*destCount = sourceCount;
129127
destString[sourceCount] = WCHAR(0);
130-
*destStringPtr = destString;
131128
}
132129
else
133130
{
@@ -136,20 +133,56 @@ namespace utf8
136133

137134
charcount_t cchDestString = utf8::ByteIndexIntoCharacterIndex(remSourceString, cbSourceString - sourceStart);
138135
cchDestString += (charcount_t)sourceStart;
139-
Assert (cchDestString <= sourceCount);
136+
if (cchDestString > sourceCount)
137+
{
138+
return E_OUTOFMEMORY;
139+
}
140140

141141
// Some node tests depend on the utf8 decoder not swallowing invalid unicode characters
142142
// instead of replacing them with the "replacement" chracter. Pass a flag to our
143143
// decoder to require such behavior
144144
utf8::DecodeUnitsIntoAndNullTerminateNoAdvance(remDestString, remSourceString, (LPCUTF8) sourceString + cbSourceString, DecodeOptions::doAllowInvalidWCHARs);
145-
Assert(destString[cchDestString] == 0);
145+
146146
static_assert(sizeof(utf8char_t) == sizeof(char), "Needs to be valid for cast");
147-
*destStringPtr = destString;
148147
*destCount = cchDestString;
149148
}
149+
150+
Assert(destString[*destCount] == 0);
151+
150152
return S_OK;
151153
}
152154

155+
///
156+
/// Use the codex library to encode a UTF8 string to UTF16.
157+
/// The caller is responsible for freeing the memory, which is allocated
158+
/// using Allocator.
159+
/// The returned string is null terminated.
160+
///
161+
template <typename AllocatorFunction>
162+
HRESULT NarrowStringToWide(_In_ AllocatorFunction allocator,_In_ LPCSTR sourceString,
163+
size_t sourceCount, _Out_ LPWSTR* destStringPtr, _Out_ size_t* destCount, size_t* allocateCount = nullptr)
164+
{
165+
size_t cbDestString = (sourceCount + 1) * sizeof(WCHAR);
166+
if (cbDestString < sourceCount) // overflow ?
167+
{
168+
return E_OUTOFMEMORY;
169+
}
170+
171+
WCHAR* destString = (WCHAR*)allocator(cbDestString);
172+
if (destString == nullptr)
173+
{
174+
return E_OUTOFMEMORY;
175+
}
176+
177+
if (allocateCount != nullptr)
178+
{
179+
*allocateCount = cbDestString;
180+
}
181+
182+
*destStringPtr = destString;
183+
return NarrowStringToWideNoAlloc(sourceString, sourceCount, destString, sourceCount + 1, destCount);
184+
}
185+
153186
template <class Allocator>
154187
HRESULT NarrowStringToWide(_In_ LPCSTR sourceString, size_t sourceCount, _Out_ LPWSTR* destStringPtr, _Out_ size_t* destCount, size_t* allocateCount = nullptr)
155188
{

lib/Jsrt/ChakraCore.h

Lines changed: 139 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -763,10 +763,10 @@ CHAKRA_API
763763
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
764764
/// </returns>
765765
CHAKRA_API
766-
JsLessThan(
767-
_In_ JsValueRef object1,
768-
_In_ JsValueRef object2,
769-
_Out_ bool *result);
766+
JsLessThan(
767+
_In_ JsValueRef object1,
768+
_In_ JsValueRef object2,
769+
_Out_ bool *result);
770770

771771
/// <summary>
772772
/// Determine if one JavaScript value is less than or equal to another JavaScript value.
@@ -786,10 +786,141 @@ JsLessThan(
786786
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
787787
/// </returns>
788788
CHAKRA_API
789-
JsLessThanOrEqual(
790-
_In_ JsValueRef object1,
791-
_In_ JsValueRef object2,
792-
_Out_ bool *result);
789+
JsLessThanOrEqual(
790+
_In_ JsValueRef object1,
791+
_In_ JsValueRef object2,
792+
_Out_ bool *result);
793793

794+
/// <summary>
795+
/// Gets an object's property.
796+
/// </summary>
797+
/// <remarks>
798+
/// Requires an active script context.
799+
/// </remarks>
800+
/// <param name="object">The object that contains the property.</param>
801+
/// <param name="key">The key (JavascriptString) to the property.</param>
802+
/// <param name="value">The value of the property.</param>
803+
/// <returns>
804+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
805+
/// </returns>
806+
CHAKRA_API
807+
JsObjectGetProperty(
808+
_In_ JsValueRef object,
809+
_In_ JsValueRef key,
810+
_Out_ JsValueRef *value);
811+
812+
/// <summary>
813+
/// Puts an object's property.
814+
/// </summary>
815+
/// <remarks>
816+
/// Requires an active script context.
817+
/// </remarks>
818+
/// <param name="object">The object that contains the property.</param>
819+
/// <param name="key">The key (JavascriptString) to the property.</param>
820+
/// <param name="value">The new value of the property.</param>
821+
/// <param name="useStrictRules">The property set should follow strict mode rules.</param>
822+
/// <returns>
823+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
824+
/// </returns>
825+
CHAKRA_API
826+
JsObjectSetProperty(
827+
_In_ JsValueRef object,
828+
_In_ JsValueRef key,
829+
_In_ JsValueRef value,
830+
_In_ bool useStrictRules);
831+
832+
/// <summary>
833+
/// Determines whether an object has a property.
834+
/// </summary>
835+
/// <remarks>
836+
/// Requires an active script context.
837+
/// </remarks>
838+
/// <param name="object">The object that may contain the property.</param>
839+
/// <param name="key">The key (JavascriptString) to the property.</param>
840+
/// <param name="hasProperty">Whether the object (or a prototype) has the property.</param>
841+
/// <returns>
842+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
843+
/// </returns>
844+
CHAKRA_API
845+
JsObjectHasProperty(
846+
_In_ JsValueRef object,
847+
_In_ JsValueRef key,
848+
_Out_ bool *hasProperty);
849+
850+
/// <summary>
851+
/// Defines a new object's own property from a property descriptor.
852+
/// </summary>
853+
/// <remarks>
854+
/// Requires an active script context.
855+
/// </remarks>
856+
/// <param name="object">The object that has the property.</param>
857+
/// <param name="key">The key (JavascriptString) to the property.</param>
858+
/// <param name="propertyDescriptor">The property descriptor.</param>
859+
/// <param name="result">Whether the property was defined.</param>
860+
/// <returns>
861+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
862+
/// </returns>
863+
CHAKRA_API
864+
JsObjectDefineProperty(
865+
_In_ JsValueRef object,
866+
_In_ JsValueRef key,
867+
_In_ JsValueRef propertyDescriptor,
868+
_Out_ bool *result);
869+
870+
/// <summary>
871+
/// Deletes an object's property.
872+
/// </summary>
873+
/// <remarks>
874+
/// Requires an active script context.
875+
/// </remarks>
876+
/// <param name="object">The object that contains the property.</param>
877+
/// <param name="key">The key (JavascriptString) to the property.</param>
878+
/// <param name="useStrictRules">The property set should follow strict mode rules.</param>
879+
/// <param name="result">Whether the property was deleted.</param>
880+
/// <returns>
881+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
882+
/// </returns>
883+
CHAKRA_API
884+
JsObjectDeleteProperty(
885+
_In_ JsValueRef object,
886+
_In_ JsValueRef key,
887+
_In_ bool useStrictRules,
888+
_Out_ JsValueRef *result);
889+
890+
/// <summary>
891+
/// Gets a property descriptor for an object's own property.
892+
/// </summary>
893+
/// <remarks>
894+
/// Requires an active script context.
895+
/// </remarks>
896+
/// <param name="object">The object that has the property.</param>
897+
/// <param name="key">The key (JavascriptString) to the property.</param>
898+
/// <param name="propertyDescriptor">The property descriptor.</param>
899+
/// <returns>
900+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
901+
/// </returns>
902+
CHAKRA_API
903+
JsObjectGetOwnPropertyDescriptor(
904+
_In_ JsValueRef object,
905+
_In_ JsValueRef key,
906+
_Out_ JsValueRef *propertyDescriptor);
907+
908+
/// <summary>
909+
/// Determines whether an object has a non-inherited property.
910+
/// </summary>
911+
/// <remarks>
912+
/// Requires an active script context.
913+
/// </remarks>
914+
/// <param name="object">The object that may contain the property.</param>
915+
/// <param name="key">The key (JavascriptString) to the property.</param>
916+
/// <param name="hasOwnProperty">Whether the object has the non-inherited property.</param>
917+
/// <returns>
918+
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
919+
/// </returns>
920+
CHAKRA_API
921+
JsObjectHasOwnProperty(
922+
_In_ JsValueRef object,
923+
_In_ JsValueRef key,
924+
_Out_ bool *hasOwnProperty);
794925
#endif // _CHAKRACOREBUILD
795926
#endif // _CHAKRACORE_H_

0 commit comments

Comments
 (0)