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

Land extension fixes #518

Merged
merged 10 commits into from
Aug 14, 2023
2 changes: 1 addition & 1 deletion api/dgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -630,7 +630,7 @@ export class Socket extends EventEmitter {
constructor (options, callback) {
super()

this.id = rand64()
this.id = options?.id || rand64()
bcomnes marked this conversation as resolved.
Show resolved Hide resolved

if (typeof options === 'string') {
options = { type: options }
Expand Down
6 changes: 3 additions & 3 deletions api/extension.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,14 @@ export class Extension extends EventTarget {
/**
* Load an extension by name.
* @param {string} name
* @param {{ features: string[] | string ?} [options]
* @param {{ allow: string[] | string ?} [options]
* @return {Promise<Extension>}
*/
static async load (name, options) {
options = { name, ...options }

if (Array.isArray(options.features)) {
options.features = options.features.join(',')
if (Array.isArray(options.allow)) {
options.allow = options.allow.join(',')
}

const result = await ipc.request('extension.load', options)
Expand Down
4 changes: 2 additions & 2 deletions api/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3609,7 +3609,7 @@ declare module "socket:dgram" {
*/
export class Socket extends EventEmitter {
constructor(options: any, callback: any);
id: bigint;
id: any;
Copy link
Member

Choose a reason for hiding this comment

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

hmm is this loose typing because of this.id = options?.id || rand64()?
can we type options bag?

type: any;
signal: any;
state: {
Expand Down Expand Up @@ -3871,7 +3871,7 @@ declare module "socket:extension" {
/**
* Load an extension by name.
* @param {string} name
* @param {{ features: string[] | string ?} [options]
* @param {{ allow: string[] | string ?} [options]
* @return {Promise<Extension>}
*/
static load(name: string, options: any): Promise<Extension>;
Expand Down
4 changes: 4 additions & 0 deletions api/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,10 @@ export function parseJSON (string) {
}

export function parseHeaders (headers) {
if (Array.isArray(headers)) {
headers = headers.map((h) => h.trim()).join('\n')
}

if (typeof headers !== 'string') {
return []
}
Expand Down
31 changes: 29 additions & 2 deletions include/socket/extension.h
Original file line number Diff line number Diff line change
Expand Up @@ -296,11 +296,18 @@ extern "C" {
/**
* Get a context error location.
* @param context - An extension context
* @preturn The location of the error
* @return The location of the error
*/
SOCKET_RUNTIME_EXTENSION_EXPORT
const char* sapi_context_error_get_location (const sapi_context_t* context);

/**
* @param context - An extension context
* @return Allocated memmory for the context
*/
SOCKET_RUNTIME_EXTENSION_EXPORT
void* sapi_context_alloc (sapi_context_t* context, unsigned int size);


/**
* JavaScript API
Expand All @@ -315,7 +322,7 @@ extern "C" {
* @param source - The source of the script to evaluate
*/
SOCKET_RUNTIME_EXTENSION_EXPORT
void sapi_evaluate_javascript (
void sapi_javascript_evaluate (
sapi_context_t* context,
const char* name,
const char* source
Expand Down Expand Up @@ -782,6 +789,26 @@ extern "C" {
const sapi_ipc_message_t* message
);

/**
* Get the buffer bytes associated with the IPC message.
* @param message The IPC message
* @return The IPC message va (possibly `NULL`)
*/
SOCKET_RUNTIME_EXTENSION_EXPORT
const unsigned char* sapi_ipc_message_get_bytes (
const sapi_ipc_message_t* message
);

/**
* Get the buffer bytes size associated with the IPC message.
* @param message The IPC message
* @return The IPC message va (possibly `NULL`)
*/
SOCKET_RUNTIME_EXTENSION_EXPORT
unsigned int sapi_ipc_message_get_bytes_size (
const sapi_ipc_message_t* message
);

/**
* Get the IPC message name.
* @param message The IPC message
Expand Down
30 changes: 26 additions & 4 deletions src/cli/cli.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1693,6 +1693,26 @@ int main (const int argc, const char* argv[]) {

settings = parseINI(ini);

if (settings["meta_type"] == "extension" || settings["build_type"] == "extension") {
auto extension = settings["build_name"];
settings["build_extensions_" + extension + "_path"] = fs::current_path().string();

for (const auto& entry : settings) {
if (entry.first.starts_with("extension_sources")) {
settings["build_extensions_" + extension] += entry.second;
} else if (entry.first.starts_with("extension_")) {
auto key = replace(entry.first, "extension_", extension + "_");
auto value = entry.second;
auto index = "build_extensions_" + key;
if (settings[index].size() > 0) {
settings[index] += " " + value;
} else {
settings[index] = value;
}
}
}
}

// allow for local `.sscrc` '[settings] ...' entries to overload the
// project's settings in `socket.ini`:
// [settings.ios]
Expand Down Expand Up @@ -2543,6 +2563,7 @@ int main (const int argc, const char* argv[]) {
}

bool isForDesktop = !flagBuildForIOS && !flagBuildForAndroid;
auto isForExtensionOnly = settings["meta_type"] == "extension" || settings["build_type"] == "extension";

if (isForDesktop) {
fs::create_directories(paths.platformSpecificOutputPath / "include");
Expand Down Expand Up @@ -4545,7 +4566,7 @@ int main (const int argc, const char* argv[]) {
} else if (source.ends_with(".o") || source.ends_with(".a")) {
objects << source << " ";
continue;
} else if (source.ends_with(".c")) {
} else if (source.ends_with(".c") || source.ends_with(".m")) {
compiler = CC.size() > 0 ? CC : "clang";
if (platform.mac) {
compilerFlags += " -ObjC -v";
Expand Down Expand Up @@ -4583,6 +4604,7 @@ int main (const int argc, const char* argv[]) {
<< (" -L" + quote + trim(prefixFile("lib/" + platform.arch + "-desktop")) + quote)
<< " -lsocket-runtime"
#endif
<< " -fvisibility=hidden"
<< " -DIOS=0"
// << " -U__CYGWIN__"
<< " -DANDROID=0"
Expand Down Expand Up @@ -4701,9 +4723,9 @@ int main (const int argc, const char* argv[]) {
<< " " << extraFlags
<< " -lsocket-runtime"
<< " -luv"
<< " -fvisibility=hidden"
<< (" -L" + quote + trim(prefixFile("lib/" + platform.arch + "-desktop")) + quote)
#endif
<< " -fvisibility=hidden"
<< " " << trim(linkerFlags + " " + (flagDebugMode ? linkerDebugFlags : ""))
<< (" -I" + quote + trim(prefixFile("include")) + quote)
<< (" -I" + quote + trim(prefixFile("src")) + quote)
Expand Down Expand Up @@ -4750,7 +4772,7 @@ int main (const int argc, const char* argv[]) {
fs::current_path(oldCwd);
}

if (flagRunUserBuildOnly == false && isForDesktop) {
if (flagRunUserBuildOnly == false && isForDesktop && !isForExtensionOnly) {
StringStream compileCommand;

// windows / spaces in bin path - https://stackoverflow.com/a/27976653/3739540
Expand Down Expand Up @@ -4832,7 +4854,7 @@ int main (const int argc, const char* argv[]) {
//
// MacOS Stripping
//
if (platform.mac && isForDesktop) {
if (platform.mac && isForDesktop && !isForExtensionOnly) {
StringStream stripCommand;

stripCommand
Expand Down
2 changes: 1 addition & 1 deletion src/cli/templates.hh
Original file line number Diff line number Diff line change
Expand Up @@ -176,7 +176,7 @@ constexpr auto gPListInfo = R"XML(<?xml version="1.0" encoding="UTF-8"?>
<key>DTSDKBuild</key>
<string>10.13</string>
<key>CFBundleVersion</key>
<string>v{{meta_version}}</string>
<string>{{meta_version}}</string>
Copy link
Member

Choose a reason for hiding this comment

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

oh good catch!

<key>BuildMachineOSBuild</key>
<string>17D102</string>
<key>NSCameraUsageDescription</key>
Expand Down
3 changes: 2 additions & 1 deletion src/core/core.cc
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,8 @@ namespace SSC {
"const headers = `" + trim(post.headers) + "` \n"
" .trim() \n"
" .split(/[\\r\\n]+/) \n"
" .filter(Boolean); \n"
" .filter(Boolean) \n"
" .map((header) => header.trim()); \n"
" \n"
"let params = `" + params + "`; \n"
" \n"
Expand Down
22 changes: 11 additions & 11 deletions src/extension/context.cc
Original file line number Diff line number Diff line change
Expand Up @@ -9,23 +9,15 @@ sapi_context_t* sapi_context_create (
return nullptr;
}

auto context = retained || parent == nullptr
retained = retained || parent == nullptr;
auto context = retained
? new sapi_context_t(parent)
: parent->memory.alloc<sapi_context_t>();
: parent->memory.alloc<sapi_context_t>(parent, parent);

if (retained || parent == nullptr) {
context->retained = true;
}

if (parent != nullptr) {
context->context = parent;
context->extension = parent->extension;
context->router = parent->router;
context->config = parent->config;
context->data = parent->data;
context->policies = parent->policies;
}

return context;
}

Expand Down Expand Up @@ -195,3 +187,11 @@ void sapi_context_config_set (
if (context == nullptr || key == nullptr) return;
context->config[key] = value;
}

void* sapi_context_alloc (sapi_context_t* context, unsigned int size) {
if (context == nullptr || size == 0) {
return nullptr;
}

return reinterpret_cast<void*>(context->memory.alloc<unsigned char>(size));
}
29 changes: 27 additions & 2 deletions src/extension/extension.cc
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace SSC {
static Extension::Map extensions = {};
static Vector<String> initializedExtensions;
static Mutex mutex;

static String getcwd () {
Expand Down Expand Up @@ -107,6 +108,7 @@ namespace SSC {
this->config = context.config;
this->data = context.data;
this->policies = context.policies;
this->internal = context.internal;
}

Extension::Context::Context (const Context* context) {
Expand All @@ -116,6 +118,7 @@ namespace SSC {
this->config = context->config;
this->data = context->data;
this->policies = context->policies;
this->internal = context->internal;
}
}

Expand All @@ -128,6 +131,7 @@ namespace SSC {
this->config = context.config;
this->data = context.data;
this->policies = context.policies;
this->internal = context.internal;
}

Extension::Context::Context (IPC::Router* router) : Context() {
Expand All @@ -148,6 +152,7 @@ namespace SSC {
}

void Extension::Context::setPolicy (const String& name, bool allowed) {
if (name.size() == 0) return;
if (this->hasPolicy(name)) {
auto policy = this->getPolicy(name);
policy.allowed = allowed;
Expand Down Expand Up @@ -406,7 +411,7 @@ namespace SSC {
return;
}

auto extension = std::shared_ptr<Extension>(new Extension(name, initializer));
auto extension = std::make_shared<Extension>(name, initializer);
extensions.insert_or_assign(name, extension);
}

Expand All @@ -421,11 +426,21 @@ namespace SSC {
return false;
}

if (std::count(initializedExtensions.begin(), initializedExtensions.end(), name) > 0) {
debug("Extension '%s' already loaded", name.c_str());
// already initializedExtensions
return true;
}

auto extension = extensions.at(name);
if (extension != nullptr && extension->initializer != nullptr) {
debug("Initializing loaded extension: %s", name.c_str());
extension->context.data = data;
return extension->initializer(ctx, data);
auto didInitialize = extension->initializer(ctx, data);
if (didInitialize) {
initializedExtensions.push_back(name);
}
return didInitialize;
}

return false;
Expand Down Expand Up @@ -457,6 +472,16 @@ bool sapi_extension_register (
auto deinitializer = registration->deinitializer;
if (deinitializer != nullptr) {
debug("Unloading extension: %s", registration->name);
auto initializedExtensionsCursor = std::find(
SSC::initializedExtensions.begin(),
SSC::initializedExtensions.end(),
SSC::String(registration->name)
);

if (initializedExtensionsCursor != SSC::initializedExtensions.end()) {
SSC::initializedExtensions.erase(initializedExtensionsCursor);
}

return deinitializer(reinterpret_cast<sapi_context_t*>(ctx), data);
}

Expand Down
25 changes: 19 additions & 6 deletions src/extension/ipc.cc
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ bool sapi_ipc_router_map (
message.buffer.bytes,
message.buffer.size
);
context->internal = context->memory.alloc<SSC::IPC::Router::ReplyCallback>(reply);
context->internal = new SSC::IPC::Router::ReplyCallback(reply);
callback(
context,
(sapi_ipc_message_t*) &msg,
Expand Down Expand Up @@ -127,10 +127,9 @@ bool sapi_ipc_reply (const sapi_ipc_result_t* result) {
auto fn = reinterpret_cast<SSC::IPC::Router::ReplyCallback*>(internal);

if (fn != nullptr) {
if (fn != nullptr && result != nullptr) {
(*fn)(*result);
success = true;
}
(*fn)(*result);
success = true;
delete fn;
}

// if retained, then then caller must eventually call `sapi_context_release()`
Expand Down Expand Up @@ -158,7 +157,7 @@ bool sapi_ipc_send_bytes (
.ttl = 0,
.body = new char[size]{0},
.length = size,
.headers =headers ? headers : ""
.headers = headers ? headers : ""
};

memcpy(post.body, bytes, size);
Expand Down Expand Up @@ -405,6 +404,20 @@ sapi_ipc_result_t* sapi_ipc_result_clone (
return context->memory.alloc<sapi_ipc_result_t>(context, *result);
}

const unsigned char* sapi_ipc_message_get_bytes (
const sapi_ipc_message_t* message
) {
if (!message) return nullptr;
return reinterpret_cast<const unsigned char*>(message->buffer.bytes);
}

unsigned int sapi_ipc_message_get_bytes_size (
const sapi_ipc_message_t* message
) {
if (!message || !message->buffer.bytes) return 0;
return static_cast<unsigned int>(message->buffer.size);
}

void sapi_ipc_result_set_seq (sapi_ipc_result_t* result, const char* seq) {
if (result && seq) {
result->seq = seq;
Expand Down
Loading
Loading