i::HandleScopeData* data = i_isolate->handle_scope_data(); EXPECT_EQ(data->level, 1); }
TEST_F(HandleScopeTest, HandleScopeImplementer) { i::Isolate* i_isolate = asInternal(isolate_); i::HandleScopeImplementer implementer{i_isolate}; // Context is just a HeapObject so we can construct using the default not // args constructor. i::Context context{};
#include<stdio.h> #include<stdlib.h> #include<string.h> #include"include/libplatform/libplatform.h" #include"include/v8.h" intmain(int argc, char* argv[]){ // Initialize V8. v8::V8::InitializeICUDefaultLocation(argv[0]); v8::V8::InitializeExternalStartupData(argv[0]); std::unique_ptr<v8::Platform> platform = v8::platform::NewDefaultPlatform(); v8::V8::InitializePlatform(platform.get()); v8::V8::Initialize(); // Create a new Isolate and make it the current one. v8::Isolate::CreateParams create_params; create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator(); v8::Isolate* isolate = v8::Isolate::New(create_params); { v8::Isolate::Scope isolate_scope(isolate); // Create a stack-allocated handle scope. v8::HandleScope handle_scope(isolate); // Create a new context. v8::Local<v8::Context> context = v8::Context::New(isolate); // Enter the context for compiling and running the hello world script. v8::Context::Scope context_scope(context); // Create a string containing the JavaScript source code. v8::Local<v8::String> source = v8::String::NewFromUtf8(isolate, "'Hello' + ', World!'", v8::NewStringType::kNormal) .ToLocalChecked(); // Compile the source code. v8::Local<v8::Script> script = v8::Script::Compile(context, source).ToLocalChecked(); // Run the script to get the result. v8::Local<v8::Value> result = script->Run(context).ToLocalChecked(); // Convert the result to an UTF8 string and print it. v8::String::Utf8Value utf8(isolate, result); printf("%s\n", *utf8); } // Dispose the isolate and tear down V8. isolate->Dispose(); v8::V8::Dispose(); v8::V8::ShutdownPlatform(); delete create_params.array_buffer_allocator; return0; }
/** * Pushes the value into the previous scope and returns a handle to it. * Cannot be called twice. */ template <classT> V8_INLINE Local<T> Escape(Local<T> value){ internal::Address* slot = Escape(reinterpret_cast<internal::Address*>(*value)); returnLocal<T>(reinterpret_cast<T*>(slot)); }
private: // Declaring operator new and delete as deleted is not spec compliant. // Therefore declare them private instead to disable dynamic alloc void* operatornew(size_t size); void* operatornew[](size_t size); voidoperatordelete(void*, size_t); voidoperatordelete[](void*, size_t);
Address* HandleScope::CreateHandle(Isolate* isolate, Address value){ DCHECK(AllowHandleAllocation::IsAllowed()); HandleScopeData* data = isolate->handle_scope_data(); Address* result = data->next; if (result == data->limit) { result = Extend(isolate); } // Update the current next field, set the value in the created handle, // and return the result. DCHECK_LT(reinterpret_cast<Address>(result), reinterpret_cast<Address>(data->limit)); data->next = reinterpret_cast<Address*>(reinterpret_cast<Address>(result) + sizeof(Address)); *result = value; return result; }
Escape函数:
1 2 3 4 5 6 7 8 9 10 11
i::Address* EscapableHandleScope::Escape(i::Address* escape_value){ i::Heap* heap = reinterpret_cast<i::Isolate*>(GetIsolate())->heap(); Utils::ApiCheck(i::Object(*escape_slot_).IsTheHole(heap->isolate()), "EscapableHandleScope::Escape", "Escape value set twice"); if (escape_value == nullptr) { *escape_slot_ = i::ReadOnlyRoots(heap).undefined_value().ptr(); returnnullptr; } *escape_slot_ = *escape_value; return escape_slot_; }
// This function returns a new array with three elements, x, y, and z. Local<Array> NewPointArray(int x, int y, int z){ v8::Isolate* isolate = v8::Isolate::GetCurrent();
// We will be creating temporary handles so we use a handle scope. v8::EscapableHandleScope handle_scope(isolate);
// Create a new empty array. v8::Local<v8::Array> array = v8::Array::New(isolate, 3);
// Return an empty result if there was an error creating the array. if (array.IsEmpty()) return v8::Local<v8::Array>();
// Fill out the values array->Set(0, Integer::New(isolate, x)); array->Set(1, Integer::New(isolate, y)); array->Set(2, Integer::New(isolate, z));
// Return the value through Escape. return handle_scope.Escape(array); }
classV8_EXPORT FunctionTemplate : public Template { ... }
可以用下述方法定义
1 2
Local<FunctionTemplate> ft = FunctionTemplate::New(isolate_, function_callback, data); Local<Function> function = ft->GetFunction(context).ToLocalChecked();
同时这样调用函数
1
MaybeLocal<Value> ret = function->Call(context, recv, 0, nullptr);
// If the function was called using the new operator the property // new.target(NewTarget) will be set. Local<Value> new_target_value = info.NewTarget(); if (new_target_value.IsEmpty()) { std::cout << "new_target_value is undefined: " << new_target_value->IsUndefined() << '\n'; } // This is the receiver passed as the second argument to the Call function, // which is like the this. Local<Object> receiver = info.This(); Local<Name> name = String::NewFromUtf8(isolate, "nr", NewStringType::kNormal).ToLocalChecked(); Local<Value> nr_local = receiver->GetRealNamedProperty(isolate->GetCurrentContext(), name).ToLocalChecked(); Local<Number> nr = nr_local->ToNumber(isolate->GetCurrentContext()).ToLocalChecked();
// This value, data, will be made available via the FunctionCallbackInfo: Local<Value> data = String::NewFromUtf8(isolate_, "some info", NewStringType::kNormal).ToLocalChecked(); Local<FunctionTemplate> ft = FunctionTemplate::New(isolate_, function_callback, data); Local<Function> function = ft->GetFunction(context).ToLocalChecked(); Local<String> func_name = String::NewFromUtf8(isolate_, "SomeFunc", NewStringType::kNormal).ToLocalChecked(); function->SetName(func_name); Local<Value> prototype = function->GetPrototype(); V8TestFixture::print_local(prototype);
Local<Object> recv = Object::New(isolate_); Local<Name> name = String::NewFromUtf8(isolate_, "nr", NewStringType::kNormal).ToLocalChecked(); Local<Number> value = Number::New(isolate_, 18); recv->Set(context, name, value).Check();
int argc = 0; Local<Value> argv[] = {}; MaybeLocal<Value> ret = function->Call(context, recv, argc, nullptr); if (!ret.IsEmpty()) { Local<Number> nr = ret.ToLocalChecked()->ToNumber(context).ToLocalChecked(); EXPECT_EQ(nr->Value(), 20); }
Utils::ApiCheck(!value_obj->IsJSReceiver() || value_obj->IsTemplateInfo(), "v8::Template::Set", "Invalid value, must be a primitive or a Template");
// The template cache only performs shallow clones, if we set an // ObjectTemplate as a property value then we can not cache the receiver // template. if (value_obj->IsObjectTemplateInfo()) { templ->set_serial_number(i::TemplateInfo::kDoNotCache); }
Local<Value> Private::Name()const{ const Symbol* sym = reinterpret_cast<const Symbol*>(this); i::Handle<i::Symbol> i_sym = Utils::OpenHandle(sym); // v8::Private symbols are created by API and are therefore writable, so we // can always recover an Isolate. i::Isolate* isolate = i::GetIsolateFromWritableObject(*i_sym); return sym->Description(reinterpret_cast<Isolate*>(isolate)); }
// Add a property that all instanced created from this object template will // have. (Set is member function of class Template): constchar* prop_name = "prop_name"; constchar* prop_value = "prop_value"; Local<Name> name = String::NewFromUtf8(isolate_, prop_name, NewStringType::kNormal).ToLocalChecked(); Local<Data> value = String::NewFromUtf8(isolate_, prop_value, NewStringType::kNormal).ToLocalChecked(); ot->Set(name, value, PropertyAttribute::None);
// Verify that the property we added exist in the instance we created: MaybeLocal<Array> maybe_names = obj->GetPropertyNames(context); Local<Array> names = maybe_names.ToLocalChecked(); EXPECT_EQ(static_cast<int>(names->Length()), 1); // If found it iteresting that Array does not have any methods except Length() // and thress static methods (New, New, and Cast). Since Array extends Object // we can use Object::Get with the index: Local<Value> name_from_array = names->Get(context, 0).ToLocalChecked(); String::Utf8Value utf8_name{isolate_, name_from_array}; EXPECT_STREQ(*utf8_name, prop_name);
// Verify the value is correct. Local<Value> val = obj->GetRealNamedProperty(context, name).ToLocalChecked(); EXPECT_TRUE(val->IsName()); String::Utf8Value utf8_value{isolate_, val}; EXPECT_STREQ(*utf8_value, prop_value); }
/** * See ALL_CAN_READ above. 所有属性可读 */ kAllCanRead = 1,
/** Will not call into interceptor for properties on the receiver or prototype * chain, i.e., only call into interceptor for properties that do not exist. * Currently only valid for named interceptors. */ kNonMasking = 1 << 1,
/** * Will not call into interceptor for symbol lookup. Only meaningful for * named interceptors. */ kOnlyInterceptStrings = 1 << 2,
/** * The getter, query, enumerator callbacks do not produce side effects. */ kHasNoSideEffect = 1 << 3, };