Slide 1

Slide 1 text

What the heck is JavaScriptCore? Cesare Rocchi @_funkyboy

Slide 2

Slide 2 text

TOC • History • What’s JSCore • Demos • What’s new in WebKit

Slide 3

Slide 3 text

Who am I?

Slide 4

Slide 4 text

UX designer and developer

Slide 5

Slide 5 text

studiomagnolia.com

Slide 6

Slide 6 text

upbeat.it

Slide 7

Slide 7 text

appversion.io

Slide 8

Slide 8 text

podrover.com

Slide 9

Slide 9 text

Who are you?

Slide 10

Slide 10 text

History

Slide 11

Slide 11 text

stringByEvaluatingJavaScriptFromString:

Slide 12

Slide 12 text

10.2

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

No content

Slide 15

Slide 15 text

iOS7

Slide 16

Slide 16 text

iOS7

Slide 17

Slide 17 text

JSContext

Slide 18

Slide 18 text

JSValue

Slide 19

Slide 19 text

NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"temperature" ofType:@"js"];

Slide 20

Slide 20 text

NSString *scriptCode = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:nil];

Slide 21

Slide 21 text

self.context = [[JSContext alloc] init]; [self.context evaluateScript:scriptCode];

Slide 22

Slide 22 text

NSString *scriptPath = [[NSBundle mainBundle] pathForResource:@"temperature" ofType:@"js"]; NSString *scriptCode = [NSString stringWithContentsOfFile:scriptPath encoding:NSUTF8StringEncoding error:nil]; self.context = [[JSContext alloc] init]; [self.context evaluateScript:scriptCode];

Slide 23

Slide 23 text

JS <-> Native

Slide 24

Slide 24 text

Blocks

Slide 25

Slide 25 text

JSExport

Slide 26

Slide 26 text

Demo Objc Demo Swift

Slide 27

Slide 27 text

React.js

Slide 28

Slide 28 text

#define RCT_EXTERN_REMAP_METHOD(js_name, method) \ - (void)__rct_export__##method { \ __attribute__((used, section("__DATA,RCTExport"))) \ __attribute__((__aligned__(1))) \ static const char *__rct_export_entry__[] = { __func__, #method, #js_name }; \ } https://github.com/facebook/react-native/blob/b99744a164f96be2989d686495a1c7d1afac737a/React/Base/ RCTBridgeModule.h#L141

Slide 29

Slide 29 text

Questions?

Slide 30

Slide 30 text

No plugins Flash Applets

Slide 31

Slide 31 text

The full Safari engine is inside of iPhone. And so, you can write amazing Web 2.0 and Ajax apps that look exactly and behave exactly like apps on the iPhone. SJ, 2007 “ ”

Slide 32

Slide 32 text

History • No plugins • Flash • Applets

Slide 33

Slide 33 text

No content

Slide 34

Slide 34 text

Adobe, don’t even think about it!

Slide 35

Slide 35 text

No content

Slide 36

Slide 36 text

No content

Slide 37

Slide 37 text

History • Nitro was introduced in iOS 4.3 • Uses JIT • Transform JS into native code Needs to mark memory w+x • Security issues

Slide 38

Slide 38 text

No content

Slide 39

Slide 39 text

var temp = {}; temp[10123] = "cocoaconf";

Slide 40

Slide 40 text

Progress

Slide 41

Slide 41 text

iOS 3.2 -> iOS4 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iPhone40APIDiffs/index.html Added UIWebView.allowsInlineMediaPlayback Added UIWebView.mediaPlaybackRequiresUserAction

Slide 42

Slide 42 text

iOS 4.3 -> iOS5 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS50APIDiff/index.html Added UIWebView.mediaPlaybackAllowsAirPlay Added UIWebView.scrollView

Slide 43

Slide 43 text

iOS 5.1 -> iOS6 https://developer.apple.com/LIBRARY/ios/releasenotes/General/iOS60APIDiffs/index.html Added UIWebView.keyboardDisplayRequiresUserAction Added UIWebView.suppressesIncrementalRendering

Slide 44

Slide 44 text

