Commit 459909a5 authored by Evan Welsh's avatar Evan Welsh Committed by Philip Chimento

modules: Split print functions into native module.

parent 05745ab4
......@@ -29,12 +29,9 @@
#include <glib.h>
#include <js/CallArgs.h>
#include <js/CharacterEncoding.h>
#include <js/Class.h>
#include <js/CompilationAndEvaluation.h>
#include <js/CompileOptions.h>
#include <js/Conversions.h>
#include <js/PropertyDescriptor.h> // for JSPROP_PERMANENT, JSPROP_RE...
#include <js/PropertySpec.h>
#include <js/Realm.h> // for GetObjectRealmOrNull, SetRealmPrivate
......@@ -42,7 +39,6 @@
#include <js/RootingAPI.h>
#include <js/SourceText.h>
#include <js/TypeDecls.h>
#include <js/Utility.h> // for UniqueChars
#include <jsapi.h> // for AutoSaveExceptionState, ...
#include "gjs/atoms.h"
......@@ -88,145 +84,6 @@ run_bootstrap(JSContext *cx,
return JS::CloneAndExecuteScript(cx, compiled_script, &ignored);
}
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_log(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
if (argc != 1) {
gjs_throw(cx, "Must pass a single argument to log()");
return false;
}
/* JS::ToString might throw, in which case we will only log that the value
* could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
JS::RootedString jstr(cx, JS::ToString(cx, argv[0]));
exc_state.restore();
if (!jstr) {
g_message("JS LOG: <cannot convert value to string>");
return true;
}
JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
if (!s)
return false;
g_message("JS LOG: %s", s.get());
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_log_error(JSContext *cx,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
if ((argc != 1 && argc != 2) || !argv[0].isObject()) {
gjs_throw(cx, "Must pass an exception and optionally a message to logError()");
return false;
}
JS::RootedString jstr(cx);
if (argc == 2) {
/* JS::ToString might throw, in which case we will only log that the
* value could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
jstr = JS::ToString(cx, argv[1]);
exc_state.restore();
}
gjs_log_exception_full(cx, argv[0], jstr, G_LOG_LEVEL_WARNING);
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_print_parse_args(JSContext *cx,
const JS::CallArgs& argv,
GjsAutoChar *buffer)
{
GString *str;
guint n;
str = g_string_new("");
for (n = 0; n < argv.length(); ++n) {
/* JS::ToString might throw, in which case we will only log that the
* value could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
JS::RootedString jstr(cx, JS::ToString(cx, argv[n]));
exc_state.restore();
if (jstr) {
JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
if (!s) {
g_string_free(str, true);
return false;
}
g_string_append(str, s.get());
if (n < (argv.length()-1))
g_string_append_c(str, ' ');
} else {
*buffer = g_string_free(str, true);
if (!*buffer)
*buffer = g_strdup("<invalid string>");
return true;
}
}
*buffer = g_string_free(str, false);
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_print(JSContext *context,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs argv = JS::CallArgsFromVp (argc, vp);
GjsAutoChar buffer;
if (!gjs_print_parse_args(context, argv, &buffer))
return false;
g_print("%s\n", buffer.get());
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool
gjs_printerr(JSContext *context,
unsigned argc,
JS::Value *vp)
{
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
GjsAutoChar buffer;
if (!gjs_print_parse_args(context, argv, &buffer))
return false;
g_printerr("%s\n", buffer.get());
argv.rval().setUndefined();
return true;
}
const JSClassOps defaultclassops = JS::DefaultGlobalClassOps;
class GjsGlobal {
......@@ -237,10 +94,6 @@ class GjsGlobal {
};
static constexpr JSFunctionSpec static_funcs[] = {
JS_FN("log", gjs_log, 1, GJS_MODULE_PROP_FLAGS),
JS_FN("logError", gjs_log_error, 2, GJS_MODULE_PROP_FLAGS),
JS_FN("print", gjs_print, 0, GJS_MODULE_PROP_FLAGS),
JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
JS_FS_END};
public:
......
......@@ -387,6 +387,7 @@ libgjs_sources = [
'gjs/stack.cpp',
'modules/console.cpp', 'modules/console.h',
'modules/modules.cpp', 'modules/modules.h',
'modules/print.cpp', 'modules/print.h',
'modules/system.cpp', 'modules/system.h',
]
......
......@@ -26,6 +26,7 @@
#include "gjs/native.h"
#include "modules/console.h"
#include "modules/modules.h"
#include "modules/print.h"
#include "modules/system.h"
#ifdef ENABLE_CAIRO
......@@ -40,4 +41,5 @@ gjs_register_static_modules (void)
#endif
gjs_register_native_module("system", gjs_js_define_system_stuff);
gjs_register_native_module("console", gjs_define_console_stuff);
gjs_register_native_module("_print", gjs_define_print_stuff);
}
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
*
* Copyright (c) 2008 litl, LLC
* Copyright (c) 2009 Red Hat, Inc.
*/
#include <config.h>
#include <glib.h>
#include <js/CallArgs.h>
#include <js/CharacterEncoding.h> // for JS_EncodeStringToUTF8
#include <js/Conversions.h>
#include <js/PropertySpec.h> // for JS_FN, JSFunctionSpec, JS_FS_END
#include <js/RootingAPI.h>
#include <js/TypeDecls.h>
#include <js/Utility.h> // for UniqueChars
#include <js/Value.h>
#include <jsapi.h>
#include "gjs/jsapi-util.h"
#include "modules/print.h"
GJS_JSAPI_RETURN_CONVENTION
static bool gjs_log(JSContext* cx, unsigned argc, JS::Value* vp) {
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
if (argc != 1) {
gjs_throw(cx, "Must pass a single argument to log()");
return false;
}
/* JS::ToString might throw, in which case we will only log that the value
* could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
JS::RootedString jstr(cx, JS::ToString(cx, argv[0]));
exc_state.restore();
if (!jstr) {
g_message("JS LOG: <cannot convert value to string>");
return true;
}
JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
if (!s)
return false;
g_message("JS LOG: %s", s.get());
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool gjs_log_error(JSContext* cx, unsigned argc, JS::Value* vp) {
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
if ((argc != 1 && argc != 2) || !argv[0].isObject()) {
gjs_throw(
cx,
"Must pass an exception and optionally a message to logError()");
return false;
}
JS::RootedString jstr(cx);
if (argc == 2) {
/* JS::ToString might throw, in which case we will only log that the
* value could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
jstr = JS::ToString(cx, argv[1]);
exc_state.restore();
}
gjs_log_exception_full(cx, argv[0], jstr, G_LOG_LEVEL_WARNING);
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool gjs_print_parse_args(JSContext* cx, const JS::CallArgs& argv,
GjsAutoChar* buffer) {
GString* str = g_string_new("");
for (unsigned n = 0; n < argv.length(); ++n) {
/* JS::ToString might throw, in which case we will only log that the
* value could not be converted to string */
JS::AutoSaveExceptionState exc_state(cx);
JS::RootedString jstr(cx, JS::ToString(cx, argv[n]));
exc_state.restore();
if (jstr) {
JS::UniqueChars s(JS_EncodeStringToUTF8(cx, jstr));
if (!s) {
g_string_free(str, true);
return false;
}
g_string_append(str, s.get());
if (n < (argv.length() - 1))
g_string_append_c(str, ' ');
} else {
*buffer = g_string_free(str, true);
if (!*buffer)
*buffer = g_strdup("<invalid string>");
return true;
}
}
*buffer = g_string_free(str, false);
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool gjs_print(JSContext* context, unsigned argc, JS::Value* vp) {
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
GjsAutoChar buffer;
if (!gjs_print_parse_args(context, argv, &buffer))
return false;
g_print("%s\n", buffer.get());
argv.rval().setUndefined();
return true;
}
GJS_JSAPI_RETURN_CONVENTION
static bool gjs_printerr(JSContext* context, unsigned argc, JS::Value* vp) {
JS::CallArgs argv = JS::CallArgsFromVp(argc, vp);
GjsAutoChar buffer;
if (!gjs_print_parse_args(context, argv, &buffer))
return false;
g_printerr("%s\n", buffer.get());
argv.rval().setUndefined();
return true;
}
// clang-format off
static constexpr JSFunctionSpec funcs[] = {
JS_FN("log", gjs_log, 1, GJS_MODULE_PROP_FLAGS),
JS_FN("logError", gjs_log_error, 2, GJS_MODULE_PROP_FLAGS),
JS_FN("print", gjs_print, 0, GJS_MODULE_PROP_FLAGS),
JS_FN("printerr", gjs_printerr, 0, GJS_MODULE_PROP_FLAGS),
JS_FS_END};
// clang-format on
bool gjs_define_print_stuff(JSContext* context,
JS::MutableHandleObject module) {
module.set(JS_NewPlainObject(context));
if (!module)
return false;
return JS_DefineFunctions(context, module, funcs);
}
/* -*- mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; -*- */
/*
* SPDX-License-Identifier: MIT OR LGPL-2.0-or-later
*
* Copyright (c) 2020 Evan Welsh <noreply@evanwelsh.com>
*/
#ifndef MODULES_PRINT_H_
#define MODULES_PRINT_H_
#include <config.h>
#include <js/TypeDecls.h>
#include "gjs/macros.h"
GJS_JSAPI_RETURN_CONVENTION
bool gjs_define_print_stuff(JSContext* context, JS::MutableHandleObject module);
#endif // MODULES_PRINT_H_
---
extends: "../../../.eslintrc.yml"
globals:
log: "off"
logError: "off"
print: "off"
printerr: "off"
......@@ -16,6 +16,8 @@
* the first frame is executed.
*/
const {print, logError} = imports._print;
// Debugger state.
var focusedFrame = null;
var topFrame = null;
......
(function (exports) {
'use strict';
// Do early initialization here.
void exports;
const {print, printerr, log, logError} = imports._print;
Object.defineProperties(exports, {
print: {
configurable: false,
enumerable: true,
value: print,
},
printerr: {
configurable: false,
enumerable: true,
value: printerr,
},
log: {
configurable: false,
enumerable: true,
value: log,
},
logError: {
configurable: false,
enumerable: true,
value: logError,
},
});
})(globalThis);
......@@ -53,8 +53,8 @@ for FILE in $SRCDIR/gi/*.cpp $SRCDIR/gjs/atoms.cpp $SRCDIR/gjs/byteArray.cpp \
$SRCDIR/gjs/jsapi-util-error.cpp $SRCDIR/gjs/jsapi-util-string.cpp \
$SRCDIR/gjs/module.cpp $SRCDIR/gjs/native.cpp $SRCDIR/gjs/stack.cpp \
$SRCDIR/modules/cairo-*.cpp $SRCDIR/modules/console.cpp \
$SRCDIR/modules/system.cpp $SRCDIR/test/*.cpp $SRCDIR/util/*.cpp \
$SRCDIR/libgjs-private/*.c
$SRCDIR/modules/print.cpp $SRCDIR/modules/system.cpp $SRCDIR/test/*.cpp \
$SRCDIR/util/*.cpp $SRCDIR/libgjs-private/*.c
do
if should_analyze $FILE; then
if ! $IWYU $FILE -- $PRIVATE_MAPPING | $POSTPROCESS; then
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment