WebKit Bugzilla
Attachment 362364 Details for
Bug 194517
: Update JSScript SPI based on feedback
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
WIP
b-backup.diff (text/plain), 34.08 KB, created by
Saam Barati
on 2019-02-18 20:01:00 PST
(
hide
)
Description:
WIP
Filename:
MIME Type:
Creator:
Saam Barati
Created:
2019-02-18 20:01:00 PST
Size:
34.08 KB
patch
obsolete
>Index: Source/JavaScriptCore/config.h >=================================================================== >--- Source/JavaScriptCore/config.h (revision 241740) >+++ Source/JavaScriptCore/config.h (working copy) >@@ -25,6 +25,7 @@ > > #define JSC_API_AVAILABLE(...) > #define JSC_CLASS_AVAILABLE(...) JS_EXPORT >+#define JSC_API_DEPRECATED(...) > // Use zero since it will be less than any possible version number. > #define JSC_MAC_VERSION_TBA 0 > #define JSC_IOS_VERSION_TBA 0 >Index: Source/JavaScriptCore/API/JSAPIGlobalObject.h >=================================================================== >--- Source/JavaScriptCore/API/JSAPIGlobalObject.h (revision 241740) >+++ Source/JavaScriptCore/API/JSAPIGlobalObject.h (working copy) >@@ -27,6 +27,9 @@ > > #include "JSGlobalObject.h" > >+OBJC_CLASS JSScript; >+OBJC_CLASS NSURL; >+ > namespace JSC { > > class JSAPIGlobalObject : public JSGlobalObject { >@@ -55,6 +58,8 @@ public: > static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); > static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue); > >+ JSValue loadAndEvaluateJSScriptModule(JSScript *script, NSURL *url); >+ > private: > JSAPIGlobalObject(VM& vm, Structure* structure) > : Base(vm, structure, &s_globalObjectMethodTable) >Index: Source/JavaScriptCore/API/JSAPIGlobalObject.mm >=================================================================== >--- Source/JavaScriptCore/API/JSAPIGlobalObject.mm (revision 241740) >+++ Source/JavaScriptCore/API/JSAPIGlobalObject.mm (working copy) >@@ -34,8 +34,10 @@ > #import "Error.h" > #import "Exception.h" > #import "JSContextInternal.h" >+#import "JSInternalPromise.h" > #import "JSInternalPromiseDeferred.h" > #import "JSNativeStdFunction.h" >+#import "JSPromiseDeferred.h" > #import "JSScriptInternal.h" > #import "JSSourceCode.h" > #import "JSValueInternal.h" >@@ -162,9 +164,9 @@ JSInternalPromise* JSAPIGlobalObject::mo > return deferred->reject(exec, createError(exec, "No module loader provided.")); > > auto deferredPromise = Strong<JSInternalPromiseDeferred>(vm, deferred); >- auto strongKey = Strong<JSString>(vm, jsSecureCast<JSString*>(vm, key)); > auto* resolve = JSNativeStdFunction::create(vm, globalObject, 1, "resolve", [=] (ExecState* exec) { > // This captures the globalObject but that's ok because our structure keeps it alive anyway. >+ VM& vm = exec->vm(); > JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())]; > id script = valueToObject(context, toRef(exec, exec->argument(0))); > >@@ -175,7 +177,15 @@ JSInternalPromise* JSAPIGlobalObject::mo > return encodedJSUndefined(); > } > >- args.append([static_cast<JSScript *>(script) jsSourceCode:moduleKey]); >+ JSSourceCode* source = [static_cast<JSScript *>(script) jsSourceCode:moduleKey]; >+ const String& oldModuleKey = source->sourceCode().provider()->sourceOrigin().string(); >+ if (UNLIKELY(Identifier::fromString(&vm, oldModuleKey) != moduleKey)) { >+ args.append(createTypeError(exec, makeString("The same JSScript was provided for two different identifiers, previously: ", oldModuleKey, " and now: ", moduleKey.string()))); >+ call(exec, deferredPromise->JSPromiseDeferred::reject(), args, "This should never be seen..."); >+ return encodedJSUndefined(); >+ } >+ >+ args.append(source); > call(exec, deferredPromise->JSPromiseDeferred::resolve(), args, "This should never be seen..."); > return encodedJSUndefined(); > }); >@@ -210,6 +220,21 @@ JSObject* JSAPIGlobalObject::moduleLoade > return metaProperties; > } > >+JSValue JSAPIGlobalObject::loadAndEvaluateJSScriptModule(JSScript *script, NSURL *url) >+{ >+ ASSERT(script.type == kJSScriptTypeModule); >+ VM& vm = this->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ auto key = Identifier::fromString(&vm, [url absoluteString]); >+ JSInternalPromise* promise = loadAndEvaluateModule(globalExec(), [script jsSourceCode:key]->sourceCode(), jsUndefined()); >+ RETURN_IF_EXCEPTION(scope, { }); >+ auto result = JSPromiseDeferred::tryCreate(globalExec(), this); >+ RETURN_IF_EXCEPTION(scope, { }); >+ result->resolve(globalExec(), promise); >+ return result; >+} >+ > } > > #endif // JSC_OBJC_API_ENABLED >Index: Source/JavaScriptCore/API/JSBase.cpp >=================================================================== >--- Source/JavaScriptCore/API/JSBase.cpp (revision 241740) >+++ Source/JavaScriptCore/API/JSBase.cpp (working copy) >@@ -47,25 +47,12 @@ > > using namespace JSC; > >-JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) >+JSValueRef JSEvaluateScriptInternal(const JSLockHolder&, ExecState* exec, JSContextRef ctx, JSObjectRef thisObject, const SourceCode& source, JSValueRef* exception) > { >- if (!ctx) { >- ASSERT_NOT_REACHED(); >- return 0; >- } >- ExecState* exec = toJS(ctx); >- VM& vm = exec->vm(); >- JSLockHolder locker(vm); >- > JSObject* jsThisObject = toJS(thisObject); > >- startingLineNumber = std::max(1, startingLineNumber); >- > // evaluate sets "this" to the global object if it is NULL > JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec); >- auto sourceURLString = sourceURL ? sourceURL->string() : String(); >- SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, URL({ }, sourceURLString), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); >- > NakedPtr<Exception> evaluationException; > JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException); > >@@ -90,6 +77,24 @@ JSValueRef JSEvaluateScript(JSContextRef > return toRef(exec, jsUndefined()); > } > >+JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) >+{ >+ if (!ctx) { >+ ASSERT_NOT_REACHED(); >+ return 0; >+ } >+ ExecState* exec = toJS(ctx); >+ VM& vm = exec->vm(); >+ JSLockHolder locker(vm); >+ >+ startingLineNumber = std::max(1, startingLineNumber); >+ >+ auto sourceURLString = sourceURL ? sourceURL->string() : String(); >+ SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, URL({ }, sourceURLString), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); >+ >+ return JSEvaluateScriptInternal(locker, exec, ctx, thisObject, source, exception); >+} >+ > bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) > { > if (!ctx) { >Index: Source/JavaScriptCore/API/JSContext.mm >=================================================================== >--- Source/JavaScriptCore/API/JSContext.mm (revision 241740) >+++ Source/JavaScriptCore/API/JSContext.mm (working copy) >@@ -103,17 +103,37 @@ - (JSValue *)evaluateScript:(NSString *) > return [self evaluateScript:script withSourceURL:nil]; > } > >-- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL >+static JSValue *evaluateScript(JSContext *context, RefPtr<OpaqueJSString> source, RefPtr<OpaqueJSString> url) > { > JSValueRef exceptionValue = nullptr; >+ JSValueRef result = JSEvaluateScript(context->m_context, source.get(), nullptr, url.get(), 0, &exceptionValue); >+ >+ if (exceptionValue) >+ return [context valueFromNotifyException:exceptionValue]; >+ return [JSValue valueWithJSValueRef:result inContext:context]; >+} >+ >+- (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL >+{ > auto scriptJS = OpaqueJSString::tryCreate(script); > auto sourceURLJS = OpaqueJSString::tryCreate([sourceURL absoluteString]); >- JSValueRef result = JSEvaluateScript(m_context, scriptJS.get(), nullptr, sourceURLJS.get(), 0, &exceptionValue); >+ return evaluateScript(self, scriptJS, sourceURLJS); >+} > >- if (exceptionValue) >- return [self valueFromNotifyException:exceptionValue]; >+- (JSValue *)evaluateJSScript:(JSScript *)script withSourceURL:(NSURL *)url >+{ >+ if (script.type == kJSScriptTypeProgram) { >+ String source = [script source]; >+ return evaluateScript(self, OpaqueJSString::tryCreate(WTFMove(source)), OpaqueJSString::tryCreate([url absoluteString])); >+ } >+ >+ JSC::ExecState* exec = toJS(m_context); >+ JSC::VM& vm = exec->vm(); >+ auto* globalObject = JSC::jsDynamicCast<JSC::JSAPIGlobalObject*>(vm, exec->lexicalGlobalObject()); >+ if (!globalObject) >+ return [JSValue valueWithNewPromiseRejectedWithReason:[JSValue valueWithNewErrorFromMessage:@"Context does not support module loading" inContext:self] inContext:self]; > >- return [JSValue valueWithJSValueRef:result inContext:self]; >+ return [JSValue valueWithJSValueRef:toRef(vm, globalObject->loadAndEvaluateJSScriptModule(script, url)) inContext:self]; > } > > - (void)setException:(JSValue *)value >@@ -300,6 +320,11 @@ - (BOOL)boolFromNotifyException:(JSValue > return NO; > } > >+- (JSValue *)valueFromNotifyExceptionWithString:(String&)string >+{ >+ return [self valueFromNotifyException:[JSValue valueWithNewErrorFromMessage:string inContext:self].JSValueRef]; >+} >+ > - (void)beginCallbackWithData:(CallbackData *)callbackData calleeValue:(JSValueRef)calleeValue thisValue:(JSValueRef)thisValue argumentCount:(size_t)argumentCount arguments:(const JSValueRef *)arguments > { > Thread& thread = Thread::current(); >Index: Source/JavaScriptCore/API/JSContextPrivate.h >=================================================================== >--- Source/JavaScriptCore/API/JSContextPrivate.h (revision 241740) >+++ Source/JavaScriptCore/API/JSContextPrivate.h (working copy) >@@ -74,6 +74,16 @@ > /*! @abstract The delegate the context will use when trying to load a module. Note, this delegate will be ignored for contexts returned by UIWebView. */ > @property (nonatomic, weak) id <JSModuleLoaderDelegate> moduleLoaderDelegate JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)); > >+/*! >+ @method >+ @abstract Run a JSScript. >+ @param script the JSScript to evaluate. >+ @discussion If the provided JSScript was created with JSScriptTypeProgram, the script will run synchronously and return the result of evaluation. >+ >+ Otherwise, if the script was created with JSScriptTypeModule, the module will be run asynchronously and will return a promise resolved when the module and any transitive dependencies are loaded. The module loader will treat the script as if it had been returned from a delegate call to moduleLoaderDelegate with its identefier as url. This mirrors the JavaScript dynamic import operation. >+ */ >+- (JSValue *)evaluateJSScript:(JSScript *)script withSourceURL:(NSURL *)url; >+ > @end > > #endif >Index: Source/JavaScriptCore/API/JSScript.h >=================================================================== >--- Source/JavaScriptCore/API/JSScript.h (revision 241740) >+++ Source/JavaScriptCore/API/JSScript.h (working copy) >@@ -31,6 +31,18 @@ NS_ASSUME_NONNULL_BEGIN > > @class JSVirtualMachine; > >+/*! >+ @enum JSScriptType >+ @abstract A constant identifying the execution type of a JSScript. >+ @constant kJSScriptTypeProgram The type of a normal JavaScript program. >+ @constant kJSScriptTypeModule The type of a module JavaScript program. >+ */ >+typedef NS_ENUM(NSInteger, JSScriptType) { >+ kJSScriptTypeProgram, >+ kJSScriptTypeModule, >+}; >+ >+ > JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)) > @interface JSScript : NSObject > >@@ -41,7 +53,7 @@ JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), > @param vm The JSVirtualMachine the script can be evaluated in. > @result The new script. > */ >-+ (nullable instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm; >++ (nullable instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm JSC_API_DEPRECATED(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)); > > /*! > @method >@@ -55,13 +67,44 @@ JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), > > If the file at filePath is not ascii this method will return nil. > */ >-+ (nullable instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath; >- >++ (nullable instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath JSC_API_DEPRECATED(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)); > > /*! > This is deprecated and is equivalent to scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:. > */ >-+ (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath; >++ (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath JSC_API_DEPRECATED(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)); >+ >+/*! >+ @method >+ @abstract Create a JSScript for the specified virtual machine. >+ @param type The type of JavaScript source. >+ @param source The source code to use when the script is evaluated by the JS vm. >+ @param vm The JSVirtualMachine the script can be evaluated in. >+ @param cachePath A URL containing the path where the VM should cache for future execution. >+ @param error A description of why the script could not be created if the result is nil. >+ @result The new script. >+ */ >++ (nullable instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm andBytecodeCache:(nullable NSURL *)cachePath error:(out NSError * _Nullable * _Nullable)error; >+ >+/*! >+ @method >+ @abstract Create a JSScript for the specified virtual machine with a path to a codesigning and bytecode caching. >+ @param type The type of JavaScript source. >+ @param filePath A URL containing the path to a JS source code file on disk. >+ @param vm The JSVirtualMachine the script can be evaluated in. >+ @param cachePath A URL containing the path where the VM should cache for future execution. >+ @param error A description of why the script could not be created if the result is nil. >+ @result The new script. >+ @discussion The files at filePath and cachePath should not be externally modified for the lifecycle of vm. This method will file back the memory for the source. >+ >+ If the file at filePath is not ascii this method will return nil. >+ */ >++ (nullable instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm andBytecodeCache:(nullable NSURL *)cachePath error:(out NSError * _Nullable * _Nullable)error; >+ >+/*! @abstract The type of script provided during creation. */ >+@property (readonly) JSScriptType type; >+ >+- (BOOL)cacheBytecodeWithError:(out NSError * _Nullable * _Nullable)error; > > @end > >Index: Source/JavaScriptCore/API/JSScript.mm >=================================================================== >--- Source/JavaScriptCore/API/JSScript.mm (revision 241740) >+++ Source/JavaScriptCore/API/JSScript.mm (working copy) >@@ -36,11 +36,14 @@ > #import "ParserError.h" > #import "Symbol.h" > #include <sys/stat.h> >+#include <wtf/FileSystem.h> > > #if JSC_OBJC_API_ENABLED > > @implementation JSScript { > __weak JSVirtualMachine* m_virtualMachine; >+ JSScriptType m_type; >+ FileSystem::MappedFileData m_mappedSource; > String m_source; > RetainPtr<NSURL> m_cachePath; > JSC::CachedBytecode m_cachedBytecode; >@@ -116,6 +119,50 @@ + (instancetype)scriptFromUTF8File:(NSUR > return [JSScript scriptFromASCIIFile:filePath inVirtualMachine:vm withCodeSigning:codeSigningPath andBytecodeCache:cachePath]; > } > >+static JSScript *createError(NSString *message, NSError** error) >+{ >+ if (error) >+ *error = [NSError errorWithDomain:@"JSScriptErrorDomain" code:1 userInfo:@{ @"message": message }]; >+ return nil; >+} >+ >++ (instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm andBytecodeCache:(NSURL *)cachePath error:(NSError **)error >+{ >+ UNUSED_PARAM(error); >+ JSScript *result = [[[JSScript alloc] init] autorelease]; >+ result->m_virtualMachine = vm; >+ result->m_type = type; >+ result->m_source = source; >+ result->m_cachePath = cachePath; >+ return result; >+} >+ >++ (instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm andBytecodeCache:(NSURL *)cachePath error:(NSError **)error >+{ >+ UNUSED_PARAM(error); >+ URL filePathURL([filePath absoluteURL]); >+ if (!filePathURL.isLocalFile()) >+ return createError([NSString stringWithFormat:@"File path %@ is not a local file", static_cast<NSString *>(filePathURL)], error); >+ >+ bool success = false; >+ String systemPath = filePathURL.fileSystemPath(); >+ FileSystem::MappedFileData fileData(systemPath, success); >+ if (!success) >+ return createError([NSString stringWithFormat:@"File at path %@ could not be mapped.", static_cast<NSString *>(systemPath)], error); >+ >+ if (!charactersAreAllASCII(reinterpret_cast<const LChar*>(fileData.data()), fileData.size())) >+ return createError([NSString stringWithFormat:@"Not all characters in file at %@ are ASCII.", static_cast<NSString *>(systemPath)], error); >+ >+ JSScript *result = [[[JSScript alloc] init] autorelease]; >+ result->m_virtualMachine = vm; >+ result->m_type = type; >+ result->m_source = String(StringImpl::createWithoutCopying(reinterpret_cast<const LChar*>(fileData.data()), fileData.size())); >+ result->m_mappedSource = WTFMove(fileData); >+ result->m_cachePath = cachePath; >+ [result readCache]; >+ return result; >+} >+ > - (void)dealloc > { > if (m_cachedBytecode.size() && !m_cachedBytecode.owned()) >@@ -152,22 +199,14 @@ - (void)readCache > m_cachedBytecode = JSC::CachedBytecode { buffer, size }; > } > >-- (void)writeCache >+- (BOOL)cacheBytecodeWithError:(NSError **)error > { >- if (m_cachedBytecode.size() || !m_cachePath) >- return; >- >- JSC::ParserError error; >- m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, m_jsSourceCode->sourceCode(), error); >- if (error.isValid()) >- return; >- int fd = open([m_cachePath path].UTF8String, O_CREAT | O_WRONLY, 0666); >- if (fd == -1) >- return; >- int rc = flock(fd, LOCK_EX | LOCK_NB); >- if (!rc) >- write(fd, m_cachedBytecode.data(), m_cachedBytecode.size()); >- close(fd); >+ String errorString { }; >+ [self writeCache:errorString]; >+ if (!errorString.isNull()) >+ return !!createError(errorString, error); >+ >+ return YES; > } > > @end >@@ -191,10 +230,8 @@ - (const JSC::CachedBytecode*)cachedByte > > - (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey > { >- if (m_jsSourceCode) { >- ASSERT(moduleKey.impl() == m_moduleKey); >+ if (m_jsSourceCode) > return m_jsSourceCode.get(); >- } > > JSC::VM& vm = m_virtualMachine.vm; > TextPosition startPosition { }; >@@ -202,10 +239,40 @@ - (JSC::JSSourceCode*)jsSourceCode:(cons > JSC::SourceCode sourceCode(WTFMove(sourceProvider), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt()); > JSC::JSSourceCode* jsSourceCode = JSC::JSSourceCode::create(vm, WTFMove(sourceCode)); > m_jsSourceCode.set(vm, jsSourceCode); >- [self writeCache]; > return jsSourceCode; > } > >+- (BOOL)writeCache:(String&)error >+{ >+ >+ if (m_cachedBytecode.size()) >+ return YES; >+ >+ if (!m_cachePath) { >+ error = "no cache path provided"; >+ return NO; >+ } >+ >+ JSC::ParserError parserError; >+ auto key = JSC::Identifier::fromString(&m_virtualMachine.vm, "API Placeholder string"_s); >+ m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, [self jsSourceCode:key]->sourceCode(), parserError); >+ if (parserError.isValid()) { >+ error = "unable to generate complete bytecode"; >+ return NO; >+ } >+ int fd = open([m_cachePath path].UTF8String, O_CREAT | O_WRONLY, 0666); >+ if (fd == -1) { >+ error = makeString("Unable to open file: ", [m_cachePath path].UTF8String, " due to error: ", strerror(errno)); >+ return NO; >+ } >+ int returnCode = flock(fd, LOCK_EX | LOCK_NB); >+ if (returnCode) >+ error = "Unable to lock the cache file; it may already be in use."; >+ else >+ write(fd, m_cachedBytecode.data(), m_cachedBytecode.size()); >+ close(fd); >+ return !returnCode; >+} > @end > > >Index: Source/JavaScriptCore/API/JSScriptInternal.h >=================================================================== >--- Source/JavaScriptCore/API/JSScriptInternal.h (revision 241740) >+++ Source/JavaScriptCore/API/JSScriptInternal.h (working copy) >@@ -48,6 +48,7 @@ class String; > - (const WTF::String&)source; > - (const JSC::CachedBytecode*)cachedBytecode; > - (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey; >+- (BOOL)writeCache:(String&)error; > > @end > >Index: Source/JavaScriptCore/API/tests/testIncludes.m >=================================================================== >--- Source/JavaScriptCore/API/tests/testIncludes.m (revision 241740) >+++ Source/JavaScriptCore/API/tests/testIncludes.m (working copy) >@@ -27,6 +27,7 @@ > // Since we include files that haven't passed through the rewriter we need to handle the non-rewritten values... > #define JSC_API_AVAILABLE(...) > #define JSC_CLASS_AVAILABLE(...) >+#define JSC_API_DEPRECATED(...) > #define JSC_MAC_VERSION_TBA 0 > #define JSC_IOS_VERSION_TBA 0 > >Index: Source/JavaScriptCore/API/tests/testapi.c >=================================================================== >--- Source/JavaScriptCore/API/tests/testapi.c (revision 241740) >+++ Source/JavaScriptCore/API/tests/testapi.c (working copy) >@@ -67,7 +67,7 @@ > #endif > > #if JSC_OBJC_API_ENABLED >-void testObjectiveCAPI(void); >+void testObjectiveCAPI(const char*); > #endif > > int testCAPIViaCpp(const char* filter); >@@ -1380,11 +1380,11 @@ int main(int argc, char* argv[]) > SetErrorMode(0); > #endif > >+ const char* filter = argc > 1 ? argv[1] : NULL; > #if JSC_OBJC_API_ENABLED >- testObjectiveCAPI(); >+ testObjectiveCAPI(filter); > #endif > >- const char* filter = argc > 1 ? argv[1] : NULL; > RELEASE_ASSERT(!testCAPIViaCpp(filter)); > if (filter) > return 0; >Index: Source/JavaScriptCore/API/tests/testapi.mm >=================================================================== >--- Source/JavaScriptCore/API/tests/testapi.mm (revision 241740) >+++ Source/JavaScriptCore/API/tests/testapi.mm (working copy) >@@ -41,12 +41,14 @@ > #import "Regress141275.h" > #import "Regress141809.h" > >+#import <libproc.h> > #import <pthread.h> > #import <vector> > #import <wtf/MemoryFootprint.h> > #import <wtf/Optional.h> > #import <wtf/DataLog.h> > >+ > extern "C" void JSSynchronousGarbageCollectForDebugging(JSContextRef); > extern "C" void JSSynchronousEdenCollectForDebugging(JSContextRef); > >@@ -54,7 +56,7 @@ extern "C" bool _Block_has_signature(id) > extern "C" const char * _Block_signature(id); > > extern int failed; >-extern "C" void testObjectiveCAPI(void); >+extern "C" void testObjectiveCAPI(const char*); > extern "C" void checkResult(NSString *, bool); > > #if JSC_OBJC_API_ENABLED >@@ -1985,9 +1987,9 @@ static void testBytecodeCache() > @autoreleasepool { > NSURL* tempDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; > >- NSString* fooSource = @"import { n } from \"../foo.js\"; export let foo = n;"; >- NSString* barSource = @"import \"otherDirectory/baz.js\"; export let n = null;"; >- NSString* bazSource = @"import { foo } from \"../directory/bar.js\"; globalThis.ran = null; export let exp = foo;"; >+ NSString* fooSource = @"import \"otherDirectory/baz.js\"; export let n = null;"; >+ NSString* barSource = @"import { n } from \"../foo.js\"; export let foo = () => n;"; >+ NSString* bazSource = @"import { foo } from \"../directory/bar.js\"; globalThis.ran = null; export let exp = foo();"; > > NSURL* fooPath = [tempDirectory URLByAppendingPathComponent:@"foo.js"]; > NSURL* barPath = [tempDirectory URLByAppendingPathComponent:@"bar.js"]; >@@ -2023,12 +2025,14 @@ static void testBytecodeCache() > } > > NSFileManager* fileManager = [NSFileManager defaultManager]; >- [fileManager removeItemAtURL:fooPath error:nil]; >- [fileManager removeItemAtURL:barPath error:nil]; >- [fileManager removeItemAtURL:bazPath error:nil]; >- [fileManager removeItemAtURL:fooCachePath error:nil]; >- [fileManager removeItemAtURL:barCachePath error:nil]; >- [fileManager removeItemAtURL:bazCachePath error:nil]; >+ BOOL removedAll = true; >+ removedAll &= [fileManager removeItemAtURL:fooPath error:nil]; >+ removedAll &= [fileManager removeItemAtURL:barPath error:nil]; >+ removedAll &= [fileManager removeItemAtURL:bazPath error:nil]; >+ removedAll &= [fileManager removeItemAtURL:fooCachePath error:nil]; >+ removedAll &= [fileManager removeItemAtURL:barCachePath error:nil]; >+ removedAll &= [fileManager removeItemAtURL:bazCachePath error:nil]; >+ checkResult(@"Removed all temp files created", removedAll); > } > } > >@@ -2078,7 +2082,7 @@ - (void)context:(JSContext *)context fet > > @end > >-static void testLoadBasicFile() >+static void testLoadBasicFileLegacySPI() > { > @autoreleasepool { > auto *context = [JSContextFileLoaderDelegate newContext]; >@@ -2089,34 +2093,118 @@ static void testLoadBasicFile() > } > } > >-void testObjectiveCAPI() >+ >+@interface JSContextMemoryMappedLoaderDelegate : JSContext <JSModuleLoaderDelegate> >+ >++ (instancetype)newContext; >+ >+@end >+ >+@implementation JSContextMemoryMappedLoaderDelegate { >+} >+ >++ (instancetype)newContext >+{ >+ auto *result = [[JSContextMemoryMappedLoaderDelegate alloc] init]; >+ return result; >+} >+ >+- (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject >+{ >+ NSURL *filePath = [NSURL URLWithString:[identifier toString]]; >+ auto *script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:filePath inVirtualMachine:context.virtualMachine andBytecodeCache:nil error:nil]; >+ if (script) >+ [resolve callWithArguments:@[script]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Unable to create Script" inContext:context]]]; >+} >+ >+@end >+ >+static void testLoadBasicFile() >+{ >+ size_t count = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); >+ @autoreleasepool { >+ auto *context = [JSContextMemoryMappedLoaderDelegate newContext]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('./basic.js');" withSourceURL:resolvePathToScripts()]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ size_t afterCount = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); >+ checkResult(@"JSScript should not hold a file descriptor", count == afterCount); >+ checkModuleCodeRan(context, promise, null); >+ } >+ size_t after = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); >+ checkResult(@"File descriptor count sholudn't change after context is dealloced", count == after); >+} >+ >+static void testJSScriptURL() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextMemoryMappedLoaderDelegate newContext]; >+ context.moduleLoaderDelegate = context; >+ NSURL *url = [NSURL URLWithString:@"./basic.js" relativeToURL:resolvePathToScripts()]; >+ JSScript *script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:url inVirtualMachine:context.virtualMachine andBytecodeCache:nil error:nil]; >+ >+ JSValue *result1 = [context evaluateJSScript:script withSourceURL:[NSURL fileURLWithPath:@"/foo/bar.js"]]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, result1, null); >+ >+ JSValue *result2 = [context evaluateJSScript:script withSourceURL:[NSURL fileURLWithPath:@"/foo/baz.js"]]; >+ >+ __block bool wasRejected = false; >+ [result2 invokeMethod:@"catch" withArguments:@[^(JSValue *reason) { >+ wasRejected = [reason isObject]; >+ }]]; >+ >+ checkResult(@"Module JSScript imported with different identifiers is rejected", wasRejected); >+ } >+} >+ >+#define RUN(test) do { \ >+ if (!shouldRun(#test)) \ >+ break; \ >+ NSLog(@"%s...\n", #test); \ >+ test; \ >+ NSLog(@"%s: done.\n", #test); \ >+ } while (false) >+ >+void testObjectiveCAPI(const char* filter) > { > NSLog(@"Testing Objective-C API"); > >- checkNegativeNSIntegers(); >- runJITThreadLimitTests(); >+ auto shouldRun = [&] (const char* test) -> bool { >+ if (filter) >+ return strcasestr(test, filter); >+ return true; >+ }; >+ >+ RUN(checkNegativeNSIntegers()); >+ RUN(runJITThreadLimitTests()); >+ >+ RUN(testLoaderResolvesAbsoluteScriptURL()); >+ RUN(testFetch()); >+ RUN(testFetchWithTwoCycle()); >+ RUN(testFetchWithThreeCycle()); >+ RUN(testImportModuleTwice()); >+ RUN(testBytecodeCache()); > >- testLoaderResolvesAbsoluteScriptURL(); >- testFetch(); >- testFetchWithTwoCycle(); >- testFetchWithThreeCycle(); >- testImportModuleTwice(); >- testBytecodeCache(); >+ RUN(testLoaderRejectsNilScriptURL()); >+ RUN(testLoaderRejectsFailedFetch()); > >- testLoaderRejectsNilScriptURL(); >- testLoaderRejectsFailedFetch(); >+ RUN(testJSScriptURL()); > > // File loading >- testLoadBasicFile(); >+ RUN(testLoadBasicFileLegacySPI()); >+ RUN(testLoadBasicFile()); > >- promiseWithExecutor(Resolution::ResolveEager); >- promiseWithExecutor(Resolution::RejectEager); >- promiseWithExecutor(Resolution::ResolveLate); >- promiseWithExecutor(Resolution::RejectLate); >- promiseRejectOnJSException(); >- promiseCreateResolved(); >- promiseCreateRejected(); >- parallelPromiseResolveTest(); >+ RUN(promiseWithExecutor(Resolution::ResolveEager)); >+ RUN(promiseWithExecutor(Resolution::RejectEager)); >+ RUN(promiseWithExecutor(Resolution::ResolveLate)); >+ RUN(promiseWithExecutor(Resolution::RejectLate)); >+ RUN(promiseRejectOnJSException()); >+ RUN(promiseCreateResolved()); >+ RUN(promiseCreateRejected()); >+ RUN(parallelPromiseResolveTest()); > > testObjectiveCAPIMain(); > } >Index: Source/JavaScriptCore/runtime/CachedTypes.cpp >=================================================================== >--- Source/JavaScriptCore/runtime/CachedTypes.cpp (revision 241740) >+++ Source/JavaScriptCore/runtime/CachedTypes.cpp (working copy) >@@ -215,9 +215,10 @@ class Decoder { > WTF_FORBID_HEAP_ALLOCATION; > > public: >- Decoder(VM& vm, const void* baseAddress, size_t size) >+ Decoder(VM& vm, const void* baseAddress, size_t size, URL&& sourceURLOverride) > : m_vm(vm) > , m_baseAddress(reinterpret_cast<const uint8_t*>(baseAddress)) >+ , m_sourceURLOverride(WTFMove(sourceURLOverride)) > #ifndef NDEBUG > , m_size(size) > #endif >@@ -259,9 +260,12 @@ public: > m_finalizers.add(offset, fn); > } > >+ const URL& sourceURLOverride() { return m_sourceURLOverride; } >+ > private: > VM& m_vm; > const uint8_t* m_baseAddress; >+ URL m_sourceURLOverride; > #ifndef NDEBUG > size_t m_size; > #endif >@@ -1301,10 +1305,16 @@ public: > { > String decodedSource = m_source.decode(decoder); > SourceOrigin decodedSourceOrigin = m_sourceOrigin.decode(decoder); >- String decodedURL = m_url.decode(decoder); >+ String decodedURLString = m_url.decode(decoder); >+ URL sourceURL; >+ if (decoder.sourceURLOverride()) { >+ decodedSourceOrigin = SourceOrigin { decoder.sourceURLOverride() }; >+ sourceURL = decoder.sourceURLOverride(); >+ } else >+ sourceURL = URL(URL(), decodedURLString); > TextPosition decodedStartPosition = m_startPosition.decode(decoder); > >- Ref<StringSourceProvider> sourceProvider = StringSourceProvider::create(decodedSource, decodedSourceOrigin, URL(URL(), decodedURL), decodedStartPosition, sourceType); >+ Ref<StringSourceProvider> sourceProvider = StringSourceProvider::create(decodedSource, decodedSourceOrigin, WTFMove(sourceURL), decodedStartPosition, sourceType); > Base::decode(decoder, sourceProvider.get()); > return &sourceProvider.leakRef(); > } >@@ -2080,10 +2090,10 @@ std::pair<MallocPtr<uint8_t>, size_t> en > return encoder.release(); > } > >-UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, const void* buffer, size_t size) >+UnlinkedCodeBlock* decodeCodeBlockImpl(VM& vm, const SourceCodeKey& key, const void* buffer, size_t size, URL&& sourceURLOverride) > { > const auto* cachedEntry = reinterpret_cast<const GenericCacheEntry*>(buffer); >- Decoder decoder(vm, buffer, size); >+ Decoder decoder(vm, buffer, size, WTFMove(sourceURLOverride)); > std::pair<SourceCodeKey, UnlinkedCodeBlock*> entry; > { > DeferGC deferGC(vm.heap); >Index: Source/JavaScriptCore/runtime/CachedTypes.h >=================================================================== >--- Source/JavaScriptCore/runtime/CachedTypes.h (revision 241740) >+++ Source/JavaScriptCore/runtime/CachedTypes.h (working copy) >@@ -27,6 +27,7 @@ > > #include "JSCast.h" > #include <wtf/MallocPtr.h> >+#include <wtf/URL.h> > > namespace JSC { > >@@ -34,13 +35,13 @@ class SourceCodeKey; > class UnlinkedCodeBlock; > > std::pair<MallocPtr<uint8_t>, size_t> encodeCodeBlock(VM&, const SourceCodeKey&, const UnlinkedCodeBlock*); >-UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, const void*, size_t); >+UnlinkedCodeBlock* decodeCodeBlockImpl(VM&, const SourceCodeKey&, const void*, size_t, URL&&); > > > template<typename UnlinkedCodeBlockType> >-UnlinkedCodeBlockType* decodeCodeBlock(VM& vm, const SourceCodeKey& key, const void* buffer, size_t size) >+UnlinkedCodeBlockType* decodeCodeBlock(VM& vm, const SourceCodeKey& key, const void* buffer, size_t size, URL&& sourceURLOverride = URL()) > { >- return jsCast<UnlinkedCodeBlockType*>(decodeCodeBlockImpl(vm, key, buffer, size)); >+ return jsCast<UnlinkedCodeBlockType*>(decodeCodeBlockImpl(vm, key, buffer, size, WTFMove(sourceURLOverride))); > } > > } // namespace JSC
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Formatted Diff
|
Diff
Attachments on
bug 194517
:
361720
|
361924
|
362351
|
362364
|
362365
|
362414
|
362464
|
362473
|
362579
|
362626
|
362635
|
362644
|
362653
|
362654
|
362656
|
362657
|
362663