iOS 6.1 -> iOS7 https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDiffs/index.html Added UIWebView.gapBetweenPages Added UIWebView.pageCount Added UIWebView.pageLength Added UIWebView.paginationBreakingMode Added UIWebView.paginationMode Added UIWebPaginationBreakingMode Added UIWebPaginationBreakingModeColumn Added UIWebPaginationBreakingModePage Added UIWebPaginationMode Added UIWebPaginationModeBottomToTop Added UIWebPaginationModeLeftToRight Added UIWebPaginationModeRightToLeft Added UIWebPaginationModeTopToBottom Added UIWebPaginationModeUnpaginated

Slide 45

Slide 45 text

iOS 6.1 -> iOS7 https://developer.apple.com/library/IOS/releasenotes/General/iOS70APIDiffs/index.html Added #def JSC_OBJC_API_ENABLED Added JSCheckScriptSyntax() Added JSClassRef Added JSContextGroupRef Added JSContextRef Added JSEvaluateScript() Added JSGarbageCollect() Added JSGlobalContextRef Added JSObjectRef Added JSPropertyNameAccumulatorRef Added JSPropertyNameArrayRef Added JSStringRef Added JSValueRef Added #def WTF_EXPORT_PRIVATE Added #def WTF_PLATFORM_IOS Added JSContext Added -[JSContext JSGlobalContextRef] Added +[JSContext contextWithJSGlobalContextRef:] Added +[JSContext currentArguments] Added +[JSContext currentContext] Added +[JSContext currentThis] Added -[JSContext evaluateScript:] Added JSContext.exception Added JSContext.exceptionHandler Added -[JSContext globalObject] Added -[JSContext init] Added -[JSContext initWithVirtualMachine:] Added -[JSContext objectForKeyedSubscript:] Added -[JSContext setObject:forKeyedSubscript:] Added JSContext.virtualMachine Added JSContext(JSContextRefSupport) Added JSContext(SubscriptSupport) Added #def JSContext_h Added JSContextGetGlobalObject() Added JSContextGetGroup() Added JSContextGroupCreate() Added JSContextGroupRelease() Added JSContextGroupRetain() Added JSGlobalContextCreate() Added JSGlobalContextCreateInGroup() Added JSGlobalContextRelease() Added JSGlobalContextRetain() Added JSExport Added #def JSExportAs Added JSManagedValue Added -[JSManagedValue initWithValue:] Added +[JSManagedValue managedValueWithValue:] Added -[JSManagedValue value] Added #def JSManagedValue_h Added JSClassAttributes Added JSClassCreate() Added JSClassDefinition Added JSClassRelease() Added JSClassRetain() Added JSObjectCallAsConstructor() Added JSObjectCallAsConstructorCallback Added JSObjectCallAsFunction() Added JSObjectCallAsFunctionCallback Added JSObjectConvertToTypeCallback Added JSObjectCopyPropertyNames() Added JSObjectDeleteProperty() Added JSObjectDeletePropertyCallback Added JSObjectFinalizeCallback Added JSObjectGetPrivate() Added JSObjectGetProperty() Added JSObjectGetPropertyAtIndex() Added JSObjectGetPropertyCallback Added JSObjectGetPropertyNamesCallback Added JSObjectGetPrototype() Added JSObjectHasInstanceCallback Added JSObjectHasProperty() Added JSObjectHasPropertyCallback Added JSObjectInitializeCallback Added JSObjectIsConstructor() Added JSObjectIsFunction() Added JSObjectMake() Added JSObjectMakeArray() Added JSObjectMakeConstructor() Added JSObjectMakeDate() Added JSObjectMakeError() Added JSObjectMakeFunction() Added JSObjectMakeFunctionWithCallback() Added JSObjectMakeRegExp() Added JSObjectSetPrivate() Added JSObjectSetProperty() Added JSObjectSetPropertyAtIndex() Added JSObjectSetPropertyCallback Added JSObjectSetPrototype() Added JSPropertyAttributes Added JSPropertyNameAccumulatorAddName() Added JSPropertyNameArrayGetCount() Added JSPropertyNameArrayGetNameAtIndex() Added JSPropertyNameArrayRelease() Added JSPropertyNameArrayRetain() Added JSStaticFunction Added JSStaticValue Added kJSClassAttributeNoAutomaticPrototype Added kJSClassAttributeNone Added kJSClassDefinitionEmpty Added kJSPropertyAttributeDontDelete Added kJSPropertyAttributeDontEnum Added kJSPropertyAttributeNone Added kJSPropertyAttributeReadOnly Added JSChar Added JSStringCreateWithCharacters() Added JSStringCreateWithUTF8CString() Added JSStringGetCharactersPtr() Added JSStringGetLength() Added JSStringGetMaximumUTF8CStringSize() Added JSStringGetUTF8CString() Added JSStringIsEqual() Added JSStringIsEqualToUTF8CString() Added JSStringRelease() Added JSStringRetain() Added JSStringCopyCFString() Added JSStringCreateWithCFString() Added JSValue Added -[JSValue JSValueRef] Added -[JSValue callWithArguments:] Added -[JSValue constructWithArguments:] Added JSValue.context Added -[JSValue defineProperty:descriptor:] Added -[JSValue deleteProperty:] Added -[JSValue hasProperty:] Added -[JSValue invokeMethod:withArguments:] Added -[JSValue isBoolean] Added -[JSValue isEqualToObject:] Added -[JSValue isEqualWithTypeCoercionToObject:] Added -[JSValue isInstanceOf:] Added -[JSValue isNull] Added -[JSValue isNumber] Added -[JSValue isObject] Added -[JSValue isString] Added -[JSValue isUndefined] Added -[JSValue objectAtIndexedSubscript:] Added -[JSValue objectForKeyedSubscript:] Added -[JSValue setObject:atIndexedSubscript:] Added -[JSValue setObject:forKeyedSubscript:] Added -[JSValue setValue:atIndex:] Added -[JSValue setValue:forProperty:] Added -[JSValue toArray] Added -[JSValue toBool] Added -[JSValue toDate] Added -[JSValue toDictionary] Added -[JSValue toDouble] Added -[JSValue toInt32] Added -[JSValue toNumber] Added -[JSValue toObject] Added -[JSValue toObjectOfClass:] Added -[JSValue toPoint] Added -[JSValue toRange] Added -[JSValue toRect] Added -[JSValue toSize] Added -[JSValue toString] Added -[JSValue toUInt32] Added -[JSValue valueAtIndex:] Added -[JSValue valueForProperty:] Added +[JSValue valueWithBool:inContext:] Added +[JSValue valueWithDouble:inContext:] Added +[JSValue valueWithInt32:inContext:] Added +[JSValue valueWithJSValueRef:inContext:] Added +[JSValue valueWithNewArrayInContext:] Added +[JSValue valueWithNewErrorFromMessage:inContext:] Added +[JSValue valueWithNewObjectInContext:] Added +[JSValue valueWithNewRegularExpressionFromPattern:flags:inContext:] Added +[JSValue valueWithNullInContext:] Added +[JSValue valueWithObject:inContext:] Added +[JSValue valueWithPoint:inContext:] Added +[JSValue valueWithRange:inContext:] Added +[JSValue valueWithRect:inContext:] Added +[JSValue valueWithSize:inContext:] Added +[JSValue valueWithUInt32:inContext:] Added +[JSValue valueWithUndefinedInContext:] Added JSPropertyDescriptorConfigurableKey Added JSPropertyDescriptorEnumerableKey Added JSPropertyDescriptorGetKey Added JSPropertyDescriptorSetKey Added JSPropertyDescriptorValueKey Added JSPropertyDescriptorWritableKey Added JSValue(JSValueRefSupport) Added JSValue(StructSupport) Added JSValue(SubscriptSupport) Added #def JSValue_h Added JSType Added JSValueCreateJSONString() Added JSValueGetType() Added JSValueIsBoolean() Added JSValueIsEqual() Added JSValueIsInstanceOfConstructor() Added JSValueIsNull() Added JSValueIsNumber() Added JSValueIsObject() Added JSValueIsObjectOfClass() Added JSValueIsStrictEqual() Added JSValueIsString() Added JSValueIsUndefined() Added JSValueMakeBoolean() Added JSValueMakeFromJSONString() Added JSValueMakeNull() Added JSValueMakeNumber() Added JSValueMakeString() Added JSValueMakeUndefined() Added JSValueProtect() Added JSValueToBoolean() Added JSValueToNumber() Added JSValueToObject() Added JSValueToStringCopy() Added JSValueUnprotect() Added kJSTypeBoolean Added kJSTypeNull Added kJSTypeNumber Added kJSTypeObject Added kJSTypeString Added kJSTypeUndefined Added JSVirtualMachine Added -[JSVirtualMachine addManagedReference:withOwner:] Added -[JSVirtualMachine init] Added -[JSVirtualMachine removeManagedReference:withOwner:] Added #def AVAILABLE_AFTER_WEBKIT_VERSION_5_1 Added #def AVAILABLE_WEBKIT_VERSION_1_3_AND_LATER_BUT_DEPRECATED_AFTER_WEBKIT_VERSION_5_1 Added #def WEBKIT_OBJC_METHOD_ANNOTATION Added #def WEBKIT_VERSION_1_0 Added #def WEBKIT_VERSION_1_1 Added #def WEBKIT_VERSION_1_2 Added #def WEBKIT_VERSION_1_3 Added #def WEBKIT_VERSION_2_0 Added #def WEBKIT_VERSION_3_0 Added #def WEBKIT_VERSION_3_1 Added #def WEBKIT_VERSION_4_0 Added #def WEBKIT_VERSION_LATEST Added #def WEBKIT_VERSION_MAX_ALLOWED Added #def WEBKIT_VERSION_MIN_REQUIRED 232 APIs }

Slide 46

Slide 46 text

No content

Slide 47

Slide 47 text

iOS7 -> iOS8 https://developer.apple.com/library/prerelease/ios/releasenotes/General/iOS80APIDiffs/frameworks/WebKit.html

Slide 48

Slide 48 text

1 Class 1 Protocol

Slide 49

Slide 49 text

UIWebView UIWebViewDelegate

Slide 50

Slide 50 text

14 Classes 3 Protocols

Slide 51

Slide 51 text

WKWebView WKFrameInfo WKBackForwardList WKBackForwardListItem WKNavigation WKNavigationAction WKNavigationResponse WKPreferences WKProcessPool WKUserContentController WKWebViewConfiguration WKWindowFeatures WKScriptMessage WKUserScript WKNavigationDelegate WKScriptMessageHandler WKUIDelegate

Slide 52

Slide 52 text

XPC • Greatly improved in iOS8 • Third party keyboards • Sharing extensions

Slide 53

Slide 53 text

XPC find /Applications -name \*.xpc | grep Web | wc -l

Slide 54

Slide 54 text

XPC • Split app in multiple processes • E.g. Sourcekit • http://www.jpsim.com/uncovering-sourcekit/

Slide 55

Slide 55 text

r167958

Slide 56

Slide 56 text

No content

