Skip to content
This repository was archived by the owner on Jun 24, 2022. It is now read-only.

Commit 105499e

Browse files
Update JSScript SPI based on feedback
https://bugs.webkit.org/show_bug.cgi?id=194517 Reviewed by Keith Miller. This patch updates the JSScript SPI in the following ways: - JSScript can now represent both modules and programs. This is a property of the script determined during creation. - JSScript now takes a sourceURL during construction. For modules, this acts as the module identifier. - JSScript now has SPI for writing the cache out to disk. We don't do this automatically. - JSScript will load the bytecode cache on creation if it exists. - We retrofit these new requirements on the prior JSScript SPI that we're going to remove as soon as we can: https://bugs.webkit.org/show_bug.cgi?id=194909. Previous SPI assumes all JSScripts are modules. Previous SPI also assigns a sourceURL to the JSScript based on what the module loader decided the identifier should be. We'll remove this once we remove the old SPI. This patch also adds SPI to JSContext to evaluate a JSScript. For modules, this is like returning the result of doing dynamic import. For programs, this does normal program evaluation. This patch also fixes a bug in generateBytecode/generateModuleBytecode where we would try to cache the bytecode even if recursivelyGenerateUnlinkedCodeBlock returned null. E.g, if the script had a syntax error. When writing tests, I also discovered that someone previously broke testapi. This patch also fixes those failures. They were broken when we switched to using a testapiScripts directory to hold our test .js scripts. * API/JSAPIGlobalObject.h: * API/JSAPIGlobalObject.mm: (JSC::JSAPIGlobalObject::moduleLoaderResolve): (JSC::JSAPIGlobalObject::moduleLoaderFetch): (JSC::JSAPIGlobalObject::loadAndEvaluateJSScriptModule): * API/JSBase.cpp: (JSEvaluateScriptInternal): (JSEvaluateScript): * API/JSBaseInternal.h: Added. * API/JSContext.mm: (-[JSContext evaluateScript:withSourceURL:]): (-[JSContext evaluateJSScript:]): * API/JSContextPrivate.h: * API/JSScript.h: * API/JSScript.mm: (+[JSScript scriptWithSource:inVirtualMachine:]): (+[JSScript scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:]): (createError): (+[JSScript scriptOfType:inVirtualMachine:withSourceURL:andSource:andBytecodeCache:error:]): (+[JSScript scriptOfType:inVirtualMachine:memoryMappedFromASCIIFile:withSourceURL:andBytecodeCache:error:]): (-[JSScript cacheBytecodeWithError:]): (-[JSScript sourceURL]): (-[JSScript type]): (-[JSScript jsSourceCode]): (-[JSScript writeCache:]): (-[JSScript setSourceURL:]): (-[JSScript forceRecreateJSSourceCode]): (-[JSScript writeCache]): Deleted. (-[JSScript jsSourceCode:]): Deleted. * API/JSScriptInternal.h: * API/tests/FunctionOverridesTest.cpp: (testFunctionOverrides): * API/tests/testapi.c: (main): * API/tests/testapi.mm: (tempFile): (testModuleBytecodeCache): (testProgramBytecodeCache): (testBytecodeCacheWithSyntaxError): (testProgramJSScriptException): (testLoadBasicFileLegacySPI): (+[JSContextMemoryMappedLoaderDelegate newContext]): (-[JSContextMemoryMappedLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): (testLoadBasicFile): (+[JSContextAugmentedLoaderDelegate newContext]): (-[JSContextAugmentedLoaderDelegate context:fetchModuleForIdentifier:withResolveHandler:andRejectHandler:]): (testJSScriptURL): (testObjectiveCAPI): (testBytecodeCache): Deleted. * API/tests/testapiScripts/foo.js: Added. * JavaScriptCore.xcodeproj/project.pbxproj: * runtime/Completion.cpp: (JSC::generateBytecode): (JSC::generateModuleBytecode): git-svn-id: http://svn.webkit.org/repository/webkit/trunk@241929 268f45cc-cd09-0410-ab3c-d52691b4dbfc
1 parent a9ad782 commit 105499e

File tree

18 files changed

+778
-119
lines changed

18 files changed

+778
-119
lines changed

Source/JavaScriptCore/API/JSAPIGlobalObject.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,8 @@
2727

2828
#include "JSGlobalObject.h"
2929

30+
OBJC_CLASS JSScript;
31+
3032
namespace JSC {
3133

3234
class JSAPIGlobalObject : public JSGlobalObject {
@@ -55,6 +57,8 @@ class JSAPIGlobalObject : public JSGlobalObject {
5557
static JSInternalPromise* moduleLoaderFetch(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSValue, JSValue);
5658
static JSObject* moduleLoaderCreateImportMetaProperties(JSGlobalObject*, ExecState*, JSModuleLoader*, JSValue, JSModuleRecord*, JSValue);
5759

60+
JSValue loadAndEvaluateJSScriptModule(const JSLockHolder&, JSScript *);
61+
5862
private:
5963
JSAPIGlobalObject(VM& vm, Structure* structure)
6064
: Base(vm, structure, &s_globalObjectMethodTable)

Source/JavaScriptCore/API/JSAPIGlobalObject.mm

Lines changed: 59 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -34,16 +34,17 @@
3434
#import "Error.h"
3535
#import "Exception.h"
3636
#import "JSContextInternal.h"
37+
#import "JSInternalPromise.h"
3738
#import "JSInternalPromiseDeferred.h"
3839
#import "JSNativeStdFunction.h"
40+
#import "JSPromiseDeferred.h"
3941
#import "JSScriptInternal.h"
4042
#import "JSSourceCode.h"
4143
#import "JSValueInternal.h"
4244
#import "JSVirtualMachineInternal.h"
4345
#import "JavaScriptCore.h"
4446
#import "ObjectConstructor.h"
4547
#import "SourceOrigin.h"
46-
4748
#import <wtf/URL.h>
4849

4950
namespace JSC {
@@ -75,12 +76,20 @@
7576
ASSERT(key.isString() || key.isSymbol());
7677
String name = key.toWTFString(exec);
7778

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+
}
8493

8594
throwVMError(exec, scope, "Could not form valid URL from identifier and base"_s);
8695
return { };
@@ -162,20 +171,43 @@
162171
return deferred->reject(exec, createError(exec, "No module loader provided."));
163172

164173
auto deferredPromise = Strong<JSInternalPromiseDeferred>(vm, deferred);
165-
auto strongKey = Strong<JSString>(vm, jsSecureCast<JSString*>(vm, key));
166174
auto* resolve = JSNativeStdFunction::create(vm, globalObject, 1, "resolve", [=] (ExecState* exec) {
167175
// This captures the globalObject but that's ok because our structure keeps it alive anyway.
176+
VM& vm = exec->vm();
168177
JSContext *context = [JSContext contextWithJSGlobalContextRef:toGlobalRef(globalObject->globalExec())];
169178
id script = valueToObject(context, toRef(exec, exec->argument(0)));
170179

171180
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));
174184
call(exec, deferredPromise->JSPromiseDeferred::reject(), args, "This should never be seen...");
175185
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];
176208
}
177209

178-
args.append([static_cast<JSScript *>(script) jsSourceCode:moduleKey]);
210+
args.append(source);
179211
call(exec, deferredPromise->JSPromiseDeferred::resolve(), args, "This should never be seen...");
180212
return encodedJSUndefined();
181213
});
@@ -210,6 +242,22 @@
210242
return metaProperties;
211243
}
212244

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+
213261
}
214262

215263
#endif // JSC_OBJC_API_ENABLED

Source/JavaScriptCore/API/JSBase.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525

2626
#include "config.h"
2727
#include "JSBase.h"
28+
#include "JSBaseInternal.h"
2829
#include "JSBasePrivate.h"
2930

3031
#include "APICast.h"
@@ -47,25 +48,15 @@
4748

4849
using namespace JSC;
4950

50-
JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef thisObject, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
51+
JSValueRef JSEvaluateScriptInternal(const JSLockHolder&, ExecState* exec, JSContextRef ctx, JSObjectRef thisObject, const SourceCode& source, JSValueRef* exception)
5152
{
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);
53+
UNUSED_PARAM(ctx);
5954

6055
JSObject* jsThisObject = toJS(thisObject);
6156

62-
startingLineNumber = std::max(1, startingLineNumber);
63-
6457
// evaluate sets "this" to the global object if it is NULL
58+
VM& vm = exec->vm();
6559
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-
6960
NakedPtr<Exception> evaluationException;
7061
JSValue returnValue = profiledEvaluate(globalObject->globalExec(), ProfilingReason::API, source, jsThisObject, evaluationException);
7162

@@ -80,7 +71,7 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
8071
// We could stash it in the inspector in case an inspector is ever opened.
8172
globalObject->inspectorController().reportAPIException(exec, evaluationException);
8273
#endif
83-
return 0;
74+
return nullptr;
8475
}
8576

8677
if (returnValue)
@@ -90,6 +81,24 @@ JSValueRef JSEvaluateScript(JSContextRef ctx, JSStringRef script, JSObjectRef th
9081
return toRef(exec, jsUndefined());
9182
}
9283

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);
100+
}
101+
93102
bool JSCheckScriptSyntax(JSContextRef ctx, JSStringRef script, JSStringRef sourceURL, int startingLineNumber, JSValueRef* exception)
94103
{
95104
if (!ctx) {
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
/*
2+
* Copyright (C) 2019 Apple Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions
6+
* are met:
7+
* 1. Redistributions of source code must retain the above copyright
8+
* notice, this list of conditions and the following disclaimer.
9+
* 2. Redistributions in binary form must reproduce the above copyright
10+
* notice, this list of conditions and the following disclaimer in the
11+
* documentation and/or other materials provided with the distribution.
12+
*
13+
* THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14+
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16+
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17+
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18+
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19+
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20+
* PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21+
* OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
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.
24+
*/
25+
26+
#pragma once
27+
28+
#include <JavaScriptCore/JSBase.h>
29+
#include <JavaScriptCore/WebKitAvailability.h>
30+
31+
namespace JSC {
32+
class JSLockHolder;
33+
class ExecState;
34+
}
35+
36+
extern "C" JSValueRef JSEvaluateScriptInternal(const JSC::JSLockHolder&, JSC::ExecState*, JSContextRef, JSObjectRef thisObject, const JSC::SourceCode&, JSValueRef* exception);

Source/JavaScriptCore/API/JSContext.mm

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
#import "APICast.h"
2929
#import "Completion.h"
30+
#import "JSBaseInternal.h"
3031
#import "JSCInlines.h"
3132
#import "JSContextInternal.h"
3233
#import "JSContextPrivate.h"
@@ -112,10 +113,38 @@ - (JSValue *)evaluateScript:(NSString *)script withSourceURL:(NSURL *)sourceURL
112113

113114
if (exceptionValue)
114115
return [self valueFromNotifyException:exceptionValue];
115-
116116
return [JSValue valueWithJSValueRef:result inContext:self];
117117
}
118118

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];
146+
}
147+
119148
- (void)setException:(JSValue *)value
120149
{
121150
JSC::ExecState* exec = toJS(m_context);

Source/JavaScriptCore/API/JSContextPrivate.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@
7474
/*! @abstract The delegate the context will use when trying to load a module. Note, this delegate will be ignored for contexts returned by UIWebView. */
7575
@property (nonatomic, weak) id <JSModuleLoaderDelegate> moduleLoaderDelegate JSC_API_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA));
7676

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+
7787
@end
7888

7989
#endif

Source/JavaScriptCore/API/JSScript.h

Lines changed: 54 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,37 +31,84 @@ NS_ASSUME_NONNULL_BEGIN
3131

3232
@class JSVirtualMachine;
3333

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+
3446
JSC_CLASS_AVAILABLE(macosx(JSC_MAC_TBA), ios(JSC_IOS_TBA))
3547
@interface JSScript : NSObject
3648

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+
3764
/*!
3865
@method
3966
@abstract Create a JSScript for the specified virtual machine.
67+
@param type The type of JavaScript source.
4068
@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.
4171
@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.
4273
@result The new script.
74+
@discussion The file at cachePath should not be externally modified for the lifecycle of vm.
4375
*/
44-
+ (nullable instancetype)scriptWithSource:(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;
4577

4678
/*!
4779
@method
4880
@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.
4982
@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.
5085
@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.
5387
@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.
5589
5690
If the file at filePath is not ascii this method will return nil.
5791
*/
58-
+ (nullable instancetype)scriptFromASCIIFile:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath;
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;
93+
94+
/*!
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.
98+
*/
99+
- (BOOL)cacheBytecodeWithError:(out NSError * _Nullable * _Nullable)error;
59100

101+
/*!
102+
@method
103+
@abstract Returns the JSScriptType of this JSScript.
104+
*/
105+
- (JSScriptType)type;
60106

61107
/*!
62-
This is deprecated and is equivalent to scriptFromASCIIFile:inVirtualMachine:withCodeSigning:andBytecodeCache:.
108+
@method
109+
@abstract Returns the sourceURL of this JSScript.
63110
*/
64-
+ (nullable instancetype)scriptFromUTF8File:(NSURL *)filePath inVirtualMachine:(JSVirtualMachine *)vm withCodeSigning:(nullable NSURL *)codeSigningPath andBytecodeCache:(nullable NSURL *)cachePath;
111+
- (NSURL *)sourceURL;
65112

66113
@end
67114

0 commit comments

Comments
 (0)