|
|
@@ -1383,102 +1383,252 @@ CHAKRA_API JsPreventExtension(_In_ JsValueRef object)
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-CHAKRA_API JsGetProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ JsValueRef *value)
|
|
|
+static JsErrorCode InternalGetPropertyRecord(Js::ScriptContext * scriptContext,
|
|
|
+ Js::RecyclableObject * key, _Out_ const Js::PropertyRecord ** propertyRecord)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetProperty, (Js::PropertyRecord *)propertyId, object);
|
|
|
+ Assert(propertyRecord != nullptr);
|
|
|
+ *propertyRecord = nullptr;
|
|
|
+
|
|
|
+ if (key->GetTypeId() != Js::TypeIds_String)
|
|
|
+ {
|
|
|
+ return JsErrorInvalidArgument;
|
|
|
+ }
|
|
|
+
|
|
|
+ scriptContext->GetOrAddPropertyRecord(Js::JavascriptString::FromVar(key),
|
|
|
+ (Js::PropertyRecord const **)propertyRecord);
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsHasOwnPropertyCommon(Js::ScriptContext * scriptContext, _In_ JsValueRef object,
|
|
|
+ _In_ const Js::PropertyRecord * propertyRecord, _Out_ bool *hasOwnProperty,
|
|
|
+ TTDRecorder& _actionEntryPopper)
|
|
|
+{
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTHasOwnProperty, propertyRecord, object);
|
|
|
+
|
|
|
+ *hasOwnProperty = Js::JavascriptOperators::OP_HasOwnProperty(object,
|
|
|
+ propertyRecord->GetPropertyId(), scriptContext) != 0;
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsHasOwnProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId,
|
|
|
+ _Out_ bool *hasOwnProperty)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<true>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
- PARAM_NOT_NULL(value);
|
|
|
- *value = nullptr;
|
|
|
+ PARAM_NOT_NULL(hasOwnProperty);
|
|
|
+ *hasOwnProperty = false;
|
|
|
|
|
|
- *value = Js::JavascriptOperators::OP_GetProperty((Js::Var)object, ((Js::PropertyRecord *)propertyId)->GetPropertyId(), scriptContext);
|
|
|
- Assert(*value == nullptr || !Js::CrossSite::NeedMarshalVar(*value, scriptContext));
|
|
|
+ return JsHasOwnPropertyCommon(scriptContext, object,
|
|
|
+ (const Js::PropertyRecord *)propertyId, hasOwnProperty, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, value);
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectHasOwnProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId, _Out_ bool *hasOwnProperty)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<true>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
- return JsNoError;
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ PARAM_NOT_NULL(hasOwnProperty);
|
|
|
+ *hasOwnProperty = false;
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
+ {
|
|
|
+ return errorValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ return JsHasOwnPropertyCommon(scriptContext, object, propertyRecord, hasOwnProperty, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
-CHAKRA_API JsGetOwnPropertyDescriptor(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ JsValueRef *propertyDescriptor)
|
|
|
+static JsErrorCode JsGetPropertyCommon(Js::ScriptContext * scriptContext,
|
|
|
+ _In_ Js::RecyclableObject * object,
|
|
|
+ _In_ const Js::PropertyRecord * propertyRecord, _Out_ JsValueRef *value,
|
|
|
+ TTDRecorder& _actionEntryPopper)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertyInfo, (Js::PropertyRecord *)propertyId, object);
|
|
|
+ AssertMsg(scriptContext->GetThreadContext()->IsScriptActive(), "Caller is expected to be under ContextAPIWrapper!");
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetProperty, propertyRecord, object);
|
|
|
+
|
|
|
+ *value = Js::JavascriptOperators::GetPropertyNoCache(object, propertyRecord->GetPropertyId(), scriptContext);
|
|
|
+ Assert(*value == nullptr || !Js::CrossSite::NeedMarshalVar(*value, scriptContext));
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, value);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsGetProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ JsValueRef *value)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
- PARAM_NOT_NULL(propertyDescriptor);
|
|
|
- *propertyDescriptor = nullptr;
|
|
|
+ PARAM_NOT_NULL(value);
|
|
|
+ *value = nullptr;
|
|
|
|
|
|
- Js::PropertyDescriptor propertyDescriptorValue;
|
|
|
- if (Js::JavascriptOperators::GetOwnPropertyDescriptor(Js::RecyclableObject::FromVar(object), ((Js::PropertyRecord *)propertyId)->GetPropertyId(), scriptContext, &propertyDescriptorValue))
|
|
|
- {
|
|
|
- *propertyDescriptor = Js::JavascriptOperators::FromPropertyDescriptor(propertyDescriptorValue, scriptContext);
|
|
|
- }
|
|
|
- else
|
|
|
+ Js::RecyclableObject * instance = Js::RecyclableObject::FromVar(object);
|
|
|
+ return JsGetPropertyCommon(scriptContext, instance, (const Js::PropertyRecord *)propertyId,
|
|
|
+ value, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectGetProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId, _Out_ JsValueRef *value)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ PARAM_NOT_NULL(value);
|
|
|
+ *value = nullptr;
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
{
|
|
|
- *propertyDescriptor = scriptContext->GetLibrary()->GetUndefined();
|
|
|
+ return errorValue;
|
|
|
}
|
|
|
- Assert(*propertyDescriptor == nullptr || !Js::CrossSite::NeedMarshalVar(*propertyDescriptor, scriptContext));
|
|
|
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertyDescriptor);
|
|
|
+ Assert(propertyRecord != nullptr);
|
|
|
|
|
|
- return JsNoError;
|
|
|
+ Js::RecyclableObject * instance = Js::RecyclableObject::FromVar(object);
|
|
|
+ return JsGetPropertyCommon(scriptContext, instance, propertyRecord, value, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
-CHAKRA_API JsGetOwnPropertyNames(_In_ JsValueRef object, _Out_ JsValueRef *propertyNames)
|
|
|
+static JsErrorCode JsGetOwnPropertyDescriptorCommon(Js::ScriptContext * scriptContext,
|
|
|
+ _In_ JsValueRef object, _In_ const Js::PropertyRecord * propertyRecord, _Out_ JsValueRef *propertyDescriptor,
|
|
|
+ TTDRecorder& _actionEntryPopper)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertyNamesInfo, object);
|
|
|
+ AssertMsg(scriptContext->GetThreadContext()->IsScriptActive(), "Caller is expected to be under ContextAPIWrapper!");
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertyInfo, propertyRecord, object);
|
|
|
|
|
|
- VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
- PARAM_NOT_NULL(propertyNames);
|
|
|
- *propertyNames = nullptr;
|
|
|
+ Js::PropertyDescriptor propertyDescriptorValue;
|
|
|
+ if (Js::JavascriptOperators::GetOwnPropertyDescriptor(Js::RecyclableObject::FromVar(object),
|
|
|
+ propertyRecord->GetPropertyId(), scriptContext, &propertyDescriptorValue))
|
|
|
+ {
|
|
|
+ *propertyDescriptor = Js::JavascriptOperators::FromPropertyDescriptor(propertyDescriptorValue, scriptContext);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ *propertyDescriptor = scriptContext->GetLibrary()->GetUndefined();
|
|
|
+ }
|
|
|
+ Assert(*propertyDescriptor == nullptr || !Js::CrossSite::NeedMarshalVar(*propertyDescriptor, scriptContext));
|
|
|
|
|
|
- *propertyNames = Js::JavascriptOperators::GetOwnPropertyNames(object, scriptContext);
|
|
|
- Assert(*propertyNames == nullptr || !Js::CrossSite::NeedMarshalVar(*propertyNames, scriptContext));
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertyDescriptor);
|
|
|
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertyNames);
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
|
|
|
- return JsNoError;
|
|
|
+CHAKRA_API JsGetOwnPropertyDescriptor(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ JsValueRef *propertyDescriptor)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
+ PARAM_NOT_NULL(propertyDescriptor);
|
|
|
+ *propertyDescriptor = nullptr;
|
|
|
+
|
|
|
+ return JsGetOwnPropertyDescriptorCommon(scriptContext, object, (const Js::PropertyRecord *)propertyId,
|
|
|
+ propertyDescriptor, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-CHAKRA_API JsGetOwnPropertySymbols(_In_ JsValueRef object, _Out_ JsValueRef *propertySymbols)
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectGetOwnPropertyDescriptor(_In_ JsValueRef object, _In_ JsValueRef propertyId, _Out_ JsValueRef *propertyDescriptor)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertySymbolsInfo, object);
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
- PARAM_NOT_NULL(propertySymbols);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ PARAM_NOT_NULL(propertyDescriptor);
|
|
|
+ *propertyDescriptor = nullptr;
|
|
|
|
|
|
- *propertySymbols = Js::JavascriptOperators::GetOwnPropertySymbols(object, scriptContext);
|
|
|
- Assert(*propertySymbols == nullptr || !Js::CrossSite::NeedMarshalVar(*propertySymbols, scriptContext));
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertySymbols);
|
|
|
+ if (errorValue != JsNoError)
|
|
|
+ {
|
|
|
+ return errorValue;
|
|
|
+ }
|
|
|
|
|
|
- return JsNoError;
|
|
|
+ Assert(propertyRecord != nullptr);
|
|
|
+
|
|
|
+ return JsGetOwnPropertyDescriptorCommon(scriptContext, object, propertyRecord, propertyDescriptor, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
+#endif
|
|
|
+
|
|
|
+static JsErrorCode JsSetPropertyCommon(Js::ScriptContext * scriptContext, _In_ JsValueRef object,
|
|
|
+ _In_ const Js::PropertyRecord * propertyRecord, _In_ JsValueRef value, _In_ bool useStrictRules,
|
|
|
+ TTDRecorder& _actionEntryPopper)
|
|
|
+{
|
|
|
+ AssertMsg(scriptContext->GetThreadContext()->IsScriptActive(), "Caller is expected to be under ContextAPIWrapper!");
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTSetProperty, object,
|
|
|
+ propertyRecord, value, useStrictRules);
|
|
|
+
|
|
|
+ Js::JavascriptOperators::OP_SetProperty(object, propertyRecord->GetPropertyId(),
|
|
|
+ value, scriptContext, nullptr, useStrictRules ? Js::PropertyOperation_StrictMode : Js::PropertyOperation_None);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
|
|
|
CHAKRA_API JsSetProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _In_ JsValueRef value, _In_ bool useStrictRules)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTSetProperty, object, (Js::PropertyRecord *)propertyId, value, useStrictRules);
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
VALIDATE_INCOMING_REFERENCE(value, scriptContext);
|
|
|
|
|
|
- Js::JavascriptOperators::OP_SetProperty(object, ((Js::PropertyRecord *)propertyId)->GetPropertyId(), value, scriptContext,
|
|
|
- nullptr, useStrictRules ? Js::PropertyOperation_StrictMode : Js::PropertyOperation_None);
|
|
|
+ return JsSetPropertyCommon(scriptContext, object, (const Js::PropertyRecord *)propertyId,
|
|
|
+ value, useStrictRules, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
- return JsNoError;
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectSetProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId, _In_ JsValueRef value, _In_ bool useStrictRules)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ VALIDATE_INCOMING_REFERENCE(value, scriptContext);
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
+ {
|
|
|
+ return errorValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Assert(propertyRecord != nullptr);
|
|
|
+
|
|
|
+ return JsSetPropertyCommon(scriptContext, object, propertyRecord, value, useStrictRules, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
CHAKRA_API JsHasProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ bool *hasProperty)
|
|
|
{
|
|
|
@@ -1493,7 +1643,8 @@ CHAKRA_API JsHasProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId
|
|
|
PARAM_NOT_NULL(hasProperty);
|
|
|
*hasProperty = false;
|
|
|
|
|
|
- *hasProperty = Js::JavascriptOperators::OP_HasProperty(object, ((Js::PropertyRecord *)propertyId)->GetPropertyId(), scriptContext) != 0;
|
|
|
+ Js::RecyclableObject * instance = Js::RecyclableObject::FromVar(object);
|
|
|
+ *hasProperty = Js::JavascriptOperators::HasProperty(instance, ((Js::PropertyRecord *)propertyId)->GetPropertyId()) != 0;
|
|
|
|
|
|
return JsNoError;
|
|
|
};
|
|
|
@@ -1516,30 +1667,144 @@ CHAKRA_API JsHasProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-CHAKRA_API JsDeleteProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _In_ bool useStrictRules, _Out_ JsValueRef *result)
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectHasProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId, _Out_ bool *hasProperty)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTDeleteProperty, object, (Js::PropertyRecord *)propertyId, useStrictRules);
|
|
|
+ VALIDATE_JSREF(object);
|
|
|
+ if (!Js::JavascriptOperators::IsObject(object)) return JsErrorArgumentNotObject;
|
|
|
+
|
|
|
+ auto internalHasProperty = [&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ PARAM_NOT_NULL(hasProperty);
|
|
|
+ *hasProperty = false;
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
+ {
|
|
|
+ return errorValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTHasProperty, propertyRecord, object);
|
|
|
+
|
|
|
+ Js::RecyclableObject * instance = Js::RecyclableObject::FromVar(object);
|
|
|
+ *hasProperty = Js::JavascriptOperators::HasProperty(instance, propertyRecord->GetPropertyId()) != 0;
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+ };
|
|
|
+
|
|
|
+ Js::RecyclableObject* robject = Js::RecyclableObject::FromVar(object);
|
|
|
+ Js::TypeId typeId = Js::JavascriptOperators::GetTypeId(robject);
|
|
|
+ while (typeId != Js::TypeIds_Null && typeId != Js::TypeIds_Proxy)
|
|
|
+ {
|
|
|
+ robject = robject->GetPrototype();
|
|
|
+ typeId = Js::JavascriptOperators::GetTypeId(robject);
|
|
|
+ }
|
|
|
+
|
|
|
+ if (typeId == Js::TypeIds_Proxy)
|
|
|
+ {
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>(internalHasProperty);
|
|
|
+ }
|
|
|
+ else
|
|
|
+ {
|
|
|
+ return ContextAPINoScriptWrapper(internalHasProperty);
|
|
|
+ }
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+static JsErrorCode JsDeletePropertyCommon(Js::ScriptContext * scriptContext, _In_ JsValueRef object,
|
|
|
+ _In_ const Js::PropertyRecord * propertyRecord, _In_ bool useStrictRules, _Out_ JsValueRef *result,
|
|
|
+ TTDRecorder& _actionEntryPopper)
|
|
|
+{
|
|
|
+ AssertMsg(scriptContext->GetThreadContext()->IsScriptActive(), "Caller is expected to be under ContextAPIWrapper!");
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTDeleteProperty, object,
|
|
|
+ propertyRecord, useStrictRules);
|
|
|
+
|
|
|
+ *result = Js::JavascriptOperators::OP_DeleteProperty((Js::Var)object,
|
|
|
+ propertyRecord->GetPropertyId(),
|
|
|
+ scriptContext, useStrictRules ? Js::PropertyOperation_StrictMode : Js::PropertyOperation_None);
|
|
|
+
|
|
|
+ Assert(*result == nullptr || !Js::CrossSite::NeedMarshalVar(*result, scriptContext));
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, result);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsDeleteProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId,
|
|
|
+ _In_ bool useStrictRules, _Out_ JsValueRef *result)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
PARAM_NOT_NULL(result);
|
|
|
*result = nullptr;
|
|
|
|
|
|
- *result = Js::JavascriptOperators::OP_DeleteProperty((Js::Var)object, ((Js::PropertyRecord *)propertyId)->GetPropertyId(),
|
|
|
- scriptContext, useStrictRules ? Js::PropertyOperation_StrictMode : Js::PropertyOperation_None);
|
|
|
- Assert(*result == nullptr || !Js::CrossSite::NeedMarshalVar(*result, scriptContext));
|
|
|
+ return JsDeletePropertyCommon(scriptContext, object, (const Js::PropertyRecord *)propertyId,
|
|
|
+ useStrictRules, result, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, result);
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectDeleteProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId,
|
|
|
+ _In_ bool useStrictRules, _Out_ JsValueRef *result)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
- return JsNoError;
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ PARAM_NOT_NULL(result);
|
|
|
+ *result = nullptr;
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
+ {
|
|
|
+ return errorValue;
|
|
|
+ }
|
|
|
+
|
|
|
+ Assert(propertyRecord != nullptr);
|
|
|
+
|
|
|
+ return JsDeletePropertyCommon(scriptContext, object, propertyRecord,
|
|
|
+ useStrictRules, result, _actionEntryPopper);
|
|
|
});
|
|
|
}
|
|
|
+#endif
|
|
|
|
|
|
-CHAKRA_API JsDefineProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _In_ JsValueRef propertyDescriptor, _Out_ bool *result)
|
|
|
+static JsErrorCode JsDefinePropertyCommon(Js::ScriptContext * scriptContext, _In_ JsValueRef object,
|
|
|
+ _In_ const Js::PropertyRecord *propertyRecord, _In_ JsValueRef propertyDescriptor,
|
|
|
+ _Out_ bool *result, TTDRecorder& _actionEntryPopper)
|
|
|
{
|
|
|
- return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTDefineProperty, object, (Js::PropertyRecord *)propertyId, propertyDescriptor);
|
|
|
+ AssertMsg(scriptContext->GetThreadContext()->IsScriptActive(), "Caller is expected to be under ContextAPIWrapper!");
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTDefineProperty, object,
|
|
|
+ propertyRecord, propertyDescriptor);
|
|
|
+
|
|
|
+ Js::PropertyDescriptor propertyDescriptorValue;
|
|
|
+ if (!Js::JavascriptOperators::ToPropertyDescriptor(propertyDescriptor, &propertyDescriptorValue, scriptContext))
|
|
|
+ {
|
|
|
+ return JsErrorInvalidArgument;
|
|
|
+ }
|
|
|
+
|
|
|
+ *result = Js::JavascriptOperators::DefineOwnPropertyDescriptor(
|
|
|
+ Js::RecyclableObject::FromVar(object), propertyRecord->GetPropertyId(),
|
|
|
+ propertyDescriptorValue, true, scriptContext) != 0;
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsDefineProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId,
|
|
|
+ _In_ JsValueRef propertyDescriptor, _Out_ bool *result)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
|
|
|
VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
@@ -1547,15 +1812,68 @@ CHAKRA_API JsDefineProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propert
|
|
|
PARAM_NOT_NULL(result);
|
|
|
*result = false;
|
|
|
|
|
|
- Js::PropertyDescriptor propertyDescriptorValue;
|
|
|
- if (!Js::JavascriptOperators::ToPropertyDescriptor(propertyDescriptor, &propertyDescriptorValue, scriptContext))
|
|
|
+ return JsDefinePropertyCommon(scriptContext, object, (const Js::PropertyRecord *)propertyId,
|
|
|
+ propertyDescriptor, result, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+#ifdef _CHAKRACOREBUILD
|
|
|
+CHAKRA_API JsObjectDefineProperty(_In_ JsValueRef object, _In_ JsValueRef propertyId,
|
|
|
+ _In_ JsValueRef propertyDescriptor, _Out_ bool *result)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext,
|
|
|
+ TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ VALIDATE_INCOMING_RECYCLABLE(propertyId, scriptContext);
|
|
|
+ VALIDATE_INCOMING_OBJECT(propertyDescriptor, scriptContext);
|
|
|
+ PARAM_NOT_NULL(result);
|
|
|
+ *result = false;
|
|
|
+
|
|
|
+ const Js::PropertyRecord *propertyRecord = nullptr;
|
|
|
+ JsErrorCode errorValue = InternalGetPropertyRecord(scriptContext,
|
|
|
+ Js::RecyclableObject::FromVar(propertyId), &propertyRecord);
|
|
|
+
|
|
|
+ if (errorValue != JsNoError)
|
|
|
{
|
|
|
- return JsErrorInvalidArgument;
|
|
|
+ return errorValue;
|
|
|
}
|
|
|
|
|
|
- *result = Js::JavascriptOperators::DefineOwnPropertyDescriptor(
|
|
|
- Js::RecyclableObject::FromVar(object), ((Js::PropertyRecord *)propertyId)->GetPropertyId(), propertyDescriptorValue,
|
|
|
- true, scriptContext) != 0;
|
|
|
+ return JsDefinePropertyCommon(scriptContext, object, propertyRecord, propertyDescriptor, result, _actionEntryPopper);
|
|
|
+ });
|
|
|
+}
|
|
|
+#endif
|
|
|
+
|
|
|
+CHAKRA_API JsGetOwnPropertyNames(_In_ JsValueRef object, _Out_ JsValueRef *propertyNames)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertyNamesInfo, object);
|
|
|
+
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ PARAM_NOT_NULL(propertyNames);
|
|
|
+ *propertyNames = nullptr;
|
|
|
+
|
|
|
+ *propertyNames = Js::JavascriptOperators::GetOwnPropertyNames(object, scriptContext);
|
|
|
+ Assert(*propertyNames == nullptr || !Js::CrossSite::NeedMarshalVar(*propertyNames, scriptContext));
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertyNames);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+ });
|
|
|
+}
|
|
|
+
|
|
|
+CHAKRA_API JsGetOwnPropertySymbols(_In_ JsValueRef object, _Out_ JsValueRef *propertySymbols)
|
|
|
+{
|
|
|
+ return ContextAPIWrapper<JSRT_MAYBE_TRUE>([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTGetOwnPropertySymbolsInfo, object);
|
|
|
+
|
|
|
+ VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
+ PARAM_NOT_NULL(propertySymbols);
|
|
|
+
|
|
|
+ *propertySymbols = Js::JavascriptOperators::GetOwnPropertySymbols(object, scriptContext);
|
|
|
+ Assert(*propertySymbols == nullptr || !Js::CrossSite::NeedMarshalVar(*propertySymbols, scriptContext));
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, propertySymbols);
|
|
|
|
|
|
return JsNoError;
|
|
|
});
|
|
|
@@ -4225,14 +4543,21 @@ CHAKRA_API JsCreateString(
|
|
|
_Out_ JsValueRef *value)
|
|
|
{
|
|
|
PARAM_NOT_NULL(content);
|
|
|
+ PARAM_NOT_NULL(value);
|
|
|
|
|
|
- utf8::NarrowToWide wstr(content, length);
|
|
|
- if (!wstr)
|
|
|
- {
|
|
|
- return JsErrorOutOfMemory;
|
|
|
- }
|
|
|
+ return ContextAPINoScriptWrapper([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+
|
|
|
+ Js::JavascriptString *stringValue = Js::LiteralStringWithPropertyStringPtr::
|
|
|
+ NewFromCString(content, (CharCount)length, scriptContext->GetLibrary());
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTCreateString, stringValue->GetSz(), stringValue->GetLength());
|
|
|
+
|
|
|
+ *value = stringValue;
|
|
|
|
|
|
- return JsPointerToString(wstr, wstr.Length(), value);
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, value);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
CHAKRA_API JsCreateStringUtf16(
|
|
|
@@ -4241,9 +4566,21 @@ CHAKRA_API JsCreateStringUtf16(
|
|
|
_Out_ JsValueRef *value)
|
|
|
{
|
|
|
PARAM_NOT_NULL(content);
|
|
|
+ PARAM_NOT_NULL(value);
|
|
|
+
|
|
|
+ return ContextAPINoScriptWrapper([&](Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
+
|
|
|
+ Js::JavascriptString *stringValue = Js::LiteralStringWithPropertyStringPtr::
|
|
|
+ NewFromWideString(content, (CharCount)length, scriptContext->GetLibrary());
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTCreateString, stringValue->GetSz(), stringValue->GetLength());
|
|
|
|
|
|
- return JsPointerToString(
|
|
|
- reinterpret_cast<const char16*>(content), length, value);
|
|
|
+ *value = stringValue;
|
|
|
+
|
|
|
+ PERFORM_JSRT_TTD_RECORD_ACTION_RESULT(scriptContext, value);
|
|
|
+
|
|
|
+ return JsNoError;
|
|
|
+ });
|
|
|
}
|
|
|
|
|
|
|
|
|
@@ -4798,22 +5135,6 @@ CHAKRA_API JsGetAndClearExceptionWithMetadata(_Out_ JsValueRef *metadata)
|
|
|
});
|
|
|
}
|
|
|
|
|
|
-CHAKRA_API JsHasOwnProperty(_In_ JsValueRef object, _In_ JsPropertyIdRef propertyId, _Out_ bool *hasOwnProperty)
|
|
|
-{
|
|
|
- return ContextAPIWrapper<true>([&] (Js::ScriptContext *scriptContext, TTDRecorder& _actionEntryPopper) -> JsErrorCode {
|
|
|
- PERFORM_JSRT_TTD_RECORD_ACTION(scriptContext, RecordJsRTHasOwnProperty, (Js::PropertyRecord *)propertyId, object);
|
|
|
-
|
|
|
- VALIDATE_INCOMING_OBJECT(object, scriptContext);
|
|
|
- VALIDATE_INCOMING_PROPERTYID(propertyId);
|
|
|
- PARAM_NOT_NULL(hasOwnProperty);
|
|
|
- *hasOwnProperty = false;
|
|
|
-
|
|
|
- *hasOwnProperty = Js::JavascriptOperators::OP_HasOwnProperty(object, ((Js::PropertyRecord *)propertyId)->GetPropertyId(), scriptContext) != 0;
|
|
|
-
|
|
|
- return JsNoError;
|
|
|
- });
|
|
|
-}
|
|
|
-
|
|
|
CHAKRA_API JsCopyStringOneByte(
|
|
|
_In_ JsValueRef value,
|
|
|
_In_ int start,
|