Slide 57

Slide 57 text

Optimizing JS

Slide 58

Slide 58 text

Wat? https://www.youtube.com/watch?v=20BySC_6HyY

Slide 59

Slide 59 text

jsc sudo ln -s /System/Library/Frameworks/ JavaScriptCore.framework/Versions/Current/Resources/jsc /bin/jsc

Slide 60

Slide 60 text

JS bytecode LLInt JIT DFG optimization

Slide 61

Slide 61 text

function sum(a, b) { return a + b; }

Slide 62

Slide 62 text

LLInt JIT DFG optimization function sum(a, b) { return a + b; }

Slide 63

Slide 63 text

LLInt JIT DFG

Slide 64

Slide 64 text

LLVM

Slide 65

Slide 65 text

LLVM • Infrastructure • Meant to optimize *time • Started by Mr. Swift

Slide 66

Slide 66 text

LLInt JIT DFG

Slide 67

Slide 67 text

LLInt JIT DFG FTL

Slide 68

Slide 68 text

What’s new

Slide 69

Slide 69 text

Observable values

Slide 70

Slide 70 text

Observable values • loading • title • URL • estimatedProgress

Slide 71

Slide 71 text

Observable values webView.addObserver(self, forKeyPath: "loading", options: .New, context: nil)

Slide 72

Slide 72 text

Observable values override func observeValueForKeyPath(...) { switch keyPath { case "loading": println("\(webView.loading)") case "estimatedProgress": println("\(webView.estimatedProgress)") … } }

Slide 73

Slide 73 text

Injecting

Slide 74

Slide 74 text

Action Request Response Rendering

Slide 75

Slide 75 text

Action Request Response Rendering

Slide 76

Slide 76 text

Action Request

Slide 77

Slide 77 text

Action Request webView:decidePolicyForNavigationAction:decisionHandler

Slide 78

Slide 78 text

Response Rendering

Slide 79

Slide 79 text

