-
Notifications
You must be signed in to change notification settings - Fork 1.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[MERGE #4267 @obastemur] jsrt: JsCreateExternalObjectWithPrototype
Merge pull request #4267 from obastemur:Jsrt_external_with_proto node-chakracore, each `ObjectTemplate` creation first creates an external object and sets prototype separately. `JsSetPrototype` is decently expensive to lazy call. This new `JsCreateExternalObjectWithPrototype` should supersede `JsCreateExternalObject` since prototype can be provided as `nullptr` if there is none. Also VS export Jsrt***ObjectProperty
- Loading branch information
Showing
7 changed files
with
279 additions
and
5 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,52 @@ | ||
//------------------------------------------------------------------------------------------------------- | ||
// Copyright (C) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
//------------------------------------------------------------------------------------------------------- | ||
|
||
var isWindows = !WScript.Platform || WScript.Platform.OS == 'win32'; | ||
var path_sep = isWindows ? '\\' : '/'; | ||
var isStaticBuild = WScript.Platform && WScript.Platform.LINK_TYPE == 'static'; | ||
|
||
if (!isStaticBuild) { | ||
// test will be ignored | ||
print("# IGNORE_THIS_TEST"); | ||
} else { | ||
var platform = WScript.Platform.OS; | ||
var binaryPath = WScript.Platform.BINARY_PATH; | ||
// discard `ch` from path | ||
binaryPath = binaryPath.substr(0, binaryPath.lastIndexOf(path_sep)); | ||
var makefile = | ||
"IDIR=" + binaryPath + "/../../lib/Jsrt \n\ | ||
\n\ | ||
LIBRARY_PATH=" + binaryPath + "/lib\n\ | ||
PLATFORM=" + platform + "\n\ | ||
LDIR=$(LIBRARY_PATH)/libChakraCoreStatic.a \n\ | ||
\n\ | ||
ifeq (darwin, ${PLATFORM})\n\ | ||
\tICU4C_LIBRARY_PATH ?= /usr/local/opt/icu4c\n\ | ||
\tCFLAGS=-lstdc++ -std=c++11 -I$(IDIR)\n\ | ||
\tFORCE_STARTS=-Wl,-force_load,\n\ | ||
\tFORCE_ENDS=\n\ | ||
\tLIBS=-framework CoreFoundation -framework Security -lm -ldl -Wno-c++11-compat-deprecated-writable-strings \ | ||
-Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ | ||
\tLDIR+=$(ICU4C_LIBRARY_PATH)/lib/libicudata.a \ | ||
$(ICU4C_LIBRARY_PATH)/lib/libicuuc.a \ | ||
$(ICU4C_LIBRARY_PATH)/lib/libicui18n.a\n\ | ||
else\n\ | ||
\tCFLAGS=-lstdc++ -std=c++0x -I$(IDIR)\n\ | ||
\tFORCE_STARTS=-Wl,--whole-archive\n\ | ||
\tFORCE_ENDS=-Wl,--no-whole-archive\n\ | ||
\tLIBS=-pthread -lm -ldl -licuuc -Wno-c++11-compat-deprecated-writable-strings \ | ||
-Wno-deprecated-declarations -Wno-unknown-warning-option -o sample.o\n\ | ||
endif\n\ | ||
\n\ | ||
testmake:\n\ | ||
\t$(CC) sample.cpp $(CFLAGS) $(FORCE_STARTS) $(LDIR) $(FORCE_ENDS) $(LIBS)\n\ | ||
\n\ | ||
.PHONY: clean\n\ | ||
\n\ | ||
clean:\n\ | ||
\trm sample.o\n"; | ||
|
||
print(makefile) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,153 @@ | ||
//------------------------------------------------------------------------------------------------------- | ||
// Copyright (C) Microsoft. All rights reserved. | ||
// Licensed under the MIT license. See LICENSE.txt file in the project root for full license information. | ||
//------------------------------------------------------------------------------------------------------- | ||
|
||
#include "ChakraCore.h" | ||
#include <stdlib.h> | ||
#include <stdio.h> | ||
#include <string> | ||
#include <cstring> | ||
|
||
#define FAIL_CHECK(cmd) \ | ||
do \ | ||
{ \ | ||
JsErrorCode errCode = (JsErrorCode) cmd; \ | ||
if (errCode != JsNoError) \ | ||
{ \ | ||
printf("Error %d at '%s'\n", \ | ||
errCode, #cmd); \ | ||
return 1; \ | ||
} \ | ||
} while(0) | ||
|
||
using namespace std; | ||
|
||
unsigned int AddMethodProperty(JsValueRef target, const char* str, | ||
JsNativeFunction func) | ||
{ | ||
JsPropertyIdRef Id; | ||
FAIL_CHECK(JsCreatePropertyId(str, strlen(str), &Id)); | ||
|
||
JsValueRef nameVar; | ||
FAIL_CHECK(JsCreateString(str, strlen(str), &nameVar)); | ||
|
||
JsValueRef functionVar; | ||
FAIL_CHECK(JsCreateNamedFunction(nameVar, func, nullptr, &functionVar)); | ||
|
||
FAIL_CHECK(JsSetProperty(target, Id, functionVar, true)); | ||
|
||
return JsNoError; | ||
} | ||
|
||
JsValueRef CHECK(JsValueRef callee, bool isConstructCall, | ||
JsValueRef * arguments, unsigned short argumentCount, void * callbackState) | ||
{ | ||
void * data; | ||
if (JsGetExternalData(arguments[1], &data) == JsNoError && | ||
((size_t*)data)[122] - ((size_t*)data)[0] == 41976) | ||
{ | ||
fprintf(stdout, "SU"); // CCESS will be printed during finalizer call | ||
} | ||
else | ||
{ | ||
fprintf(stderr, "External data corrupt?"); | ||
} | ||
|
||
return nullptr; | ||
} | ||
|
||
JsValueRef createWithProto(JsValueRef callee, bool isConstructCall, | ||
JsValueRef * arguments, unsigned short argumentCount, void * callbackState) | ||
{ | ||
size_t *data = new size_t[123]; | ||
data[0] = 12345; | ||
data[122] = 54321; | ||
|
||
JsValueRef obj; | ||
|
||
JsErrorCode code = JsCreateExternalObjectWithPrototype(data, [](void* buffer) | ||
{ | ||
size_t * mem = (size_t*)buffer; | ||
if(!(mem[122] - mem[0] == 41976)) abort(); | ||
delete mem; | ||
|
||
// test tool needs to see `SUCCESS` to determine if script was | ||
// successful. So far the test printed `SU`, | ||
// this should print the last part `CCESS` | ||
fprintf(stdout, "CCESS\n"); | ||
}, arguments[1], &obj); | ||
|
||
if (code != JsNoError) | ||
{ | ||
printf("FAILED to create external object %d \n", code); | ||
} | ||
|
||
return obj; | ||
} | ||
|
||
int main() | ||
{ | ||
JsRuntimeHandle runtime; | ||
JsContextRef context; | ||
JsValueRef result; | ||
unsigned currentSourceContext = 0; | ||
|
||
const char* script = "\ | ||
(function(){\ | ||
var proto = { sub: 3 }; \ | ||
var ext = CreateWithProto(proto); \ | ||
if (ext.sub === 3) CHECK(ext); \ | ||
return \'\'; \ | ||
})();\ | ||
"; | ||
|
||
// Create a runtime. | ||
JsCreateRuntime(JsRuntimeAttributeNone, nullptr, &runtime); | ||
|
||
// Create an execution context. | ||
JsCreateContext(runtime, &context); | ||
|
||
// Now set the current execution context. | ||
JsSetCurrentContext(context); | ||
|
||
JsValueRef fname; | ||
FAIL_CHECK(JsCreateString("sample", strlen("sample"), &fname)); | ||
|
||
JsValueRef scriptSource; | ||
FAIL_CHECK(JsCreateExternalArrayBuffer((void*)script, | ||
(unsigned)strlen(script), | ||
nullptr, nullptr, &scriptSource)); | ||
|
||
JsValueRef global; | ||
FAIL_CHECK(JsGetGlobalObject(&global)); | ||
|
||
FAIL_CHECK(AddMethodProperty(global, "CreateWithProto", &createWithProto)); | ||
FAIL_CHECK(AddMethodProperty(global, "CHECK", &CHECK)); | ||
|
||
// Run the script. | ||
FAIL_CHECK(JsRun(scriptSource, currentSourceContext++, fname, | ||
JsParseScriptAttributeNone, &result)); | ||
|
||
// Convert your script result to String in JavaScript; | ||
// redundant if your script returns a String | ||
JsValueRef resultJSString; | ||
FAIL_CHECK(JsConvertValueToString(result, &resultJSString)); | ||
|
||
// Project script result back to C++. | ||
char *resultSTR = nullptr; | ||
size_t stringLength; | ||
FAIL_CHECK(JsCopyString(resultJSString, nullptr, 0, &stringLength)); | ||
resultSTR = (char*)malloc(stringLength + 1); | ||
FAIL_CHECK(JsCopyString(resultJSString, resultSTR, stringLength, nullptr)); | ||
resultSTR[stringLength] = 0; | ||
|
||
fprintf(stdout, "%s", resultSTR); // prints an empty string `` | ||
free(resultSTR); | ||
|
||
// Dispose runtime | ||
JsSetCurrentContext(JS_INVALID_REFERENCE); | ||
JsDisposeRuntime(runtime); | ||
|
||
return 0; | ||
} |