Skip to content

Commit fc6240e

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 718f271 commit fc6240e

23 files changed

+981
-278
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
@@ -764,10 +764,10 @@ CHAKRA_API
764764
/// The code <c>JsNoError</c> if the operation succeeded, a failure code otherwise.
765765
/// </returns>
766766
CHAKRA_API
767-
JsLessThan(
768-
_In_ JsValueRef object1,
769-
_In_ JsValueRef object2,
770-
_Out_ bool *result);
767+
JsLessThan(
768+
_In_ JsValueRef object1,
769+
_In_ JsValueRef object2,
770+
_Out_ bool *result);
771771

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

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

0 commit comments

Comments
 (0)