Response Rendering webView:decidePolicyForNavigationResponse:decisionHandler:

Slide 80

Slide 80 text

func webView(webView: WKWebView!, decidePolicyForNavigationAction navigationAction: WKNavigationAction!, decisionHandler: ((WKNavigationActionPolicy) -> Void)!) { if (navigationAction.navigationType == .LinkActivated && navigationAction.request.URL.host?. lowercaseString.hasPrefix("cocoaconference.com/") != nil) { // Open Safari UIApplication.sharedApplication().openURL(navigationAction.request.URL); decisionHandler(.Cancel) } else { decisionHandler(.Allow) } }

Slide 81

Slide 81 text

Native code HTML Page JS Data

Slide 82

Slide 82 text

Data is serialized into native objects!

Slide 83

Slide 83 text

Injecting 1. Create configuration 2. Wrap JS script in a WKUserScript 3. Add script to configuration controller 4. Set up handler 5. Use configuration to build a Web view

Slide 84

Slide 84 text

let speakersWebViewConfiguration = WKWebViewConfiguration()

Slide 85

Slide 85 text

let scriptURL = NSBundle.mainBundle().pathForResource("fetchSpeakers", ofType: “js") let jsScript = String(contentsOfFile:scriptURL, encoding:NSUTF8StringEncoding, error: nil) let fetchAuthorsScript = WKUserScript(source: jsScript, injectionTime: .AtDocumentEnd, forMainFrameOnly: true)

Slide 86

Slide 86 text

speakersWebViewConfiguration. userContentController. addUserScript(fetchAuthorsScript)

Slide 87

Slide 87 text

speakersWebViewConfiguration. userContentController. addScriptMessageHandler(self, name: MESSAGE_HANDLER)

Slide 88

Slide 88 text

speakersWebView = WKWebView(frame: CGRectZero, configuration: speakersWebViewConfiguration)

Slide 89

Slide 89 text

speakersWebView.addObserver(self, forKeyPath: "loading", options: .New, context: nil) speakersWebView.addObserver(self, forKeyPath: "estimatedProgress", options: .New, context: nil)

Slide 90

Slide 90 text

let speakersRequest = NSURLRequest(URL:speakersURL) speakersWebView!.loadRequest(speakersRequest)

Slide 91

Slide 91 text

No content

Slide 92

Slide 92 text

No content

Slide 93

Slide 93 text

No content

Slide 94

Slide 94 text

No content

Slide 95

Slide 95 text

No content

Slide 96

Slide 96 text

Demo

Slide 97

Slide 97 text

https://github.com/ funkyboy/Cocoaconf- SanJose-2015

Slide 98

Slide 98 text

Caution

Slide 99

Slide 99 text

https://developer.apple.com/app-store/review/guidelines/

Slide 100

Slide 100 text

https://developer.apple.com/app-store/review/guidelines/

Slide 101

Slide 101 text

https://developer.apple.com/app-store/review/guidelines/

Slide 102

Slide 102 text

https://developer.apple.com/app-store/review/guidelines/

Slide 103

Slide 103 text

https://developer.apple.com/programs/terms/ios/standard/ ios_program_standard_agreement_20140909.pdf An Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple's built- in WebKit framework, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.

Slide 104

Slide 104 text

https://developer.apple.com/programs/terms/ios/standard/ ios_program_standard_agreement_20140909.pdf An Application may not download or install executable code. Interpreted code may only be used in an Application if all scripts, code and interpreters are packaged in the Application and not downloaded. The only exception to the foregoing is scripts and code downloaded and run by Apple's built- in WebKit framework, provided that such scripts and code do not change the primary purpose of the Application by providing features or functionality that are inconsistent with the intended and advertised purpose of the Application as submitted to the App Store.

Slide 105

Slide 105 text

Building a native app is like building a custom browser

Slide 106

Slide 106 text

Building a native app is like building a custom browser Me, now

Slide 107

Slide 107 text

Summing up

Slide 108

Slide 108 text

No content

Slide 109

Slide 109 text

Links • https://www.webkit.org/blog/3362/ introducing-the-webkit-ftl-jit/ • http://trac.webkit.org/changeset/167958 • https://www.destroyallsoftware.com/ talks/wat • WWDC Video #206

Slide 110

Slide 110 text

Contact • [email protected] • @_funkyboy