Bug 197134 - Can't create a const attribute via the JSC C API
Summary: Can't create a const attribute via the JSC C API
Status: RESOLVED WORKSFORME
Alias: None
Product: WebKit
Classification: Unclassified
Component: JavaScriptCore (show other bugs)
Version: WebKit Nightly Build
Hardware: Unspecified Unspecified
: P2 Normal
Assignee: Nobody
URL:
Keywords:
Depends on:
Blocks: 197133
  Show dependency treegraph
 
Reported: 2019-04-19 21:01 PDT by Simon Fraser (smfr)
Modified: 2019-04-22 15:39 PDT (History)
6 users (show)

See Also:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Simon Fraser (smfr) 2019-04-19 21:01:09 PDT
There's no way that I could find to create a readonly, const attribute on a class via the JSC C API. I need a

I need the C equivalent of making an attribute with { JSC::PropertyAttribute::DontDelete | JSC::PropertyAttribute::ReadOnly | JSC::PropertyAttribute::ConstantInteger, NoIntrinsic }

This is for DumpRenderTree/WebKitTestRunner.
Comment 1 Sam Weinig 2019-04-20 19:39:52 PDT
I think you can do this with using the staticValues array for a class definition:

static JSValueRef GetConstantValue(JSContextRef ctx, JSObjectRef, JSStringRef, JSValueRef*)
{
    return JSValueMakeNumber(ctx, 7);
}

JSStaticValue StaticValueArray[] = {
    { "constantValue", GetConstantValue, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
    { 0, 0, 0, 0 }
};

If memory serves me, JSC::PropertyAttribute::ConstantInteger is an optimization, and doesn't change behavior.
Comment 2 Sam Weinig 2019-04-20 19:44:37 PDT
Or, if you don't want to go the callback route, you can create the properties after the object has been created.

JSObjectSetProperty(ctx, objectToAddPropertyTo, JSStringCreateWithUTF8CString("constantValue), JSValueMakeNumber(ctx, 7), kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete, &exceptionPtr);
Comment 3 Saam Barati 2019-04-22 10:49:35 PDT
(In reply to Sam Weinig from comment #2)
> Or, if you don't want to go the callback route, you can create the
> properties after the object has been created.
> 
> JSObjectSetProperty(ctx, objectToAddPropertyTo,
> JSStringCreateWithUTF8CString("constantValue), JSValueMakeNumber(ctx, 7),
> kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete,
> &exceptionPtr);

I think this is what you want.

From the JS spec, these things mean:
- kJSPropertyAttributeReadOnly means you can't Put to the property. E.g, if you have kJSPropertyAttributeReadOnly property "foo", "x.foo = 42" won't succeed. This makes it a "writable: false" property.
- kJSPropertyAttributeDontDelete means the property descriptor is non-configurable. E.g, "delete x.foo" will fail. So will "Object.defineProperty(x, "foo", { ... })"
Comment 4 Simon Fraser (smfr) 2019-04-22 15:39:13 PDT
OK, that seems to work.