Skip to content

Commit

Permalink
ALTV-380 Update v8 version
Browse files Browse the repository at this point in the history
  • Loading branch information
vadzz-dev committed Sep 16, 2024
1 parent 9c8caa9 commit a59e8e6
Show file tree
Hide file tree
Showing 13 changed files with 71 additions and 50 deletions.
16 changes: 8 additions & 8 deletions client/cmake/DepsDownload.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -2,32 +2,32 @@ include(../shared/cmake/DepsHelpers.cmake)

# Set this to false, when using a custom v8 build for testing
set(__deps_check_enabled true)
set(V8_VERSION "12.4.254")

function(DownloadDeps)
set(__base_path "${PROJECT_SOURCE_DIR}/deps/v8")

GetBranchAndOS(__deps_branch __deps_os_path_name)
set(__deps_url_base_path "https://cdn.alt-mp.com/deps/v8/${__deps_branch}")
set(__deps_url_base_path "https://cdn.alt-mp.com/deps/v8/${V8_VERSION}")

if(__deps_check_enabled)
message("Checking release binaries...")

GetCDNInfo("${__deps_url_base_path}/${__deps_os_path_name}/Release" __deps_release_hashes __deps_current_version)

DownloadFile("v8_monolith.lib" "${__base_path}/lib/Release" "${__deps_os_path_name}/Release" ${__deps_release_hashes})

# Only download debug binary in Debug builds
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
message("Checking debug binaries...")

GetCDNInfo("${__deps_url_base_path}/${__deps_os_path_name}/Debug" __deps_debug_hashes __deps_current_version)

DownloadFile("v8_monolith.lib" "${__base_path}/lib/Debug" "${__deps_os_path_name}/Debug" ${__deps_debug_hashes})
# GetCDNInfo("${__deps_url_base_path}/${__deps_os_path_name}/Debug" __deps_debug_hashes __deps_current_version)
# DownloadFile("v8_monolith.lib" "${__base_path}/lib/Debug" "${__deps_os_path_name}/Debug" ${__deps_debug_hashes})
endif()

GetCDNInfo("${__deps_url_base_path}" __deps_headers_hashes __deps_current_version)
DownloadFile("headers.zip" "${__base_path}/include" "" ${__deps_headers_hashes})
file(ARCHIVE_EXTRACT INPUT "${__base_path}/include/headers.zip" DESTINATION "${__base_path}/..")
GetCDNInfo("${__deps_url_base_path}/include" __deps_headers_hashes __deps_current_version)
DownloadFile("include.zip" "${__base_path}/include" "include" ${__deps_headers_hashes})
file(ARCHIVE_EXTRACT INPUT "${__base_path}/include/include.zip" DESTINATION "${__base_path}/include")
file(REMOVE "${__base_path}/include/include.zip")

if(__deps_current_version)
message("V8 deps version: ${__deps_current_version}")
Expand Down
10 changes: 7 additions & 3 deletions client/src/CV8Resource.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,12 +567,16 @@ v8::MaybeLocal<v8::Value> EvaluateSyntheticModule(v8::Local<v8::Context> context

v8::Local<v8::Module> CV8ResourceImpl::CreateSyntheticModule(const std::string& name, v8::Local<v8::Value> exportValue)
{
std::vector<v8::Local<v8::String>> exports = {V8Helpers::JSValue("default")};
v8::Local<v8::String> defaultExport = V8Helpers::JSValue("default");
v8::MemorySpan<const v8::Local<v8::String>> exports = { &defaultExport, 1 };

v8::Local<v8::Module> syntheticModule = v8::Module::CreateSyntheticModule(
isolate, V8Helpers::JSValue(name), exports, &EvaluateSyntheticModule);
isolate, V8Helpers::JSValue(name), exports, &EvaluateSyntheticModule);

syntheticModuleExports.insert({
syntheticModule->GetIdentityHash(), V8Helpers::CPersistent<v8::Value>(isolate, exportValue)
});
});

return syntheticModule;
}

Expand Down
31 changes: 20 additions & 11 deletions client/src/CV8ScriptRuntime.cpp
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@

#include "CV8ScriptRuntime.h"
#include "inspector/CV8InspectorClient.h"
#include "inspector/CV8InspectorChannel.h"
#include "V8Module.h"
#include "events/Events.h"
#include "CProfiler.h"
#include "CProfiler.h"
#include <Windows.h>

CV8ScriptRuntime::CV8ScriptRuntime()
{
// !!! Don't change these without adjusting bytecode module !!!
v8::V8::SetFlagsFromString("--harmony-import-assertions --short-builtin-calls --no-lazy --no-flush-bytecode");
platform = v8::platform::NewDefaultPlatform();
platform = v8::platform::NewDefaultPlatform();

v8::LogEventCallback;

v8::V8::InitializePlatform(platform.get());
v8::V8::InitializeICU((alt::ICore::Instance().GetClientPath() + "/libs/icudtl_v8.dat").c_str());
// MessageBoxA(NULL, "js init 3", "", MB_OK);
v8::V8::Initialize();

create_params.array_buffer_allocator = v8::ArrayBuffer::Allocator::NewDefaultAllocator();
Expand All @@ -22,9 +26,10 @@ CV8ScriptRuntime::CV8ScriptRuntime()
isolate->SetFatalErrorHandler([](const char* location, const char* message) { Log::Error << "[V8] " << location << ": " << message << Log::Endl; });

isolate->SetOOMErrorHandler(
[](const char* location, bool isHeap)
[](const char* location, const v8::OOMDetails& details)
{
if(!isHeap) return;
if(!details.is_heap_oom) return;

Log::Error << "[V8] " << location << ": Heap out of memory. Forward this to the server developers." << Log::Endl;
Log::Error << "[V8] The current heap limit can be shown with the 'heap' console command. Consider increasing your system RAM." << Log::Endl;
});
Expand Down Expand Up @@ -79,22 +84,26 @@ CV8ScriptRuntime::CV8ScriptRuntime()
});

