Writing Web Apps in C++? Eric Bidelman, Google COSCUP / GNOME.Asia - Taipei, Taiwan August 14, 2010

Similar documents
Get your port on! porting to Native Client as of Pepper 18. Colt "MainRoach" McAnlis

Build Native-like Experiences in HTML5

CSCE 120: Learning To Code

JavaScript CS 4640 Programming Languages for Web Applications

CS 211 Programming Practicum Spring 2017

The Stack and Queue Types

STACKS AND QUEUES. Problem Solving with Computers-II

PA3 Design Specification

CS 211 Programming Practicum Fall 2018

JavaScript CS 4640 Programming Languages for Web Applications

Mobile development initiation

Writing Secure Chrome Apps and Extensions

Institutionen för datavetenskap. Extending browser platforms with native capabilities, enabling additional features in a media streaming context

CS 211 Programming Practicum Spring 2018

ArcGIS Runtime: Building Cross-Platform Apps. Rex Hansen Mark Baird Michael Tims Morten Nielsen

Client Side JavaScript and AJAX

This walkthrough assumes you have completed the Getting Started walkthrough and the first lift and shift walkthrough.

Multithreading and Interactive Programs

Serverless Single Page Web Apps, Part Four. CSCI 5828: Foundations of Software Engineering Lecture 24 11/10/2016

GWT: The Technical Advantage. Presenter: Anirudh Dewani Company Name: Google

Cisco Spark Widgets Technical drill down

HTML Advanced Portlets. Your Guides: Ben Rimmasch, Rahul Agrawal

Portable Native Client

SCRIPT REFERENCE. UBot Studio Version 4. The UI Commands

An overview of mobile and embedded platforms

Stacks. Chapter 5. Copyright 2012 by Pearson Education, Inc. All rights reserved

March 13/2003 Jayakanth Srinivasan,

welcome to BOILERCAMP HOW TO WEB DEV

JavaScript: the language of browser interactions. Claudia Hauff TI1506: Web and Database Technology

Beginner s Guide to Cordova and Mobile Application Development

Traditional Ajax vs. New business targeted Ajax

Software Integration Guide

HTML5 Mobile App Development

generates scaffolding/framework for models, views

ArcGIS Runtime: Building Cross-Platform Apps. Mike Branscomb Michael Tims Tyler Schiewe

Non Recursive Stack Algorithm

JavaScript By: A. Mousavi & P. Broomhead SERG, School of Engineering Design, Brunel University, UK

VS005 - Cordova vs NativeScript

3 strategies to make your apps feel all the

CMPSCI 187 / Spring 2015 Postfix Expression Evaluator

Deep Dive on How ArcGIS API for JavaScript Widgets Were Built

Static Webpage Development

Google Web Toolkit (GWT)

Unifer Documentation. Release V1.0. Matthew S

WebApp development. Outline. Web app structure. HTML basics. 1. Fundamentals of a web app / website. Tiberiu Vilcu

Stack Applications. parsing a postfix expression evaluating postfix expressions. converting infix sums from infix to postfix

Formal Languages and Automata Theory, SS Project (due Week 14)

Embedding and linking to media

Configuring Anonymous Access to Analysis Files in TIBCO Spotfire 7.5

Xcode Encountered An Internal Logic Error >>>CLICK HERE<<<

Android App Development. Muhammad Sharjeel COMSATS Institute of Information Technology, Lahore

Safe Harbor Statement

Where s the difference?

Lecture 1 Introduction to Android. App Development for Mobile Devices. App Development for Mobile Devices. Announcement.

Kick Start your Embedded Development with Qt

Roy Lawson. Introduction to Office 365 Development Presented By. SDS pays for referrals!

How to start with 3DHOP

Esri Developer Summit in Europe Building Applications with ArcGIS Runtime SDK for Java

User Interfaces for Web Sites and Mobile Devices. System and Networks

Web API for Vehicle Data RI

MVC: Model View Controller

Apps Framework API. Version Samsung Smart Electronics Copyright All Rights Reserved

Building a Django Twilio Programmable Chat Application

Introduce C# as Object Oriented programming language. Explain, tokens,

NDK OVERVIEW OF THE ANDROID NATIVE DEVELOPMENT KIT


