Last active
January 11, 2017 08:15
-
-
Save rayburgemeestre/c0abd528f6f67edbfe686d484c45ddbb to your computer and use it in GitHub Desktop.
V8 stackoverflow question
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
/* | |
In my case, compile with: | |
/usr/bin/c++ --std=c++14 -I${PWD}/include testcase2.cpp -o testcase -L$PWD/lib $PWD/lib/libv8_base.a -lv8_libbase $PWD/lib/libv8_nosnapshot.a -lv8_libplatform $PWD/lib/libv8_libsampler.a -licui18n -licuuc -Wl,-rpath,$PWD/lib -pthread | |
Run with ./testcase | |
*/ | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <string.h> | |
#include "include/libplatform/libplatform.h" | |
#include "include/v8.h" | |
#include <iostream> | |
#include <string> | |
using namespace v8; | |
void construct_with_non_ec6_syntax(const FunctionCallbackInfo<Value>& args) { | |
Handle<Object> global = args.GetIsolate()->GetCurrentContext()->Global(); | |
std::string newvecfunc = "some_non_ec6_class"; | |
Handle<Value> value = global->Get(String::NewFromUtf8(args.GetIsolate(), newvecfunc.c_str(), String::kNormalString, newvecfunc.length())); | |
Local<Value> result; | |
if (value->IsFunction()) { | |
Handle<Function> func = Handle<Function>::Cast(value); | |
Handle<Value> args2[2]; | |
args2[0] = Number::New(args.GetIsolate(), 111); | |
args2[1] = Number::New(args.GetIsolate(), 222); | |
result = func->CallAsConstructor(args.GetIsolate()->GetCurrentContext(), 2, args2).ToLocalChecked(); | |
} | |
args.GetReturnValue().Set(result); | |
} | |
void construct_with_ec6_syntax(const FunctionCallbackInfo<Value>& args) { | |
Handle<Object> global = args.GetIsolate()->GetCurrentContext()->Global(); | |
std::string newvecfunc = "some_ec6_class"; | |
Handle<Value> value = global->Get(String::NewFromUtf8(args.GetIsolate(), newvecfunc.c_str(), String::kNormalString, newvecfunc.length())); | |
Local<Value> result; | |
if (value->IsFunction()) { | |
Handle<Function> func = Handle<Function>::Cast(value); | |
Handle<Value> args2[2]; | |
args2[0] = Number::New(args.GetIsolate(), 111); | |
args2[1] = Number::New(args.GetIsolate(), 222); | |
result = func->CallAsConstructor(args.GetIsolate()->GetCurrentContext(), 2, args2).ToLocalChecked(); | |
} | |
args.GetReturnValue().Set(result); | |
} | |
int main(int argc, char* argv[]) { | |
// Initialize V8. | |
V8::InitializeICUDefaultLocation(argv[0]); | |
V8::InitializeExternalStartupData(argv[0]); | |
Platform* platform = platform::CreateDefaultPlatform(); | |
V8::InitializePlatform(platform); | |
V8::Initialize(); | |
// Create a new Isolate and make it the current one. | |
Isolate::CreateParams create_params; | |
create_params.array_buffer_allocator = ArrayBuffer::Allocator::NewDefaultAllocator(); | |
Isolate* isolate = Isolate::New(create_params); | |
{ | |
Isolate::Scope isolate_scope(isolate); | |
HandleScope handle_scope(isolate); | |
Local<Context> context = Context::New(isolate); | |
Context::Scope context_scope(context); | |
// Expose a C++ function to V8 | |
Local<ObjectTemplate> global = ObjectTemplate::New(isolate); | |
auto ftpl = FunctionTemplate::New(isolate, construct_with_non_ec6_syntax); | |
global->Set(String::NewFromUtf8(isolate, "construct_with_non_ec6_syntax", NewStringType::kNormal).ToLocalChecked(), ftpl); | |
auto ftpl2 = FunctionTemplate::New(isolate, construct_with_ec6_syntax); | |
global->Set(String::NewFromUtf8(isolate, "construct_with_ec6_syntax", NewStringType::kNormal).ToLocalChecked(), ftpl2); | |
context = Context::New(isolate, NULL, global); | |
// Using non EC6 syntax | |
{ | |
// Compile and run test function | |
Local<String> source = String::NewFromUtf8(isolate, "function some_non_ec6_class(x, y) { this.result = x + y; };", NewStringType::kNormal).ToLocalChecked(); | |
Local<Script> script = Script::Compile(context, source).ToLocalChecked(); | |
Local<Value> result = script->Run(context).ToLocalChecked(); | |
// Invoke test function and print result | |
Local<String> source2 = String::NewFromUtf8(isolate, "t = construct_with_non_ec6_syntax(); t.result;", NewStringType::kNormal).ToLocalChecked(); | |
Local<Script> script2 = Script::Compile(context, source2).ToLocalChecked(); | |
Local<Value> result2 = script2->Run(context).ToLocalChecked(); | |
String::Utf8Value utf8(result2); | |
printf("%s\n", *utf8); // prints 333.. which is OK! (111 + 222) | |
} | |
// Using EC6 syntax | |
{ | |
// Compile and run test function | |
Local<String> source = String::NewFromUtf8(isolate, "class some_ec6_class { constructor(x, y) { this.result = x + y; } };", NewStringType::kNormal).ToLocalChecked(); | |
Local<Script> script = Script::Compile(context, source).ToLocalChecked(); | |
Local<Value> result = script->Run(context).ToLocalChecked(); | |
// Invoke test function, will throw because `t` is undefined.. | |
Local<String> source2 = String::NewFromUtf8(isolate, "t = construct_with_ec6_syntax(); t.result;", NewStringType::kNormal).ToLocalChecked(); | |
Local<Script> script2 = Script::Compile(context, source2).ToLocalChecked(); | |
Local<Value> result2 = script2->Run(context).ToLocalChecked(); | |
String::Utf8Value utf8(result2); | |
printf("%s\n", *utf8); // should print 333 as well..? | |
} | |
} | |
isolate->Dispose(); | |
V8::Dispose(); | |
V8::ShutdownPlatform(); | |
delete platform; | |
delete create_params.array_buffer_allocator; | |
return 0; | |
} | |
/** | |
* Running this program results in the following output; | |
* ----------------------------------------------------- | |
* 333 | |
* <unknown>:34: Uncaught TypeError: Cannot read property 'result' of undefined | |
* | |
* # | |
* # Fatal error in v8::ToLocalChecked | |
* # Empty MaybeLocal. | |
* # | |
* | |
* /bin/bash: line 1: 4287 Illegal instruction (core dumped) ./testcase | |
**/ |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment