Changeset 241929 in webkit
- Timestamp:
- Feb 21, 2019 8:21:54 PM (5 years ago)
- Location:
- trunk/Source/JavaScriptCore
- Files:
-
- 16 edited
- 2 copied
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/API/JSAPIGlobalObject.h
r239933 r241929 28 28 #include "JSGlobalObject.h" 29 29 30 OBJC_CLASS JSScript; 31 30 32 namespace JSC { 31 33 … … 56 58 static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue); 57 59 60 JSValue loadAndEvaluateJSScriptModule(const JSLockHolder&, JSScript *); 61 58 62 private: 59 63 JSAPIGlobalObject(VM& vm, Structure* structure) -
trunk/Source/JavaScriptCore/API/JSAPIGlobalObject.mm
r241172 r241929 35 35 #import "Exception.h" 36 36 #import "JSContextInternal.h" 37 #import "JSInternalPromise.h" 37 38 #import "JSInternalPromiseDeferred.h" 38 39 #import "JSNativeStdFunction.h" 40 #import "JSPromiseDeferred.h" 39 41 #import "JSScriptInternal.h" 40 42 #import "JSSourceCode.h" … … 44 46 #import "ObjectConstructor.h" 45 47 #import "SourceOrigin.h" 46 47 48 #import <wtf/URL.h> 48 49 … … 76 77 String name = key.toWTFString(exec); 77 78 78 URL referrerURL(URL(), jsCast<JSString*>(referrer)->tryGetValue()); 79 RELEASE_ASSERT(referrerURL.isValid()); 80 81 URL url = URL(referrerURL, name); 82 if (url.isValid()) 83 return Identifier::fromString(exec, url); 79 if (JSString* referrerString = jsDynamicCast<JSString*>(vm, referrer)) { 80 String value = referrerString->value(exec); 81 URL referrerURL({ }, value); 82 RETURN_IF_EXCEPTION(scope, { }); 83 RELEASE_ASSERT(referrerURL.isValid()); 84 85 URL url = URL(referrerURL, name); 86 if (url.isValid()) 87 return Identifier::fromString(exec, url); 88 } else { 89 URL url = URL({ }, name); 90 if (url.isValid()) 91 return Identifier::fromString(exec, url); 92 } 84 93 85 94 throwVMError(exec, scope, "Could not form valid URL from identifier and base"_s); … … 163 172 164 173 auto deferredPromise = Strong<JSInternalPromiseDeferred>(vm, deferred); 165 auto strongKey = Strong<JSString>(vm, jsSecureCast<JSString*>(vm, key));166 174 auto* resolve = JSNativeStdFunction::create(vm, globalObject, 1, "resolve", [=] (ExecState* exec) { 167 175 // This captures the globalObject but that's ok because our structure keeps it alive anyway. 176 VM& vm = exec->vm(); 168 177 JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())]; 169 178 id script = valueToObject(context, toRef(exec, exec->argument(0))); 170 179 171 180 MarkedArgumentBuffer args; 172 if (UNLIKELY(![script isKindOfClass:[JSScript class]])) { 173 args.append(createTypeError(exec, "First argument of resolution callback is not a JSScript")); 181 182 auto rejectPromise = [&] (String message) { 183 args.append(createTypeError(exec, message)); 174 184 call(exec, deferredPromise->JSPromiseDeferred::reject(), args, "This should never be seen..."); 175 185 return encodedJSUndefined(); 186 }; 187 188 if (UNLIKELY(![script isKindOfClass:[JSScript class]])) 189 return rejectPromise("First argument of resolution callback is not a JSScript"_s); 190 191 JSScript* jsScript = static_cast<JSScript *>(script); 192 193 JSSourceCode* source = [jsScript jsSourceCode]; 194 if (UNLIKELY([jsScript type] != kJSScriptTypeModule)) 195 return rejectPromise("The JSScript that was provided did not have expected type of kJSScriptTypeModule."_s); 196 197 // FIXME: The SPI we're deprecating did not require sourceURL, so we just 198 // ignore this check for such use cases until we can remove that SPI. Once 199 // we do that, we can remove the null check for sourceURL: 200 // https://bugs.webkit.org/show_bug.cgi?id=194909 201 if (NSURL *sourceURL = [jsScript sourceURL]) { 202 String oldModuleKey { [sourceURL absoluteString] }; 203 if (UNLIKELY(Identifier::fromString(&vm, oldModuleKey) != moduleKey)) 204 return rejectPromise(makeString("The same JSScript was provided for two different identifiers, previously: ", oldModuleKey, " and now: ", moduleKey.string())); 205 } else { 206 [jsScript setSourceURL:[NSURL URLWithString:static_cast<NSString *>(moduleKey.string())]]; 207 source = [jsScript forceRecreateJSSourceCode]; 176 208 } 177 209 178 args.append( [static_cast<JSScript *>(script) jsSourceCode:moduleKey]);210 args.append(source); 179 211 call(exec, deferredPromise->JSPromiseDeferred::resolve(), args, "This should never be seen..."); 180 212 return encodedJSUndefined(); … … 211 243 } 212 244 245 JSValue JSAPIGlobalObject::loadAndEvaluateJSScriptModule(const JSLockHolder&, JSScript *script) 246 { 247 ASSERT(script.type == kJSScriptTypeModule); 248 VM& vm = this->vm(); 249 ExecState* exec = globalExec(); 250 auto scope = DECLARE_THROW_SCOPE(vm); 251 252 Identifier key = Identifier::fromString(exec, String { [[script sourceURL] absoluteString] }); 253 JSInternalPromise* promise = importModule(exec, key, jsUndefined(), jsUndefined()); 254 RETURN_IF_EXCEPTION(scope, { }); 255 auto result = JSPromiseDeferred::tryCreate(exec, this); 256 RETURN_IF_EXCEPTION(scope, { }); 257 result->resolve(exec, promise); 258 return result->promise(); 259 } 260 213 261 } 214 262 -
trunk/Source/JavaScriptCore/API/JSBase.cpp
r239569 r241929 26 26 #include "config.h" 27 27 #include "JSBase.h" 28 #include "JSBaseInternal.h" 28 29 #include "JSBasePrivate.h" 29 30 … … 48 49 using namespace JSC; 49 50 50 JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) 51 { 52 if (!ctx) { 53 ASSERT_NOT_REACHED(); 54 return 0; 55 } 56 ExecState* exec = toJS(ctx); 57 VM& vm = exec->vm(); 58 JSLockHolder locker(vm); 51 JSValueRef JSEvaluateScriptInternal(const JSLockHolder&, ExecState* exec, JSContextRef ctx, JSObjectRef thisObject, const SourceCode& source, JSValueRef* exception) 52 { 53 UNUSED_PARAM(ctx); 59 54 60 55 JSObject* jsThisObject = toJS(thisObject); 61 56 62 startingLineNumber = std::max(1, startingLineNumber);63 64 57 // evaluate sets "this" to the global object if it is NULL 58 VM& vm = exec->vm(); 65 59 JSGlobalObject* globalObject = vm.vmEntryGlobalObject(exec); 66 auto sourceURLString = sourceURL ? sourceURL->string() : String();67 SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, URL({ }, sourceURLString), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber()));68 69 60 NakedPtr<Exception> evaluationException; 70 61 JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException); … … 81 72 globalObject->inspectorController().reportAPIException(exec, evaluationException); 82 73 #endif 83 return 0;74 return nullptr; 84 75 } 85 76 … … 89 80 // happens, for example, when the only statement is an empty (';') statement 90 81 return toRef(exec, jsUndefined()); 82 } 83 84 JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception) 85 { 86 if (!ctx) { 87 ASSERT_NOT_REACHED(); 88 return nullptr; 89 } 90 ExecState* exec = toJS(ctx); 91 VM& vm = exec->vm(); 92 JSLockHolder locker(vm); 93 94 startingLineNumber = std::max(1, startingLineNumber); 95 96 auto sourceURLString = sourceURL ? sourceURL->string() : String(); 97 SourceCode source = makeSource(script->string(), SourceOrigin { sourceURLString }, URL({ }, sourceURLString), TextPosition(OrdinalNumber::fromOneBasedInt(startingLineNumber), OrdinalNumber())); 98 99 return JSEvaluateScriptInternal(locker, exec, ctx, thisObject, source, exception); 91 100 } 92 101 -
trunk/Source/JavaScriptCore/API/JSBaseInternal.h
r241928 r241929 21 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 25 26 #pragma once 26 27 27 // Since we include files that haven't passed through the rewriter we need to handle the non-rewritten values... 28 #define JSC_API_AVAILABLE(...) 29 #define JSC_CLASS_AVAILABLE(...) 30 #define JSC_MAC_VERSION_TBA 0 31 #define JSC_IOS_VERSION_TBA 0 28 #include <JavaScriptCore/JSBase.h> 29 #include <JavaScriptCore/WebKitAvailability.h> 32 30 33 // umbrella header 34 #import <JavaScriptCore/JavaScriptCore.h> 31 namespace JSC { 32 class JSLockHolder; 33 class ExecState; 34 } 35 35 36 // private headers 37 #import <JavaScriptCore/JSContextPrivate.h> 38 #import <JavaScriptCore/JSScript.h> 39 #import <JavaScriptCore/JSValuePrivate.h> 40 #import <JavaScriptCore/JSVirtualMachinePrivate.h> 41 36 extern "C" JSValueRef JSEvaluateScriptInternal(const JSC::JSLockHolder&, JSC::ExecState*, JSContextRef, JSObjectRef thisObject, const JSC::SourceCode&, JSValueRef* exception); -
trunk/Source/JavaScriptCore/API/JSContext.mm
r240511 r241929 28 28 #import "APICast.h" 29 29 #import "Completion.h" 30 #import "JSBaseInternal.h" 30 31 #import "JSCInlines.h" 31 32 #import "JSContextInternal.h" … … 113 114 if (exceptionValue) 114 115 return [self valueFromNotifyException:exceptionValue]; 115 116 116 return [JSValue valueWithJSValueRef:result inContext:self]; 117 } 118 119 - (JSValue *)evaluateJSScript:(JSScript *)script 120 { 121 JSC::ExecState* exec = toJS(m_context); 122 JSC::VM& vm = exec->vm(); 123 JSC::JSLockHolder locker(vm); 124 125 if (script.type == kJSScriptTypeProgram) { 126 JSValueRef exceptionValue = nullptr; 127 JSValueRef result = JSEvaluateScriptInternal(locker, exec, m_context, nullptr, [script jsSourceCode]->sourceCode(), &exceptionValue); 128 129 if (exceptionValue) 130 return [self valueFromNotifyException:exceptionValue]; 131 return [JSValue valueWithJSValueRef:result inContext:self]; 132 } 133 134 auto* globalObject = JSC::jsDynamicCast<JSC::JSAPIGlobalObject*>(vm, exec->lexicalGlobalObject()); 135 if (!globalObject) 136 return [JSValue valueWithNewPromiseRejectedWithReason:[JSValue valueWithNewErrorFromMessage:@"Context does not support module loading" inContext:self] inContext:self]; 137 138 auto scope = DECLARE_CATCH_SCOPE(vm); 139 JSC::JSValue result = globalObject->loadAndEvaluateJSScriptModule(locker, script); 140 if (scope.exception()) { 141 JSValueRef exceptionValue = toRef(exec, scope.exception()->value()); 142 scope.clearException(); 143 return [JSValue valueWithNewPromiseRejectedWithReason:[JSValue valueWithJSValueRef:exceptionValue inContext:self] inContext:self]; 144 } 145 return [JSValue valueWithJSValueRef:toRef(vm, result) inContext:self]; 117 146 } 118 147 -
trunk/Source/JavaScriptCore/API/JSContextPrivate.h
r239933 r241929 75 75 @property (nonatomic, weak) id <JSModuleLoaderDelegate> moduleLoaderDelegate JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)); 76 76 77 /*! 78 @method 79 @abstract Run a JSScript. 80 @param script the JSScript to evaluate. 81 @discussion If the provided JSScript was created with kJSScriptTypeProgram, the script will run synchronously and return the result of evaluation. 82 83 Otherwise, if the script was created with kJSScriptTypeModule, 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. This mirrors the JavaScript dynamic import operation. 84 */ 85 - (JSValue *)evaluateJSScript:(JSScript *)script; 86 77 87 @end 78 88 -
trunk/Source/JavaScriptCore/API/JSScript.h
r240468 r241929 32 32 @class JSVirtualMachine; 33 33 34 /*! 35 @enum JSScriptType 36 @abstract A constant identifying the execution type of a JSScript. 37 @constant kJSScriptTypeProgram The type of a normal JavaScript program. 38 @constant kJSScriptTypeModule The type of a module JavaScript program. 39 */ 40 typedef NS_ENUM(NSInteger, JSScriptType) { 41 kJSScriptTypeProgram, 42 kJSScriptTypeModule, 43 }; 44 45 34 46 JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)) 35 47 @interface JSScript : NSObject 36 48 37 49 /*! 50 This SPI is deprecated and should not be used. Use "scriptOfType:withSource:andSourceURL:andBytecodeCache:inVirtualMachine:error:" instead. 51 */ 52 + (nullable instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm JSC_API_DEPRECATED("Use +scriptOfType:withSource:andSourceURL:andBytecodeCache:inVirtualMachine:error: instead.", macosx(JSC_MAC_TBA, JSC_MAC_TBA), ios(JSC_IOS_TBA, JSC_IOS_TBA)); 53 54 /*! 55 This SPI is deprecated and should not be used. Use "scriptOfType:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:inVirtualMachine:error:" instead. 56 */ 57 + (nullable instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath JSC_API_DEPRECATED("Use +scriptOfType:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:inVirtualMachine:error: instead.", macosx(JSC_MAC_TBA, JSC_MAC_TBA), ios(JSC_IOS_TBA, JSC_IOS_TBA)); 58 59 /*! 60 This API is deprecated and should not be used. 61 */ 62 + (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath JSC_API_DEPRECATED("Do not use this. Use +scriptOfType:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:inVirtualMachine:error: or +scriptOfType:withSource:andSourceURL:andBytecodeCache:inVirtualMachine:error: instead", macosx(JSC_MAC_TBA, JSC_MAC_TBA), ios(JSC_IOS_TBA, JSC_IOS_TBA)); 63 64 /*! 38 65 @method 39 66 @abstract Create a JSScript for the specified virtual machine. 67 @param type The type of JavaScript source. 40 68 @param source The source code to use when the script is evaluated by the JS vm. 69 @param sourceURL The source URL to associate with this script. For modules, this is the module identifier. 70 @param cachePath A URL containing the path where the VM should cache for future execution. On creation, we use this path to load the cached bytecode off disk. If the cached bytecode at this location is stale, you should delete that file before calling this constructor. 41 71 @param vm The JSVirtualMachine the script can be evaluated in. 72 @param error A description of why the script could not be created if the result is nil. 42 73 @result The new script. 74 @discussion The file at cachePath should not be externally modified for the lifecycle of vm. 43 75 */ 44 + (nullable instancetype)script WithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm;76 + (nullable instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source andSourceURL:(NSURL *)sourceURL andBytecodeCache:(nullable NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError * _Nullable * _Nullable)error; 45 77 46 78 /*! 47 79 @method 48 80 @abstract Create a JSScript for the specified virtual machine with a path to a codesigning and bytecode caching. 81 @param type The type of JavaScript source. 49 82 @param filePath A URL containing the path to a JS source code file on disk. 83 @param sourceURL The source URL to associate with this script. For modules, this is the module identifier. 84 @param cachePath A URL containing the path where the VM should cache for future execution. On creation, we use this path to load the cached bytecode off disk. If the cached bytecode at this location is stale, you should delete that file before calling this constructor. 50 85 @param vm The JSVirtualMachine the script can be evaluated in. 51 @param codeSigningPath A URL containing the path to the codeSigning file for filePath on disk. 52 @param cachePath A URL containing the path where the VM should cache for future execution. 86 @param error A description of why the script could not be created if the result is nil. 53 87 @result The new script. 54 @discussion the files at filePath, codeSigningPath, and cachePath should not be externally modified for the lifecycle of vm. Note that codeSigningPath and cachePath are not used currently, but that will change in the near future.88 @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. 55 89 56 90 If the file at filePath is not ascii this method will return nil. 57 91 */ 58 + (nullable instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath; 59 92 + (nullable instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL *)filePath withSourceURL:(NSURL *)sourceURL andBytecodeCache:(nullable NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError * _Nullable * _Nullable)error; 60 93 61 94 /*! 62 This is deprecated and is equivalent to scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:. 95 @method 96 @abstract Cache the bytecode for this JSScript to disk at the path passed in during creation. 97 @param error A description of why the script could not be cached if the result is FALSE. 63 98 */ 64 + (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath; 99 - (BOOL)cacheBytecodeWithError:(out NSError * _Nullable * _Nullable)error; 100 101 /*! 102 @method 103 @abstract Returns the JSScriptType of this JSScript. 104 */ 105 - (JSScriptType)type; 106 107 /*! 108 @method 109 @abstract Returns the sourceURL of this JSScript. 110 */ 111 - (NSURL *)sourceURL; 65 112 66 113 @end -
trunk/Source/JavaScriptCore/API/JSScript.mm
r241340 r241929 37 37 #import "Symbol.h" 38 38 #include <sys/stat.h> 39 #include <wtf/FileSystem.h> 39 40 40 41 #if JSC_OBJC_API_ENABLED … … 42 43 @implementation JSScript { 43 44 __weak JSVirtualMachine* m_virtualMachine; 45 JSScriptType m_type; 46 FileSystem::MappedFileData m_mappedSource; 44 47 String m_source; 48 RetainPtr<NSURL> m_sourceURL; 45 49 RetainPtr<NSURL> m_cachePath; 46 50 JSC::CachedBytecode m_cachedBytecode; … … 54 58 result->m_source = source; 55 59 result->m_virtualMachine = vm; 60 result->m_type = kJSScriptTypeModule; 56 61 return result; 57 62 } … … 91 96 + (instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(NSURL *)codeSigningPath andBytecodeCache:(NSURL *)cachePath 92 97 { 93 // FIXME: This should check codeSigning.94 98 UNUSED_PARAM(codeSigningPath); 99 UNUSED_PARAM(cachePath); 100 95 101 URL filePathURL([filePath absoluteURL]); 96 102 if (!filePathURL.isLocalFile()) 97 103 return nil; 98 // FIXME: This should mmap the contents of the file instead of copying it into dirty memory. 104 99 105 Vector<LChar> buffer; 100 106 if (!fillBufferWithContentsOfFile(filePathURL.fileSystemPath(), buffer)) … … 107 113 result->m_virtualMachine = vm; 108 114 result->m_source = String::fromUTF8WithLatin1Fallback(buffer.data(), buffer.size()); 115 result->m_type = kJSScriptTypeModule; 116 return result; 117 } 118 119 + (instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(NSURL *)codeSigningPath andBytecodeCache:(NSURL *)cachePath 120 { 121 return [JSScript scriptFromASCIIFile:filePath inVirtualMachine:vm withCodeSigning:codeSigningPath andBytecodeCache:cachePath]; 122 } 123 124 static JSScript *createError(NSString *message, NSError** error) 125 { 126 if (error) 127 *error = [NSError errorWithDomain:@"JSScriptErrorDomain" code:1 userInfo:@{ @"message": message }]; 128 return nil; 129 } 130 131 + (instancetype)scriptOfType:(JSScriptType)type withSource:(NSString *)source andSourceURL:(NSURL *)sourceURL andBytecodeCache:(NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError **)error 132 { 133 UNUSED_PARAM(error); 134 JSScript *result = [[[JSScript alloc] init] autorelease]; 135 result->m_virtualMachine = vm; 136 result->m_type = type; 137 result->m_source = source; 138 result->m_sourceURL = sourceURL; 109 139 result->m_cachePath = cachePath; 110 140 [result readCache]; … … 112 142 } 113 143 114 + (instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(NSURL *)codeSigningPath andBytecodeCache:(NSURL *)cachePath 115 { 116 return [JSScript scriptFromASCIIFile:filePath inVirtualMachine:vm withCodeSigning:codeSigningPath andBytecodeCache:cachePath]; 144 + (instancetype)scriptOfType:(JSScriptType)type memoryMappedFromASCIIFile:(NSURL *)filePath withSourceURL:(NSURL *)sourceURL andBytecodeCache:(NSURL *)cachePath inVirtualMachine:(JSVirtualMachine *)vm error:(out NSError **)error 145 { 146 UNUSED_PARAM(error); 147 URL filePathURL([filePath absoluteURL]); 148 if (!filePathURL.isLocalFile()) 149 return createError([NSString stringWithFormat:@"File path %@ is not a local file", static_cast<NSString *>(filePathURL)], error); 150 151 bool success = false; 152 String systemPath = filePathURL.fileSystemPath(); 153 FileSystem::MappedFileData fileData(systemPath, success); 154 if (!success) 155 return createError([NSString stringWithFormat:@"File at path %@ could not be mapped.", static_cast<NSString *>(systemPath)], error); 156 157 if (!charactersAreAllASCII(reinterpret_cast<const LChar*>(fileData.data()), fileData.size())) 158 return createError([NSString stringWithFormat:@"Not all characters in file at %@ are ASCII.", static_cast<NSString *>(systemPath)], error); 159 160 JSScript *result = [[[JSScript alloc] init] autorelease]; 161 result->m_virtualMachine = vm; 162 result->m_type = type; 163 result->m_source = String(StringImpl::createWithoutCopying(bitwise_cast<const LChar*>(fileData.data()), fileData.size())); 164 result->m_mappedSource = WTFMove(fileData); 165 result->m_sourceURL = sourceURL; 166 result->m_cachePath = cachePath; 167 [result readCache]; 168 return result; 117 169 } 118 170 … … 153 205 } 154 206 155 - (void)writeCache 156 { 157 if (m_cachedBytecode.size() || !m_cachePath) 158 return; 159 160 JSC::ParserError error; 161 m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, m_jsSourceCode->sourceCode(), error); 162 if (error.isValid()) 163 return; 207 - (BOOL)cacheBytecodeWithError:(NSError **)error 208 { 209 String errorString { }; 210 [self writeCache:errorString]; 211 if (!errorString.isNull()) { 212 createError(errorString, error); 213 return NO; 214 } 215 216 return YES; 217 } 218 219 - (NSURL *)sourceURL 220 { 221 return m_sourceURL.get(); 222 } 223 224 - (JSScriptType)type 225 { 226 return m_type; 227 } 228 229 @end 230 231 @implementation JSScript(Internal) 232 233 - (unsigned)hash 234 { 235 return m_source.hash(); 236 } 237 238 - (const String&)source 239 { 240 return m_source; 241 } 242 243 - (const JSC::CachedBytecode*)cachedBytecode 244 { 245 return &m_cachedBytecode; 246 } 247 248 - (JSC::JSSourceCode*)jsSourceCode 249 { 250 if (m_jsSourceCode) 251 return m_jsSourceCode.get(); 252 253 return [self forceRecreateJSSourceCode]; 254 } 255 256 - (BOOL)writeCache:(String&)error 257 { 258 if (m_cachedBytecode.size()) 259 return YES; 260 261 if (!m_cachePath) { 262 error = "No cache was path provided during construction of this JSScript."_s; 263 return NO; 264 } 265 266 JSC::ParserError parserError; 267 switch (m_type) { 268 case kJSScriptTypeModule: 269 m_cachedBytecode = JSC::generateModuleBytecode(m_virtualMachine.vm, [self jsSourceCode]->sourceCode(), parserError); 270 break; 271 case kJSScriptTypeProgram: 272 m_cachedBytecode = JSC::generateBytecode(m_virtualMachine.vm, [self jsSourceCode]->sourceCode(), parserError); 273 break; 274 } 275 276 if (parserError.isValid()) { 277 m_cachedBytecode = { }; 278 error = makeString("Unable to generate bytecode for this JSScript because of a parser error: ", parserError.message()); 279 return NO; 280 } 281 164 282 int fd = open([m_cachePath path].UTF8String, O_CREAT | O_WRONLY, 0666); 165 if (fd == -1) 166 return; 167 int rc = flock(fd, LOCK_EX | LOCK_NB); 168 if (!rc) 283 if (fd == -1) { 284 error = makeString("Unable to open file: ", [m_cachePath path].UTF8String, " due to error: ", strerror(errno)); 285 return NO; 286 } 287 int returnCode = flock(fd, LOCK_EX | LOCK_NB); 288 if (returnCode) 289 error = "Unable to lock the cache file; it may already be in use."_s; 290 else 169 291 write(fd, m_cachedBytecode.data(), m_cachedBytecode.size()); 170 292 close(fd); 171 } 172 173 @end 174 175 @implementation JSScript(Internal) 176 177 - (unsigned)hash 178 { 179 return m_source.hash(); 180 } 181 182 - (const String&)source 183 { 184 return m_source; 185 } 186 187 - (const JSC::CachedBytecode*)cachedBytecode 188 { 189 return &m_cachedBytecode; 190 } 191 192 - (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey 193 { 194 if (m_jsSourceCode) { 195 ASSERT(moduleKey.impl() == m_moduleKey); 196 return m_jsSourceCode.get(); 197 } 198 293 return !returnCode; 294 } 295 296 - (void)setSourceURL:(NSURL *)url 297 { 298 m_sourceURL = url; 299 } 300 301 - (JSC::JSSourceCode*)forceRecreateJSSourceCode 302 { 199 303 JSC::VM& vm = m_virtualMachine.vm; 304 JSC::JSLockHolder locker(vm); 305 200 306 TextPosition startPosition { }; 201 Ref<JSScriptSourceProvider> sourceProvider = JSScriptSourceProvider::create(self, JSC::SourceOrigin(moduleKey.string()), URL({ }, moduleKey.string()), TextPosition(), JSC::SourceProviderSourceType::Module); 307 308 String url = String { [[self sourceURL] absoluteString] }; 309 auto type = m_type == kJSScriptTypeModule ? JSC::SourceProviderSourceType::Module : JSC::SourceProviderSourceType::Program; 310 Ref<JSScriptSourceProvider> sourceProvider = JSScriptSourceProvider::create(self, JSC::SourceOrigin(url), URL({ }, url), startPosition, type); 202 311 JSC::SourceCode sourceCode(WTFMove(sourceProvider), startPosition.m_line.oneBasedInt(), startPosition.m_column.oneBasedInt()); 203 312 JSC::JSSourceCode* jsSourceCode = JSC::JSSourceCode::create(vm, WTFMove(sourceCode)); 204 313 m_jsSourceCode.set(vm, jsSourceCode); 205 [self writeCache];206 314 return jsSourceCode; 207 315 } … … 209 317 @end 210 318 211 212 319 #endif -
trunk/Source/JavaScriptCore/API/JSScriptInternal.h
r240511 r241929 47 47 - (unsigned)hash; 48 48 - (const WTF::String&)source; 49 - (const JSC::CachedBytecode*)cachedBytecode; 50 - (JSC::JSSourceCode*)jsSourceCode:(const JSC::Identifier&)moduleKey; 49 - (nullable const JSC::CachedBytecode*)cachedBytecode; 50 - (JSC::JSSourceCode*)jsSourceCode; 51 // FIXME: Remove this once we require sourceURL upon creation: https://bugs.webkit.org/show_bug.cgi?id=194909 52 - (JSC::JSSourceCode*)forceRecreateJSSourceCode; 53 - (BOOL)writeCache:(String&)error; 54 - (void)setSourceURL:(NSURL *)url; 51 55 52 56 @end -
trunk/Source/JavaScriptCore/API/tests/FunctionOverridesTest.cpp
r236032 r241929 45 45 const char* oldFunctionOverrides = Options::functionOverrides(); 46 46 47 Options::functionOverrides() = " testapi-function-overrides.js";47 Options::functionOverrides() = "./testapiScripts/testapi-function-overrides.js"; 48 48 JSC::FunctionOverrides::reinstallOverrides(); 49 49 -
trunk/Source/JavaScriptCore/API/tests/testIncludes.m
r240468 r241929 27 27 // Since we include files that haven't passed through the rewriter we need to handle the non-rewritten values... 28 28 #define JSC_API_AVAILABLE(...) 29 #define JSC_API_DEPRECATED(...) 29 30 #define JSC_CLASS_AVAILABLE(...) 30 31 #define JSC_MAC_VERSION_TBA 0 -
trunk/Source/JavaScriptCore/API/tests/testapi.c
r237440 r241929 41 41 #include "JSStringRefPrivate.h" 42 42 #include "JSWeakPrivate.h" 43 #if !OS(WINDOWS) 44 #include <libgen.h> 45 #endif 46 #include <limits.h> 43 47 #include <math.h> 44 48 #include <stdio.h> … … 46 50 #include <string.h> 47 51 #include <time.h> 52 #if !OS(WINDOWS) 53 #include <unistd.h> 54 #endif 48 55 #include <wtf/Assertions.h> 49 56 … … 68 75 69 76 #if JSC_OBJC_API_ENABLED 70 void testObjectiveCAPI( void);77 void testObjectiveCAPI(const char*); 71 78 #endif 72 79 … … 1381 1388 #endif 1382 1389 1390 #if !OS(WINDOWS) 1391 char resolvedPath[PATH_MAX]; 1392 realpath(argv[0], resolvedPath); 1393 char* newCWD = dirname(resolvedPath); 1394 if (chdir(newCWD)) 1395 fprintf(stdout, "Could not chdir to: %s\n", newCWD); 1396 #endif 1397 1398 const char* filter = argc > 1 ? argv[1] : NULL; 1383 1399 #if JSC_OBJC_API_ENABLED 1384 testObjectiveCAPI( );1400 testObjectiveCAPI(filter); 1385 1401 #endif 1386 1402 1387 const char* filter = argc > 1 ? argv[1] : NULL;1388 1403 RELEASE_ASSERT(!testCAPIViaCpp(filter)); 1389 1404 if (filter) … … 1980 1995 JSClassRelease(nullClass); 1981 1996 1982 const char* scriptPath = " testapi.js";1997 const char* scriptPath = "./testapiScripts/testapi.js"; 1983 1998 char* scriptUTF8 = createStringWithContentsOfFile(scriptPath); 1984 1999 if (!scriptUTF8) { … … 2083 2098 JSGlobalContextRelease(context); 2084 2099 } 2085 failed = testTypedArrayCAPI() || failed;2086 failed = testExecutionTimeLimit() || failed;2087 failed = testFunctionOverrides() || failed;2088 failed = testGlobalContextWithFinalizer() || failed;2089 failed = testPingPongStackOverflow() || failed;2090 failed = testJSONParse() || failed;2091 failed = testJSObjectGetProxyTarget() || failed;2100 failed |= testTypedArrayCAPI(); 2101 failed |= testExecutionTimeLimit(); 2102 failed |= testFunctionOverrides(); 2103 failed |= testGlobalContextWithFinalizer(); 2104 failed |= testPingPongStackOverflow(); 2105 failed |= testJSONParse(); 2106 failed |= testJSObjectGetProxyTarget(); 2092 2107 2093 2108 // Clear out local variables pointing at JSObjectRefs to allow their values to be collected -
trunk/Source/JavaScriptCore/API/tests/testapi.mm
r240821 r241929 42 42 #import "Regress141809.h" 43 43 44 #if __has_include(<libproc.h>) 45 #define HAS_LIBPROC 1 46 #import <libproc.h> 47 #else 48 #define HAS_LIBPROC 0 49 #endif 44 50 #import <pthread.h> 45 51 #import <vector> … … 55 61 56 62 extern int failed; 57 extern "C" void testObjectiveCAPI( void);63 extern "C" void testObjectiveCAPI(const char*); 58 64 extern "C" void checkResult(NSString *, bool); 59 65 … … 1981 1987 } 1982 1988 1983 static void testBytecodeCache() 1984 { 1985 @autoreleasepool { 1986 NSURL* tempDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; 1987 1988 NSString* fooSource = @"import { n } from \"../foo.js\"; export let foo = n;"; 1989 NSString* barSource = @"import \"otherDirectory/baz.js\"; export let n = null;"; 1990 NSString* bazSource = @"import { foo } from \"../directory/bar.js\"; globalThis.ran = null; export let exp = foo;"; 1991 1992 NSURL* fooPath = [tempDirectory URLByAppendingPathComponent:@"foo.js"]; 1993 NSURL* barPath = [tempDirectory URLByAppendingPathComponent:@"bar.js"]; 1994 NSURL* bazPath = [tempDirectory URLByAppendingPathComponent:@"baz.js"]; 1995 1996 NSURL* fooCachePath = [tempDirectory URLByAppendingPathComponent:@"foo.js.cache"]; 1997 NSURL* barCachePath = [tempDirectory URLByAppendingPathComponent:@"bar.js.cache"]; 1998 NSURL* bazCachePath = [tempDirectory URLByAppendingPathComponent:@"baz.js.cache"]; 1989 static NSURL *tempFile(NSString *string) 1990 { 1991 NSURL* tempDirectory = [NSURL fileURLWithPath:NSTemporaryDirectory() isDirectory:YES]; 1992 return [tempDirectory URLByAppendingPathComponent:string]; 1993 } 1994 1995 static void testModuleBytecodeCache() 1996 { 1997 @autoreleasepool { 1998 NSString *fooSource = @"import 'otherDirectory/baz.js'; export let n = null;"; 1999 NSString *barSource = @"import { n } from '../foo.js'; export let foo = () => n;"; 2000 NSString *bazSource = @"import { foo } from '../directory/bar.js'; globalThis.ran = null; export let exp = foo();"; 2001 2002 NSURL *fooPath = tempFile(@"foo.js"); 2003 NSURL *barPath = tempFile(@"bar.js"); 2004 NSURL *bazPath = tempFile(@"baz.js"); 2005 2006 NSURL *fooCachePath = tempFile(@"foo.js.cache"); 2007 NSURL *barCachePath = tempFile(@"bar.js.cache"); 2008 NSURL *bazCachePath = tempFile(@"baz.js.cache"); 2009 2010 NSURL *fooFakePath = [NSURL fileURLWithPath:@"/foo.js"]; 2011 NSURL *barFakePath = [NSURL fileURLWithPath:@"/directory/bar.js"]; 2012 NSURL *bazFakePath = [NSURL fileURLWithPath:@"/otherDirectory/baz.js"]; 1999 2013 2000 2014 [fooSource writeToURL:fooPath atomically:NO encoding:NSASCIIStringEncoding error:nil]; … … 2004 2018 auto block = ^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) { 2005 2019 JSC::Options::forceDiskCache() = true; 2006 if ([identifier isEqualToObject:@"file:///directory/bar.js"]) 2007 [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:fooPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:fooCachePath]]]; 2008 else if ([identifier isEqualToObject:@"file:///foo.js"]) 2009 [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:barPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:barCachePath]]]; 2010 else if ([identifier isEqualToObject:@"file:///otherDirectory/baz.js"]) 2011 [resolve callWithArguments:@[[JSScript scriptFromASCIIFile:bazPath inVirtualMachine:context.virtualMachine withCodeSigning:nil andBytecodeCache:bazCachePath]]]; 2012 else 2020 JSScript *script = nil; 2021 if ([identifier isEqualToObject:[fooFakePath absoluteString]]) 2022 script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:fooPath withSourceURL:fooFakePath andBytecodeCache:fooCachePath inVirtualMachine:context.virtualMachine error:nil]; 2023 else if ([identifier isEqualToObject:[barFakePath absoluteString]]) 2024 script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:barPath withSourceURL:barFakePath andBytecodeCache:barCachePath inVirtualMachine:context.virtualMachine error:nil]; 2025 else if ([identifier isEqualToObject:[bazFakePath absoluteString]]) 2026 script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:bazPath withSourceURL:bazFakePath andBytecodeCache:bazCachePath inVirtualMachine:context.virtualMachine error:nil]; 2027 2028 if (script) { 2029 if (![script cacheBytecodeWithError:nil]) 2030 CRASH(); 2031 [resolve callWithArguments:@[script]]; 2032 } else 2013 2033 [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]]; 2014 2034 }; … … 2024 2044 2025 2045 NSFileManager* fileManager = [NSFileManager defaultManager]; 2026 [fileManager removeItemAtURL:fooPath error:nil]; 2027 [fileManager removeItemAtURL:barPath error:nil]; 2028 [fileManager removeItemAtURL:bazPath error:nil]; 2029 [fileManager removeItemAtURL:fooCachePath error:nil]; 2030 [fileManager removeItemAtURL:barCachePath error:nil]; 2031 [fileManager removeItemAtURL:bazCachePath error:nil]; 2046 BOOL removedAll = true; 2047 removedAll &= [fileManager removeItemAtURL:fooPath error:nil]; 2048 removedAll &= [fileManager removeItemAtURL:barPath error:nil]; 2049 removedAll &= [fileManager removeItemAtURL:bazPath error:nil]; 2050 removedAll &= [fileManager removeItemAtURL:fooCachePath error:nil]; 2051 removedAll &= [fileManager removeItemAtURL:barCachePath error:nil]; 2052 removedAll &= [fileManager removeItemAtURL:bazCachePath error:nil]; 2053 checkResult(@"Removed all temp files created", removedAll); 2054 } 2055 } 2056 2057 static void testProgramBytecodeCache() 2058 { 2059 @autoreleasepool { 2060 NSString *fooSource = @"function foo() { return 42; }; function bar() { return 40; }; foo() + bar();"; 2061 NSURL *fooCachePath = tempFile(@"foo.js.cache"); 2062 JSContext *context = [[JSContext alloc] init]; 2063 JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:fooSource andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:fooCachePath inVirtualMachine:context.virtualMachine error:nil]; 2064 RELEASE_ASSERT(script); 2065 if (![script cacheBytecodeWithError:nil]) 2066 CRASH(); 2067 2068 JSC::Options::forceDiskCache() = true; 2069 JSValue *result = [context evaluateJSScript:script]; 2070 RELEASE_ASSERT(result); 2071 RELEASE_ASSERT([result isNumber]); 2072 checkResult(@"result of cached program is 40+42", [[result toNumber] intValue] == 40 + 42); 2073 JSC::Options::forceDiskCache() = false; 2074 2075 NSFileManager* fileManager = [NSFileManager defaultManager]; 2076 BOOL removedAll = [fileManager removeItemAtURL:fooCachePath error:nil]; 2077 checkResult(@"Removed all temp files created", removedAll); 2078 } 2079 } 2080 2081 static void testBytecodeCacheWithSyntaxError(JSScriptType type) 2082 { 2083 @autoreleasepool { 2084 NSString *fooSource = @"this is a syntax error"; 2085 NSURL *fooCachePath = tempFile(@"foo.js.cache"); 2086 JSContext *context = [[JSContext alloc] init]; 2087 JSScript *script = [JSScript scriptOfType:type withSource:fooSource andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:fooCachePath inVirtualMachine:context.virtualMachine error:nil]; 2088 RELEASE_ASSERT(script); 2089 NSError *error = nil; 2090 if ([script cacheBytecodeWithError:&error]) 2091 CRASH(); 2092 RELEASE_ASSERT(error); 2093 checkResult(@"Got error when trying to cache bytecode for a script with a syntax error.", [[error description] containsString:@"Unable to generate bytecode for this JSScript because of a parser error"]); 2094 } 2095 } 2096 2097 static void testProgramJSScriptException() 2098 { 2099 @autoreleasepool { 2100 NSString *source = @"throw 42;"; 2101 JSContext *context = [[JSContext alloc] init]; 2102 JSScript *script = [JSScript scriptOfType:kJSScriptTypeProgram withSource:source andSourceURL:[NSURL URLWithString:@"my-path"] andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2103 RELEASE_ASSERT(script); 2104 __block bool handledException = false; 2105 context.exceptionHandler = ^(JSContext *, JSValue *exception) { 2106 handledException = true; 2107 RELEASE_ASSERT([exception isNumber]); 2108 checkResult(@"Program JSScript with exception should have the exception value be 42.", [[exception toNumber] intValue] == 42); 2109 }; 2110 2111 JSValue *result = [context evaluateJSScript:script]; 2112 RELEASE_ASSERT(result); 2113 checkResult(@"Program JSScript with exception should return undefined.", [result isUndefined]); 2114 checkResult(@"Program JSScript with exception should call exception handler.", handledException); 2032 2115 } 2033 2116 } … … 2079 2162 @end 2080 2163 2081 static void testLoadBasicFile ()2164 static void testLoadBasicFileLegacySPI() 2082 2165 { 2083 2166 @autoreleasepool { … … 2090 2173 } 2091 2174 2092 void testObjectiveCAPI() 2175 2176 @interface JSContextMemoryMappedLoaderDelegate : JSContext <JSModuleLoaderDelegate> 2177 2178 + (instancetype)newContext; 2179 2180 @end 2181 2182 @implementation JSContextMemoryMappedLoaderDelegate { 2183 } 2184 2185 + (instancetype)newContext 2186 { 2187 auto *result = [[JSContextMemoryMappedLoaderDelegate alloc] init]; 2188 return result; 2189 } 2190 2191 - (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject 2192 { 2193 NSURL *filePath = [NSURL URLWithString:[identifier toString]]; 2194 auto *script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:filePath withSourceURL:filePath andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2195 if (script) 2196 [resolve callWithArguments:@[script]]; 2197 else 2198 [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Unable to create Script" inContext:context]]]; 2199 } 2200 2201 @end 2202 2203 static void testLoadBasicFile() 2204 { 2205 #if HAS_LIBPROC 2206 size_t count = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); 2207 #endif 2208 @autoreleasepool { 2209 auto *context = [JSContextMemoryMappedLoaderDelegate newContext]; 2210 context.moduleLoaderDelegate = context; 2211 JSValue *promise = [context evaluateScript:@"import('./basic.js');" withSourceURL:resolvePathToScripts()]; 2212 JSValue *null = [JSValue valueWithNullInContext:context]; 2213 #if HAS_LIBPROC 2214 size_t afterCount = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); 2215 checkResult(@"JSScript should not hold a file descriptor", count == afterCount); 2216 #endif 2217 checkModuleCodeRan(context, promise, null); 2218 } 2219 #if HAS_LIBPROC 2220 size_t after = proc_pidinfo(getpid(), PROC_PIDLISTFDS, 0, 0, 0); 2221 checkResult(@"File descriptor count sholudn't change after context is dealloced", count == after); 2222 #endif 2223 } 2224 2225 @interface JSContextAugmentedLoaderDelegate : JSContext <JSModuleLoaderDelegate> 2226 2227 + (instancetype)newContext; 2228 2229 @end 2230 2231 @implementation JSContextAugmentedLoaderDelegate { 2232 } 2233 2234 + (instancetype)newContext 2235 { 2236 auto *result = [[JSContextAugmentedLoaderDelegate alloc] init]; 2237 return result; 2238 } 2239 2240 - (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject 2241 { 2242 UNUSED_PARAM(reject); 2243 2244 NSURL *filePath = [NSURL URLWithString:[identifier toString]]; 2245 NSString *pathString = [filePath absoluteString]; 2246 if ([pathString containsString:@"basic.js"] || [pathString containsString:@"foo.js"]) { 2247 auto *script = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:filePath withSourceURL:filePath andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2248 RELEASE_ASSERT(script); 2249 [resolve callWithArguments:@[script]]; 2250 return; 2251 } 2252 2253 if ([pathString containsString:@"bar.js"]) { 2254 auto *script = [JSScript scriptOfType:kJSScriptTypeModule withSource:@"" andSourceURL:[NSURL fileURLWithPath:@"/not/path/to/bar.js"] andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2255 RELEASE_ASSERT(script); 2256 [resolve callWithArguments:@[script]]; 2257 return; 2258 } 2259 2260 RELEASE_ASSERT_NOT_REACHED(); 2261 } 2262 2263 @end 2264 2265 static void testJSScriptURL() 2266 { 2267 @autoreleasepool { 2268 auto *context = [JSContextAugmentedLoaderDelegate newContext]; 2269 context.moduleLoaderDelegate = context; 2270 NSURL *basic = [NSURL URLWithString:@"./basic.js" relativeToURL:resolvePathToScripts()]; 2271 JSScript *script1 = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:basic withSourceURL:basic andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2272 2273 JSValue *result1 = [context evaluateJSScript:script1]; 2274 JSValue *null = [JSValue valueWithNullInContext:context]; 2275 checkModuleCodeRan(context, result1, null); 2276 2277 NSURL *foo = [NSURL URLWithString:@"./foo.js" relativeToURL:resolvePathToScripts()]; 2278 JSScript *script2 = [JSScript scriptOfType:kJSScriptTypeModule memoryMappedFromASCIIFile:foo withSourceURL:foo andBytecodeCache:nil inVirtualMachine:context.virtualMachine error:nil]; 2279 RELEASE_ASSERT(script2); 2280 JSValue *result2 = [context evaluateJSScript:script2]; 2281 2282 __block bool wasRejected = false; 2283 [result2 invokeMethod:@"catch" withArguments:@[^(JSValue *reason) { 2284 wasRejected = [reason isObject]; 2285 RELEASE_ASSERT([[reason toString] containsString:@"The same JSScript was provided for two different identifiers"]); 2286 }]]; 2287 2288 checkResult(@"Module JSScript imported with different identifiers is rejected", wasRejected); 2289 } 2290 } 2291 2292 #define RUN(test) do { \ 2293 if (!shouldRun(#test)) \ 2294 break; \ 2295 NSLog(@"%s...\n", #test); \ 2296 test; \ 2297 NSLog(@"%s: done.\n", #test); \ 2298 } while (false) 2299 2300 void testObjectiveCAPI(const char* filter) 2093 2301 { 2094 2302 NSLog(@"Testing Objective-C API"); 2095 2303 2096 checkNegativeNSIntegers(); 2097 runJITThreadLimitTests(); 2098 2099 testLoaderResolvesAbsoluteScriptURL(); 2100 testFetch(); 2101 testFetchWithTwoCycle(); 2102 testFetchWithThreeCycle(); 2103 testImportModuleTwice(); 2104 testBytecodeCache(); 2105 2106 testLoaderRejectsNilScriptURL(); 2107 testLoaderRejectsFailedFetch(); 2304 auto shouldRun = [&] (const char* test) -> bool { 2305 if (filter) 2306 return strcasestr(test, filter); 2307 return true; 2308 }; 2309 2310 RUN(checkNegativeNSIntegers()); 2311 RUN(runJITThreadLimitTests()); 2312 2313 RUN(testLoaderResolvesAbsoluteScriptURL()); 2314 RUN(testFetch()); 2315 RUN(testFetchWithTwoCycle()); 2316 RUN(testFetchWithThreeCycle()); 2317 RUN(testImportModuleTwice()); 2318 RUN(testModuleBytecodeCache()); 2319 RUN(testProgramBytecodeCache()); 2320 RUN(testBytecodeCacheWithSyntaxError(kJSScriptTypeProgram)); 2321 RUN(testBytecodeCacheWithSyntaxError(kJSScriptTypeModule)); 2322 RUN(testProgramJSScriptException()); 2323 2324 RUN(testLoaderRejectsNilScriptURL()); 2325 RUN(testLoaderRejectsFailedFetch()); 2326 2327 RUN(testJSScriptURL()); 2108 2328 2109 2329 // File loading 2110 testLoadBasicFile(); 2111 2112 promiseWithExecutor(Resolution::ResolveEager); 2113 promiseWithExecutor(Resolution::RejectEager); 2114 promiseWithExecutor(Resolution::ResolveLate); 2115 promiseWithExecutor(Resolution::RejectLate); 2116 promiseRejectOnJSException(); 2117 promiseCreateResolved(); 2118 promiseCreateRejected(); 2119 parallelPromiseResolveTest(); 2330 RUN(testLoadBasicFileLegacySPI()); 2331 RUN(testLoadBasicFile()); 2332 2333 RUN(promiseWithExecutor(Resolution::ResolveEager)); 2334 RUN(promiseWithExecutor(Resolution::RejectEager)); 2335 RUN(promiseWithExecutor(Resolution::ResolveLate)); 2336 RUN(promiseWithExecutor(Resolution::RejectLate)); 2337 RUN(promiseRejectOnJSException()); 2338 RUN(promiseCreateResolved()); 2339 RUN(promiseCreateRejected()); 2340 RUN(parallelPromiseResolveTest()); 2120 2341 2121 2342 testObjectiveCAPIMain(); … … 2124 2345 #else 2125 2346 2126 void testObjectiveCAPI( )2347 void testObjectiveCAPI(const char*) 2127 2348 { 2128 2349 } -
trunk/Source/JavaScriptCore/API/tests/testapiScripts/foo.js
r241928 r241929 24 24 */ 25 25 26 27 // Since we include files that haven't passed through the rewriter we need to handle the non-rewritten values... 28 #define JSC_API_AVAILABLE(...) 29 #define JSC_CLASS_AVAILABLE(...) 30 #define JSC_MAC_VERSION_TBA 0 31 #define JSC_IOS_VERSION_TBA 0 32 33 // umbrella header 34 #import <JavaScriptCore/JavaScriptCore.h> 35 36 // private headers 37 #import <JavaScriptCore/JSContextPrivate.h> 38 #import <JavaScriptCore/JSScript.h> 39 #import <JavaScriptCore/JSValuePrivate.h> 40 #import <JavaScriptCore/JSVirtualMachinePrivate.h> 41 26 import "./bar.js"; -
trunk/Source/JavaScriptCore/ChangeLog
r241927 r241929 1 2019-02-21 Saam Barati <sbarati@apple.com> 2 3 Update JSScript SPI based on feedback 4 https://bugs.webkit.org/show_bug.cgi?id=194517 5 6 Reviewed by Keith Miller. 7 8 This patch updates the JSScript SPI in the following ways: 9 - JSScript can now represent both modules and programs. This is a property 10 of the script determined during creation. 11 - JSScript now takes a sourceURL during construction. For modules, this acts 12 as the module identifier. 13 - JSScript now has SPI for writing the cache out to disk. We don't do this 14 automatically. 15 - JSScript will load the bytecode cache on creation if it exists. 16 - We retrofit these new requirements on the prior JSScript SPI that 17 we're going to remove as soon as we can: https://bugs.webkit.org/show_bug.cgi?id=194909. 18 Previous SPI assumes all JSScripts are modules. Previous SPI also assigns 19 a sourceURL to the JSScript based on what the module loader decided the 20 identifier should be. We'll remove this once we remove the old SPI. 21 22 This patch also adds SPI to JSContext to evaluate a JSScript. For modules, 23 this is like returning the result of doing dynamic import. For programs, 24 this does normal program evaluation. 25 26 This patch also fixes a bug in generateBytecode/generateModuleBytecode where 27 we would try to cache the bytecode even if recursivelyGenerateUnlinkedCodeBlock 28 returned null. E.g, if the script had a syntax error. 29 30 When writing tests, I also discovered that someone previously broke 31 testapi. This patch also fixes those failures. They were broken when 32 we switched to using a testapiScripts directory to hold our test .js 33 scripts. 34 35 * API/JSAPIGlobalObject.h: 36 * API/JSAPIGlobalObject.mm: 37 (JSC::JSAPIGlobalObject::moduleLoaderResolve): 38 (JSC::JSAPIGlobalObject::moduleLoaderFetch): 39 (JSC::JSAPIGlobalObject::loadAndEvaluateJSScriptModule): 40 * API/JSBase.cpp: 41 (JSEvaluateScriptInternal): 42 (JSEvaluateScript): 43 * API/JSBaseInternal.h: Added. 44 * API/JSContext.mm: 45 (-[JSContext evaluateScript:withSourceURL:]): 46 (-[JSContext evaluateJSScript:]): 47 * API/JSContextPrivate.h: 48 * API/JSScript.h: 49 * API/JSScript.mm: 50 (+[JSScript scriptWithSource:inVirtualMachine:]): 51 (+[JSScript scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:]): 52 (createError): 53 (+[JSScript scriptOfType:inVirtualMachine:withSourceURL:andSource:andBytecodeCache:error:]): 54 (+[JSScript scriptOfType:inVirtualMachine:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:error:]): 55 (-[JSScript cacheBytecodeWithError:]): 56 (-[JSScript sourceURL]): 57 (-[JSScript type]): 58 (-[JSScript jsSourceCode]): 59 (-[JSScript writeCache:]): 60 (-[JSScript setSourceURL:]): 61 (-[JSScript forceRecreateJSSourceCode]): 62 (-[JSScript writeCache]): Deleted. 63 (-[JSScript jsSourceCode:]): Deleted. 64 * API/JSScriptInternal.h: 65 * API/tests/FunctionOverridesTest.cpp: 66 (testFunctionOverrides): 67 * API/tests/testapi.c: 68 (main): 69 * API/tests/testapi.mm: 70 (tempFile): 71 (testModuleBytecodeCache): 72 (testProgramBytecodeCache): 73 (testBytecodeCacheWithSyntaxError): 74 (testProgramJSScriptException): 75 (testLoadBasicFileLegacySPI): 76 (+[JSContextMemoryMappedLoaderDelegate newContext]): 77 (-[JSContextMemoryMappedLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): 78 (testLoadBasicFile): 79 (+[JSContextAugmentedLoaderDelegate newContext]): 80 (-[JSContextAugmentedLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): 81 (testJSScriptURL): 82 (testObjectiveCAPI): 83 (testBytecodeCache): Deleted. 84 * API/tests/testapiScripts/foo.js: Added. 85 * JavaScriptCore.xcodeproj/project.pbxproj: 86 * runtime/Completion.cpp: 87 (JSC::generateBytecode): 88 (JSC::generateModuleBytecode): 89 1 90 2019-02-21 Mark Lam <mark.lam@apple.com> 2 91 -
trunk/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj
r241841 r241929 885 885 52C0611F1AA51E1C00B4ADBA /* RuntimeType.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C0611D1AA51E1B00B4ADBA /* RuntimeType.h */; settings = {ATTRIBUTES = (Private, ); }; }; 886 886 52C952B719A289850069B386 /* TypeProfiler.h in Headers */ = {isa = PBXBuildFile; fileRef = 52C952B619A289850069B386 /* TypeProfiler.h */; settings = {ATTRIBUTES = (Private, ); }; }; 887 52D13091221CE176009C836C /* foo.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 52D1308F221CE03A009C836C /* foo.js */; }; 887 888 52F6C35E1E71EB080081F4CC /* WebAssemblyWrapperFunction.h in Headers */ = {isa = PBXBuildFile; fileRef = 52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */; }; 888 889 530A66B91FA3E78B0026A545 /* UnifiedSource3-mm.mm in Sources */ = {isa = PBXBuildFile; fileRef = 530A66B11FA3E77A0026A545 /* UnifiedSource3-mm.mm */; }; … … 1161 1162 7980C16D1E3A940E00B71615 /* DFGRegisteredStructureSet.h in Headers */ = {isa = PBXBuildFile; fileRef = 7980C16B1E3A940E00B71615 /* DFGRegisteredStructureSet.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1162 1163 7986943B1F8C0ACC009232AE /* StructureCache.h in Headers */ = {isa = PBXBuildFile; fileRef = 7986943A1F8C0AC8009232AE /* StructureCache.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1164 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 79872C47221BBAED008C6969 /* JSBaseInternal.h */; }; 1163 1165 798937791DCAB57300F8D4FB /* JSFixedArray.h in Headers */ = {isa = PBXBuildFile; fileRef = 798937771DCAB57300F8D4FB /* JSFixedArray.h */; settings = {ATTRIBUTES = (Private, ); }; }; 1164 1166 799EF7C41C56ED96002B0534 /* B3PCToOriginMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 799EF7C31C56ED96002B0534 /* B3PCToOriginMap.h */; settings = {ATTRIBUTES = (Private, ); }; }; … … 2030 2032 dstSubfolderSpec = 16; 2031 2033 files = ( 2034 52D13091221CE176009C836C /* foo.js in Copy Support Script */, 2032 2035 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */, 2033 2036 FECB8B2A1D25CB5A006F2463 /* testapi-function-overrides.js in Copy Support Script */, … … 3378 3381 52C952B619A289850069B386 /* TypeProfiler.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = TypeProfiler.h; sourceTree = "<group>"; }; 3379 3382 52C952B819A28A1C0069B386 /* TypeProfiler.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = TypeProfiler.cpp; sourceTree = "<group>"; }; 3383 52D1308F221CE03A009C836C /* foo.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = foo.js; sourceTree = "<group>"; }; 3380 3384 52F6C35B1E71EB080081F4CC /* WebAssemblyWrapperFunction.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = WebAssemblyWrapperFunction.cpp; path = js/WebAssemblyWrapperFunction.cpp; sourceTree = "<group>"; }; 3381 3385 52F6C35C1E71EB080081F4CC /* WebAssemblyWrapperFunction.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = WebAssemblyWrapperFunction.h; path = js/WebAssemblyWrapperFunction.h; sourceTree = "<group>"; }; … … 3773 3777 798694391F8C0AC7009232AE /* StructureCache.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = StructureCache.cpp; sourceTree = "<group>"; }; 3774 3778 7986943A1F8C0AC8009232AE /* StructureCache.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = StructureCache.h; sourceTree = "<group>"; }; 3779 79872C47221BBAED008C6969 /* JSBaseInternal.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSBaseInternal.h; sourceTree = "<group>"; }; 3775 3780 798937761DCAB57300F8D4FB /* JSFixedArray.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSFixedArray.cpp; sourceTree = "<group>"; }; 3776 3781 798937771DCAB57300F8D4FB /* JSFixedArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSFixedArray.h; sourceTree = "<group>"; }; … … 5996 6001 1421359A0A677F4F00A8195E /* JSBase.cpp */, 5997 6002 142711380A460BBB0080EEEA /* JSBase.h */, 6003 79872C47221BBAED008C6969 /* JSBaseInternal.h */, 5998 6004 140D17D60E8AD4A9000CD17D /* JSBasePrivate.h */, 5999 6005 1440F8AD0A508D200005F061 /* JSCallbackConstructor.cpp */, … … 6341 6347 children = ( 6342 6348 53C3D5E421ECE6CE0087FDFC /* basic.js */, 6349 52D1308F221CE03A009C836C /* foo.js */, 6343 6350 ); 6344 6351 name = testapiScripts; … … 9759 9766 0FF42749158EBE91004CB9FF /* udis86_types.h in Headers */, 9760 9767 A7E5AB391799E4B200D2833D /* UDis86Disassembler.h in Headers */, 9768 79872C48221BBAF3008C6969 /* JSBaseInternal.h in Headers */, 9761 9769 A7A8AF4117ADB5F3005AB174 /* Uint16Array.h in Headers */, 9762 9770 866739D313BFDE710023D87C /* Uint16WithFraction.h in Headers */, -
trunk/Source/JavaScriptCore/config.h
r239933 r241929 26 26 #define JSC_API_AVAILABLE(...) 27 27 #define JSC_CLASS_AVAILABLE(...) JS_EXPORT 28 #define JSC_API_DEPRECATED(...) 28 29 // Use zero since it will be less than any possible version number. 29 30 #define JSC_MAC_VERSION_TBA 0 -
trunk/Source/JavaScriptCore/runtime/Completion.cpp
r240511 r241929 104 104 105 105 UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ); 106 if (!unlinkedCodeBlock) 107 return { }; 106 108 return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ProgramType, strictMode, scriptMode, debuggerMode); 107 109 } … … 119 121 120 122 UnlinkedCodeBlock* unlinkedCodeBlock = recursivelyGenerateUnlinkedCodeBlock<UnlinkedModuleProgramCodeBlock>(vm, source, strictMode, scriptMode, debuggerMode, error, evalContextType, &variablesUnderTDZ); 123 if (!unlinkedCodeBlock) 124 return { }; 121 125 return serializeBytecode(vm, unlinkedCodeBlock, source, SourceCodeType::ModuleType, strictMode, scriptMode, debuggerMode); 122 126 }
Note: See TracChangeset
for help on using the changeset viewer.