Visual HTML5. Human Information Interaction for Knowledge Extraction, Interaction, Utilization, Decision making HI-I-KEIUD

Oracle Utilities Customer Self Service

AngularJS Fundamentals

PubNub Training Webinar. Introduction to PubNub JavaScript SDK

COMP 202 Java in one week

Contents. Demos folder: Demos\14-Ajax. 1. Overview of Ajax. 2. Using Ajax directly. 3. jquery and Ajax. 4. Consuming RESTful services

Force.com Mobile Web with Sencha Touch

Application Development in JAVA. Data Types, Variable, Comments & Operators. Part I: Core Java (J2SE) Getting Started

Google Web Toolkit. David Geary. code.google.com/webtoolkit. corewebdeveloper.com

GRITS AJAX & GWT. Trey Roby. GRITS 5/14/09 Roby - 1

Connect and Transform Your Digital Business with IBM

Custom Embedded Tabs, on page 1 Configure Cisco Jabber for Android on Chromebook, on page 8 Cisco Jabber Mobile App Promotion, on page 9

The Discussion of Cross-platform Mobile Application Development Based on Phone Gap Method Limei Cui

Website Development Lecture 18: Working with JQuery ================================================================================== JQuery

WEB APPLICATIONS SECTION A. 1. Multiple Choice Questions (Attempt any six questions) : 1 6=6

Slide 1: Developer Preview

IV. Stacks. A. Introduction 1. Consider the 4 problems on pp (1) Model the discard pile in a card game. (2) Model a railroad switching yard

An Introduction to Trees

Programming for Digital Media. Lecture 7 JavaScript By: A. Mousavi and P. Broomhead SERG, School of Engineering Design, Brunel University, UK

Data Structure. Recitation IV

Building mobile app using Cordova and AngularJS, common practices. Goran Kopevski

Syncfusion Report Platform. Version - v Release Date - March 22, 2017

What Is React Native?

Mobile Application Development

Pintos Project 2 User Programs

Firefox for Android. Reviewer s Guide. Contact us:

AJAX Programming Chris Seddon

Uninstall A Apps Windows 8 Programming Using Microsoft Visual C++

Eclipse CDT Tutorial. Eclipse CDT Homepage: Tutorial written by: James D Aniello

Data Structures and Algorithms

Using and Extending the Xcode Source Editor

Developing Ajax Web Apps with GWT. Session I

Google Web Toolkit for quick relief of AJAX pain. Kelly Norton & Miguel Méndez

JavaScript: Introduction, Types

Transcription:

Writing Web Apps in C++? Eric Bidelman, Google COSCUP / GNOME.Asia - Taipei, Taiwan August 14, 2010

Agenda Overview of Native Client SDK Calculator tutorial Demos

Native Client

Native Client ( NaCl )

The Vision NaCl

The Vision NaCl

NaCl

Write once, run anywhere NaCl

Write once, run anywhere NaCl

+ + = NaCl

+ + = x86-32 x86-64 ARM NaCl

+ + = x86-32 x86-64 ARM NaCl

x86-32 x86-64 ARM NaCl + + =

x86-32 x86-64 ARM NaCl + + =?

NaCl

What is NaCl? Sandboxing technology for safe execution of platform-independent untrusted native code in a web browser. It allows web applications that are compute-intensive and/or interactive to leverage the resources of a client's machine and avoid costly network access while running in a secure environment with restricted access to the host. NaCl

What is NaCl? Sandboxing technology for safe execution of platform-independent untrusted native code in a web browser. It allows web applications that are compute-intensive and/or interactive to leverage the resources of a client's machine and avoid costly network access while running in a secure environment with restricted access to the host. NaCl

What is it good for? Porting desktop applications to the web - No install - Native performance - e.g. games, media, large data analysis, visualizations Enhance web apps with... - Existing C/C++ libraries (libcrypt, CGAL, etc) - New high-performance compiled code Sandbox existing plugin code - Stop asking users to trust your code NaCl

Confirm Installation This webpage wants to install software from MightNotBeEvil, Inc. I know what you re thinking. Is this software safe? Well, to tell you the truth, we re not really sure ourselves. But being as this is a native plugin, most dangerous kind of code in the world, and could root your system without you even knowing it, you ve got to ask yourself one question: Do I feel lucky? Well, do ya, punk? OK Cancel NaCl

The NaCl SDK NaCl

SDK Goodies C/C++ toolchain for creating NaCl executables (.nexe) Standard GNU libraries Customized versions of gcc, gdb, binutils Pepper - NPAPI-like interface - Audio / video - OpenGL ES 2.0 Javascript interop layer (MVC): c_salt Sample code + build scripts NaCl

Calculator Tutorial NaCl

Loading a.nexe <div id="nacl_container"></div> <script> function onmoduleload() { alert('nacl Module Loaded!'); var url = 'http://example.com/path/to/mymodule.nexe'; document.getelementbyid('nacl_container').innerhtml = ['<embed id="mymodule" width="0" height="0" ', 'src="', url, '" type="pepper-application/mymodule" ', 'onload="onmoduleload();" />'].join(''); // Next 2 lines are temporary due to: // http://code.google.com/p/nativeclient/issues/detail?id=500 var nexes = 'x86-32:../x86_32/mymodule.nexe\n' + 'x86-64:../x86_64/mymodule.nexe\n' + 'ARM:../arm/myModule.nexe'; document.getelementbyid('mymodule').nexes = nexes; </script> NaCl

Loading a.nexe <div id="nacl_container"></div> <script> function onmoduleload() { alert('nacl Module Loaded!'); var url = 'http://example.com/path/to/mymodule.nexe'; document.getelementbyid('nacl_container').innerhtml = ['<embed id="mymodule" width="0" height="0" ', 'src="', url, '" type="pepper-application/mymodule" ', 'onload="onmoduleload();" />'].join(''); // Next 2 lines are temporary due to: // http://code.google.com/p/nativeclient/issues/detail?id=500 var nexes = 'x86-32:../x86_32/mymodule.nexe\n' + 'x86-64:../x86_64/mymodule.nexe\n' + 'ARM:../arm/myModule.nexe'; document.getelementbyid('mymodule').nexes = nexes; </script> NaCl

Loading a.nexe <div id="nacl_container"></div> <script> function onmoduleload() { alert('nacl Module Loaded!'); var url = 'http://example.com/path/to/mymodule.nexe'; document.getelementbyid('nacl_container').innerhtml = ['<embed id="mymodule" width="0" height="0" ', 'src="', url, '" type="pepper-application/mymodule" ', 'onload="onmoduleload();" />'].join(''); // Next 2 lines are temporary due to: // http://code.google.com/p/nativeclient/issues/detail?id=500 var nexes = 'x86-32:../x86_32/mymodule.nexe\n' + 'x86-64:../x86_64/mymodule.nexe\n' + 'ARM:../arm/myModule.nexe'; document.getelementbyid('mymodule').nexes = nexes; </script> NaCl

Loading a.nexe <div id="nacl_container"></div> <script> function onmoduleload() { alert('nacl Module Loaded!'); var url = 'http://example.com/path/to/mymodule.nexe'; document.getelementbyid('nacl_container').innerhtml = ['<embed id="mymodule" width="0" height="0" ', 'src="', url, '" type="pepper-application/mymodule" ', 'onload="onmoduleload();" />'].join(''); // Next 2 lines are temporary due to: // http://code.google.com/p/nativeclient/issues/detail?id=500 var nexes = 'x86-32:../x86_32/mymodule.nexe\n' + 'x86-64:../x86_64/mymodule.nexe\n' + 'ARM:../arm/myModule.nexe'; document.getelementbyid('mymodule').nexes = nexes; </script> NaCl

Loading a.nexe <div id="nacl_container"></div> <script> function onmoduleload() { alert('nacl Module Loaded!'); var url = 'http://example.com/path/to/mymodule.nexe'; document.getelementbyid('nacl_container').innerhtml = ['<embed id="mymodule" width="0" height="0" ', 'src="', url, '" type="pepper-application/mymodule" ', 'onload="onmoduleload();" />'].join(''); // Next 2 lines are temporary due to: // http://code.google.com/p/nativeclient/issues/detail?id=500 var nexes = 'x86-32:../x86_32/mymodule.nexe\n' + 'x86-64:../x86_64/mymodule.nexe\n' + 'ARM:../arm/myModule.nexe'; document.getelementbyid('mymodule').nexes = nexes; </script> NaCl

Anatomy of a NaCl Application JavaScript Pepper NaCl Sandbox.nexe

Anatomy of a NaCl Application JavaScript Pepper NaCl Sandbox.nexe

Anatomy of a NaCl Application JavaScript Pepper NaCl Sandbox.nexe

Anatomy of a NaCl Application JavaScript Pepper NaCl Sandbox.nexe

function onloadprogress(percent) { if (percent == 100) { alert('done loading ' + calculator.application.module().id); Tutorial: Adding UI HTML + CSS + JavaScript /** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method * calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else {

function onloadprogress(percent) { if (percent == 100) { alert('done loading ' + calculator.application.module().id); Tutorial: Adding UI HTML + CSS + JavaScript /** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method * calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { JavaScript Pepper NaCl Sandbox.nexe

function onloadprogress(percent) { if (percent == 100) { alert('done loading ' + calculator.application.module().id); Tutorial: Adding UI HTML + CSS + JavaScript /** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method * calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else {

* @param {Object.<string,offset> infix The infix-notation expression. * @return {Array.string The expression in postfix notation. * @private Tutorial: Adding UI */ google.expr.infixtopostfix_ = function(infix) { HTML + CSS + JavaScript var rpn_out = []; // Reverse Polish Notation version of the expression. var operator_stack = []; while (infix.offset < infix.string.length) { // Consume tokens until the end of the input string is reached. var token = google.expr.nexttoken_(infix); if (!token token.type == google.expr.tokentype.notype) { throw new SyntaxError("Unrecognized token."); switch (token.type) { case google.expr.tokentype.number: rpn_out.push(token.token); break; case google.expr.tokentype.operator: while (operator_stack.length > 0) { // Only handle left-associative operators. Pop off all the operators // that have less or equal precedence to token. var operator = operator_stack.pop(); if (operator.type == google.expr.tokentype.operator && operator.precedence <= token.precedence) { rpn_out.push(operator.token); else { // The top-of-stack operator has a higher precedence than the current // token, or it's a parenthesis. Push it back on the stack and stop. operator_stack.push(operator); break;

function onloadprogress(percent) { if (percent == 100) { alert('done loading ' + calculator.application.module().id); Tutorial: Adding UI HTML + CSS + JavaScript /** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method * calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else {

function onloadprogress(percent) { if (percent == 100) { alert('done loading ' + calculator.application.module().id); Tutorial: Adding UI HTML + CSS + JavaScript /** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method * calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else {

* be handled synchronously.) */ function startcalculate() { Tutorial: Adding UI // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. HTML + CSS + JavaScript postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

* be handled synchronously.) */ function startcalculate() { Tutorial: Adding UI // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. HTML + CSS + JavaScript postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

/** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method Tutorial: Adding Methods * calls for things that are really fast. This example could, of course, * be handled synchronously.) JavaScript */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

/** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method Tutorial: Adding Methods * calls for things that are really fast. This example could, of course, * be handled synchronously.) JavaScript */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression NaCl Sandbox // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result; JavaScript Pepper.nexe

/** * Here we start a calculation, calling a custom method on the nexe that * has an asynchronous callback. (The API also supports synchronous method Tutorial: Adding Methods * calls for things that are really fast. This example could, of course, * be handled synchronously.) JavaScript */ function startcalculate() { // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; JavaScript Pepper NaCl Sandbox.nexe void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

namespace calculator { Tutorial: Adding Methods Calculator::Calculator() : calculate_callback_(null) { C++ Calculator::~Calculator() { delete calculate_callback_; void Calculator::InitializeMethods(c_salt::ScriptingBridge* bridge) { calculate_callback_ = new c_salt::methodcallback<calculator>(this, &Calculator::Calculate); bridge->addmethodnamed("calculate", calculate_callback_); bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1]));

bridge->addmethodnamed("calculate", calculate_callback_); Tutorial: Adding Methods bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, C++ uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1])); // Pack the value of the expression into the first arg of the callback // function, and invoke it. NPVariant argv; NPVariant result; DOUBLE_TO_NPVARIANT(expr_value, argv); NULL_TO_NPVARIANT(result); NPN_InvokeDefault(bridge->npp(), return true; function_obj.object_value(), &argv, 1, &result);

bridge->addmethodnamed("calculate", calculate_callback_); Tutorial: Adding Methods bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, C++ uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1])); // Pack the value of the expression into the first arg of the callback // function, and invoke it. NPVariant argv; NPVariant result; DOUBLE_TO_NPVARIANT(expr_value, argv); NULL_TO_NPVARIANT(result); NPN_InvokeDefault(bridge->npp(), return true; function_obj.object_value(), &argv, 1, &result);

bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, Tutorial: Adding Methods uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; C++ c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1])); // Pack the value of the expression into the first arg of the callback // function, and invoke it. NPVariant argv; NPVariant result; DOUBLE_TO_NPVARIANT(expr_value, argv); NULL_TO_NPVARIANT(result); NPN_InvokeDefault(bridge->npp(), function_obj.object_value(), &argv, 1, &result); return true; double Calculator::EvaluateExpression(

bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, Tutorial: Adding Methods uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; C++ c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); JavaScript Pepper NaCl Sandbox.nexe // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1])); // Pack the value of the expression into the first arg of the callback // function, and invoke it. NPVariant argv; NPVariant result; DOUBLE_TO_NPVARIANT(expr_value, argv); NULL_TO_NPVARIANT(result); NPN_InvokeDefault(bridge->npp(), function_obj.object_value(), &argv, 1, &result); return true; double Calculator::EvaluateExpression(

bool Calculator::Calculate(c_salt::ScriptingBridge* bridge, const NPVariant* args, Tutorial: Adding Methods uint32_t arg_count, NPVariant* return_value) { if (arg_count < 1!NPVARIANT_IS_OBJECT(args[0])) return false; C++ c_salt::type::typearray* expression_array = c_salt::type::createarrayfromnpvariant(bridge, args[0]); double expr_value = EvaluateExpression(expression_array); // If there was a second argument, assume it's the oncalculate callback. if (arg_count > 1 && NPVARIANT_IS_OBJECT(args[1])) { // The ObjectType ctor bumps the ref count of the callback function. c_salt::objecttype function_obj(npvariant_to_object(args[1])); // Pack the value of the expression into the first arg of the callback // function, and invoke it. NPVariant argv; NPVariant result; DOUBLE_TO_NPVARIANT(expr_value, argv); NULL_TO_NPVARIANT(result); NPN_InvokeDefault(bridge->npp(), function_obj.object_value(), &argv, 1, &result); return true; double Calculator::EvaluateExpression(

* calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { Tutorial: Adding Methods // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. JavaScript postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

* calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { Tutorial: Adding Methods // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. JavaScript postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result; JavaScript Pepper NaCl Sandbox.nexe

* calls for things that are really fast. This example could, of course, * be handled synchronously.) */ function startcalculate() { Tutorial: Adding Methods // Convert the formula to postfix notation, and put the postfix expression // into an array that gets passed to the calculator module. JavaScript postfixexpr = google.expr.parseexpression( document.getelementbyid('formula').value); var calculator_module = calculator.application.module(); try { calculator_module.calculate(postfixexpr, oncalculate); catch(err) { oncalculate('42, I think'); /** * Handler for the event when the calculation is complete. */ function oncalculate(result, opt_error) { if (opt_error) { alert(opt_error); else { document.getelementbyid('formula').value = result;

Calculator Demo NaCl

Other Demos NaCl

Coming Attractions Full debugger support - GDB - Visual Studio IDE plugins - Eclipse - Visual Studio - Xcode Easy to use interop library PNaCl (portable NaCl) NaCl

Summary Choice of language! - C/C++, ASM, Objective-C, Python,... Full power of the client's CPU -...while maintaining browser neutrality -...allowing OS portability -...providing safety that people expect from web applications NaCl

Resources http://code.google.com/p/nativeclient/ http://code.google.com/p/nativeclient-sdk/ http://sites.google.com/a/chromium.org/dev/nativeclient/ NaCl