Category Archives: Hosting

The Two Faces of JsRT (in Windows 10)

In terms of Windows 10, probably the biggest thing to happen to the JsRT APIs in Windows was the IE/Edge browser split.

For anyone who’s been living under a rock, Microsoft introduced a new browser in Windows 10 called Edge (neé Project Spartan). Edge basically represents a fork in the road for the web browser codebase at Microsoft: down one path the IE code will continue on, largely unchanged and preserving all that crufty backwards compatibility we all love to hate, and down another path will go Edge, discarding all the legacy shackles of IE and committing to a thoroughly modern browser experience.

And, just as the browser now splits into IE and Edge, so does the underlying JavaScript engine, Chakra. There are now two (yes, two!) JsRT APIs:

  • The “legacy” JsRT APIs that are exposed by jscript9.dll (the one that IE uses), have not changed since Windows 8.1, and will not be added to.
  • The “Edge” JsRT APIs that are exposed by chakra.dll (the one that Edge uses), have some breaking changes since Windows 8.1, and will be updated as the Edge browser moves forward.

You can find more details on the breaking changes that were made to the Edge JsRT on MSDN, but in a nutshell they are:

  • In C++ you #define USE_EDGEMODE_JSRT before including jsrt.h, and you link against chakrart.lib instead of jsrt.lib.
  • In C# and VB, you target your PInvoke declarations at chakra.dll instead of jscript9.dll.
  • The “version” parameter of JsCreateRuntime disappears (since there will only ever be one evergreen version of the Edge Chakra).
  • The debugging no longer requires an IDebugApplication. Thus, JsStartDebugging and JsCreateContext lose a parameter.

The last bullet point may seem a little odd and arbitrary. The reason is that the Edge version of the JsRT API is now supported as a part of the UWP (Universal Windows Platform). That means that a “modern” UWP application can host the Edge Chakra runtime and still qualify for the Windows Store (i.e. it won’t be rejected for using non-UWP APIs). To get there, though, the Chakra team needed to remove things that don’t work on the UWP, namely talking to the PDM (Process Debug Manager), which is what you need to get an IDebugApplication. Since it turns out in almost every possible case you don’t need to be able to supply your own IDebugApplication, Chakra now just acquires one on your behalf.

I’ve updated my chakra-host sample on GitHub to include samples that show hosting both “legacy” and “edge” JsRT on Windows 10. I’ve also added a new sample to the Windows Samples showing this. The Chakra team also now has a GitHub repo where they host their own samples.

You should also follow me on Twitter here.

Running node.js on Chakra!

It’s been a very busy year since I last posted, and a lot has been happening. As a result, I’ve kind of fallen behind a bit on all the stuff that came out around the Windows 10 launch. And one of the biggest things that I missed blogging about was the revelation of a (temporary) fork of node.js that runs Node on Chakra instead of V8!

This was actually the culmination of some work that I started several years ago as an internal project to enable some teams at Microsoft to author node.js applications that ran on Chakra instead of V8. The problem, then as now, was that there were some platforms where V8 didn’t or couldn’t run. So I spent a fun month or so working with another team concocting a shim over the nascent JSRT APIs that made them look a lot like the V8 APIs. The end result was a node.js binary that used Chakra and ran all the stuff that the team I was working with needed. Then the code went sort of into hibernation, and when I left the Chakra team, my expectation was that nothing more would come of it.

But, lo and behold, the IoT folks wanted node.js and they wanted it on ARM, which V8 doesn’t have an official code generator for, so that code miraculously got a second chance at life! After a lot of extra work on the part of the Chakra team (since the original shim only covered the scenarios the internal team needed), it was polished up and is now running out in the wild. It’s great to see that work continuing, especially since node.js can really be a joy to program in. Combining node.js with the ability of Chakra to access UWP (Universal Windows Platform) APIs also opens intriguing possibilities.

I’ve been thinking that I wanted to clone the fork to see if there was anything I could contribute, but things have been just too busy. Soon, maybe!

You should also follow me on Twitter here.

JsRT: Wrappers updated to v1.1

Even though I may not be working on the Chakra team any more, I’m still doing some noodling on making the hosting APIs easier to use. I’ve got some other interesting things coming soon, but on the way there I made some improvements/fixes to the wrappers that I released a while back.

Changes to v1.1:

  • PDB files are generated along with the LIB, and debug builds are included. All flavors are now packaged together.
  • Header file name is changed to jsrt-wrappers.h to be consistent with the other files.
  • Added equality operators for handles.
  • Added function_base::create which can deduce the strongly typed function wrapper from the function signature.
  • Fixes the handling of optional parameters in functions.
  • Changes the handling of rest parameters to use std::vector rather than a JavaScript array, which is more efficient.
  • Simplified prototype handling.
  • Bug fixes.

Let me know if there are any problems!

You should also follow me on Twitter here.

JsRT: Wrappers for C++

One unfortunate side-effect of the fact that the JsRT API is a flat Win32-style API is that it can be a little… painful to use in C++. Some of the conventions, particularly the use of error code returns everywhere and the use of return parameters, mean that you have to write a lot of boilerplate code. And marshalling values between C++ and JavaScript can be very cumbersome. So with that in mind, I’ve written some sample C++ wrappers that make the process of working with the JsRT APIs a lot nicer in C++.

You can get them from my GitHub account here. For more information, here’s part of the readme, which covers some of the highlights of the wrappers:

A Tour Through the Helpers

Most of the wrappers simply provide a nice object-oriented interface over the JsRT API. For example, creating a runtime and a context works like this:

jsrt::runtime runtime = jsrt::runtime::create();
jsrt::context context = runtime.create_context();

