Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add JSRT basic tasks tutorials #44

Merged
merged 1 commit into from
Dec 6, 2017
Merged

Conversation

liminzhu
Copy link
Member

Per #5, I'm adding some tutorials for JSRT. I'm putting the content in JSRT Overview before I find a better spot (feel free to make suggestions).

This PR adds illustration for

And another temporary section for

  • Set up ES6 modules

@liminzhu
Copy link
Member Author

@dilijev fyi

Copy link
Contributor

@dilijev dilijev left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM modulo comments

@@ -85,9 +85,117 @@ All other supported ES2015 features do not require any setup to run in JSRT.

Features based on promises, such as [ES2016/ES7 Async Functions](https://blogs.windows.com/msedgedev/2015/09/30/asynchronous-code-gets-easier-with-es2016-async-function-support-in-chakra-and-microsoft-edge/), would require setting up promises before usage.

## Modules
ES6 Modules are supported in ChakraCore. However, the host needs to specify how to resolve a module specifier since this part is host-specific not runtime-related. JSRT provides experimental APIs to set up ES6 modules. This [PR](https://github.com/Microsoft/ChakraCore/commit/50767f9f33812b4a036794a6a98404145563409f) gives you an overview of the related APIs and an example implementation (see WScriptJsrt.cpp) in the ch test host. Better documentation will be provided in the future.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For the PR you might want to link to the actual PR instead of the commit

chakra-core/ChakraCore#1254

}
wprintf(L"\n");
return JS_INVALID_REFERENCE;
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code above uses tabs while the rest uses 4 spaces. We use 4 spaces in ChakraCore so we should probably unify to that.

// load script when necessary
*scriptBuffer = LoadScript(((SerializedSourceContext*)sourceContext)->scriptPath);
return true;
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this whole block (starting from open brace line 186) be indented one level deeper (to line up with [] starting the lambda)?

[](JsSourceContext sourceContext)
{
// free resources
},
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same comment re indentation.

JsSetProperty(global, consolePropId, console, true);
```

Now in JavaScript, you can do,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: change the trailing , to :

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: also add a newline before the code block

console.log('Hello world');
```

If you need to expose an object that hosts data not directly exposed to JS, you can create an external object via `JsCreateExternalObject`.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we show an example of this?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the API shape is pretty self-explanatory so I left that out.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that this line is helpful without an example at least illustrating what type of data you might expose and why you might expose it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please also consider that we have JsCreateExternalObjectWithPrototype . IMHO we may show an example of that one instead (usage is available under test/native-tests)

Copy link
Member Author

@liminzhu liminzhu Nov 28, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@obastemur I didn't know that's a thing! Will look into it.


### Script serialization with lazy source loading

To support startup and execution efficiency, JSRT APIs provide the capability of pre-parsing, generating syntax trees and caching the bytecode for scripts. It is especially useful for server scenarios where the same script could get executed for thousands of times.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: executed for thousands of times -> executed thousands of times


The basic idea is to use variants of `JsSerializeScript` to parse and store the bytecode and then use `JsParse/RunSerializedScript` to parse or run the bytecode. Source is typically not needed for running serialized code, therefore you can also lazy-load the source script using `JsRunSerialized/JsRunSerializedScriptWithCallback`.


Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: remove extra newline

JsValueRef result;
unsigned long bufferSize = 0;
BYTE *buffer = nullptr;
JsSerializeScript(script, buffer, &bufferSize); // get correct buffer size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: to make this clearer (passing nullptr for buffer argument to get size without filling a buffer or getting an error about buffer too small), replace buffer with nullptr in this line.

[](JsSourceContext sourceContext, const WCHAR** scriptBuffer)
{
// load script when necessary
*scriptBuffer = LoadScript(((SerializedSourceContext*)sourceContext)->scriptPath);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are LoadScript and LoadByteCode visible to user code through JSRT or are these stubs not defined in this example?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are pseudo-code methods user need to define

@liminzhu
Copy link
Member Author

Thanks for the comments @dilijev !

JsConvertValueToString(arguments[index], &stringValue);
const wchar_t *string;
size_t length;
JsStringToPointer(stringValue, &string, &length);
Copy link
Member

@kfarnung kfarnung Nov 23, 2017

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want these examples to also work cross-plat? For instance JsStringToPointer isn't exposed on Linux/Mac, instead JsCopyString needs to be used.

// create console object, log function, and set log function as property of console
JsCreateObject(&console);
JsCreateFunction(LogCB, nullptr, &logFunc);
JsGetPropertyIdFromName(L"log", &logPropId);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JsGetPropertyIdFromName is also only available on Windows, JsCreatePropertyId should be used instead.

Copy link
Member

@kfarnung kfarnung left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM keeping in mind that the examples will only run on Windows. I'd recommend that another pass it made to ensure that all examples work cross-platform.

JsValueRef result;
unsigned long bufferSize = 0;
BYTE *buffer = nullptr;
JsSerializeScript(script, nullptr, &bufferSize); // get correct buffer size
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is also not ChakraCore. Use JsSerialize please.

@liminzhu
Copy link
Member Author

I will crossplat-fy all the samples. Thanks for the suggestion @kfarnung @obastemur .

}

// load and run bytecode
void runSerializeScript(const wchar_t *bytecodeBufferPath, const wchar_t *scriptBufferPath) {
// load and run bytecode
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: looks like accidental space

@liminzhu
Copy link
Member Author

liminzhu commented Dec 5, 2017

All feedback addressed and ready to merge if yall have no additional feedback. Thanks guys!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants