Skip to content

Add support for CF data structures/utils on WASI #3039

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Aug 12, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions CoreFoundation/Collections.subproj/CFData.c
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ CF_INLINE unsigned long __CFPageSize() {
CF_INLINE unsigned long __CFPageSize() {
return (unsigned long)getpagesize();
}
#elif TARGET_OS_WASI
CF_INLINE unsigned long __CFPageSize() {
// WebAssembly linear memory pages are always 64KiB in size
return 65536;
}
#endif

#define INLINE_BYTES_THRESHOLD ((4 * __CFPageSize()) - sizeof(struct __CFData) - 15)
Expand Down
15 changes: 13 additions & 2 deletions CoreFoundation/Locale.subproj/CFDateIntervalFormatter.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,15 @@

#include <unicode/udateintervalformat.h>

#if TARGET_OS_WASI
#define LOCK() do {} while (0)
#define UNLOCK() do {} while (0)
#else
#include <dispatch/dispatch.h>

#define LOCK() do { dispatch_semaphore_wait(formatter->_lock, DISPATCH_TIME_FOREVER); } while(0)
#define UNLOCK() do { dispatch_semaphore_signal(formatter->_lock); } while(0)
#endif

CF_INLINE void __CFReleaseIfNotNull(CFTypeRef object) {
if (object) {
Expand All @@ -51,7 +56,9 @@ struct __CFDateIntervalFormatter {
CFDateIntervalFormatterStyle _dateStyle;
CFDateIntervalFormatterStyle _timeStyle;
_CFDateIntervalFormatterBoundaryStyle _boundaryStyle;
#if !TARGET_OS_WASI
dispatch_semaphore_t _lock;
#endif
bool _modified:1;
bool _useTemplate:1;
};
Expand Down Expand Up @@ -141,14 +148,14 @@ static void updateFormatter(CFDateIntervalFormatterRef dif) {
timeZone = CFTimeZoneCopyDefault();
}
CFStringRef unretainedTimeZoneName = CFTimeZoneGetName(timeZone);
CFStringGetCharacters(unretainedTimeZoneName, CFRangeMake(0, MIN(CFStringGetLength(unretainedTimeZoneName), 100)), timeZoneID);
CFStringGetCharacters(unretainedTimeZoneName, CFRangeMake(0, __CFMin(CFStringGetLength(unretainedTimeZoneName), 100)), timeZoneID);

CFStringRef unretainedTemplate = dif->_dateTemplateFromStyles;
if (dif->_useTemplate) {
unretainedTemplate = dif->_dateTemplate;
}
UniChar templateStr[100] = {0};
CFStringGetCharacters(unretainedTemplate, CFRangeMake(0, MIN(CFStringGetLength(unretainedTemplate), 100)), templateStr);
CFStringGetCharacters(unretainedTemplate, CFRangeMake(0, __CFMin(CFStringGetLength(unretainedTemplate), 100)), templateStr);

UErrorCode status = U_ZERO_ERROR;
dif->_formatter = udtitvfmt_open(localeBuffer, templateStr, CFStringGetLength(unretainedTemplate), timeZoneID, CFStringGetLength(unretainedTimeZoneName), &status);
Expand Down Expand Up @@ -230,7 +237,9 @@ CFDateIntervalFormatterRef CFDateIntervalFormatterCreate(CFAllocatorRef allocato
memory->_dateTemplate = CFRetain(CFSTR(""));
memory->_formatter = NULL;
memory->_boundaryStyle = kCFDateIntervalFormatterBoundaryStyleDefault;
#if !TARGET_OS_WASI
memory->_lock = dispatch_semaphore_create(1);
#endif
memory->_modified = false;
memory->_useTemplate = false;

Expand Down Expand Up @@ -337,7 +346,9 @@ static void __CFDateIntervalFormatterDeallocate(CFTypeRef object) {
udtitvfmt_close(formatter->_formatter);
}

#if !TARGET_OS_WASI
dispatch_release(formatter->_lock);
#endif
}

CFLocaleRef CFDateIntervalFormatterCopyLocale(CFDateIntervalFormatterRef formatter) {
Expand Down
6 changes: 5 additions & 1 deletion CoreFoundation/Locale.subproj/CFLocale.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,16 @@
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFArray.h>
#include <CoreFoundation/CFDictionary.h>
#include <CoreFoundation/CFPreferences.h>
#include <CoreFoundation/CFCalendar.h>
#include <CoreFoundation/CFNumber.h>
#include "CFInternal.h"
#include "CFRuntime_Internal.h"
#if !TARGET_OS_WASI
#include <CoreFoundation/CFPreferences.h>
#include "CFBundle_Internal.h"
#else
#include "CFBase.h"
#endif
#include "CFLocaleInternal.h"
#include <stdatomic.h>
#if TARGET_OS_MAC || TARGET_OS_WIN32 || TARGET_OS_LINUX || TARGET_OS_BSD
Expand Down
2 changes: 1 addition & 1 deletion CoreFoundation/Locale.subproj/CFLocaleKeys.c
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ CONST_STRING_DECL(kCFCalendarIdentifierEthiopicAmeteMihret, "ethiopic");
CONST_STRING_DECL(kCFCalendarIdentifierEthiopicAmeteAlem, "ethiopic-amete-alem");

// Aliases for other platforms.
#if TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WIN32
#if TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WIN32 || TARGET_OS_WASI

CF_EXPORT CFStringRef const kCFBuddhistCalendar __attribute__((alias ("kCFCalendarIdentifierBuddhist")));
CF_EXPORT CFStringRef const kCFChineseCalendar __attribute__((alias ("kCFCalendarIdentifierChinese")));
Expand Down
2 changes: 1 addition & 1 deletion CoreFoundation/NumberDate.subproj/CFNumber.c
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ static const Float64Bits doubleOneBits = {.floatValue = 1.0f};
#define BITSFORDOUBLEZERO doubleZeroBits.bits
#define BITSFORDOUBLEONE doubleOneBits.bits

#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
#define FLOAT_POSITIVE_2_TO_THE_64 0x1.0p+64L
#define FLOAT_NEGATIVE_2_TO_THE_127 -0x1.0p+127L
#define FLOAT_POSITIVE_2_TO_THE_127 0x1.0p+127L
Expand Down
25 changes: 15 additions & 10 deletions CoreFoundation/NumberDate.subproj/CFTimeZone.c
Original file line number Diff line number Diff line change
Expand Up @@ -25,11 +25,13 @@
#include <unicode/udat.h>
#include <unicode/ustring.h>
#include <CoreFoundation/CFDateFormatter.h>
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
#include <dirent.h>
#include <unistd.h>
#if !TARGET_OS_ANDROID
#if !TARGET_OS_ANDROID && !TARGET_OS_WASI
#include <sys/fcntl.h>
#elif TARGET_OS_WASI
#include <fcntl.h>
#else
#include <sys/endian.h>
#endif
Expand All @@ -47,7 +49,7 @@
#include <tzfile.h>
#define MACOS_TZDIR1 "/usr/share/zoneinfo/" // 10.12 and earlier
#define MACOS_TZDIR2 "/var/db/timezone/zoneinfo/" // 10.13 onwards
#elif TARGET_OS_LINUX || TARGET_OS_BSD
#elif TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
#ifndef TZDIR
#define TZDIR "/usr/share/zoneinfo/" /* Time zone object file directory */
#endif /* !defined TZDIR */
Expand All @@ -57,7 +59,7 @@
#endif /* !defined TZDEFAULT */
#endif

#if TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WIN32
#if TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WIN32 || TARGET_OS_WASI
struct tzhead {
char tzh_magic[4]; /* TZ_MAGIC */
char tzh_reserved[16]; /* reserved for future use */
Expand Down Expand Up @@ -351,7 +353,7 @@ static CFMutableArrayRef __CFCopyAndroidTimeZoneList() {
return result;
}

#elif TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
#elif TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
static CFMutableArrayRef __CFCopyRecursiveDirectoryList() {
CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorSystemDefault, 0, &kCFTypeArrayCallBacks);
#if !TARGET_OS_ANDROID
Expand Down Expand Up @@ -810,7 +812,7 @@ static void __InitTZStrings(void) {

#elif TARGET_OS_ANDROID
// Nothing
#elif TARGET_OS_LINUX || TARGET_OS_BSD
#elif TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
static void __InitTZStrings(void) {
__tzZoneInfo = CFSTR(TZDIR);
__tzDir = TZDIR "zone.tab";
Expand Down Expand Up @@ -863,7 +865,7 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
if (result) return result;
}

#if !TARGET_OS_ANDROID
#if !TARGET_OS_ANDROID && !TARGET_OS_WASI
if (!__tzZoneInfo) __InitTZStrings();
ret = readlink(TZDEFAULT, linkbuf, sizeof(linkbuf));
// The link can be relative, we treat this the same as if there was no link
Expand All @@ -880,9 +882,11 @@ static CFTimeZoneRef __CFTimeZoneCreateSystem(void) {
} else
#endif
{
#if !TARGET_OS_WASI
// TODO: This can still fail on Linux if the time zone is not recognized by ICU later
// Try localtime
tzset();
#endif
time_t t = time(NULL);
struct tm lt = {0};
localtime_r(&t, &lt);
Expand Down Expand Up @@ -1348,7 +1352,8 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data

return FALSE;
#else
#if !TARGET_OS_ANDROID
#if !TARGET_OS_ANDROID && !TARGET_OS_WASI

if (!__tzZoneInfo) __InitTZStrings();
if (!__tzZoneInfo) return NULL;
baseURL = CFURLCreateWithFileSystemPath(kCFAllocatorSystemDefault, __tzZoneInfo, kCFURLPOSIXPathStyle, true);
Expand All @@ -1367,7 +1372,7 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data
if (mapping) {
name = mapping;
}
#if !TARGET_OS_ANDROID
#if !TARGET_OS_ANDROID && !TARGET_OS_WASI
else if (CFStringHasPrefix(name, __tzZoneInfo)) {
CFMutableStringRef unprefixed = CFStringCreateMutableCopy(kCFAllocatorSystemDefault, CFStringGetLength(name), name);
CFStringDelete(unprefixed, CFRangeMake(0, CFStringGetLength(__tzZoneInfo)));
Expand All @@ -1383,7 +1388,7 @@ Boolean _CFTimeZoneInit(CFTimeZoneRef timeZone, CFStringRef name, CFDataRef data
return false;
}
}
if (NULL == data) {
if (NULL == data && NULL != baseURL) {
tzName = name;
data = _CFTimeZoneDataCreate(baseURL, tzName);
}
Expand Down
5 changes: 5 additions & 0 deletions CoreFoundation/Parsing.subproj/CFBinaryPList.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,10 @@
#include <string.h>
#include "CFInternal.h"
#include "CFRuntime_Internal.h"

#if !TARGET_OS_WASI
#include <CoreFoundation/CFStream.h>
#endif

enum {
CF_NO_ERROR = 0,
Expand Down Expand Up @@ -130,6 +133,7 @@ uint32_t _CFKeyedArchiverUIDGetValue(CFKeyedArchiverUIDRef uid) {

CF_PRIVATE CFErrorRef __CFPropertyListCreateError(CFIndex code, CFStringRef debugString, ...);

#if !TARGET_OS_WASI
typedef struct {
CFTypeRef stream;
void *databytes;
Expand Down Expand Up @@ -691,6 +695,7 @@ CF_PRIVATE CFDataRef __CFBinaryPlistCreateDataUsingExternalBufferAllocator(CFPro
}
return result;
}
#endif

#pragma mark -
#pragma mark Reading
Expand Down
5 changes: 4 additions & 1 deletion CoreFoundation/Parsing.subproj/CFPropertyList.c
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#include "CFRuntime_Internal.h"
#include <CoreFoundation/CFBurstTrie.h>
#include <CoreFoundation/CFString.h>
#if !TARGET_OS_WASI
#include <CoreFoundation/CFStream.h>
#endif
#include <CoreFoundation/CFCalendar.h>
#include "CFLocaleInternal.h"
#include <limits.h>
Expand Down Expand Up @@ -2850,7 +2852,6 @@ CFSetRef _CFPropertyListCopyTopLevelKeys(CFAllocatorRef allocator, CFDataRef dat
}



// Legacy
CFTypeRef _CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDataRef xmlData, CFOptionFlags option, CFStringRef *errorString, Boolean allowNewTypes, CFPropertyListFormat *format) {
CFTypeRef out = NULL;
Expand Down Expand Up @@ -2883,6 +2884,7 @@ CFPropertyListRef CFPropertyListCreateFromXMLData(CFAllocatorRef allocator, CFDa
return result;
}

#if !TARGET_OS_WASI
CFDataRef CFPropertyListCreateData(CFAllocatorRef allocator, CFPropertyListRef propertyList, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) {
CFAssert1(format != kCFPropertyListOpenStepFormat, __kCFLogAssertion, "%s(): kCFPropertyListOpenStepFormat not supported for writing", __PRETTY_FUNCTION__);
CFAssert2(format == kCFPropertyListXMLFormat_v1_0 || format == kCFPropertyListBinaryFormat_v1_0, __kCFLogAssertion, "%s(): Unrecognized option %ld", __PRETTY_FUNCTION__, format);
Expand Down Expand Up @@ -3136,6 +3138,7 @@ bool _CFPropertyListValidateData(CFDataRef data, CFTypeID *outTopLevelTypeID) {
return result;
}

#endif

#pragma mark -
#pragma mark Property List Copies
Expand Down
8 changes: 7 additions & 1 deletion CoreFoundation/Parsing.subproj/CFPropertyList.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,10 @@
#include <CoreFoundation/CFData.h>
#include <CoreFoundation/CFString.h>
#include <CoreFoundation/CFError.h>

#if !TARGET_OS_WASI
#include <CoreFoundation/CFStream.h>
#endif

CF_IMPLICIT_BRIDGING_ENABLED
CF_EXTERN_C_BEGIN
Expand Down Expand Up @@ -82,6 +85,7 @@ Boolean CFPropertyListIsValid(CFPropertyListRef plist, CFPropertyListFormat form

CF_IMPLICIT_BRIDGING_DISABLED

#if !TARGET_OS_WASI
/* Writes the bytes of a plist serialization out to the stream. The
* stream must be opened and configured -- the function simply writes
* a bunch of bytes to the stream. The output plist format can be chosen.
Expand Down Expand Up @@ -113,6 +117,7 @@ CFPropertyListRef CFPropertyListCreateFromStream(CFAllocatorRef allocator, CFRea
CF_IMPLICIT_BRIDGING_ENABLED

CF_IMPLICIT_BRIDGING_DISABLED
#endif

CF_ENUM(CFIndex) {
kCFPropertyListReadCorruptError = 3840, // Error parsing a property list
Expand All @@ -126,6 +131,7 @@ CF_ENUM(CFIndex) {
CF_EXPORT
CFPropertyListRef CFPropertyListCreateWithData(CFAllocatorRef allocator, CFDataRef data, CFOptionFlags options, CFPropertyListFormat *format, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));

#if !TARGET_OS_WASI
/* Create and return a property list with a CFReadStream input. If the format parameter is non-NULL, it will be set to the format of the data after parsing is complete. The options parameter is used to specify CFPropertyListMutabilityOptions. The streamLength parameter specifies the number of bytes to read from the stream. Set streamLength to 0 to read until the end of the stream is detected. If an error occurs while parsing the data, the return value will be NULL. Additionally, if an error occurs and the error parameter is non-NULL, the error parameter will be set to a CFError describing the problem, which the caller must release. If the parse succeeds, the returned value is a reference to the new property list. It is the responsibility of the caller to release this value.
*/
CF_EXPORT
Expand All @@ -135,6 +141,7 @@ CFPropertyListRef CFPropertyListCreateWithStream(CFAllocatorRef allocator, CFRea
*/
CF_EXPORT
CFIndex CFPropertyListWrite(CFPropertyListRef propertyList, CFWriteStreamRef stream, CFPropertyListFormat format, CFOptionFlags options, CFErrorRef *error) API_AVAILABLE(macos(10.6), ios(4.0), watchos(2.0), tvos(9.0));
#endif

/* Create a CFData with the bytes of a serialized property list. The format of the property list can be chosen with the format parameter. The options parameter is currently unused and should be set to 0. If an error occurs while parsing the data, the return value will be NULL. Additionally, if an error occurs and the error parameter is non-NULL, the error parameter will be set to a CFError describing the problem, which the caller must release. If the conversion succeeds, the returned value is a reference to the created data. It is the responsibility of the caller to release this value.
*/
Expand All @@ -145,6 +152,5 @@ CF_IMPLICIT_BRIDGING_ENABLED

CF_EXTERN_C_END
CF_IMPLICIT_BRIDGING_DISABLED

#endif /* ! __COREFOUNDATION_CFPROPERTYLIST__ */

2 changes: 1 addition & 1 deletion CoreFoundation/String.subproj/CFBurstTrie.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include <limits.h>
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD
#if TARGET_OS_MAC || TARGET_OS_LINUX || TARGET_OS_BSD || TARGET_OS_WASI
#include <unistd.h>
#include <sys/param.h>
#include <sys/mman.h>
Expand Down
4 changes: 2 additions & 2 deletions CoreFoundation/String.subproj/CFCharacterSet.c
Original file line number Diff line number Diff line change
Expand Up @@ -731,7 +731,7 @@ static void __CFCSetAddNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFRang
int firstChar = (range.location & 0xFFFF);
int maxChar = range.location + range.length;
int idx = range.location >> 16; // first plane
int maxPlane = MIN((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane
int maxPlane = __CFMin((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane
CFRange planeRange;
CFMutableCharacterSetRef annexPlane;

Expand Down Expand Up @@ -775,7 +775,7 @@ static void __CFCSetRemoveNonBMPPlanesInRange(CFMutableCharacterSetRef cset, CFR
int firstChar = (range.location & 0xFFFF);
int maxChar = range.location + range.length;
int idx = range.location >> 16; // first plane
int maxPlane = MIN((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane
int maxPlane = __CFMin((maxChar - 1) >> 16, MAX_ANNEX_PLANE); // last plane
CFRange planeRange;
CFMutableCharacterSetRef annexPlane;

Expand Down
2 changes: 1 addition & 1 deletion CoreFoundation/String.subproj/CFString.c
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ CFStringEncoding __CFDefaultEightBitStringEncoding = kCFStringEncodingInvalidId;

#if TARGET_OS_MAC
#define __defaultEncoding kCFStringEncodingMacRoman
#elif TARGET_OS_LINUX
#elif TARGET_OS_LINUX || TARGET_OS_WASI
#define __defaultEncoding kCFStringEncodingUTF8
#elif TARGET_OS_WIN32
#define __defaultEncoding kCFStringEncodingWindowsLatin1
Expand Down
2 changes: 1 addition & 1 deletion CoreFoundation/String.subproj/CFStringEncodings.c
Original file line number Diff line number Diff line change
Expand Up @@ -656,7 +656,7 @@ CFIndex __CFStringEncodeByteStream(CFStringRef string, CFIndex rangeLoc, CFIndex
return numCharsProcessed;
}

CFIndex uninterestingTailLen = buffer ? (rangeLen - MIN(max, rangeLen)) : 0;
CFIndex uninterestingTailLen = buffer ? (rangeLen - __CFMin(max, rangeLen)) : 0;
while (*ptr < 0x80 && rangeLen > uninterestingTailLen) {
++ptr;
--rangeLen;
Expand Down
2 changes: 1 addition & 1 deletion CoreFoundation/String.subproj/CFStringUtilities.c
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@ CF_PRIVATE CFComparisonResult _CFCompareStringsWithLocale(CFStringInlineBuffer *
} else
#endif
{
compResult = ((memcmp(characters1, characters2, sizeof(UniChar) * MIN(range1.length, range2.length)) < 0) ? kCFCompareLessThan : kCFCompareGreaterThan);
compResult = ((memcmp(characters1, characters2, sizeof(UniChar) * __CFMin(range1.length, range2.length)) < 0) ? kCFCompareLessThan : kCFCompareGreaterThan);
}
} else {
UniChar *buffer1 = NULL;
Expand Down
Loading