Skip to content

Instantly share code, notes, and snippets.

@w3cj

w3cj/jsapi.c Secret

Created November 29, 2024 00:19
Show Gist options
  • Select an option

  • Save w3cj/754709a0643256c6179ca70656301377 to your computer and use it in GitHub Desktop.

Select an option

Save w3cj/754709a0643256c6179ca70656301377 to your computer and use it in GitHub Desktop.
// Code from here:
// https://github.com/jrmuizel/mozilla-cvs-history/blob/781c48087175615674b38b31fcc0aae17f0651b6/js/src/jsapi.h
// https://github.com/jrmuizel/mozilla-cvs-history/blob/781c48087175615674b38b31fcc0aae17f0651b6/js/src/jsapi.c
#include <stdio.h>
/*
// what is jsval?
// js/src/jspubtd.h
// line 36
typedef prword jsval;
// js/src/jscompat.h
// line 47
typedef prword_t prword;
// nsprpub/pr/include/obsolete/protypes.h
// line 76
typedef PRWord prword_t;
// nsprpub/pr/include/prtypes.h
// line 355
// ** A PRWord is an integer that is the same size as a void*
typedef long PRWord;
// Long signed integer type. Capable of containing at least the [−2147483647, +2147483647] range
// https://en.wikipedia.org/wiki/C_data_types
*/
typedef long jsval;
typedef unsigned int uint;
#define JSVAL_OBJECT 0x0 /* untagged reference to object */
#define JSVAL_INT 0x1 /* tagged 31-bit integer value */
#define JSVAL_DOUBLE 0x2 /* tagged reference to double */
#define JSVAL_STRING 0x4 /* tagged reference to string */
#define JSVAL_BOOLEAN 0x6 /* tagged boolean value */
#define PR_BIT(n) ((uint)1 << (n))
#define PR_BITMASK(n) (PR_BIT(n) - 1)
#define JSVAL_TAGMASK PR_BITMASK(JSVAL_TAGBITS)
#define JSVAL_TAG(v) ((v) & JSVAL_TAGMASK)
#define JSVAL_TAGBITS 3
#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL)
#define JSVAL_NULL OBJECT_TO_JSVAL(0)
#define OBJECT_TO_JSVAL(obj) ((jsval)(obj))
#define JSVAL_IS_OBJECT(v) (JSVAL_TAG(v) == JSVAL_OBJECT)
#define JSVAL_VOID INT_TO_JSVAL(0 - JSVAL_INT_POW2(30))
#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
#define INT_TO_JSVAL(i) (((jsval)(i) << 1) | JSVAL_INT)
#define JSVAL_INT_POW2(n) ((jsval)1 << (n))
/* Type tag bitfield length and derived macros. */
#define JSVAL_TAGBITS 3
#define JSVAL_TAGMASK PR_BITMASK(JSVAL_TAGBITS)
#define JSVAL_TAG(v) ((v) & JSVAL_TAGMASK)
#define JSVAL_SETTAG(v, t) ((v) | (t))
#define JSVAL_CLRTAG(v) ((v) & ~(jsval)JSVAL_TAGMASK)
#define JSVAL_ALIGN PR_BIT(JSVAL_TAGBITS)
#define JSVAL_TO_GCTHING(v) ((void *)JSVAL_CLRTAG(v))
#define JSVAL_TO_OBJECT(v) ((JSObject *)JSVAL_TO_GCTHING(v))
/* Predicates for type testing. */
#define JSVAL_IS_OBJECT(v) (JSVAL_TAG(v) == JSVAL_OBJECT)
#define JSVAL_IS_NUMBER(v) (JSVAL_IS_INT(v) || JSVAL_IS_DOUBLE(v))
#define JSVAL_IS_INT(v) (((v) & JSVAL_INT) && (v) != JSVAL_VOID)
#define JSVAL_IS_DOUBLE(v) (JSVAL_TAG(v) == JSVAL_DOUBLE)
#define JSVAL_IS_STRING(v) (JSVAL_TAG(v) == JSVAL_STRING)
#define JSVAL_IS_BOOLEAN(v) (JSVAL_TAG(v) == JSVAL_BOOLEAN)
#define JSVAL_IS_NULL(v) ((v) == JSVAL_NULL)
#define JSVAL_IS_VOID(v) ((v) == JSVAL_VOID)
struct JSClass
{
};
typedef struct JSClass JSClass;
struct JSContext
{
};
typedef struct JSContext JSContext;
struct JSObjectMap
{
JSClass *clasp;
};
typedef struct JSObjectMap JSObjectMap;
struct JSObject
{
JSObjectMap *map;
};
typedef struct JSObject JSObject;
JSClass js_FunctionClass = {};
/* Typeof operator result enumeration. */
typedef enum JSType
{
JSTYPE_VOID, /* undefined */
JSTYPE_OBJECT, /* object */
JSTYPE_FUNCTION, /* function */
JSTYPE_STRING, /* string */
JSTYPE_NUMBER, /* number */
JSTYPE_BOOLEAN, /* boolean */
JSTYPE_NULL,
JSTYPE_LIMIT
} JSType;
/*
* Keep this in sync with jspubtd.h -- an assertion below will insist that
* its length match the JSType enum's JSTYPE_LIMIT limit value.
*/
char *js_type_str[] = {
"undefined",
"object",
"function",
"string",
"number",
"boolean",
"null"};
char *JS_GetTypeName(JSType type)
{
if ((uint)type >= (uint)JSTYPE_LIMIT)
return NULL;
return js_type_str[type];
}
JSType JS_TypeOfValue(jsval v)
{
JSType type;
JSObject *obj;
if (JSVAL_IS_NULL(v))
{
type = JSTYPE_NULL;
}
else if (JSVAL_IS_VOID(v))
{
type = JSTYPE_VOID;
}
else if (JSVAL_IS_OBJECT(v))
{
obj = JSVAL_TO_OBJECT(v);
if (obj &&
(obj->map->clasp == &js_FunctionClass))
{
type = JSTYPE_FUNCTION;
}
}
else if (JSVAL_IS_NUMBER(v))
{
type = JSTYPE_NUMBER;
}
else if (JSVAL_IS_STRING(v))
{
type = JSTYPE_STRING;
}
else if (JSVAL_IS_BOOLEAN(v))
{
type = JSTYPE_BOOLEAN;
}
return type;
}
int main()
{
jsval value = JSVAL_NULL;
JSType type = JS_TypeOfValue(value);
char *typeName = JS_GetTypeName(type);
printf("type: %s\n", typeName);
if (value == NULL) {
printf("value points to NULL\n");
}
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment