2020-12-20 08:57:39 +01:00
|
|
|
#ifndef js_value_h
|
|
|
|
#define js_value_h
|
|
|
|
|
|
|
|
typedef struct js_Property js_Property;
|
|
|
|
typedef struct js_Iterator js_Iterator;
|
|
|
|
|
|
|
|
/* Hint to ToPrimitive() */
|
|
|
|
enum {
|
|
|
|
JS_HNONE,
|
|
|
|
JS_HNUMBER,
|
|
|
|
JS_HSTRING
|
|
|
|
};
|
|
|
|
|
|
|
|
enum js_Type {
|
|
|
|
JS_TSHRSTR, /* type tag doubles as string zero-terminator */
|
|
|
|
JS_TUNDEFINED,
|
|
|
|
JS_TNULL,
|
|
|
|
JS_TBOOLEAN,
|
|
|
|
JS_TNUMBER,
|
|
|
|
JS_TLITSTR,
|
|
|
|
JS_TMEMSTR,
|
|
|
|
JS_TOBJECT,
|
|
|
|
};
|
|
|
|
|
|
|
|
enum js_Class {
|
|
|
|
JS_COBJECT,
|
|
|
|
JS_CARRAY,
|
|
|
|
JS_CFUNCTION,
|
|
|
|
JS_CSCRIPT, /* function created from global code */
|
|
|
|
JS_CEVAL, /* function created from eval code */
|
|
|
|
JS_CCFUNCTION, /* built-in function */
|
|
|
|
JS_CERROR,
|
|
|
|
JS_CBOOLEAN,
|
|
|
|
JS_CNUMBER,
|
|
|
|
JS_CSTRING,
|
|
|
|
JS_CREGEXP,
|
|
|
|
JS_CDATE,
|
|
|
|
JS_CMATH,
|
|
|
|
JS_CJSON,
|
|
|
|
JS_CARGUMENTS,
|
|
|
|
JS_CITERATOR,
|
|
|
|
JS_CUSERDATA,
|
|
|
|
};
|
|
|
|
|
|
|
|
/*
|
|
|
|
Short strings abuse the js_Value struct. By putting the type tag in the
|
|
|
|
last byte, and using 0 as the tag for short strings, we can use the
|
|
|
|
entire js_Value as string storage by letting the type tag serve double
|
|
|
|
purpose as the string zero terminator.
|
|
|
|
*/
|
|
|
|
|
|
|
|
struct js_Value
|
|
|
|
{
|
|
|
|
union {
|
|
|
|
int boolean;
|
|
|
|
double number;
|
|
|
|
char shrstr[8];
|
|
|
|
const char *litstr;
|
|
|
|
js_String *memstr;
|
|
|
|
js_Object *object;
|
|
|
|
} u;
|
|
|
|
char pad[7]; /* extra storage for shrstr */
|
|
|
|
char type; /* type tag and zero terminator for shrstr */
|
|
|
|
};
|
|
|
|
|
|
|
|
struct js_String
|
|
|
|
{
|
|
|
|
js_String *gcnext;
|
|
|
|
char gcmark;
|
|
|
|
char p[1];
|
|
|
|
};
|
|
|
|
|
|
|
|
struct js_Regexp
|
|
|
|
{
|
|
|
|
void *prog;
|
|
|
|
char *source;
|
|
|
|
unsigned short flags;
|
|
|
|
unsigned short last;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct js_Object
|
|
|
|
{
|
|
|
|
enum js_Class type;
|
|
|
|
int extensible;
|
|
|
|
js_Property *properties;
|
|
|
|
int count; /* number of properties, for array sparseness check */
|
|
|
|
js_Object *prototype;
|
|
|
|
union {
|
|
|
|
int boolean;
|
|
|
|
double number;
|
|
|
|
struct {
|
|
|
|
const char *string;
|
|
|
|
int length;
|
|
|
|
} s;
|
|
|
|
struct {
|
|
|
|
int length;
|
|
|
|
} a;
|
|
|
|
struct {
|
|
|
|
js_Function *function;
|
|
|
|
js_Environment *scope;
|
|
|
|
} f;
|
|
|
|
struct {
|
|
|
|
const char *name;
|
|
|
|
js_CFunction function;
|
|
|
|
js_CFunction constructor;
|
|
|
|
int length;
|
|
|
|
} c;
|
|
|
|
js_Regexp r;
|
|
|
|
struct {
|
|
|
|
js_Object *target;
|
|
|
|
js_Iterator *head;
|
|
|
|
} iter;
|
|
|
|
struct {
|
|
|
|
const char *tag;
|
|
|
|
void *data;
|
|
|
|
js_HasProperty has;
|
|
|
|
js_Put put;
|
|
|
|
js_Delete delete;
|
|
|
|
js_Finalize finalize;
|
|
|
|
} user;
|
|
|
|
} u;
|
2020-12-20 09:45:42 +01:00
|
|
|
js_Object *gcnext; /* allocation list */
|
|
|
|
js_Object *gcroot; /* scan list */
|
2020-12-20 08:57:39 +01:00
|
|
|
int gcmark;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct js_Property
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
js_Property *left, *right;
|
|
|
|
int level;
|
|
|
|
int atts;
|
|
|
|
js_Value value;
|
|
|
|
js_Object *getter;
|
|
|
|
js_Object *setter;
|
|
|
|
};
|
|
|
|
|
|
|
|
struct js_Iterator
|
|
|
|
{
|
|
|
|
const char *name;
|
|
|
|
js_Iterator *next;
|
|
|
|
};
|
|
|
|
|
|
|
|
/* jsrun.c */
|
|
|
|
js_String *jsV_newmemstring(js_State *J, const char *s, int n);
|
|
|
|
js_Value *js_tovalue(js_State *J, int idx);
|
|
|
|
void js_toprimitive(js_State *J, int idx, int hint);
|
|
|
|
js_Object *js_toobject(js_State *J, int idx);
|
|
|
|
void js_pushvalue(js_State *J, js_Value v);
|
|
|
|
void js_pushobject(js_State *J, js_Object *v);
|
|
|
|
|
|
|
|
/* jsvalue.c */
|
|
|
|
int jsV_toboolean(js_State *J, js_Value *v);
|
|
|
|
double jsV_tonumber(js_State *J, js_Value *v);
|
|
|
|
double jsV_tointeger(js_State *J, js_Value *v);
|
|
|
|
const char *jsV_tostring(js_State *J, js_Value *v);
|
|
|
|
js_Object *jsV_toobject(js_State *J, js_Value *v);
|
|
|
|
void jsV_toprimitive(js_State *J, js_Value *v, int preferred);
|
|
|
|
|
|
|
|
const char *js_itoa(char buf[32], int a);
|
|
|
|
double js_stringtofloat(const char *s, char **ep);
|
|
|
|
int jsV_numbertointeger(double n);
|
|
|
|
int jsV_numbertoint32(double n);
|
|
|
|
unsigned int jsV_numbertouint32(double n);
|
|
|
|
short jsV_numbertoint16(double n);
|
|
|
|
unsigned short jsV_numbertouint16(double n);
|
|
|
|
const char *jsV_numbertostring(js_State *J, char buf[32], double number);
|
|
|
|
double jsV_stringtonumber(js_State *J, const char *string);
|
|
|
|
|
|
|
|
/* jsproperty.c */
|
|
|
|
js_Object *jsV_newobject(js_State *J, enum js_Class type, js_Object *prototype);
|
|
|
|
js_Property *jsV_getownproperty(js_State *J, js_Object *obj, const char *name);
|
|
|
|
js_Property *jsV_getpropertyx(js_State *J, js_Object *obj, const char *name, int *own);
|
|
|
|
js_Property *jsV_getproperty(js_State *J, js_Object *obj, const char *name);
|
|
|
|
js_Property *jsV_setproperty(js_State *J, js_Object *obj, const char *name);
|
|
|
|
js_Property *jsV_nextproperty(js_State *J, js_Object *obj, const char *name);
|
|
|
|
void jsV_delproperty(js_State *J, js_Object *obj, const char *name);
|
|
|
|
|
|
|
|
js_Object *jsV_newiterator(js_State *J, js_Object *obj, int own);
|
|
|
|
const char *jsV_nextiterator(js_State *J, js_Object *iter);
|
|
|
|
|
|
|
|
void jsV_resizearray(js_State *J, js_Object *obj, int newlen);
|
|
|
|
|
|
|
|
/* jsdump.c */
|
|
|
|
void js_dumpobject(js_State *J, js_Object *obj);
|
|
|
|
void js_dumpvalue(js_State *J, js_Value v);
|
|
|
|
|
|
|
|
#endif
|