WebKit Bugzilla
Attachment 359048 Details for
Bug 191121
: JSC should have a module loader API
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Patch
bug-191121-20190114095928.patch (text/plain), 70.50 KB, created by
Keith Miller
on 2019-01-14 09:59:29 PST
(
hide
)
Description:
Patch
Filename:
MIME Type:
Creator:
Keith Miller
Created:
2019-01-14 09:59:29 PST
Size:
70.50 KB
patch
obsolete
>Subversion Revision: 239569 >diff --git a/Source/JavaScriptCore/ChangeLog b/Source/JavaScriptCore/ChangeLog >index 94368dc8b20244ce53c842e6165d996f5baea610..b728df64872f2f29c62be10860201fdfead2d1fc 100644 >--- a/Source/JavaScriptCore/ChangeLog >+++ b/Source/JavaScriptCore/ChangeLog >@@ -1,3 +1,88 @@ >+2019-01-14 Keith Miller <keith_miller@apple.com> >+ >+ JSC should have a module loader API >+ https://bugs.webkit.org/show_bug.cgi?id=191121 >+ >+ Reviewed by NOBODY (OOPS!). >+ >+ This patch adds a new delegate to JSContxt that is called to fetch >+ any resolved module. The resolution of a module identifier is computed >+ as if it were a URL on the web with the caveat that it must be a file URL. >+ >+ A new class JSScript has also been added that is similar to JSScriptRef. >+ Right now all JSScripts are copied into memory. In the future we should >+ mmap the provided file into memory so the OS can evict it to disk under >+ pressure. Additionally, the API does not make use of the code signing path >+ nor the bytecode caching path, which we will add in subsequent patches. >+ >+ Lastly, a couple of new convenience methods have been added. C API >+ conversion, can now toRef a JSValue with just a vm rather than >+ requiring an ExecState. Secondly, there is now a call wrapper that >+ does not require CallData and CallType since many places don't >+ care about this. >+ >+ * API/APICast.h: >+ (toRef): >+ * API/JSAPIGlobalObject.h: Added. >+ (JSC::JSAPIGlobalObject::create): >+ (JSC::JSAPIGlobalObject::createStructure): >+ (JSC::JSAPIGlobalObject::JSAPIGlobalObject): >+ * API/JSAPIGlobalObject.mm: Added. >+ (JSC::JSAPIGlobalObject::moduleLoaderResolve): >+ (JSC::JSAPIGlobalObject::moduleLoaderImportModule): >+ (JSC::JSAPIGlobalObject::moduleLoaderFetch): >+ (JSC::JSAPIGlobalObject::moduleLoaderCreateImportMetaProperties): >+ * API/JSAPIValueWrapper.h: >+ (JSC::jsAPIValueWrapper): Deleted. >+ * API/JSContext.h: >+ * API/JSContext.mm: >+ (-[JSContext moduleLoaderDelegate]): >+ (-[JSContext setModuleLoaderDelegate:]): >+ * API/JSContextInternal.h: >+ * API/JSContextPrivate.h: >+ * API/JSContextRef.cpp: >+ (JSGlobalContextCreateInGroup): >+ * API/JSScript.h: Added. >+ * API/JSScript.mm: Added. >+ (+[JSScript scriptWithSource:inVirtualMachine:]): >+ (fillBufferWithContentsOfFile): >+ (+[JSScript scriptFromUTF8File:inVirtualMachine:withCodeSigning:andBytecodeCache:]): >+ (getJSScriptSourceCode): >+ * API/JSScriptInternal.h: Copied from Source/JavaScriptCore/API/JSVirtualMachineInternal.h. >+ * API/JSValueInternal.h: >+ * API/JSVirtualMachineInternal.h: >+ * API/tests/testapi.mm: >+ (+[JSContextFetchDelegate contextWithBlockForFetch:]): >+ (-[JSContextFetchDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): >+ (checkModuleCodeRan): >+ (checkModuleWasRejected): >+ (testFetch): >+ (testFetchWithTwoCycle): >+ (testFetchWithThreeCycle): >+ (testLoaderResolvesAbsoluteScriptURL): >+ (testLoaderRejectsNilScriptURL): >+ (testLoaderRejectsFailedFetch): >+ (testImportModuleTwice): >+ (+[JSContextFileLoaderDelegate newContext]): >+ (resolvePathToScripts): >+ (-[JSContextFileLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): >+ (testLoadBasicFile): >+ (testObjectiveCAPI): >+ * API/tests/testapiScripts/basic.js: Copied from Source/JavaScriptCore/API/JSVirtualMachineInternal.h. >+ * JavaScriptCore.xcodeproj/project.pbxproj: >+ * SourcesCocoa.txt: >+ * config.h: >+ * runtime/CallData.cpp: >+ (JSC::call): >+ * runtime/CallData.h: >+ * runtime/Completion.cpp: >+ (JSC::loadAndEvaluateModule): >+ * runtime/Completion.h: >+ * runtime/JSCast.h: >+ (JSC::jsSecureCast): >+ * runtime/JSGlobalObject.cpp: >+ (JSC::createProxyProperty): >+ > 2018-12-31 Keith Miller <keith_miller@apple.com> > > SourceProviders should use an actual URL instead of a string >diff --git a/Source/JavaScriptCore/API/APICast.h b/Source/JavaScriptCore/API/APICast.h >index 3b559119e22a1e5688088727f9ba7dcb2824af4d..8b086f0f451f283a52763e198ab0ce96ecd6596e 100644 >--- a/Source/JavaScriptCore/API/APICast.h >+++ b/Source/JavaScriptCore/API/APICast.h >@@ -128,21 +128,26 @@ inline JSC::VM* toJS(JSContextGroupRef g) > return reinterpret_cast<JSC::VM*>(const_cast<OpaqueJSContextGroup*>(g)); > } > >-inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v) >+inline JSValueRef toRef(JSC::VM& vm, JSC::JSValue v) > { >- ASSERT(exec->vm().currentThreadIsHoldingAPILock()); >+ ASSERT(vm.currentThreadIsHoldingAPILock()); > #if !CPU(ADDRESS64) > if (!v) > return 0; > if (!v.isCell()) >- return reinterpret_cast<JSValueRef>(JSC::jsAPIValueWrapper(exec, v).asCell()); >+ return reinterpret_cast<JSValueRef>(JSC::JSAPIWrapperValue::create(vm, v).asCell()); > return reinterpret_cast<JSValueRef>(v.asCell()); > #else >- UNUSED_PARAM(exec); >+ UNUSED_PARAM(vm); > return bitwise_cast<JSValueRef>(v); > #endif > } > >+inline JSValueRef toRef(JSC::ExecState* exec, JSC::JSValue v) >+{ >+ return toRef(exec->vm(), v); >+} >+ > inline JSObjectRef toRef(JSC::JSObject* o) > { > return reinterpret_cast<JSObjectRef>(o); >diff --git a/Source/JavaScriptCore/API/JSAPIGlobalObject.h b/Source/JavaScriptCore/API/JSAPIGlobalObject.h >new file mode 100644 >index 0000000000000000000000000000000000000000..f0c24abc77a2adb39aa025108191db3a4368c9aa >--- /dev/null >+++ b/Source/JavaScriptCore/API/JSAPIGlobalObject.h >@@ -0,0 +1,64 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#include "JSGlobalObject.h" >+ >+namespace JSC { >+ >+class JSAPIGlobalObject : public JSGlobalObject { >+public: >+ using Base = JSGlobalObject; >+ >+ DECLARE_INFO; >+ static const GlobalObjectMethodTable s_globalObjectMethodTable; >+ >+ static JSAPIGlobalObject* create(VM& vm, Structure* structure) >+ { >+ auto* object = new (NotNull, allocateCell<JSAPIGlobalObject>(vm.heap)) JSAPIGlobalObject(vm, structure); >+ object->finishCreation(vm); >+ return object; >+ } >+ >+ static Structure* createStructure(VM& vm, JSValue prototype) >+ { >+ auto* result = Structure::create(vm, 0, prototype, TypeInfo(GlobalObjectType, StructureFlags), info()); >+ result->setTransitionWatchpointIsLikelyToBeFired(true); >+ return result; >+ } >+ >+ static JSInternalPromise* moduleLoaderImportModule(JSGlobalObject*, ExecState*, JSModuleLoader*, JSString* moduleNameValue, JSValue parameters, const SourceOrigin&); >+ static Identifier moduleLoaderResolve(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue keyValue, JSValue referrerValue, JSValue); >+ static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue); >+ static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue); >+ >+private: >+ JSAPIGlobalObject(VM& vm, Structure* structure) >+ : Base(vm, structure, &s_globalObjectMethodTable) >+ { } >+}; >+ >+} >diff --git a/Source/JavaScriptCore/API/JSAPIGlobalObject.mm b/Source/JavaScriptCore/API/JSAPIGlobalObject.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..c42f5f23216f46af1af07382b1853a3ea5ae74b6 >--- /dev/null >+++ b/Source/JavaScriptCore/API/JSAPIGlobalObject.mm >@@ -0,0 +1,213 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#import "config.h" >+#import "JSAPIGlobalObject.h" >+ >+#import "APICast.h" >+#import "CatchScope.h" >+#import "Completion.h" >+#import "Error.h" >+#import "Exception.h" >+#import "JSContextInternal.h" >+#import "JSInternalPromiseDeferred.h" >+#import "JSNativeStdFunction.h" >+#import "JSScriptInternal.h" >+#import "JSSourceCode.h" >+#import "JSValueInternal.h" >+#import "JSVirtualMachineInternal.h" >+#import "JavaScriptCore.h" >+#import "ObjectConstructor.h" >+#import "SourceOrigin.h" >+ >+#import <wtf/URL.h> >+ >+namespace JSC { >+ >+const ClassInfo JSAPIGlobalObject::s_info = { "GlobalObject", &Base::s_info, nullptr, nullptr, CREATE_METHOD_TABLE(JSAPIGlobalObject) }; >+ >+const GlobalObjectMethodTable JSAPIGlobalObject::s_globalObjectMethodTable = { >+ &supportsRichSourceInfo, >+ &shouldInterruptScript, >+ &javaScriptRuntimeFlags, >+ nullptr, // queueTaskToEventLoop >+ &shouldInterruptScriptBeforeTimeout, >+ &moduleLoaderImportModule, // moduleLoaderImportModule >+ &moduleLoaderResolve, // moduleLoaderResolve >+ &moduleLoaderFetch, // moduleLoaderFetch >+ &moduleLoaderCreateImportMetaProperties, // moduleLoaderCreateImportMetaProperties >+ nullptr, // moduleLoaderEvaluate >+ nullptr, // promiseRejectionTracker >+ nullptr, // defaultLanguage >+ nullptr, // compileStreaming >+ nullptr, // instantiateStreaming >+}; >+ >+Identifier JSAPIGlobalObject::moduleLoaderResolve(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue key, JSValue referrer, JSValue) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ ASSERT_UNUSED(globalObject, globalObject == exec->lexicalGlobalObject()); >+ ASSERT(key.isString() || key.isSymbol()); >+ String name = key.toWTFString(exec); >+ >+ URL referrerURL(URL(), jsCast<JSString*>(referrer)->tryGetValue()); >+ RELEASE_ASSERT(referrerURL.isValid()); >+ >+ URL url = URL(referrerURL, name); >+ if (url.isValid()) >+ return Identifier::fromString(exec, url); >+ >+ throwVMError(exec, scope, "Could not form valid URL from identifier and base"_s); >+ return { }; >+} >+ >+JSInternalPromise* JSAPIGlobalObject::moduleLoaderImportModule(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSString* specifierValue, JSValue, const SourceOrigin& sourceOrigin) >+{ >+ VM& vm = globalObject->vm(); >+ auto scope = DECLARE_CATCH_SCOPE(vm); >+ auto reject = [&] (JSValue exception) -> JSInternalPromise* { >+ scope.clearException(); >+ auto* promise = JSInternalPromiseDeferred::tryCreate(exec, globalObject); >+ scope.clearException(); >+ return promise->reject(exec, exception); >+ }; >+ >+ auto import = [&] (URL& url) { >+ auto result = importModule(exec, Identifier::fromString(&vm, url), jsUndefined(), jsUndefined()); >+ if (UNLIKELY(scope.exception())) >+ return reject(scope.exception()); >+ return result; >+ }; >+ >+ auto specifier = specifierValue->value(exec); >+ if (UNLIKELY(scope.exception())) { >+ JSValue exception = scope.exception(); >+ scope.clearException(); >+ return reject(exception); >+ } >+ >+ URL absoluteURL(URL(), specifier); >+ if (absoluteURL.isValid()) >+ return import(absoluteURL); >+ >+ if (!specifier.startsWith('/') && !specifier.startsWith("./") && !specifier.startsWith("../")) >+ return reject(createError(exec, "Module specifier does not start with \"/\", \"./\", or \"../\"."_s)); >+ >+ if (specifier.startsWith('/')) { >+ absoluteURL = URL(URL({ }, "file://"), specifier); >+ if (absoluteURL.isValid()) >+ return import(absoluteURL); >+ } >+ >+ auto noBaseErrorMessage = "Could not determine the base URL for loading."_s; >+ if (sourceOrigin.isNull()) >+ return reject(createError(exec, noBaseErrorMessage)); >+ >+ auto referrer = sourceOrigin.string(); >+ URL baseURL(URL(), referrer); >+ if (!baseURL.isValid()) >+ return reject(createError(exec, noBaseErrorMessage)); >+ >+ URL url(baseURL, specifier); >+ if (!url.isValid()) >+ return reject(createError(exec, "could not determine a valid URL for module specifier"_s)); >+ >+ return import(url); >+} >+ >+JSInternalPromise* JSAPIGlobalObject::moduleLoaderFetch(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue key, JSValue, JSValue) >+{ >+ VM& vm = globalObject->vm(); >+ auto scope = DECLARE_CATCH_SCOPE(vm); >+ >+ ASSERT(globalObject == exec->lexicalGlobalObject()); >+ JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())]; >+ >+ JSInternalPromiseDeferred* deferred = JSInternalPromiseDeferred::tryCreate(exec, globalObject); >+ RETURN_IF_EXCEPTION(scope, nullptr); >+ >+ Identifier moduleKey = key.toPropertyKey(exec); >+ if (UNLIKELY(scope.exception())) { >+ JSValue exception = scope.exception(); >+ scope.clearException(); >+ return deferred->reject(exec, exception); >+ } >+ >+ if (UNLIKELY(![context moduleLoaderDelegate])) >+ 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) { >+ VM& vm = exec->vm(); >+ // This captures the globalObject but that's ok because our structure keeps it alive anyway. >+ JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())]; >+ id script = valueToObject(context, toRef(exec, exec->argument(0))); >+ >+ MarkedArgumentBuffer args; >+ if (UNLIKELY(![script isKindOfClass:[JSScript class]])) { >+ args.append(createTypeError(exec, "First argument of resolution callback is not a JSScript")); >+ call(exec, deferredPromise->JSPromiseDeferred::reject(), args, "This should never be seen..."); >+ return encodedJSUndefined(); >+ } >+ >+ const String& source = getJSScriptSourceCode(static_cast<JSScript *>(script)); >+ args.append(JSSourceCode::create(vm, makeSource(source, SourceOrigin(moduleKey.string()), URL({ }, moduleKey.string()), TextPosition(), JSC::SourceProviderSourceType::Module))); >+ call(exec, deferredPromise->JSPromiseDeferred::resolve(), args, "This should never be seen..."); >+ return encodedJSUndefined(); >+ }); >+ >+ auto* reject = JSNativeStdFunction::create(vm, globalObject, 1, "reject", [=] (ExecState* exec) { >+ MarkedArgumentBuffer args; >+ args.append(exec->argument(0)); >+ >+ call(exec, deferredPromise->JSPromiseDeferred::reject(), args, "This should never be seen..."); >+ return encodedJSUndefined(); >+ }); >+ >+ [[context moduleLoaderDelegate] context:context fetchModuleForIdentifier:[::JSValue valueWithJSValueRef:toRef(exec, key) inContext:context] withResolveHandler:[::JSValue valueWithJSValueRef:toRef(exec, resolve) inContext:context] andRejectHandler:[::JSValue valueWithJSValueRef:toRef(exec, reject) inContext:context]]; >+ if (context.exception) { >+ deferred->reject(exec, toJS(exec, [context.exception JSValueRef])); >+ context.exception = nil; >+ } >+ return deferred->promise(); >+} >+ >+JSObject* JSAPIGlobalObject::moduleLoaderCreateImportMetaProperties(JSGlobalObject* globalObject, ExecState* exec, JSModuleLoader*, JSValue key, JSModuleRecord*, JSValue) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ JSObject* metaProperties = constructEmptyObject(exec, globalObject->nullPrototypeObjectStructure()); >+ RETURN_IF_EXCEPTION(scope, nullptr); >+ >+ metaProperties->putDirect(vm, Identifier::fromString(&vm, "filename"), key); >+ RETURN_IF_EXCEPTION(scope, nullptr); >+ >+ return metaProperties; >+} >+ >+} >diff --git a/Source/JavaScriptCore/API/JSAPIValueWrapper.h b/Source/JavaScriptCore/API/JSAPIValueWrapper.h >index 06b307103eea2340547b03029ce3fb0e6d767633..aa26082ff35bad909c1bb3a64592b0e1e1887909 100644 >--- a/Source/JavaScriptCore/API/JSAPIValueWrapper.h >+++ b/Source/JavaScriptCore/API/JSAPIValueWrapper.h >@@ -1,7 +1,7 @@ > /* > * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) > * Copyright (C) 2001 Peter Kelly (pmk@post.com) >- * Copyright (C) 2003, 2004, 2005, 2007, 2008 Apple Inc. All rights reserved. >+ * Copyright (C) 2003-2019 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -44,10 +44,9 @@ public: > > DECLARE_EXPORT_INFO; > >- static JSAPIValueWrapper* create(ExecState* exec, JSValue value) >+ static JSAPIValueWrapper* create(VM& vm, JSValue value) > { >- VM& vm = exec->vm(); >- JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(exec); >+ JSAPIValueWrapper* wrapper = new (NotNull, allocateCell<JSAPIValueWrapper>(vm.heap)) JSAPIValueWrapper(vm); > wrapper->finishCreation(vm, value); > return wrapper; > } >@@ -61,17 +60,12 @@ protected: > } > > private: >- JSAPIValueWrapper(ExecState* exec) >- : JSCell(exec->vm(), exec->vm().apiWrapperStructure.get()) >+ JSAPIValueWrapper(VM& vm) >+ : JSCell(vm, vm.apiWrapperStructure.get()) > { > } > > WriteBarrier<Unknown> m_value; > }; > >-inline JSValue jsAPIValueWrapper(ExecState* exec, JSValue value) >-{ >- return JSAPIValueWrapper::create(exec, value); >-} >- > } // namespace JSC >diff --git a/Source/JavaScriptCore/API/JSContext.h b/Source/JavaScriptCore/API/JSContext.h >index 89c87f9e2e1ff1b171b1ebba8c452159f44f475a..0a856c5958f89c7b115eead84ea53a34431b2c77 100644 >--- a/Source/JavaScriptCore/API/JSContext.h >+++ b/Source/JavaScriptCore/API/JSContext.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -31,7 +31,7 @@ > > #if JSC_OBJC_API_ENABLED > >-@class JSVirtualMachine, JSValue; >+@class JSScript, JSVirtualMachine, JSValue, JSContext; > > /*! > @interface >@@ -39,7 +39,7 @@ > JavaScript execution takes place within a context, and all JavaScript values > are tied to a context. > */ >-NS_CLASS_AVAILABLE(10_9, 7_0) >+JSC_CLASS_AVAILABLE(macosx(10.9), iso(7.0)) > @interface JSContext : NSObject > > /*! >@@ -177,7 +177,6 @@ NS_CLASS_AVAILABLE(10_9, 7_0) > @discussion Name of the JSContext. Exposed when remote debugging the context. > */ > @property (copy) NSString *name JSC_API_AVAILABLE(macosx(10.10), ios(8.0)); >- > @end > > /*! >@@ -231,6 +230,7 @@ NS_CLASS_AVAILABLE(10_9, 7_0) > @result The C API equivalent of this JSContext. > */ > @property (readonly) JSGlobalContextRef JSGlobalContextRef; >+ > @end > > #endif >diff --git a/Source/JavaScriptCore/API/JSContext.mm b/Source/JavaScriptCore/API/JSContext.mm >index 27566f41b97e1b39bdde9b48aaa559f14cb739ea..3c776d4d900ee1733362ac29f624f444d545e7b4 100644 >--- a/Source/JavaScriptCore/API/JSContext.mm >+++ b/Source/JavaScriptCore/API/JSContext.mm >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -26,11 +26,15 @@ > #include "config.h" > > #import "APICast.h" >+#import "Completion.h" > #import "JSCInlines.h" > #import "JSContextInternal.h" > #import "JSContextPrivate.h" > #import "JSContextRefInternal.h" > #import "JSGlobalObject.h" >+#import "JSInternalPromise.h" >+#import "JSModuleLoader.h" >+#import "JSScriptInternal.h" > #import "JSValueInternal.h" > #import "JSVirtualMachineInternal.h" > #import "JSWrapperMap.h" >@@ -38,12 +42,15 @@ > #import "ObjcRuntimeExtras.h" > #import "StrongInlines.h" > >+#import <wtf/WeakObjCPtr.h> >+ > #if JSC_OBJC_API_ENABLED > > @implementation JSContext { > JSVirtualMachine *m_virtualMachine; > JSGlobalContextRef m_context; > JSC::Strong<JSC::JSObject> m_exception; >+ WeakObjCPtr<id <JSModuleLoaderDelegate>> m_moduleLoaderDelegate; > } > > - (JSGlobalContextRef)JSGlobalContextRef >@@ -233,6 +240,16 @@ > JSGlobalContextSetDebuggerRunLoop(m_context, runLoop); > } > >+- (id<JSModuleLoaderDelegate>)moduleLoaderDelegate >+{ >+ return m_moduleLoaderDelegate.getAutoreleased(); >+} >+ >+- (void)setModuleLoaderDelegate:(id<JSModuleLoaderDelegate>)moduleLoaderDelegate >+{ >+ m_moduleLoaderDelegate = moduleLoaderDelegate; >+} >+ > @end > > @implementation JSContext(SubscriptSupport) >diff --git a/Source/JavaScriptCore/API/JSContextInternal.h b/Source/JavaScriptCore/API/JSContextInternal.h >index 28f709c1e48f1e1a80385650aae6e41cd35150fa..ab45829f0027e4fad6bfbd1afc402b3a1be85b58 100644 >--- a/Source/JavaScriptCore/API/JSContextInternal.h >+++ b/Source/JavaScriptCore/API/JSContextInternal.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -27,7 +27,7 @@ > > #if JSC_OBJC_API_ENABLED > >-#import <JavaScriptCore/JSContext.h> >+#import <JavaScriptCore/JSContextPrivate.h> > > struct CallbackData { > CallbackData* next; >diff --git a/Source/JavaScriptCore/API/JSContextPrivate.h b/Source/JavaScriptCore/API/JSContextPrivate.h >index ff9622addf60b7c10357daccf1c6f41ecb861f1c..d4e206b33575e9fa6d4182e9e1ad8940568a8677 100644 >--- a/Source/JavaScriptCore/API/JSContextPrivate.h >+++ b/Source/JavaScriptCore/API/JSContextPrivate.h >@@ -30,6 +30,27 @@ > > #import <JavaScriptCore/JSContext.h> > >+@protocol JSModuleLoaderDelegate <NSObject> >+ >+@required >+ >+/*! @abstract Provides source code for any JS module that is actively imported. >+ @param context The context for which the module is being requested. >+ @param identifier The resolved identifier for the requested module. >+ @param resolve A JS function to call with the desired script for identifier. >+ @param reject A JS function to call when identifier cannot be fetched. >+ @discussion Currently, identifier will always be an absolute file URL computed from specifier of the requested module relative to the URL of the requesting script. If the requesting script does not have a URL and the module specifier is not an absolute path the module loader will fail to load the module. >+ >+ The first argument to resolve sholud always be a JSScript, otherwise the module loader will reject the module. >+ >+ Once an identifier has been resolved or rejected in a given context it will never be requested again. If a script is successfully evaluated it will not be re-evaluated on any subsequent import. >+ >+ The VM will retain all evaluated modules for the lifetime of the context. >+ */ >+- (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject; >+ >+@end >+ > @interface JSContext(Private) > > /*! >@@ -50,6 +71,9 @@ > */ > @property (setter=_setDebuggerRunLoop:) CFRunLoopRef _debuggerRunLoop JSC_API_AVAILABLE(macosx(10.10), ios(8.0)); > >+/*! @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)); >+ > @end > > #endif >diff --git a/Source/JavaScriptCore/API/JSContextRef.cpp b/Source/JavaScriptCore/API/JSContextRef.cpp >index e18dfd21ff284007d0039e6432d9ec3c4f1f3177..9f5fdafc78196fe448c18d07915e04fa38684aaa 100644 >--- a/Source/JavaScriptCore/API/JSContextRef.cpp >+++ b/Source/JavaScriptCore/API/JSContextRef.cpp >@@ -30,9 +30,9 @@ > #include "APICast.h" > #include "CallFrame.h" > #include "InitializeThreading.h" >+#include "JSAPIGlobalObject.h" > #include "JSCallbackObject.h" > #include "JSClassRef.h" >-#include "JSGlobalObject.h" > #include "JSObject.h" > #include "JSCInlines.h" > #include "SourceProvider.h" >@@ -138,7 +138,7 @@ JSGlobalContextRef JSGlobalContextCreateInGroup(JSContextGroupRef group, JSClass > JSLockHolder locker(vm.ptr()); > > if (!globalObjectClass) { >- JSGlobalObject* globalObject = JSGlobalObject::create(vm.get(), JSGlobalObject::createStructure(vm.get(), jsNull())); >+ JSGlobalObject* globalObject = JSAPIGlobalObject::create(vm.get(), JSAPIGlobalObject::createStructure(vm.get(), jsNull())); > #if ENABLE(REMOTE_INSPECTOR) > if (JSRemoteInspectorGetInspectionEnabledByDefault()) > globalObject->setRemoteDebuggingEnabled(true); >diff --git a/Source/JavaScriptCore/API/JSScript.h b/Source/JavaScriptCore/API/JSScript.h >new file mode 100644 >index 0000000000000000000000000000000000000000..90cb609088ec82f744aa72a7cd7c1d8e13853c87 >--- /dev/null >+++ b/Source/JavaScriptCore/API/JSScript.h >@@ -0,0 +1,62 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#import <JavaScriptCore/JSValue.h> >+ >+#if JSC_OBJC_API_ENABLED >+ >+NS_ASSUME_NONNULL_BEGIN >+ >+OBJC_CLASS JSVirtualMachine; >+ >+JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA)) >+@interface JSScript : NSObject >+ >+/*! >+ @method >+ @abstract Create a JSScript for the specified virtual machine. >+ @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. >+ @result The new script. >+ */ >++ (nullable instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm; >+ >+/*! >+ @method >+ @abstract Create a JSScript for the specified virtual machine with a path to a codesigning and bytecode caching. >+ @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 codeSigningPath A URL containing the path to the codeSigning file for filePath on disk. >+ @param cachePath A URL containing the path where the VM should cache for future execution. >+ @result The new script. >+ @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. >+ */ >++ (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath; >+ >+@end >+ >+NS_ASSUME_NONNULL_END >+ >+#endif // JSC_OBJC_API_ENABLED >diff --git a/Source/JavaScriptCore/API/JSScript.mm b/Source/JavaScriptCore/API/JSScript.mm >new file mode 100644 >index 0000000000000000000000000000000000000000..796c41ef9ecc39847006cfb1b6573c5349d3fddd >--- /dev/null >+++ b/Source/JavaScriptCore/API/JSScript.mm >@@ -0,0 +1,105 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#import "config.h" >+#import "JSScriptInternal.h" >+ >+#import "APICast.h" >+#import "JSContextInternal.h" >+#import "JSValuePrivate.h" >+#import "Symbol.h" >+ >+#if JSC_OBJC_API_ENABLED >+ >+@implementation JSScript { >+ String m_source; >+} >+ >++ (instancetype)scriptWithSource:(NSString *)source inVirtualMachine:(JSVirtualMachine *)vm >+{ >+ UNUSED_PARAM(vm); >+ JSScript *result = [[JSScript alloc] init]; >+ result->m_source = source; >+ return result; >+} >+ >+template<typename Vector> >+static bool fillBufferWithContentsOfFile(FILE* file, Vector& buffer) >+{ >+ // We might have injected "use strict"; at the top. >+ size_t initialSize = buffer.size(); >+ if (fseek(file, 0, SEEK_END) == -1) >+ return false; >+ long bufferCapacity = ftell(file); >+ if (bufferCapacity == -1) >+ return false; >+ if (fseek(file, 0, SEEK_SET) == -1) >+ return false; >+ buffer.resize(bufferCapacity + initialSize); >+ size_t readSize = fread(buffer.data() + initialSize, 1, buffer.size(), file); >+ return readSize == buffer.size() - initialSize; >+} >+ >+static bool fillBufferWithContentsOfFile(const String& fileName, Vector<char>& buffer) >+{ >+ FILE* f = fopen(fileName.utf8().data(), "rb"); >+ if (!f) { >+ fprintf(stderr, "Could not open file: %s\n", fileName.utf8().data()); >+ return false; >+ } >+ >+ bool result = fillBufferWithContentsOfFile(f, buffer); >+ fclose(f); >+ >+ return result; >+} >+ >+ >++ (instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(NSURL *)codeSigningPath andBytecodeCache:(NSURL *)cachePath >+{ >+ // FIXME: This should check codeSigning. >+ UNUSED_PARAM(codeSigningPath); >+ // FIXME: This should actually cache bytecode. >+ UNUSED_PARAM(cachePath); >+ UNUSED_PARAM(vm); >+ URL filePathURL([filePath absoluteURL]); >+ if (!filePathURL.isLocalFile()) >+ return nil; >+ // FIXME: This should mmap the contents of the file instead of copying it into dirty memory. >+ Vector<char> buffer; >+ if (!fillBufferWithContentsOfFile(filePathURL.fileSystemPath(), buffer)) >+ return nil; >+ >+ JSScript *result = [[JSScript alloc] init]; >+ result->m_source = String::fromUTF8WithLatin1Fallback(buffer.data(), buffer.size()); >+ return result; >+} >+ >+const String& getJSScriptSourceCode(JSScript *module) { return module->m_source; } >+ >+@end >+ >+ >+#endif >diff --git a/Source/JavaScriptCore/API/JSScriptInternal.h b/Source/JavaScriptCore/API/JSScriptInternal.h >new file mode 100644 >index 0000000000000000000000000000000000000000..54fdfae00c746b99582b96c819007ebdd8be5a81 >--- /dev/null >+++ b/Source/JavaScriptCore/API/JSScriptInternal.h >@@ -0,0 +1,32 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+#pragma once >+ >+#import "JSScript.h" >+#import "SourceCode.h" >+ >+ >+const String& getJSScriptSourceCode(JSScript *); >diff --git a/Source/JavaScriptCore/API/JSValueInternal.h b/Source/JavaScriptCore/API/JSValueInternal.h >index 4f1a8f69cbfcc29aeb26747381d8d5f5e81baeaa..54b755efffe6ed24a5c3022b7d4c3a18500b01e0 100644 >--- a/Source/JavaScriptCore/API/JSValueInternal.h >+++ b/Source/JavaScriptCore/API/JSValueInternal.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2013 Apple Inc. All rights reserved. >+ * Copyright (C) 2013-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -26,8 +26,7 @@ > #ifndef JSValueInternal_h > #define JSValueInternal_h > >-#import <JavaScriptCore/JavaScriptCore.h> >-#import <JavaScriptCore/JSValue.h> >+#import <JavaScriptCore/JSValuePrivate.h> > > #if JSC_OBJC_API_ENABLED > >diff --git a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h >index 5ca9a7f4a107044d609b11277be8976a4367aa9b..9122ed49a4ea1aa49ec667fef6627fc43b77716d 100644 >--- a/Source/JavaScriptCore/API/JSVirtualMachineInternal.h >+++ b/Source/JavaScriptCore/API/JSVirtualMachineInternal.h >@@ -46,8 +46,8 @@ JSContextGroupRef getGroupFromVirtualMachine(JSVirtualMachine *); > > - (JSContext *)contextForGlobalContextRef:(JSGlobalContextRef)globalContext; > - (void)addContext:(JSContext *)wrapper forGlobalContextRef:(JSGlobalContextRef)globalContext; >- > @end >+ > #endif // defined(__OBJC__) > > void scanExternalObjectGraph(JSC::VM&, JSC::SlotVisitor&, void* root); >diff --git a/Source/JavaScriptCore/API/tests/testapi.mm b/Source/JavaScriptCore/API/tests/testapi.mm >index 37e1385c8c484efae8a9c3f92e135ca73f959192..435fdbb36d2446e85db5313633cd764fef7998b0 100644 >--- a/Source/JavaScriptCore/API/tests/testapi.mm >+++ b/Source/JavaScriptCore/API/tests/testapi.mm >@@ -31,7 +31,9 @@ > #import "DFGWorklist.h" > #import "DateTests.h" > #import "JSCast.h" >+#import "JSContextPrivate.h" > #import "JSExportTests.h" >+#import "JSScript.h" > #import "JSValuePrivate.h" > #import "JSVirtualMachineInternal.h" > #import "JSVirtualMachinePrivate.h" >@@ -1812,12 +1814,248 @@ static void parallelPromiseResolveTest() > } > } > >+typedef JSValue *(^ResolveBlock)(JSContext *, JSValue *, JSScript *); >+typedef void (^FetchBlock)(JSContext *, JSValue *, JSValue *, JSValue *); >+ >+@interface JSContextFetchDelegate : JSContext <JSModuleLoaderDelegate> >+ >++ (instancetype)contextWithBlockForFetch:(FetchBlock)block; >+ >+@end >+ >+@implementation JSContextFetchDelegate { >+ FetchBlock m_fetchBlock; >+} >+ >++ (instancetype)contextWithBlockForFetch:(FetchBlock)block >+{ >+ auto *result = [[JSContextFetchDelegate alloc] init]; >+ result->m_fetchBlock = block; >+ return result; >+} >+ >+- (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject >+{ >+ m_fetchBlock(context, identifier, resolve, reject); >+} >+ >+@end >+ >+static void checkModuleCodeRan(JSContext *context, JSValue *promise, JSValue *expected) >+{ >+ __block BOOL promiseWasResolved = false; >+ [promise invokeMethod:@"then" withArguments:@[^(JSValue *exportValue) { >+ promiseWasResolved = true; >+ checkResult(@"module exported value 'exp' is null", [exportValue[@"exp"] isEqualToObject:expected]); >+ checkResult(@"ran is %@", [context[@"ran"] isEqualToObject:expected]); >+ }, ^(JSValue *error) { >+ NSLog(@"%@", [error toString]); >+ checkResult(@"module graph was resolved as expected", NO); >+ }]]; >+ checkResult(@"Promise was resolved", promiseWasResolved); >+} >+ >+static void checkModuleWasRejected(JSContext *context, JSValue *promise) >+{ >+ __block BOOL promiseWasRejected = false; >+ [promise invokeMethod:@"then" withArguments:@[^() { >+ checkResult(@"module was rejected as expected", NO); >+ }, ^(JSValue *error) { >+ promiseWasRejected = true; >+ NSLog(@"%@", [error toString]); >+ checkResult(@"module graph was rejected with error", ![error isEqualWithTypeCoercionToObject:[JSValue valueWithNullInContext:context]]); >+ }]]; >+} >+ >+static void testFetch() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) { >+ if ([identifier isEqualToObject:@"file:///directory/bar.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import \"../foo.js\"; export let exp = null;" inVirtualMachine:[context virtualMachine]]]]; >+ else if ([identifier isEqualToObject:@"file:///foo.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"globalThis.ran = null;" inVirtualMachine:[context virtualMachine]]]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('./bar.js');" withSourceURL:[NSURL fileURLWithPath:@"/directory" isDirectory:YES]]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, promise, null); >+ } >+} >+ >+static void testFetchWithTwoCycle() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) { >+ if ([identifier isEqualToObject:@"file:///directory/bar.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import { n } from \"../foo.js\"; export let exp = n;" inVirtualMachine:[context virtualMachine]]]]; >+ else if ([identifier isEqualToObject:@"file:///foo.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import \"directory/bar.js\"; globalThis.ran = null; export let n = null;" inVirtualMachine:[context virtualMachine]]]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('./bar.js');" withSourceURL:[NSURL fileURLWithPath:@"/directory" isDirectory:YES]]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, promise, null); >+ } >+} >+ >+ >+static void testFetchWithThreeCycle() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) { >+ if ([identifier isEqualToObject:@"file:///directory/bar.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import { n } from \"../foo.js\"; export let foo = n;" inVirtualMachine:[context virtualMachine]]]]; >+ else if ([identifier isEqualToObject:@"file:///foo.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import \"otherDirectory/baz.js\"; export let n = null;" inVirtualMachine:[context virtualMachine]]]]; >+ else if ([identifier isEqualToObject:@"file:///otherDirectory/baz.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"import { foo } from \"../directory/bar.js\"; globalThis.ran = null; export let exp = foo;" inVirtualMachine:[context virtualMachine]]]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('../otherDirectory/baz.js');" withSourceURL:[NSURL fileURLWithPath:@"/directory" isDirectory:YES]]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, promise, null); >+ } >+} >+ >+static void testLoaderResolvesAbsoluteScriptURL() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *context, JSValue *identifier, JSValue *resolve, JSValue *reject) { >+ if ([identifier isEqualToObject:@"file:///directory/bar.js"]) >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"export let exp = null; globalThis.ran = null;" inVirtualMachine:[context virtualMachine]]]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Weird path" inContext:context]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('/directory/bar.js');"]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, promise, null); >+ } >+} >+ >+static void testLoaderRejectsNilScriptURL() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *, JSValue *, JSValue *, JSValue *) { >+ checkResult(@"Code is not run", NO); >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('../otherDirectory/baz.js');"]; >+ checkModuleWasRejected(context, promise); >+ } >+} >+ >+static void testLoaderRejectsFailedFetch() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext *context, JSValue *, JSValue *, JSValue *reject) { >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Nope" inContext:context]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('/otherDirectory/baz.js');"]; >+ checkModuleWasRejected(context, promise); >+ } >+} >+ >+static void testImportModuleTwice() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFetchDelegate contextWithBlockForFetch:^(JSContext * context, JSValue *, JSValue *resolve, JSValue *) { >+ [resolve callWithArguments:@[[JSScript scriptWithSource:@"ran++; export let exp = 1;" inVirtualMachine:[context virtualMachine]]]]; >+ }]; >+ context.moduleLoaderDelegate = context; >+ context[@"ran"] = @(0); >+ JSValue *promise = [context evaluateScript:@"import('/baz.js');"]; >+ JSValue *promise2 = [context evaluateScript:@"import('/baz.js');"]; >+ JSValue *one = [JSValue valueWithInt32:1 inContext:context]; >+ checkModuleCodeRan(context, promise, one); >+ checkModuleCodeRan(context, promise2, one); >+ } >+} >+ >+@interface JSContextFileLoaderDelegate : JSContext <JSModuleLoaderDelegate> >+ >++ (instancetype)newContext; >+ >+@end >+ >+@implementation JSContextFileLoaderDelegate { >+} >+ >++ (instancetype)newContext >+{ >+ auto *result = [[JSContextFileLoaderDelegate alloc] init]; >+ return result; >+} >+ >+static NSURL *resolvePathToScripts() >+{ >+ NSString *arg0 = NSProcessInfo.processInfo.arguments[0]; >+ NSURL *base; >+ if ([arg0 hasPrefix:@"/"]) >+ base = [NSURL fileURLWithPath:arg0 isDirectory:NO]; >+ else { >+ const size_t maxLength = 10000; >+ char cwd[maxLength]; >+ if (!getcwd(cwd, maxLength)) { >+ NSLog(@"getcwd errored with code: %s", strerror(errno)); >+ exit(1); >+ } >+ NSURL *cwdURL = [NSURL fileURLWithPath:[NSString stringWithFormat:@"%s", cwd]]; >+ base = [NSURL fileURLWithPath:arg0 isDirectory:NO relativeToURL:cwdURL]; >+ } >+ return [NSURL fileURLWithPath:@"./testapiScripts/" isDirectory:YES relativeToURL:base]; >+} >+ >+- (void)context:(JSContext *)context fetchModuleForIdentifier:(JSValue *)identifier withResolveHandler:(JSValue *)resolve andRejectHandler:(JSValue *)reject >+{ >+ NSURL *filePath = [NSURL URLWithString:[identifier toString]]; >+ auto *script = [JSScript scriptFromUTF8File:filePath inVirtualMachine:[context virtualMachine] withCodeSigning:nil andBytecodeCache:nil]; >+ if (script) >+ [resolve callWithArguments:@[script]]; >+ else >+ [reject callWithArguments:@[[JSValue valueWithNewErrorFromMessage:@"Unable to create Script" inContext:context]]]; >+} >+ >+@end >+ >+static void testLoadBasicFile() >+{ >+ @autoreleasepool { >+ auto *context = [JSContextFileLoaderDelegate newContext]; >+ context.moduleLoaderDelegate = context; >+ JSValue *promise = [context evaluateScript:@"import('./basic.js');" withSourceURL:resolvePathToScripts()]; >+ JSValue *null = [JSValue valueWithNullInContext:context]; >+ checkModuleCodeRan(context, promise, null); >+ } >+} >+ > void testObjectiveCAPI() > { > NSLog(@"Testing Objective-C API"); >+ > checkNegativeNSIntegers(); > runJITThreadLimitTests(); > >+ testLoaderResolvesAbsoluteScriptURL(); >+ testFetch(); >+ testFetchWithTwoCycle(); >+ testFetchWithThreeCycle(); >+ testImportModuleTwice(); >+ >+ testLoaderRejectsNilScriptURL(); >+ testLoaderRejectsFailedFetch(); >+ >+ // File loading >+ testLoadBasicFile(); >+ > promiseWithExecutor(Resolution::ResolveEager); > promiseWithExecutor(Resolution::RejectEager); > promiseWithExecutor(Resolution::ResolveLate); >diff --git a/Source/JavaScriptCore/API/tests/testapiScripts/basic.js b/Source/JavaScriptCore/API/tests/testapiScripts/basic.js >new file mode 100644 >index 0000000000000000000000000000000000000000..8528c49cc2a74e6699266b2c8a2c7d10da777238 >--- /dev/null >+++ b/Source/JavaScriptCore/API/tests/testapiScripts/basic.js >@@ -0,0 +1,27 @@ >+/* >+ * Copyright (C) 2019 Apple Inc. All rights reserved. >+ * >+ * Redistribution and use in source and binary forms, with or without >+ * modification, are permitted provided that the following conditions >+ * are met: >+ * 1. Redistributions of source code must retain the above copyright >+ * notice, this list of conditions and the following disclaimer. >+ * 2. Redistributions in binary form must reproduce the above copyright >+ * notice, this list of conditions and the following disclaimer in the >+ * documentation and/or other materials provided with the distribution. >+ * >+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY >+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE >+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR >+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR >+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, >+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, >+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR >+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY >+ * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT >+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE >+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. >+ */ >+ >+export let exp = null; >+globalThis.ran = null; >diff --git a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >index f3ef1c42380b3cef2f00fac658e92e9d6e799f03..638bd710e683e167cae91c503b418e24acff2e21 100644 >--- a/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >+++ b/Source/JavaScriptCore/JavaScriptCore.xcodeproj/project.pbxproj >@@ -1057,6 +1057,8 @@ > 539FB8BA1C99DA7C00940FA1 /* JSArrayInlines.h in Headers */ = {isa = PBXBuildFile; fileRef = 539FB8B91C99DA7C00940FA1 /* JSArrayInlines.h */; }; > 53B4BD121F68B32500D2BEA3 /* WasmOps.h in Headers */ = {isa = PBXBuildFile; fileRef = 533B15DE1DC7F463004D500A /* WasmOps.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 53B601EC2034B8C5006BE667 /* JSCast.h in Headers */ = {isa = PBXBuildFile; fileRef = 53B601EB2034B8C5006BE667 /* JSCast.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */ = {isa = PBXBuildFile; fileRef = 53C3D5E421ECE6CE0087FDFC /* basic.js */; }; >+ 53C4F66B21B1A409002FD009 /* JSAPIGlobalObject.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C4F66A21B1A409002FD009 /* JSAPIGlobalObject.h */; }; > 53C6FEEF1E8ADFA900B18425 /* WasmOpcodeOrigin.h in Headers */ = {isa = PBXBuildFile; fileRef = 53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */; }; > 53CA730A1EA533D80076049D /* WasmBBQPlan.h in Headers */ = {isa = PBXBuildFile; fileRef = 53CA73081EA533D80076049D /* WasmBBQPlan.h */; }; > 53D444DC1DAF08AB00B92784 /* B3WasmAddressValue.h in Headers */ = {isa = PBXBuildFile; fileRef = 53D444DB1DAF08AB00B92784 /* B3WasmAddressValue.h */; }; >@@ -1065,6 +1067,8 @@ > 53E9E0AC1EAE83DF00FEE251 /* WasmMachineThreads.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */; }; > 53E9E0AF1EAEC45700FEE251 /* WasmTierUpCount.h in Headers */ = {isa = PBXBuildFile; fileRef = 53E9E0AE1EAEC45700FEE251 /* WasmTierUpCount.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 53EAFE2F208DFAB4007D524B /* testapi.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 531D4E191F59CDD200EC836C /* testapi.cpp */; }; >+ 53EE01B6218F691600AD1F8D /* JSScript.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EE01B5218F690F00AD1F8D /* JSScript.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 53EE01B8218F7EFF00AD1F8D /* JSScriptInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 53EE01B7218F7EFF00AD1F8D /* JSScriptInternal.h */; }; > 53F11F41209138D700E411A7 /* JSImmutableButterfly.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F11F40209138D700E411A7 /* JSImmutableButterfly.h */; }; > 53F40E851D58F9770099A1B6 /* WasmSections.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E841D58F9770099A1B6 /* WasmSections.h */; }; > 53F40E8B1D5901BB0099A1B6 /* WasmFunctionParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 53F40E8A1D5901BB0099A1B6 /* WasmFunctionParser.h */; }; >@@ -1219,7 +1223,7 @@ > 86E3C615167BABD7006D760A /* JSVirtualMachine.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60F167BAB87006D760A /* JSVirtualMachine.h */; settings = {ATTRIBUTES = (Public, ); }; }; > 86E3C617167BABEE006D760A /* JSContextInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C609167BAB87006D760A /* JSContextInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 86E3C619167BABEE006D760A /* JSWrapperMap.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60C167BAB87006D760A /* JSWrapperMap.h */; }; >- 86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60E167BAB87006D760A /* JSValueInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; >+ 86E3C61B167BABEE006D760A /* JSValueInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C60E167BAB87006D760A /* JSValueInternal.h */; }; > 86E3C61D167BABEE006D760A /* JSVirtualMachineInternal.h in Headers */ = {isa = PBXBuildFile; fileRef = 86E3C611167BAB87006D760A /* JSVirtualMachineInternal.h */; settings = {ATTRIBUTES = (Private, ); }; }; > 86EC9DC51328DF82002B2AD7 /* DFGByteCodeParser.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB51328DF82002B2AD7 /* DFGByteCodeParser.h */; }; > 86EC9DC61328DF82002B2AD7 /* DFGGenerationInfo.h in Headers */ = {isa = PBXBuildFile; fileRef = 86EC9DB61328DF82002B2AD7 /* DFGGenerationInfo.h */; }; >@@ -2003,9 +2007,10 @@ > 5DBB1511131D0B130056AD36 /* Copy Support Script */ = { > isa = PBXCopyFilesBuildPhase; > buildActionMask = 12; >- dstPath = ""; >+ dstPath = testapiScripts; > dstSubfolderSpec = 16; > files = ( >+ 53C3D5E521ECE7720087FDFC /* basic.js in Copy Support Script */, > FECB8B2A1D25CB5A006F2463 /* testapi-function-overrides.js in Copy Support Script */, > 5DBB151B131D0B310056AD36 /* testapi.js in Copy Support Script */, > ); >@@ -3557,6 +3562,9 @@ > 53B0BE351E561B0900A8FC29 /* ProxyableAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ProxyableAccessCase.cpp; sourceTree = "<group>"; }; > 53B0BE371E561B2400A8FC29 /* IntrinsicGetterAccessCase.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = IntrinsicGetterAccessCase.cpp; sourceTree = "<group>"; }; > 53B601EB2034B8C5006BE667 /* JSCast.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSCast.h; sourceTree = "<group>"; }; >+ 53C3D5E421ECE6CE0087FDFC /* basic.js */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.javascript; path = basic.js; sourceTree = "<group>"; }; >+ 53C4F66A21B1A409002FD009 /* JSAPIGlobalObject.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSAPIGlobalObject.h; sourceTree = "<group>"; }; >+ 53C4F66C21B1A7CA002FD009 /* JSAPIGlobalObject.mm */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.objcpp; path = JSAPIGlobalObject.mm; sourceTree = "<group>"; }; > 53C6FEEE1E8ADFA900B18425 /* WasmOpcodeOrigin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmOpcodeOrigin.h; sourceTree = "<group>"; }; > 53C6FEF01E8AFE0C00B18425 /* WasmOpcodeOrigin.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmOpcodeOrigin.cpp; sourceTree = "<group>"; }; > 53CA73071EA533D80076049D /* WasmBBQPlan.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmBBQPlan.cpp; sourceTree = "<group>"; }; >@@ -3569,6 +3577,9 @@ > 53E9E0A91EAE83DE00FEE251 /* WasmMachineThreads.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = WasmMachineThreads.cpp; sourceTree = "<group>"; }; > 53E9E0AA1EAE83DE00FEE251 /* WasmMachineThreads.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmMachineThreads.h; sourceTree = "<group>"; }; > 53E9E0AE1EAEC45700FEE251 /* WasmTierUpCount.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = WasmTierUpCount.h; sourceTree = "<group>"; }; >+ 53EE01B4218F690E00AD1F8D /* JSScript.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = JSScript.mm; sourceTree = "<group>"; }; >+ 53EE01B5218F690F00AD1F8D /* JSScript.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScript.h; sourceTree = "<group>"; }; >+ 53EE01B7218F7EFF00AD1F8D /* JSScriptInternal.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = JSScriptInternal.h; sourceTree = "<group>"; }; > 53F11F40209138D700E411A7 /* JSImmutableButterfly.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = JSImmutableButterfly.h; sourceTree = "<group>"; }; > 53F11F422091749800E411A7 /* JSImmutableButterfly.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = JSImmutableButterfly.cpp; sourceTree = "<group>"; }; > 53F256E11B87E28000B4B768 /* JSTypedArrayViewPrototype.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = JSTypedArrayViewPrototype.cpp; sourceTree = "<group>"; }; >@@ -5538,6 +5549,7 @@ > 141211000A48772600480255 /* tests */ = { > isa = PBXGroup; > children = ( >+ 53C3D5E321ECE68E0087FDFC /* testapiScripts */, > FEF040501AAE662D00BD28B0 /* CompareAndSwapTest.cpp */, > FEF040521AAEC4ED00BD28B0 /* CompareAndSwapTest.h */, > C29ECB021804D0ED00D2CBB4 /* CurrentThisInsideBlockGetterTest.h */, >@@ -5937,6 +5949,8 @@ > 53529A4B1C457B75000B49C6 /* APIUtils.h */, > 1CAA8B4A0D32C39A0041BCFF /* JavaScript.h */, > 1CAA8B4B0D32C39A0041BCFF /* JavaScriptCore.h */, >+ 53C4F66A21B1A409002FD009 /* JSAPIGlobalObject.h */, >+ 53C4F66C21B1A7CA002FD009 /* JSAPIGlobalObject.mm */, > BC0894D50FAFBA2D00001865 /* JSAPIValueWrapper.cpp */, > BC0894D60FAFBA2D00001865 /* JSAPIValueWrapper.h */, > C2CF39C016E15A8100DD69BE /* JSAPIWrapperObject.h */, >@@ -5978,6 +5992,9 @@ > A552C37D1ADDB8FE00139726 /* JSRemoteInspector.cpp */, > A552C37E1ADDB8FE00139726 /* JSRemoteInspector.h */, > 95C18D3E0C90E7EF00E72F73 /* JSRetainPtr.h */, >+ 53EE01B5218F690F00AD1F8D /* JSScript.h */, >+ 53EE01B4218F690E00AD1F8D /* JSScript.mm */, >+ 53EE01B7218F7EFF00AD1F8D /* JSScriptInternal.h */, > A7C0C4AA167C08CD0017011D /* JSScriptRef.cpp */, > A7C0C4AB167C08CD0017011D /* JSScriptRefPrivate.h */, > 1482B74C0A43032800517CFC /* JSStringRef.cpp */, >@@ -6278,6 +6295,15 @@ > path = "unified-sources"; > sourceTree = "<group>"; > }; >+ 53C3D5E321ECE68E0087FDFC /* testapiScripts */ = { >+ isa = PBXGroup; >+ children = ( >+ 53C3D5E421ECE6CE0087FDFC /* basic.js */, >+ ); >+ name = testapiScripts; >+ path = API/tests/testapiScripts; >+ sourceTree = "<group>"; >+ }; > 650FDF8D09D0FCA700769E54 /* Derived Sources */ = { > isa = PBXGroup; > children = ( >@@ -9166,6 +9192,7 @@ > 0F5EF91F16878F7D003E5C25 /* JITThunks.h in Headers */, > 0FC712E317CD8793008CC93C /* JITToDFGDeferredCompilationCallback.h in Headers */, > DC0184191D10C1890057B053 /* JITWorklist.h in Headers */, >+ 53C4F66B21B1A409002FD009 /* JSAPIGlobalObject.h in Headers */, > 840480131021A1D9008E7F01 /* JSAPIValueWrapper.h in Headers */, > C2CF39C216E15A8100DD69BE /* JSAPIWrapperObject.h in Headers */, > BC18C4170E16F5CD00B34460 /* JSArray.h in Headers */, >@@ -9286,8 +9313,10 @@ > BC18C4260E16F5CD00B34460 /* JSRetainPtr.h in Headers */, > 534638711E70CF3D00F12AC1 /* JSRunLoopTimer.h in Headers */, > 14874AE615EBDE4A002E3587 /* JSScope.h in Headers */, >+ 53EE01B6218F691600AD1F8D /* JSScript.h in Headers */, > 9064337DD4B0402BAF34A592 /* JSScriptFetcher.h in Headers */, > E3201C1D1F8E82360076A032 /* JSScriptFetchParameters.h in Headers */, >+ 53EE01B8218F7EFF00AD1F8D /* JSScriptInternal.h in Headers */, > A7C0C4AC168103020017011D /* JSScriptRefPrivate.h in Headers */, > 0F919D11157F332C004A4E7D /* JSSegmentedVariableObject.h in Headers */, > 0F4F82881E2FFDE00075184C /* JSSegmentedVariableObjectHeapCellType.h in Headers */, >diff --git a/Source/JavaScriptCore/SourcesCocoa.txt b/Source/JavaScriptCore/SourcesCocoa.txt >index acf4fdb016d885708a4300904809a295c550da8e..af6f9ef5fc33e01f1def673f12679b1d77776b4d 100644 >--- a/Source/JavaScriptCore/SourcesCocoa.txt >+++ b/Source/JavaScriptCore/SourcesCocoa.txt >@@ -21,7 +21,9 @@ > // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF > // THE POSSIBILITY OF SUCH DAMAGE. > >+API/JSAPIGlobalObject.mm > API/JSAPIWrapperObject.mm >+API/JSScript.mm > API/JSContext.mm > API/JSManagedValue.mm > API/JSRemoteInspector.cpp >diff --git a/Source/JavaScriptCore/config.h b/Source/JavaScriptCore/config.h >index e0232cf5786af0f45d0d1308b6766806cae4e00a..e364390fdd0f7d4577dce1e46883b7e127ea5c0c 100644 >--- a/Source/JavaScriptCore/config.h >+++ b/Source/JavaScriptCore/config.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2006-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2006-2019 Apple Inc. All rights reserved. > * Copyright (C) 2006 Samuel Weinig <sam.weinig@gmail.com> > * > * This library is free software; you can redistribute it and/or >@@ -24,6 +24,7 @@ > #endif > > #define JSC_API_AVAILABLE(...) >+#define JSC_CLASS_AVAILABLE(...) JS_EXPORT > // Use zero since it will be less than any possible version number. > #define JSC_MAC_VERSION_TBA 0 > #define JSC_IOS_VERSION_TBA 0 >diff --git a/Source/JavaScriptCore/postprocess-headers.sh b/Source/JavaScriptCore/postprocess-headers.sh >index fd28836dc8bdf1e5f4939f42599a1c07f4f9bfc9..107ae1bdaed59766b170b8421d708e4c7b7f6709 100755 >--- a/Source/JavaScriptCore/postprocess-headers.sh >+++ b/Source/JavaScriptCore/postprocess-headers.sh >@@ -72,8 +72,8 @@ function rewrite_headers () { > -e s/JSC_IOS_VERSION_TBA/${IOS_VERSION_NUMBER}/g > -e s/JSC_API_AVAILABLE/API_AVAILABLE/ > -e s/JSC_API_DEPRECATED/API_DEPRECATED/ >- -e "s/^JSC_CLASS_AVAILABLE/JSC_EXTERN API_AVAILABLE/" >- -e "s/^JSC_CLASS_DEPRECATED/JSC_EXTERN API_DEPRECATED/" >+ -e "s/^JSC_CLASS_AVAILABLE/JS_EXPORT API_AVAILABLE/" >+ -e "s/^JSC_CLASS_DEPRECATED/JS_EXPORT API_DEPRECATED/" > ) > else > SED_OPTIONS+=( >diff --git a/Source/JavaScriptCore/runtime/CallData.cpp b/Source/JavaScriptCore/runtime/CallData.cpp >index c8d08ecf029b6a17a5f817eff78f1024f78d7ca0..1383a54c6f696a6adc2f45e81d37638134ca7b2f 100644 >--- a/Source/JavaScriptCore/runtime/CallData.cpp >+++ b/Source/JavaScriptCore/runtime/CallData.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2008-2018 Apple Inc. All Rights Reserved. >+ * Copyright (C) 2008-2019 Apple Inc. All Rights Reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -34,6 +34,24 @@ > > namespace JSC { > >+JSValue call(ExecState* exec, JSValue functionObject, const ArgList& args, const char* errorMessage) >+{ >+ return call(exec, functionObject, functionObject, args, errorMessage); >+} >+ >+JSValue call(ExecState* exec, JSValue functionObject, JSValue thisValue, const ArgList& args, const char* errorMessage) >+{ >+ VM& vm = exec->vm(); >+ auto scope = DECLARE_THROW_SCOPE(vm); >+ >+ CallData callData; >+ CallType callType = getCallData(vm, functionObject, callData); >+ if (callType == CallType::None) >+ return throwTypeError(exec, scope, errorMessage); >+ >+ RELEASE_AND_RETURN(scope, call(exec, functionObject, callType, callData, thisValue, args)); >+} >+ > JSValue call(ExecState* exec, JSValue functionObject, CallType callType, const CallData& callData, JSValue thisValue, const ArgList& args) > { > VM& vm = exec->vm(); >diff --git a/Source/JavaScriptCore/runtime/CallData.h b/Source/JavaScriptCore/runtime/CallData.h >index cbf916761a5b1030fe15cb6285aeac919e05bdfb..08f79df4d678013444a6a639ab4ffa49ae71b5a0 100644 >--- a/Source/JavaScriptCore/runtime/CallData.h >+++ b/Source/JavaScriptCore/runtime/CallData.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2008-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2008-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -64,6 +64,10 @@ enum class ProfilingReason { > Other > }; > >+// Convenience wrapper so you don't need to deal with CallData and CallType unless you are going to use them. >+JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, const ArgList&, const char* errorMessage); >+JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, JSValue thisValue, const ArgList&, const char* errorMessage); >+ > JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&); > JS_EXPORT_PRIVATE JSValue call(ExecState*, JSValue functionObject, CallType, const CallData&, JSValue thisValue, const ArgList&, NakedPtr<Exception>& returnedException); > >diff --git a/Source/JavaScriptCore/runtime/Completion.cpp b/Source/JavaScriptCore/runtime/Completion.cpp >index 1102f66c3226d745cae8cfba20f6af43379abed9..3fb4ab9d3aa2e34bbcd9adffa7307e7076a461af 100644 >--- a/Source/JavaScriptCore/runtime/Completion.cpp >+++ b/Source/JavaScriptCore/runtime/Completion.cpp >@@ -1,7 +1,7 @@ > /* > * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) > * Copyright (C) 2001 Peter Kelly (pmk@post.com) >- * Copyright (C) 2003-2018 Apple Inc. >+ * Copyright (C) 2003-2019 Apple Inc. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -161,6 +161,16 @@ static JSInternalPromise* rejectPromise(ExecState* exec, JSGlobalObject* globalO > return deferred->promise(); > } > >+JSInternalPromise* loadAndEvaluateModule(ExecState* exec, Symbol* moduleId, JSValue parameters, JSValue scriptFetcher) >+{ >+ VM& vm = exec->vm(); >+ JSLockHolder lock(vm); >+ RELEASE_ASSERT(vm.atomicStringTable() == Thread::current().atomicStringTable()); >+ RELEASE_ASSERT(!vm.isCollectorBusyOnCurrentThread()); >+ >+ return vm.vmEntryGlobalObject(exec)->moduleLoader()->loadAndEvaluateModule(exec, moduleId, parameters, scriptFetcher); >+} >+ > JSInternalPromise* loadAndEvaluateModule(ExecState* exec, const String& moduleName, JSValue parameters, JSValue scriptFetcher) > { > VM& vm = exec->vm(); >diff --git a/Source/JavaScriptCore/runtime/Completion.h b/Source/JavaScriptCore/runtime/Completion.h >index de448a408471c742e6f2288f1aa724e33f897497..827e61f3c61d0cb7bbe75a61277124fb0da72aae 100644 >--- a/Source/JavaScriptCore/runtime/Completion.h >+++ b/Source/JavaScriptCore/runtime/Completion.h >@@ -1,7 +1,7 @@ > /* > * Copyright (C) 1999-2001 Harri Porten (porten@kde.org) > * Copyright (C) 2001 Peter Kelly (pmk@post.com) >- * Copyright (C) 2003, 2007 Apple Inc. All rights reserved. >+ * Copyright (C) 2003-2019 Apple Inc. All rights reserved. > * > * This library is free software; you can redistribute it and/or > * modify it under the terms of the GNU Library General Public >@@ -33,6 +33,7 @@ class ExecState; > class JSObject; > class ParserError; > class SourceCode; >+class Symbol; > class VM; > class JSInternalPromise; > >@@ -57,6 +58,7 @@ inline JSValue profiledEvaluate(ExecState* exec, ProfilingReason reason, const S > JS_EXPORT_PRIVATE JSValue evaluateWithScopeExtension(ExecState*, const SourceCode&, JSObject* scopeExtension, NakedPtr<Exception>& returnedException); > > // Load the module source and evaluate it. >+JS_EXPORT_PRIVATE JSInternalPromise* loadAndEvaluateModule(ExecState*, Symbol* moduleId, JSValue parameters, JSValue scriptFetcher); > JS_EXPORT_PRIVATE JSInternalPromise* loadAndEvaluateModule(ExecState*, const String& moduleName, JSValue parameters, JSValue scriptFetcher); > JS_EXPORT_PRIVATE JSInternalPromise* loadAndEvaluateModule(ExecState*, const SourceCode&, JSValue scriptFetcher); > >diff --git a/Source/JavaScriptCore/runtime/JSCast.h b/Source/JavaScriptCore/runtime/JSCast.h >index a369d48966262aa1b629f343cb24f1f7463ac5f7..495c7e11effdf557a922b426717e8e3d4dbacde3 100644 >--- a/Source/JavaScriptCore/runtime/JSCast.h >+++ b/Source/JavaScriptCore/runtime/JSCast.h >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2018-2019 Apple Inc. All rights reserved. > * > * Redistribution and use in source and binary forms, with or without > * modification, are permitted provided that the following conditions >@@ -165,4 +165,12 @@ To jsDynamicCast(VM& vm, JSValue from) > return jsDynamicCast<To>(vm, from.asCell()); > } > >+template<typename To, typename From> >+To jsSecureCast(VM& vm, From from) >+{ >+ auto* result = jsDynamicCast<To>(vm, from); >+ RELEASE_ASSERT_WITH_SECURITY_IMPLICATION(result); >+ return result; >+} >+ > } >diff --git a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >index e86e82cfc6621c2a3493079bf8a429e64f58510d..e9d2ea58fb47fb43b661edebadc44be6a9b5d138 100644 >--- a/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >+++ b/Source/JavaScriptCore/runtime/JSGlobalObject.cpp >@@ -1,5 +1,5 @@ > /* >- * Copyright (C) 2007-2018 Apple Inc. All rights reserved. >+ * Copyright (C) 2007-2019 Apple Inc. All rights reserved. > * Copyright (C) 2008 Cameron Zwarich (cwzwarich@uwaterloo.ca) > * > * Redistribution and use in source and binary forms, with or without >@@ -62,6 +62,7 @@ > #include "Error.h" > #include "ErrorConstructor.h" > #include "ErrorPrototype.h" >+#include "Exception.h" > #include "FunctionConstructor.h" > #include "FunctionPrototype.h" > #include "GeneratorFunctionConstructor.h" >@@ -192,7 +193,7 @@ > > namespace JSC { > >- static JSValue createProxyProperty(VM& vm, JSObject* object) >+static JSValue createProxyProperty(VM& vm, JSObject* object) > { > JSGlobalObject* global = jsCast<JSGlobalObject*>(object); > return ProxyConstructor::create(vm, ProxyConstructor::createStructure(vm, global, global->functionPrototype()));
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 191121
:
353502
|
359040
|
359041
|
359044
|
359048
|
359050
|
359053
|
359054
|
359058
|
359060