isolate->SetHostImportModuleDynamicallyCallback(
[](v8::Local<v8::Context> context, v8::Local<v8::ScriptOrModule> referrer, v8::Local<v8::String> specifier, v8::Local<v8::FixedArray> importAssertions)
[](v8::Local<v8::Context> context,
v8::Local<v8::Data> host_defined_options,
v8::Local<v8::Value> resource_name,
v8::Local<v8::String> specifier,
v8::Local<v8::FixedArray> import_attributes)
{
v8::Isolate* isolate = context->GetIsolate();

auto referrerVal = referrer->GetResourceName();
if(referrerVal->IsUndefined()) return v8::MaybeLocal<v8::Promise>();
if(resource_name->IsUndefined())
return v8::MaybeLocal<v8::Promise>();

std::string referrerUrl = *v8::String::Utf8Value(isolate, referrer->GetResourceName());
std::string referrerUrl = *v8::String::Utf8Value(isolate, resource_name);
auto resource = static_cast<CV8ResourceImpl*>(V8ResourceImpl::Get(context));

auto resolver = v8::Promise::Resolver::New(context).ToLocalChecked();

V8Helpers::CPersistent<v8::Promise::Resolver> presolver(isolate, resolver);
V8Helpers::CPersistent<v8::String> pspecifier(isolate, specifier);
V8Helpers::CPersistent<v8::Module> preferrerModule(isolate, resource->GetModuleFromPath(referrerUrl));
V8Helpers::CPersistent<v8::FixedArray> pimportAssertions(isolate, importAssertions);
V8Helpers::CPersistent<v8::FixedArray> pimportAssertions(isolate, import_attributes);

// careful what we take in by value in the lambda
// it is possible pass v8::Local but should not be done
Expand Down Expand Up @@ -236,7 +245,7 @@ void CV8ScriptRuntime::OnDispose()
while(isolate->IsInUse()) isolate->Exit();
isolate->Dispose();
v8::V8::Dispose();
v8::V8::ShutdownPlatform();
v8::V8::DisposePlatform();
delete create_params.array_buffer_allocator;

if(CProfiler::Instance().IsEnabled()) CProfiler::Instance().Dump(alt::ICore::Instance().GetClientPath());
Expand Down
6 changes: 3 additions & 3 deletions client/src/bindings/Handling.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -237,11 +237,11 @@ static void DriveBiasRearSetter(v8::Local<v8::String>, v8::Local<v8::Value> val,
V8_TO_NUMBER(val, fvalue);
vehicle->ReplaceHandling();
vehicle->GetHandling()->SetDriveBiasRear(fvalue);
}
}

static void AccelerationGetter(v8::Local<v8::String>, const v8::PropertyCallbackInfo<v8::Value>& info)
{
V8_DEPRECATE("HandlingData.acceleration", "HandlingData.driveBiasRear");
V8_DEPRECATE("HandlingData.acceleration", "HandlingData.driveBiasRear");

V8_GET_ISOLATE_CONTEXT();
V8_GET_THIS_INTERNAL_FIELD_ENTITY(1, vehicle, alt::IVehicle);
Expand All @@ -251,7 +251,7 @@ static void AccelerationGetter(v8::Local<v8::String>, const v8::PropertyCallback

static void AccelerationSetter(v8::Local<v8::String>, v8::Local<v8::Value> val, const v8::PropertyCallbackInfo<void>& info)
{
V8_DEPRECATE("HandlingData.acceleration", "HandlingData.driveBiasRear");
V8_DEPRECATE("HandlingData.acceleration", "HandlingData.driveBiasRear");

V8_GET_ISOLATE_CONTEXT();
V8_GET_THIS_INTERNAL_FIELD_ENTITY(1, vehicle, alt::IVehicle);
Expand Down
2 changes: 1 addition & 1 deletion client/src/bindings/HandlingData.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ static void HandlingNameHashGetter(v8::Local<v8::String>, const v8::PropertyCall

V8_GET_THIS_INTERNAL_FIELD_INTEGER(1, modelHash);

uint32_t modelHash2 = info.This()->GetInternalField(0)->IntegerValue(ctx).ToChecked();
uint32_t modelHash2 = info.This()->GetInternalField(0).As<v8::Value>()->IntegerValue(ctx).ToChecked();

auto handling = alt::ICore::Instance().GetHandlingData(modelHash);
V8_CHECK(handling, "handling data for vehicle not found");
Expand Down
2 changes: 1 addition & 1 deletion client/src/bindings/V8Natives.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ static void* ToMemoryBuffer(v8::Local<v8::Value> val, v8::Local<v8::Context> ctx
if(cls == V8Class::ObjectClass::MEMORY_BUFFER)
{
void* memory = obj->GetAlignedPointerFromInternalField(1);
uint32_t size = obj->GetInternalField(2)->Uint32Value(ctx).ToChecked();
uint32_t size = obj->GetInternalField(2).As<v8::Value>()->Uint32Value(ctx).ToChecked();

if(size > 0) return memory;
}
Expand Down
14 changes: 10 additions & 4 deletions client/src/workers/CWorker.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ void CWorker::SetupIsolate()
});

isolate->SetHostImportModuleDynamicallyCallback(
[](v8::Local<v8::Context> context, v8::Local<v8::ScriptOrModule> referrer, v8::Local<v8::String> specifier, v8::Local<v8::FixedArray> assertions)
[](v8::Local<v8::Context> context,
v8::Local<v8::Data> host_defined_options,
v8::Local<v8::Value> resource_name,
v8::Local<v8::String> specifier,
v8::Local<v8::FixedArray> import_attributes)
{
v8::Isolate* isolate = context->GetIsolate();
v8::Isolate::Scope isolateScope(isolate);
Expand All @@ -161,13 +165,15 @@ void CWorker::SetupIsolate()
if(maybeResolver.IsEmpty()) return v8::MaybeLocal<v8::Promise>();
v8::Local<v8::Promise::Resolver> resolver = maybeResolver.ToLocalChecked();

// if(!resource_name->IsString()) return v8::MaybeLocal<v8::Promise>();

CWorker* worker = static_cast<CWorker*>(context->GetAlignedPointerFromEmbedderData(2));
std::string referrerName = *v8::String::Utf8Value(isolate, referrer->GetResourceName());
std::string referrerName = *v8::String::Utf8Value(isolate, resource_name);
v8::Local<v8::Module> referrerModule = worker->GetModuleFromPath(referrerName);
if(referrerModule.IsEmpty() && referrerName != "<bootstrapper>") resolver->Reject(context, v8::Exception::ReferenceError(V8Helpers::JSValue("Could not resolve referrer module")));
else
{
v8::MaybeLocal<v8::Module> maybeModule = CWorker::Import(context, specifier, assertions, referrerModule);
v8::MaybeLocal<v8::Module> maybeModule = CWorker::Import(context, specifier, import_attributes, referrerModule);
if(maybeModule.IsEmpty()) resolver->Reject(context, v8::Exception::ReferenceError(V8Helpers::JSValue("Could not resolve module")));
else
{
Expand Down Expand Up @@ -218,7 +224,7 @@ bool CWorker::SetupScript()
{
v8::Local<v8::Context> ctx = context.Get(isolate);
v8::MaybeLocal<v8::Module> maybeModule;
v8::ScriptOrigin scriptOrigin(isolate, V8Helpers::JSValue("<bootstrapper>"), 0, 0, false, -1, v8::Local<v8::Value>(), false, false, true, v8::Local<v8::PrimitiveArray>());
v8::ScriptOrigin scriptOrigin(V8Helpers::JSValue("<bootstrapper>"), 0, 0, false, -1, v8::Local<v8::Value>(), false, false, true, v8::Local<v8::PrimitiveArray>());
v8::ScriptCompiler::Source source{ V8Helpers::JSValue(bootstrap_code), scriptOrigin };
maybeModule = v8::ScriptCompiler::CompileModule(isolate, &source);

Expand Down
7 changes: 5 additions & 2 deletions shared/V8Entity.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,11 @@ class V8Entity
v8::Local<v8::Object> obj = val.As<v8::Object>();
if(obj->InternalFieldCount() <= static_cast<int>(V8Class::InternalFields::BASE_OBJECT)) return nullptr;

v8::Local<v8::Value> i = obj->GetInternalField(static_cast<int>(V8Class::InternalFields::BASE_OBJECT));
if(!i->IsExternal()) return nullptr;
v8::Local<v8::Data> i = obj->GetInternalField(static_cast<int>(V8Class::InternalFields::BASE_OBJECT));
if(!i->IsValue()) return nullptr;

v8::Local<v8::Value> iv = i.As<v8::Value>();
if(!iv->IsExternal()) return nullptr;

return static_cast<V8Entity*>(i.As<v8::External>()->Value());
}
Expand Down
3 changes: 2 additions & 1 deletion shared/V8FastFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ v8::Local<v8::FunctionTemplate> V8FastFunction::GetTemplate(v8::Isolate* isolate

v8::Local<v8::FunctionTemplate> tpl = v8::FunctionTemplate::New(
isolate, slowCallback, v8::Local<v8::Value>(), v8::Local<v8::Signature>(), 1, v8::ConstructorBehavior::kThrow, v8::SideEffectType::kHasSideEffect, &fastCallback);
tplMap.insert({ isolate, v8::Persistent<v8::FunctionTemplate, v8::CopyablePersistentTraits<v8::FunctionTemplate>>(isolate, tpl) });

tplMap.insert({ isolate, v8::Persistent<v8::FunctionTemplate>(isolate, tpl) });
return tpl;
}

Expand Down
16 changes: 6 additions & 10 deletions shared/V8Helpers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -134,14 +134,7 @@ v8::Local<v8::Object> V8Helpers::CreateCustomObject(v8::Isolate* isolate,
v8::GenericNamedPropertyQueryCallback query)
{
v8::Local<v8::ObjectTemplate> objTemplate = v8::ObjectTemplate::New(isolate);
v8::NamedPropertyHandlerConfiguration config;
config.getter = getter;
config.setter = setter;
config.deleter = deleter;
config.query = query;
config.enumerator = enumerator;
config.data = v8::External::New(isolate, data);
config.flags = v8::PropertyHandlerFlags::kHasNoSideEffect;
v8::NamedPropertyHandlerConfiguration config{ getter, setter, query, deleter, enumerator, v8::External::New(isolate, data), v8::PropertyHandlerFlags::kHasNoSideEffect };
objTemplate->SetHandler(config);

v8::Local<v8::Object> obj = objTemplate->NewInstance(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked();
Expand Down Expand Up @@ -384,10 +377,13 @@ V8Class::ObjectClass V8Helpers::GetObjectClass(v8::Local<v8::Object> obj)
{
if(obj->InternalFieldCount() <= static_cast<int>(V8Class::InternalFields::OBJECT_CLASS))
return V8Class::ObjectClass::NONE;

auto data = obj->GetInternalField(static_cast<int>(V8Class::InternalFields::OBJECT_CLASS));
if(!data->IsValue()) return V8Class::ObjectClass::NONE;

auto val = obj->GetInternalField(static_cast<int>(V8Class::InternalFields::OBJECT_CLASS));
auto val = data.As<v8::Value>();
if(!val->IsExternal())
return V8Class::ObjectClass::NONE;
return V8Class::ObjectClass::NONE;

void* cls = val.As<v8::External>()->Value();
return *reinterpret_cast<V8Class::ObjectClass*>(&cls);
Expand Down
3 changes: 3 additions & 0 deletions shared/cmake/DepsHelpers.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ function(DownloadFile name path urlpath checksums)
else()
set(__deps_file_checksum 0)
endif()

string(JSON __deps_file_checksum_cdn GET ${checksums} ${name})
if(NOT ${__deps_file_checksum} STREQUAL ${__deps_file_checksum_cdn})
message("Downloading ${name}...")
Expand All @@ -18,9 +19,11 @@ function(DownloadFile name path urlpath checksums)
file(DOWNLOAD "${__download_url}" "${path}/${name}"
STATUS DOWNLOAD_STATUS
)

# Separate the returned status code, and error message.
list(GET DOWNLOAD_STATUS 0 STATUS_CODE)
list(GET DOWNLOAD_STATUS 1 ERROR_MESSAGE)

# Check if download was successful.
if(${STATUS_CODE} EQUAL 0)
message(STATUS "Download completed successfully!")
Expand Down
1 change: 0 additions & 1 deletion shared/helpers/Bindings.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ void V8Helpers::SetAccessor(v8::Isolate* isolate, v8::Local<v8::FunctionTemplate
getter,
setter,
v8::Local<v8::Value>(),
v8::AccessControl::DEFAULT,
setter != nullptr ? v8::PropertyAttribute::None : v8::PropertyAttribute::ReadOnly);
}

Expand Down
10 changes: 5 additions & 5 deletions shared/helpers/Macros.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,29 +50,29 @@

#define V8_GET_THIS_INTERNAL_FIELD_OBJECT(idx, val) \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
auto val = info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked();
auto val = info.This()->GetInternalField(idx).As<v8::Value>()->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked();

#define V8_GET_THIS_INTERNAL_FIELD_V8ENTITY(idx, val) \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
auto val = V8Entity::Get(info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked());
auto val = V8Entity::Get(info.This()->GetInternalField(idx).As<v8::Value>()->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked());

#define V8_GET_THIS_INTERNAL_FIELD_ENTITY(idx, val, type) \
type* val; \
{ \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
V8Entity* __val = V8Entity::Get(info.This()->GetInternalField(idx)->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); \
V8Entity* __val = V8Entity::Get(info.This()->GetInternalField(idx).As<v8::Value>()->ToObject(isolate->GetEnteredOrMicrotaskContext()).ToLocalChecked()); \
V8_CHECK(__val, "baseobject is invalid"); \
val = dynamic_cast<type*>(__val->GetHandle()); \
V8_CHECK(val, "baseobject is not of type " #type); \
}

#define V8_GET_THIS_INTERNAL_FIELD_INTEGER(idx, val) \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
auto val = info.This()->GetInternalField(idx)->IntegerValue(ctx).ToChecked();
auto val = info.This()->GetInternalField(idx).As<v8::Value>()->IntegerValue(ctx).ToChecked();

#define V8_GET_THIS_INTERNAL_FIELD_UINT32(idx, val) \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
auto val = info.This()->GetInternalField(idx)->Uint32Value(ctx).ToChecked();
auto val = info.This()->GetInternalField(idx).As<v8::Value>()->Uint32Value(ctx).ToChecked();

#define V8_GET_THIS_INTERNAL_FIELD_EXTERNAL(idx, val, type) \
V8_CHECK(info.This()->InternalFieldCount() > idx - 1, "Invalid internal field count (is the 'this' context correct?)"); \
Expand Down

0 comments on commit a59e8e6

Please sign in to comment.