There are, however, a number of special features in the wrappers.

Context scopes

A context scope (jsrt::context::scope) automatically sets the current context when it comes into scope and clears the current context when it goes out of scope. This greatly simplifies working with scopes. For example:

jsrt::runtime runtime = jsrt::runtime::create();
jsrt::context context = runtime.create_context();
{
    jsrt::context::scope scope(context);
    ... work with context ...
}
// Context has automatically been set back to original value.
runtime.dispose();

Pinned references

To keep a reference to a Chakra object alive, it must be visible to the Chakra garbage collector (i.e. on the stack or stored in the garbage collected heap) or it has to be pinned using JsAddRef. The pinned<T> class functions as a smart-pointer template that keeps a reference alive using JsAddRef and JsRelease automatically. For example:

{
    jsrt::pinned<jsrt::object> pinned_obj = jsrt::object::create();
    // Object reference does not have to stay on the stack or in the GC heap
}
// Reference can now be garbage collected

Value translation

Value getter and setter functions can be strongly-typed, allowing automatic marshalling of JavaScript values to C++ values and vice versa. For example:

jsrt::object obj = jsrt::object::create();
obj.set_property(jsrt::property_id::create(L"boolProperty"), true);
bool bool_value = obj.get_property<bool>(jsrt::property_id::create(L"boolProperty"));
obj.set_property(jsrt::property_id::create(L"stringProperty"), L"foo");

The wrappers marshal types in the following way:

  • number values are marshalled to/from double

  • string values are marshalled to/from std::wstring

  • Boolean values are marshalled to/from bool

Strongly-typed arrays

Similarly, arrays can be strongly typed and accessed using numeric indexes:

jsrt::array<double> darray = jsrt::array<double>::create(1);
darray[0] = 10;
darray[1] = 20;

Functions

Perhaps the most useful aspect of the wrappers is the way that JavaScript functions can be wrapped and their arguments and return values marshalled to C++ types, and vice versa. For example:

auto f = (jsrt::function<double, double, double>)jsrt::context::evaluate(
    L"function f(a, b) { return a + b; }; f;");
double a = f(jsrt::context::undefined(), 1, 2);

Native functions can also be wrapped:

double add(const jsrt::call_info &info, double a, double b) { return a + b; }
auto nf = jsrt::function<double, double, double>::create(add);
jsrt::context::global().set_property(jsrt::property_id::create(L"add"), nf);
jsrt::context::run(L"add(1, 2)");

When calling a function wrapper, the first argument to the function call is the this value for the call. Function wrappers can also be bound to a particular value of this. For example:

auto bf = jsrt::bound_function<jsrt::value, double, double, double>::create(
    jsrt::context::undefined(),
    (jsrt::function<double, double, double>)jsrt::context::evaluate(
        L"function f(a, b) { return a + b; }; f;"));
double ba = bf(1, 2);

You should also follow me on Twitter here.

JsRT Sample Bug Fixed

This happened a while ago but just getting to it now because of my blog hiccup. A sharp-eyed reader pointed out a problem with my C# and VB Chakra hosting samples (on MSDN and on GitHub). When passing a host callback from managed code, I forgot to hold on to a managed reference to the delegate I was passing out to Chakra. So if the CLR ran a GC, it would dispose the delegate and then a callback on that delegate would jump into hyperspace. The samples are now correct. Ah, the joys of coordinating GCs.

You should also follow me on Twitter here.

Memory profiling in Visual Studio 2013 with JsRT

One of the cool features of Visual Studio (starting in Visual Studio 2012 Update 1) is its JavaScript memory profiler. The profiler can take snapshots of the JavaScript heap and then gives you a nice UI you can use to drill in to those snapshots and compare them as you like:

Comparing two snapshots

Drilling in to a snapshot

Wouldn’t it be great to be able to utilize this to analyze the JavaScript memory usage in an app that hosts Chakra using JsRT? Well, you can! I’ve uploaded a new sample (and checked it in to my GitHub repo) that allows a JsRT app to generate heap dumps in a way that Visual Studio 2013 will be able to read. It doesn’t look quite as beautiful at the examples above–I didn’t go through the trouble of generating a screenshot for the summary page–but it should be entirely functional.

The sample project builds a C++ DLL that exports five functions:

  • bool InitializeMemoryProfileWriter() initializes the overall profile writer and should be called when you load the DLL.
  • MemoryProfileHandle StartMemoryProfile() starts a specific profile (called a “diagnostic session” in Visual Studio).
  • bool WriteSnapshot(MemoryProfileHandle memoryProfileHandle, IActiveScriptProfilerHeapEnum *enumerator) takes a memory profile handle and a heap enumerator (which can be obtained from JsEnumerateHeap) and writes the actual memory snapshot. Note that you can do this multiple times before finishing the memory profile. Each snapshot is written separately into the diagnostic session.
  • bool EndMemoryProfile(MemoryProfileHandle memoryProfileHandle, const wchar_t *filename) finishes the memory profile and writes it out to a file. The file should have a .diagsession extension if you want it to be natively recognized by VS when you open it. After this call, the memory profile handle is now invalid.
  • void ReleaseMemoryProfileWriter() releases the overall profiler writer and should be called when you’re shutting down or done with all profiling.

One thing to note is that once you’ve called JsEnumerateHeap for a particular JsRT runtime, you won’t be able to do anything in that runtime until the IActiveScriptProfilerHeapEnum pointer has been released.

We’ve already been using this code internally to look at the memory usage of some internal JsRT hosts, and it’s been very helpful! Let me know if there are problems or issues, and feel free to grab me on Twitter if you have any questions.

You should also follow me on Twitter here.