Closed ScriptBasic closed 7 years ago
could you please provide a minimal but full example of how you use this call ?
Here is my JS (V7) extension module code and Script BASIC code calling it.
http://www.allbasic.info/forum/index.php?topic=450.msg4858#msg4858
hmm, it works for me.
Could you just try this simple C file? :
#include <stdio.h>
#include "v7.h"
int main(void) {
enum v7_err rcode = V7_OK;
struct v7 *v7 = v7_create();
v7_val_t obj = v7_mk_object(v7);
v7_def(v7, obj, "foo", ~0, 0, v7_mk_number(v7, 42));
v7_def(v7, obj, "bar", ~0, V7_DESC_ENUMERABLE(0), v7_mk_number(v7, 42));
printf("obj stringifies as: ");
v7_println(v7, obj);
printf("iterating properties with v7_next_prop:\n");
struct prop_iter_ctx ctx;
v7_val_t name, val;
v7_prop_attr_t attrs;
v7_init_prop_iter_ctx(v7, obj, &ctx);
while (v7_next_prop(v7, &ctx, &name, &val, &attrs)) {
printf("prop name: ");
v7_print(v7, name);
printf(", attrs: %d\n", attrs);
}
v7_destruct_prop_iter_ctx(v7, &ctx);
v7_destroy(v7);
return (int) rcode;
}
jrs@laptop:~/sb/source/extensions/js$ gcc nextprop.c v7.c -o nextprop -lm
jrs@laptop:~/sb/source/extensions/js$ ./nextprop
obj stringifies as: {"foo":42}
iterating properties with v7_next_prop:
prop name: "bar", attrs: 2
prop name: "foo", attrs: 0
jrs@laptop:~/sb/source/extensions/js$
It looks how I'm defining the attribute is the problem. Hard coding 'V7_DESC_ENUMERABLE(0)' is returning a pointer and a value.
Thanks for your help!
I don't know :-( sorry, I cannot help you further. Just a quick hunch: are you sure that your v7_def
wrapper is correct? What happens if you create the properties from javascript Object.defineProperty
; does your next_prop wrapper work for them?
Here are a few test I ran to establish property attribute settings. Can you take a peek to make sure V7 is doing what it's suppose to be doing?
http://www.allbasic.info/forum/index.php?topic=450.msg4862#msg4862
Please read this:
/*
* Property attributes bitmask
*/
typedef unsigned short v7_prop_attr_t;
#define V7_PROPERTY_NON_WRITABLE (1 << 0)
#define V7_PROPERTY_NON_ENUMERABLE (1 << 1)
#define V7_PROPERTY_NON_CONFIGURABLE (1 << 2)
#define V7_PROPERTY_GETTER (1 << 3)
#define V7_PROPERTY_SETTER (1 << 4)
#define _V7_PROPERTY_HIDDEN (1 << 5)
/* property not managed by V7 HEAP */
#define _V7_PROPERTY_OFF_HEAP (1 << 6)
/* special property holding user data and destructor cb */
#define _V7_PROPERTY_USER_DATA_AND_DESTRUCTOR (1 << 7)
/*
* not a property attribute, but a flag for `v7_def()`. It's here in order to
* keep all offsets in one place
*/
#define _V7_DESC_PRESERVE_VALUE (1 << 8)
/*
* Internal helpers for `V7_DESC_...` macros
*/
#define _V7_DESC_SHIFT 16
#define _V7_DESC_MASK ((1 << _V7_DESC_SHIFT) - 1)
#define _V7_MK_DESC(v, n) \
(((v7_prop_attr_desc_t)(n)) << _V7_DESC_SHIFT | ((v) ? (n) : 0))
#define _V7_MK_DESC_INV(v, n) _V7_MK_DESC(!(v), (n))
/*
* Property attribute descriptors that may be given to `v7_def()`: for each
* attribute (`v7_prop_attr_t`), there is a corresponding macro, which takes
* param: either 1 (set attribute) or 0 (clear attribute). If some particular
* attribute isn't mentioned at all, it's left unchanged (or default, if the
* property is being created)
*
* There is additional flag: `V7_DESC_PRESERVE_VALUE`. If it is set, the
* property value isn't changed (or set to `undefined` if the property is being
* created)
*/
typedef unsigned long v7_prop_attr_desc_t;
#define V7_DESC_WRITABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_WRITABLE)
#define V7_DESC_ENUMERABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_ENUMERABLE)
#define V7_DESC_CONFIGURABLE(v) _V7_MK_DESC_INV(v, V7_PROPERTY_NON_CONFIGURABLE)
#define V7_DESC_GETTER(v) _V7_MK_DESC(v, V7_PROPERTY_GETTER)
#define V7_DESC_SETTER(v) _V7_MK_DESC(v, V7_PROPERTY_SETTER)
#define V7_DESC_PRESERVE_VALUE _V7_DESC_PRESERVE_VALUE
.....
static v7_prop_attr_t apply_attrs_desc(v7_prop_attr_desc_t attrs_desc,
v7_prop_attr_t old_attrs) {
v7_prop_attr_t ret = old_attrs;
if (old_attrs & V7_PROPERTY_NON_CONFIGURABLE) {
/*
* The property is non-configurable: we can only change it from being
* writable to non-writable
*/
if ((attrs_desc >> _V7_DESC_SHIFT) & V7_PROPERTY_NON_WRITABLE &&
(attrs_desc & V7_PROPERTY_NON_WRITABLE)) {
ret |= V7_PROPERTY_NON_WRITABLE;
}
} else {
/* The property is configurable: we can change any attributes */
ret = (old_attrs & ~(attrs_desc >> _V7_DESC_SHIFT)) |
(attrs_desc & _V7_DESC_MASK);
}
return ret;
}
The DESC
flags passed to v7_def
mirrors the JavaScript standard Object.defineProperty
API.
But internally we follow an inverse polarity. e.g. a bit is true if the object is not-writeable, or non-configurable; while in the user facing API of v7_def
the user decides whether a property is writable or configurable etc...
I think I have it working now. Please have a look.
http://www.allbasic.info/forum/index.php?topic=450.msg4863#msg4863
I'm curious: could you please share the rationale for embedding a JS interpreter inside a BASIC interpreter?
Adding OOP functionality seamlessly to Script BASIC is the main goal. Everything else is icing.
I have embedded Tiny Scheme, Perl and even added a BBC BASIC graphic ext. in SDL.
I'm unable to return any property attributes with the v7_next_prop() function. Always returns a zero.
BTW: The Docs for this function are wrong and had to refer to the v7.h file for the correct use.