Skip to content

Commit

Permalink
Convert JavaScriptCore to Modern Objective-C
Browse files Browse the repository at this point in the history
https://bugs.webkit.org/show_bug.cgi?id=251797

Reviewed by NOBODY (OOPS!).

JavaScriptCore was run through the Xcode's Modern Objective-C converter.
However, the results were not buildable alone, so some additional
changes were made to get the JavaScriptCore framework to build again.

As this is an API change, this warrants modernization as:
1. This code has roots going back years, which makes sense as Safari has
   been around for 2 decades. Modernizing the code helps as it lays the
   groundwork for future patches to follow modern Objective-C coding
   conventions as well as being consistent with newer code written.
2. These modernizations make the code more safe while improving
   performance in some places.
3. If we ever need to write Swift code calling this library directly, it
   will be much easier to get Swift to work with this framework.

* Source/JavaScriptCore/API/APICallbackFunction.h:
* Source/JavaScriptCore/API/JSAPIGlobalObject.mm:
* Source/JavaScriptCore/API/JSContext.mm:
* Source/JavaScriptCore/API/JSContextInternal.h:
* Source/JavaScriptCore/API/JSManagedValue.h:
* Source/JavaScriptCore/API/JSManagedValue.mm:
* Source/JavaScriptCore/API/JSScript.h:
* Source/JavaScriptCore/API/JSScript.mm:
* Source/JavaScriptCore/API/JSScriptInternal.h:
* Source/JavaScriptCore/API/JSScriptSourceProvider.mm:
* Source/JavaScriptCore/API/JSValue.mm:
* Source/JavaScriptCore/API/JSVirtualMachine.mm:
* Source/JavaScriptCore/API/JSWrapperMap.mm:
* Source/JavaScriptCore/API/ObjCCallbackFunction.mm:
* Source/JavaScriptCore/API/tests/CurrentThisInsideBlockGetterTest.mm:
* Source/JavaScriptCore/API/tests/DateTests.mm:
* Source/JavaScriptCore/API/tests/Regress141275.mm:
* Source/JavaScriptCore/API/tests/Regress141809.mm:
* Source/JavaScriptCore/API/tests/testapi.mm:
* Source/JavaScriptCore/inspector/ContentSearchUtilities.cpp:
* Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorCocoa.mm:
* Source/JavaScriptCore/inspector/remote/cocoa/RemoteInspectorXPCConnection.mm:
* Source/JavaScriptCore/testmem/testmem.mm:
* Source/WTF/wtf/cocoa/FileSystemCocoa.mm:
* Source/WTF/wtf/cocoa/LanguageCocoa.mm:
* Source/WTF/wtf/cocoa/NSURLExtras.mm:
* Source/WebCore/bridge/objc/objc_utility.mm:
* Source/WebCore/platform/mac/PluginBlocklist.mm:
* Source/WebGPU/WebGPU/Adapter.mm:
* Source/WebGPU/WebGPU/Device.mm:
* Source/WebGPU/WebGPU/HardwareCapabilities.mm:
* Source/WebKit/UIProcess/API/Cocoa/APIContentRuleListStoreCocoa.mm:
* Source/WebKit/UIProcess/Extensions/Cocoa/WebExtensionControllerConfiguration.mm:
* Source/WebKit/UIProcess/WebsiteData/Cocoa/WebsiteDataStoreCocoa.mm:
* Source/bmalloc/bmalloc/ProcessCheck.mm:
  • Loading branch information
AtariDreams committed Mar 26, 2023
1 parent 47cdb9c commit 7f1fd02
Show file tree
Hide file tree
Showing 36 changed files with 387 additions and 381 deletions.
4 changes: 2 additions & 2 deletions Source/JavaScriptCore/API/APICallbackFunction.h
Expand Up @@ -48,10 +48,10 @@ EncodedJSValue APICallbackFunction::callImpl(JSGlobalObject* globalObject, CallF
JSObjectRef functionRef = toRef(callFrame->jsCallee());
JSObjectRef thisObjRef = toRef(jsCast<JSObject*>(callFrame->thisValue().toThis(globalObject, ECMAMode::sloppy())));

int argumentCount = static_cast<int>(callFrame->argumentCount());
size_t argumentCount = callFrame->argumentCount();
Vector<JSValueRef, 16> arguments;
arguments.reserveInitialCapacity(argumentCount);
for (int i = 0; i < argumentCount; i++)
for (size_t i = 0; i < argumentCount; i++)
arguments.uncheckedAppend(toRef(globalObject, callFrame->uncheckedArgument(i)));

JSValueRef exception = nullptr;
Expand Down
14 changes: 7 additions & 7 deletions Source/JavaScriptCore/API/JSAPIGlobalObject.mm
Expand Up @@ -207,12 +207,12 @@

JSScript* jsScript = static_cast<JSScript *>(script);

JSSourceCode* source = [jsScript jsSourceCode];
JSSourceCode* source = jsScript.jsSourceCode;
if (UNLIKELY([jsScript type] != kJSScriptTypeModule))
return rejectPromise("The JSScript that was provided did not have expected type of kJSScriptTypeModule."_s);

NSURL *sourceURL = [jsScript sourceURL];
String oldModuleKey { [sourceURL absoluteString] };
NSURL *sourceURL = jsScript.sourceURL;
String oldModuleKey { sourceURL.absoluteString };
if (UNLIKELY(Identifier::fromString(vm, oldModuleKey) != moduleKey))
return rejectPromise(makeString("The same JSScript was provided for two different identifiers, previously: ", oldModuleKey, " and now: ", moduleKey.string()));

Expand All @@ -225,10 +225,10 @@
return encodedJSUndefined();
});

[[context moduleLoaderDelegate] context:context fetchModuleForIdentifier:[::JSValue valueWithJSValueRef:toRef(globalObject, key) inContext:context] withResolveHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, resolve) inContext:context] andRejectHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, reject) inContext:context]];
[context.moduleLoaderDelegate context:context fetchModuleForIdentifier:[::JSValue valueWithJSValueRef:toRef(globalObject, key) inContext:context] withResolveHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, resolve) inContext:context] andRejectHandler:[::JSValue valueWithJSValueRef:toRef(globalObject, reject) inContext:context]];
if (context.exception) {
scope.release();
promise->reject(globalObject, toJS(globalObject, [context.exception JSValueRef]));
promise->reject(globalObject, toJS(globalObject, context.exception.JSValueRef));
context.exception = nil;
}
return promise;
Expand All @@ -254,7 +254,7 @@
auto scope = DECLARE_THROW_SCOPE(vm);

JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject)];
id <JSModuleLoaderDelegate> moduleLoaderDelegate = [context moduleLoaderDelegate];
id<JSModuleLoaderDelegate> moduleLoaderDelegate = context.moduleLoaderDelegate;
NSURL *url = nil;

if ([moduleLoaderDelegate respondsToSelector:@selector(willEvaluateModule:)] || [moduleLoaderDelegate respondsToSelector:@selector(didEvaluateModule:)]) {
Expand Down Expand Up @@ -282,7 +282,7 @@
VM& vm = this->vm();
auto scope = DECLARE_THROW_SCOPE(vm);

Identifier key = Identifier::fromString(vm, String { [[script sourceURL] absoluteString] });
Identifier key = Identifier::fromString(vm, String { script.sourceURL.absoluteString });
JSInternalPromise* promise = importModule(this, key, jsUndefined(), jsUndefined(), jsUndefined());
RETURN_IF_EXCEPTION(scope, { });
auto* result = JSPromise::create(vm, this->promiseStructure());
Expand Down
18 changes: 9 additions & 9 deletions Source/JavaScriptCore/API/JSContext.mm
Expand Up @@ -63,9 +63,9 @@ - (JSGlobalContextRef)JSGlobalContextRef

- (void)ensureWrapperMap
{
if (!toJS([self JSGlobalContextRef])->wrapperMap()) {
if (!toJS(self.JSGlobalContextRef)->wrapperMap()) {
// The map will be retained by the GlobalObject in initialization.
[[[JSWrapperMap alloc] initWithGlobalContextRef:[self JSGlobalContextRef]] release];
[[[JSWrapperMap alloc] initWithGlobalContextRef:self.JSGlobalContextRef] release];
}
}

Expand Down Expand Up @@ -110,7 +110,7 @@ - (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL
{
JSValueRef exceptionValue = nullptr;
auto scriptJS = OpaqueJSString::tryCreate(script);
auto sourceURLJS = OpaqueJSString::tryCreate([sourceURL absoluteString]);
auto sourceURLJS = OpaqueJSString::tryCreate(sourceURL.absoluteString);
JSValueRef result = JSEvaluateScript(m_context, scriptJS.get(), nullptr, sourceURLJS.get(), 0, &exceptionValue);

if (exceptionValue)
Expand All @@ -126,7 +126,7 @@ - (JSValue *)evaluateJSScript:(JSScript *)script

if (script.type == kJSScriptTypeProgram) {
JSValueRef exceptionValue = nullptr;
JSC::SourceCode sourceCode = [script sourceCode];
JSC::SourceCode sourceCode = script.sourceCode;
JSValueRef result = JSEvaluateScriptInternal(locker, m_context, nullptr, sourceCode, &exceptionValue);

if (exceptionValue)
Expand Down Expand Up @@ -162,7 +162,7 @@ - (JSValue *)dependencyIdentifiersForModuleJSScript:(JSScript *)script
}

auto scope = DECLARE_CATCH_SCOPE(vm);
JSC::JSArray* result = globalObject->moduleLoader()->dependencyKeysIfEvaluated(globalObject, JSC::jsString(vm, String([[script sourceURL] absoluteString])));
JSC::JSArray* result = globalObject->moduleLoader()->dependencyKeysIfEvaluated(globalObject, JSC::jsString(vm, String(script.sourceURL.absoluteString)));
if (scope.exception()) {
JSValueRef exceptionValue = toRef(globalObject, scope.exception()->value());
scope.clearException();
Expand Down Expand Up @@ -329,12 +329,12 @@ @implementation JSContext(SubscriptSupport)

- (JSValue *)objectForKeyedSubscript:(id)key
{
return [self globalObject][key];
return self.globalObject[key];
}

- (void)setObject:(id)object forKeyedSubscript:(NSObject <NSCopying> *)key
{
[self globalObject][key] = object;
self.globalObject[key] = object;
}

@end
Expand Down Expand Up @@ -400,7 +400,7 @@ - (void)endCallbackWithData:(CallbackData *)callbackData
- (JSValue *)wrapperForObjCObject:(id)object
{
JSC::JSLockHolder locker(toJS(m_context));
return [[self wrapperMap] jsWrapperForObject:object inContext:self];
return [self.wrapperMap jsWrapperForObject:object inContext:self];
}

- (JSWrapperMap *)wrapperMap
Expand All @@ -411,7 +411,7 @@ - (JSWrapperMap *)wrapperMap
- (JSValue *)wrapperForJSObject:(JSValueRef)value
{
JSC::JSLockHolder locker(toJS(m_context));
return [[self wrapperMap] objcWrapperForJSValueRef:value inContext:self];
return [self.wrapperMap objcWrapperForJSValueRef:value inContext:self];
}

+ (JSContext *)contextWithJSGlobalContextRef:(JSGlobalContextRef)globalContext
Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/API/JSContextInternal.h
Expand Up @@ -51,7 +51,7 @@ struct CallbackData {
- (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments;
- (void)endCallbackWithData:(CallbackData *)callbackData;

- (JSWrapperMap *)wrapperMap;
@property (nonatomic, readonly, strong) JSWrapperMap *wrapperMap;
- (JSValue *)wrapperForObjCObject:(id)object;
- (JSValue *)wrapperForJSObject:(JSValueRef)value;

Expand Down
2 changes: 1 addition & 1 deletion Source/JavaScriptCore/API/JSManagedValue.h
Expand Up @@ -64,7 +64,7 @@ NS_CLASS_AVAILABLE(10_9, 7_0)
@abstract Create a JSManagedValue.
@result The new JSManagedValue.
*/
- (instancetype)initWithValue:(JSValue *)value;
- (instancetype)initWithValue:(JSValue *)value NS_DESIGNATED_INITIALIZER;

/*!
@property
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/API/JSManagedValue.mm
Expand Up @@ -85,7 +85,7 @@ - (instancetype)initWithValue:(JSValue *)value
if (!value)
return self;

JSC::JSGlobalObject* globalObject = toJS([value.context JSGlobalContextRef]);
JSC::JSGlobalObject* globalObject = toJS(value.context.JSGlobalContextRef);
auto& owner = managedValueHandleOwner();
JSC::Weak<JSC::JSGlobalObject> weak(globalObject, &owner, (__bridge void*)self);
m_globalObject.swap(weak);
Expand All @@ -96,7 +96,7 @@ - (instancetype)initWithValue:(JSValue *)value
NSPointerFunctionsOptions integerOptions = NSPointerFunctionsOpaqueMemory | NSPointerFunctionsIntegerPersonality;
m_owners = adoptNS([[NSMapTable alloc] initWithKeyOptions:weakIDOptions valueOptions:integerOptions capacity:1]);

JSC::JSValue jsValue = toJS(globalObject, [value JSValueRef]);
JSC::JSValue jsValue = toJS(globalObject, value.JSValueRef);
if (jsValue.isObject())
m_weakValue.setObject(JSC::jsCast<JSC::JSObject*>(jsValue.asCell()), owner, (__bridge void*)self);
else if (jsValue.isString())
Expand All @@ -108,7 +108,7 @@ - (instancetype)initWithValue:(JSValue *)value

- (void)dealloc
{
JSVirtualMachine *virtualMachine = [[[self value] context] virtualMachine];
JSVirtualMachine *virtualMachine = self.value.context.virtualMachine;
if (virtualMachine) {
auto copy = adoptNS([m_owners copy]);
for (id owner in [copy keyEnumerator]) {
Expand Down
12 changes: 6 additions & 6 deletions Source/JavaScriptCore/API/JSScript.h
Expand Up @@ -84,22 +84,22 @@ JSC_CLASS_AVAILABLE(macos(10.15), ios(13.0))
- (BOOL)cacheBytecodeWithError:(out NSError * _Nullable * _Nullable)error;

/*!
@method
@property
@abstract Returns true when evaluating this JSScript will use the bytecode cache. Returns false otherwise.
*/
- (BOOL)isUsingBytecodeCache;
@property (nonatomic, getter=isUsingBytecodeCache, readonly) BOOL usingBytecodeCache;

/*!
@method
@property
@abstract Returns the JSScriptType of this JSScript.
*/
- (JSScriptType)type;
@property (nonatomic, readonly) JSScriptType type;

/*!
@method
@property
@abstract Returns the sourceURL of this JSScript.
*/
- (NSURL *)sourceURL;
@property (nonatomic, readonly, copy) NSURL *sourceURL;

@end

Expand Down
20 changes: 10 additions & 10 deletions Source/JavaScriptCore/API/JSScript.mm
Expand Up @@ -72,7 +72,7 @@ static bool validateBytecodeCachePath(NSURL* cachePath, NSError** error)
if (!cachePath)
return true;

URL cachePathURL([cachePath absoluteURL]);
URL cachePathURL(cachePath.absoluteURL);
if (!cachePathURL.isLocalFile()) {
createError([NSString stringWithFormat:@"Cache path `%@` is not a local file", static_cast<NSURL *>(cachePathURL)], error);
return false;
Expand Down Expand Up @@ -128,7 +128,7 @@ + (instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL
if (!validateBytecodeCachePath(cachePath, error))
return nil;

URL filePathURL([filePath absoluteURL]);
URL filePathURL(filePath.absoluteURL);
if (!filePathURL.isLocalFile())
return createError([NSString stringWithFormat:@"File path %@ is not a local file", static_cast<NSURL *>(filePathURL)], error);

Expand Down Expand Up @@ -157,7 +157,7 @@ - (void)readCache
if (!m_cachePath)
return;

String cacheFilename = [m_cachePath path];
String cacheFilename = m_cachePath.get().path;

auto fd = FileSystem::openAndLockFile(cacheFilename, FileSystem::FileOpenMode::Read, {FileSystem::FileLockMode::Exclusive, FileSystem::FileLockMode::Nonblocking});
if (!FileSystem::isHandleValid(fd))
Expand All @@ -172,15 +172,15 @@ - (void)readCache
return;

const uint8_t* fileData = reinterpret_cast<const uint8_t*>(mappedFile.data());
unsigned fileTotalSize = mappedFile.size();
size_t fileTotalSize = mappedFile.size();

// Ensure we at least have a SHA1::Digest to read.
if (fileTotalSize < sizeof(SHA1::Digest)) {
FileSystem::deleteFile(cacheFilename);
return;
}

unsigned fileDataSize = fileTotalSize - sizeof(SHA1::Digest);
size_t fileDataSize = fileTotalSize - sizeof(SHA1::Digest);

SHA1::Digest computedHash;
SHA1 sha1;
Expand All @@ -198,7 +198,7 @@ - (void)readCache
Ref<JSC::CachedBytecode> cachedBytecode = JSC::CachedBytecode::create(WTFMove(mappedFile));

JSC::VM& vm = *toJS([m_virtualMachine JSContextGroupRef]);
JSC::SourceCode sourceCode = [self sourceCode];
JSC::SourceCode sourceCode = self.sourceCode;
JSC::SourceCodeKey key = m_type == kJSScriptTypeProgram ? sourceCodeKeyForSerializedProgram(vm, sourceCode) : sourceCodeKeyForSerializedModule(vm, sourceCode);
if (isCachedBytecodeStillValid(vm, cachedBytecode.copyRef(), key, m_type == kJSScriptTypeProgram ? JSC::SourceCodeType::ProgramType : JSC::SourceCodeType::ModuleType))
m_cachedBytecode = WTFMove(cachedBytecode);
Expand Down Expand Up @@ -269,7 +269,7 @@ - (unsigned)hash
JSC::JSLockHolder locker(vm);

TextPosition startPosition { };
String filename = String { [[self sourceURL] absoluteString] };
String filename = String { self.sourceURL.absoluteString };
URL url = URL({ }, filename);
auto type = m_type == kJSScriptTypeModule ? JSC::SourceProviderSourceType::Module : JSC::SourceProviderSourceType::Program;
JSC::SourceOrigin origin(url);
Expand All @@ -282,7 +282,7 @@ - (unsigned)hash
{
JSC::VM& vm = *toJS([m_virtualMachine JSContextGroupRef]);
JSC::JSLockHolder locker(vm);
JSC::JSSourceCode* jsSourceCode = JSC::JSSourceCode::create(vm, [self sourceCode]);
JSC::JSSourceCode* jsSourceCode = JSC::JSSourceCode::create(vm, self.sourceCode);
return jsSourceCode;
}

Expand All @@ -302,7 +302,7 @@ - (BOOL)writeCache:(String&)error
// or nothing). So, we'll write to a temp file first, and rename the temp
// file to the cache file only after we've finished writing the whole thing.

NSString *cachePathString = [m_cachePath path];
NSString *cachePathString = m_cachePath.get().path;
const char* cacheFileName = cachePathString.UTF8String;
const char* tempFileName = [cachePathString stringByAppendingString:@".tmp"].UTF8String;
int fd = open(cacheFileName, O_CREAT | O_WRONLY | O_EXLOCK | O_NONBLOCK, 0600);
Expand All @@ -326,7 +326,7 @@ - (BOOL)writeCache:(String&)error
});

JSC::BytecodeCacheError cacheError;
JSC::SourceCode sourceCode = [self sourceCode];
JSC::SourceCode sourceCode = self.sourceCode;
JSC::VM& vm = *toJS([m_virtualMachine JSContextGroupRef]);
switch (m_type) {
case kJSScriptTypeModule:
Expand Down
10 changes: 5 additions & 5 deletions Source/JavaScriptCore/API/JSScriptInternal.h
Expand Up @@ -44,11 +44,11 @@ class String;
@interface JSScript(Internal)

- (instancetype)init;
- (unsigned)hash;
- (const WTF::String&)source;
- (RefPtr<JSC::CachedBytecode>)cachedBytecode;
- (JSC::JSSourceCode*)jsSourceCode;
- (JSC::SourceCode)sourceCode;
@property (nonatomic, readonly) unsigned hash;
@property (nonatomic, readonly) const WTF::String& source;
@property (nonatomic, readonly) RefPtr<JSC::CachedBytecode> cachedBytecode;
@property (nonatomic, readonly) JSC::JSSourceCode *jsSourceCode;
@property (nonatomic, readonly) JSC::SourceCode sourceCode;
- (BOOL)writeCache:(String&)error;

@end
Expand Down
6 changes: 3 additions & 3 deletions Source/JavaScriptCore/API/JSScriptSourceProvider.mm
Expand Up @@ -33,17 +33,17 @@

unsigned JSScriptSourceProvider::hash() const
{
return [m_script.get() hash];
return m_script.get().hash;
}

StringView JSScriptSourceProvider::source() const
{
return [m_script.get() source];
return m_script.get().source;
}

RefPtr<JSC::CachedBytecode> JSScriptSourceProvider::cachedBytecode() const
{
return [m_script.get() cachedBytecode];
return m_script.get().cachedBytecode;
}

#endif // JSC_OBJC_API_ENABLED

0 comments on commit 7f1fd02

Please sign in to comment.