typedef struct {
int x;
int y;
} JSPointData;
static JSClassID js_point_class_id;
static void js_point_finalizer(JSRuntime *rt, JSValue val)
{
JSPointData *s = JS_GetOpaque(val, js_point_class_id);
js_free_rt(rt, s);
}
static JSValue js_point_norm(JSContext *ctx, JSValue this_val,
int argc, JSValue *argv)
{
JSPointData *s = JS_GetOpaque2(ctx, this_val, js_point_class_id);
if (!s)
return JS_EXCEPTION;
return JS_NewFloat64(ctx, sqrt((double)s->x * s->x + (double)s->y * s->y));
}
static JSClassDef js_point_class = {
"Point",
.finalizer = js_point_finalizer,
};
static const JSCFunctionListEntry js_point_proto_funcs[] = {
JS_CGETSET_MAGIC_DEF("x", js_point_get_xy, js_point_set_xy, 0),
JS_CGETSET_MAGIC_DEF("y", js_point_get_xy, js_point_set_xy, 1),
JS_CFUNC_DEF("norm", 0, js_point_norm),
};
static int js_point_init(JSContext *ctx, JSModuleDef *m)
{
JSRuntime *rt = JS_GetRuntime(ctx);
JS_NewClassID(rt, &js_point_class_id);
JS_NewClass(rt, js_point_class_id, &js_point_class);
JSValue point_proto = JS_NewObject(ctx);
JS_SetPropertyFunctionList(ctx, point_proto, js_point_proto_funcs,
countof(js_point_proto_funcs));
JSValue point_class = JS_NewCFunction2(ctx, js_point_ctor, "Point", 2,
JS_CFUNC_constructor, 0);
JS_SetConstructor(ctx, point_class, point_proto);
JS_SetClassProto(ctx, js_point_class_id, point_proto);
JS_SetModuleExport(ctx, m, "Point", point_class);
return 0;
}