return $ CYTypedIdentifier($ CYTypeStruct(identifier, $ CYStructTail(fields)));
}
-CYTypedIdentifier *Function::Decode(CYPool &pool) const {
+CYTypedIdentifier *Callable::Decode(CYPool &pool) const {
_assert(signature.count != 0);
- CYTypedParameter *parameter(NULL);
+ CYTypedParameter *parameters(NULL);
for (size_t i(signature.count - 1); i != 0; --i)
- parameter = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameter);
- return CYDecodeType(pool, signature.elements[0].type)->Modify($ CYTypeFunctionWith(parameter));
+ parameters = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameters);
+ return Modify(pool, CYDecodeType(pool, signature.elements[0].type), parameters);
+}
+
+CYTypedIdentifier *Function::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
+ return result->Modify($ CYTypeFunctionWith(variadic, parameters));
+}
+
+CYTypedIdentifier *Block::Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const {
+ return result->Modify($ CYTypeBlockWith(parameters));
}
CYTypedIdentifier *Block::Decode(CYPool &pool) const {
if (signature.count == 0)
return $ CYTypedIdentifier($ CYTypeVariable("NSBlock"), $ CYTypePointerTo());
- else {
- _assert(signature.count != 1);
- _assert(dynamic_cast<Object *>(signature.elements[1].type) != NULL);
-
- CYTypedParameter *parameter(NULL);
- for (size_t i(signature.count - 1); i != 0; --i)
- parameter = $ CYTypedParameter(CYDecodeType(pool, signature.elements[i].type), parameter);
- return CYDecodeType(pool, signature.elements[0].type)->Modify($ CYTypeBlockWith(parameter));
- }
+ return Callable::Decode(pool);
}
}
JSStringRef Array_s;
JSStringRef cy_s;
JSStringRef cyi_s;
+JSStringRef cyt_s;
JSStringRef length_s;
JSStringRef message_s;
JSStringRef name_s;
return JSObjectMake(context, Pointer_, internal);
}
-static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), const sig::Signature &signature) {
- return JSObjectMake(context, Functor_, new cy::Functor(signature, function));
+static JSObjectRef CYMakeFunctor(JSContextRef context, void (*function)(), bool variadic, const sig::Signature &signature) {
+ return JSObjectMake(context, Functor_, new cy::Functor(function, variadic, signature));
}
static JSObjectRef CYMakeFunctor(JSContextRef context, const char *symbol, const char *encoding) {
if (function == NULL)
return NULL;
- cy::Functor *internal(new cy::Functor(encoding, function));
+ cy::Functor *internal(new cy::Functor(function, encoding));
++internal->count_;
return JSObjectMake(context, Functor_, internal);
}
}
JSValueRef Function::FromFFI(JSContextRef context, ffi_type *ffi, void *data, bool initialize, JSObjectRef owner) const {
- return CYMakeFunctor(context, reinterpret_cast<void (*)()>(data), signature);
+ return CYMakeFunctor(context, reinterpret_cast<void (*)()>(data), variadic, signature);
}
}
return CYCastJSObject(context, CYGetCachedValue(context, name));
}
-static JSObjectRef CYMakeFunctor(JSContextRef context, JSValueRef value, const sig::Signature &signature) {
+static JSObjectRef CYMakeFunctor(JSContextRef context, JSValueRef value, bool variadic, const sig::Signature &signature) {
JSObjectRef Function(CYGetCachedObject(context, CYJSString("Function")));
bool function(_jsccall(JSValueIsInstanceOfConstructor, context, value, Function));
return CYMakeFunctor(context, function, signature);
} else {
void (*function)()(CYCastPointer<void (*)()>(context, value));
- return CYMakeFunctor(context, function, signature);
+ return CYMakeFunctor(context, function, variadic, signature);
}
}
if (sig::Function *function = dynamic_cast<sig::Function *>(typical->type_)) {
if (!JSStringIsEqualToUTF8CString(property, "$cyi"))
return NULL;
- return CYMakeFunctor(context, reinterpret_cast<void (*)()>(internal->value_), function->signature);
+ return CYMakeFunctor(context, reinterpret_cast<void (*)()>(internal->value_), function->variadic, function->signature);
}
JSObjectRef owner(internal->GetOwner() ?: object);
return CYMakePointer(context, internal->value_, *typical->type_, typical->ffi_, _this);
} CYCatch(NULL) }
-static JSValueRef Struct_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef Struct_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
Struct_privateData *internal(reinterpret_cast<Struct_privateData *>(JSObjectGetPrivate(object)));
return CYMakeType(context, *internal->type_->type_);
} CYCatch(NULL) }
}
}
+static sig::Void Void_;
+static sig::Pointer PointerToVoid_(Void_);
+
+static sig::Type *CYGetType(CYPool &pool, JSContextRef context, JSValueRef value) {
+ if (JSValueIsNull(context, value))
+ return &PointerToVoid_;
+ JSObjectRef object(CYCastJSObject(context, value));
+ JSObjectRef type(CYCastJSObject(context, CYGetProperty(context, object, cyt_s)));
+ _assert(JSValueIsObjectOfClass(context, type, Type_privateData::Class_));
+ Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(type)));
+ return internal->type_;
+}
+
void CYCallFunction(CYPool &pool, JSContextRef context, ffi_cif *cif, void (*function)(), void *value, void **values) {
ffi_call(cif, function, value, values);
}
-JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, sig::Signature *signature, ffi_cif *cif, void (*function)()) {
- if (setups + count != signature->count - 1)
- throw CYJSError(context, "incorrect number of arguments to ffi function");
+JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, bool variadic, const sig::Signature &signature, ffi_cif *cif, void (*function)()) {
+ size_t have(setups + count);
+ size_t need(signature.count - 1);
+
+ if (have < need)
+ throw CYJSError(context, "insufficient number of arguments to ffi function");
+
+ ffi_cif corrected;
+ sig::Element *elements(signature.elements);
+
+ if (have > need) {
+ if (!variadic)
+ throw CYJSError(context, "exorbitant number of arguments to ffi function");
+
+ elements = new (pool) sig::Element[have + 1];
+ memcpy(elements, signature.elements, sizeof(sig::Element) * (need + 1));
+
+ for (size_t index(need); index != have; ++index) {
+ sig::Element &element(elements[index + 1]);
+ element.name = NULL;
+ element.offset = _not(size_t);
+ element.type = CYGetType(pool, context, arguments[index - setups]);
+ }
+
+ sig::Signature extended;
+ extended.elements = elements;
+ extended.count = have + 1;
+ sig::sig_ffi_cif(pool, signature.count, extended, &corrected);
+ cif = &corrected;
+ }
- size_t size(setups + count);
- void *values[size];
+ void *values[have];
memcpy(values, setup, sizeof(void *) * setups);
- for (size_t index(setups); index != size; ++index) {
- sig::Element *element(&signature->elements[index + 1]);
+ for (size_t index(setups); index != have; ++index) {
+ sig::Element &element(elements[index + 1]);
ffi_type *ffi(cif->arg_types[index]);
values[index] = pool.malloc<uint8_t>(ffi->size, ffi->alignment);
- element->type->PoolFFI(&pool, context, ffi, values[index], arguments[index - setups]);
+ element.type->PoolFFI(&pool, context, ffi, values[index], arguments[index - setups]);
}
uint8_t value[cif->rtype->size];
call = hook->CallFunction;
call(pool, context, cif, function, value, values);
- return signature->elements[0].type->FromFFI(context, cif->rtype, value, initialize);
+ return signature.elements[0].type->FromFFI(context, cif->rtype, value, initialize);
}
static JSValueRef Functor_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
CYPool pool;
cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(object)));
- return CYCallFunction(pool, context, 0, NULL, count, arguments, false, &internal->signature_, &internal->cif_, internal->GetValue());
+ return CYCallFunction(pool, context, 0, NULL, count, arguments, false, internal->variadic_, internal->signature_, &internal->cif_, internal->GetValue());
} CYCatch(NULL) }
static JSValueRef Pointer_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
return JSObjectMake(context, Type_privateData::Class_, internal);
}
-JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature) {
- CYPool pool;
- sig::Function type;
- sig::Copy(pool, type.signature, *signature);
- return CYMakeType(context, type);
-}
-
extern "C" bool CYBridgeHash(CYPool &pool, CYUTF8String name, const char *&code, unsigned &flags) {
sqlite3_stmt *statement;
} CYCatch(NULL) }
static JSValueRef Type_callAsFunction_functionWith(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
- sig::Function type;
- return Type_callAsFunction_$With(context, object, _this, count, arguments, type, exception);
+ bool variadic(count != 0 && JSValueIsNull(context, arguments[count - 1]));
+ sig::Function type(variadic);
+ return Type_callAsFunction_$With(context, object, _this, variadic ? count - 1 : count, arguments, type, exception);
}
static JSValueRef Type_callAsFunction_pointerTo(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(object)));
if (sig::Function *function = dynamic_cast<sig::Function *>(internal->type_))
- return CYMakeFunctor(context, arguments[0], function->signature);
+ return CYMakeFunctor(context, arguments[0], function->variadic, function->signature);
CYPool pool;
sig::Type *type(internal->type_);
ffi_type *ffi(internal->GetFFI());
- void *value(pool.malloc<void>(ffi->size, ffi->alignment));
- type->PoolFFI(&pool, context, ffi, value, arguments[0]);
- return type->FromFFI(context, ffi, value);
+
+ void *data(pool.malloc<void>(ffi->size, ffi->alignment));
+ type->PoolFFI(&pool, context, ffi, data, arguments[0]);
+ JSValueRef value(type->FromFFI(context, ffi, data));
+
+ if (JSValueGetType(context, value) == kJSTypeNumber) {
+ JSObjectRef typed(_jsccall(JSObjectCallAsConstructor, context, CYGetCachedObject(context, CYJSString("Number")), 1, &value));
+ CYSetProperty(context, typed, cyt_s, object, kJSPropertyAttributeDontEnum);
+ value = typed;
+ }
+
+ return value;
} CYCatch(NULL) }
static JSObjectRef Type_callAsConstructor(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
const char *encoding(CYPoolCString(pool, context, arguments[1]));
sig::Signature signature;
sig::Parse(pool, &signature, encoding, &Structor_);
- return CYMakeFunctor(context, arguments[0], signature);
+ return CYMakeFunctor(context, arguments[0], false, signature);
} CYCatch(NULL) }
static JSValueRef CArray_callAsFunction_toPointer(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
CYPool pool;
cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(_this)));
- sig::Function type;
+ sig::Function type(internal->variadic_);
sig::Copy(pool, type.signature, internal->signature_);
return CYMakePointer(context, internal->value_, type, NULL, NULL);
return CYCastJSValue(context, strlen(string));
} CYCatch(NULL) }
-static JSValueRef CString_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef CString_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
return CYMakeType(context, sig::String());
} CYCatch(NULL) }
-static JSValueRef CArray_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef CArray_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
CArray *internal(reinterpret_cast<CArray *>(JSObjectGetPrivate(object)));
sig::Array type(*internal->type_->type_, internal->length_);
return CYMakeType(context, type);
} CYCatch(NULL) }
-static JSValueRef Pointer_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef Pointer_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
Pointer *internal(reinterpret_cast<Pointer *>(JSObjectGetPrivate(object)));
sig::Pointer type(*internal->type_->type_);
return CYMakeType(context, type);
return CYCastJSValue(context, string);
} CYCatch(NULL) }
-static JSValueRef Functor_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef Functor_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
cy::Functor *internal(reinterpret_cast<cy::Functor *>(JSObjectGetPrivate(object)));
- return CYMakeType(context, &internal->signature_);
+ CYPool pool;
+ sig::Function type(internal->variadic_);
+ sig::Copy(pool, type.signature, internal->signature_);
+ return CYMakeType(context, type);
} CYCatch(NULL) }
static JSValueRef Type_getProperty_alignment(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
};
static JSStaticValue CArray_staticValues[2] = {
- {"type", &CArray_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &CArray_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
static JSStaticValue CString_staticValues[3] = {
{"length", &CString_getProperty_length, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
- {"type", &CString_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &CString_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
};
static JSStaticValue Pointer_staticValues[2] = {
- {"type", &Pointer_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &Pointer_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
};
static JSStaticValue Struct_staticValues[2] = {
- {"type", &Struct_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &Struct_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
}
static JSStaticValue Functor_staticValues[2] = {
- {"type", &Functor_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &Functor_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
Array_s = JSStringCreateWithUTF8CString("Array");
cy_s = JSStringCreateWithUTF8CString("$cy");
cyi_s = JSStringCreateWithUTF8CString("$cyi");
+ cyt_s = JSStringCreateWithUTF8CString("$cyt");
length_s = JSStringCreateWithUTF8CString("length");
message_s = JSStringCreateWithUTF8CString("message");
name_s = JSStringCreateWithUTF8CString("name");
}
#endif
+ CYSetProperty(context, String_prototype, cyt_s, CYMakeType(context, sig::String()), kJSPropertyAttributeDontEnum);
+
CYSetProperty(context, cache, CYJSString("dlerror"), CYMakeFunctor(context, "dlerror", "*"), kJSPropertyAttributeDontEnum);
CYSetProperty(context, cache, CYJSString("RTLD_DEFAULT"), CYCastJSValue(context, reinterpret_cast<intptr_t>(RTLD_DEFAULT)), kJSPropertyAttributeDontEnum);
CYSetProperty(context, cache, CYJSString("dlsym"), CYMakeFunctor(context, "dlsym", "^v^v*"), kJSPropertyAttributeDontEnum);
signature.count = 1;
ffi_cif cif;
- sig::sig_ffi_cif(*pool_, &signature, &cif);
+ sig::sig_ffi_cif(*pool_, false, signature, &cif);
ffi_ = new(*pool_) ffi_type;
*ffi_ = *cif.rtype;
{
private:
void set() {
- sig::sig_ffi_cif(*pool_, &signature_, &cif_);
+ sig::sig_ffi_cif(*pool_, variadic_ ? signature_.count : 0, signature_, &cif_);
}
public:
+ bool variadic_;
sig::Signature signature_;
ffi_cif cif_;
- Functor(const sig::Signature &signature, void (*value)()) :
- CYValue(reinterpret_cast<void *>(value))
+ Functor(void (*value)(), bool variadic, const sig::Signature &signature) :
+ CYValue(reinterpret_cast<void *>(value)),
+ variadic_(variadic)
{
sig::Copy(*pool_, signature_, signature);
set();
}
- Functor(const char *encoding, void (*value)()) :
- CYValue(reinterpret_cast<void *>(value))
+ Functor(void (*value)(), const char *encoding) :
+ CYValue(reinterpret_cast<void *>(value)),
+ variadic_(false)
{
sig::Parse(*pool_, &signature_, encoding, &Structor_);
set();
JSValueRef (*adapter_)(JSContextRef, size_t, JSValueRef[], JSObjectRef);
Closure_privateData(JSContextRef context, JSObjectRef function, JSValueRef (*adapter)(JSContextRef, size_t, JSValueRef[], JSObjectRef), const sig::Signature &signature) :
- cy::Functor(signature, NULL),
+ cy::Functor(NULL, false, signature),
context_(CYGetJSContext(context)),
function_(function),
adapter_(adapter)
extern JSStringRef Array_s;
extern JSStringRef cy_s;
extern JSStringRef cyi_s;
+extern JSStringRef cyt_s;
extern JSStringRef length_s;
extern JSStringRef message_s;
extern JSStringRef name_s;
}
void CYCallFunction(CYPool &pool, JSContextRef context, ffi_cif *cif, void (*function)(), void *value, void **values);
-JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, sig::Signature *signature, ffi_cif *cif, void (*function)());
+JSValueRef CYCallFunction(CYPool &pool, JSContextRef context, size_t setups, void *setup[], size_t count, const JSValueRef arguments[], bool initialize, bool variadic, const sig::Signature &signature, ffi_cif *cif, void (*function)());
bool CYIsCallable(JSContextRef context, JSValueRef value);
JSValueRef CYCallAsFunction(JSContextRef context, JSObjectRef function, JSObjectRef _this, size_t count, const JSValueRef arguments[]);
JSObjectRef CYMakePointer(JSContextRef context, void *pointer, const sig::Type &type, ffi_type *ffi, JSObjectRef owner);
JSObjectRef CYMakeType(JSContextRef context, const sig::Type &type);
-JSObjectRef CYMakeType(JSContextRef context, sig::Signature *signature);
void CYFinalize(JSObjectRef object);
SEL sel_;
Message_privateData(SEL sel, const char *type, IMP value = NULL) :
- cy::Functor(type, reinterpret_cast<void (*)()>(value)),
+ cy::Functor(reinterpret_cast<void (*)()>(value), type),
sel_(sel)
{
}
@end
static const char *CYBlockEncoding(NSBlock *self);
-static sig::Signature *CYBlockSignature(CYPool &pool, NSBlock *self);
+static bool CYBlockSignature(CYPool &pool, NSBlock *self, sig::Signature &signature);
@implementation NSBlock (Cycript)
- (NSString *) cy$toCYON:(bool)objective inSet:(std::set<void *> &)objects {
CYLocalPool pool;
- sig::Signature *signature(CYBlockSignature(pool, self));
- // XXX: I am checking signature->count due to Decode doing it for block_P
- if (signature == NULL || signature->count == 0)
+ sig::Block type;
+ if (!CYBlockSignature(pool, self, type.signature))
return [super cy$toCYON:objective inSet:objects];
_oassert(objects.insert(self).second);
- sig::Block type;
- sig::Copy(pool, type.signature, *signature);
-
CYTypedIdentifier *typed((new(pool) CYTypeExpression(CYDecodeType(pool, &type)))->typed_);
- CYTypeFunctionWith *function(typed->Function());
- _assert(function != NULL);
-
- _assert(function->parameters_ != NULL);
- CYObjCBlock *block(new(pool) CYObjCBlock(typed, function->parameters_, NULL));
+ CYTypeModifier *&modifier(CYGetLast(typed->modifier_));
+ CYTypeBlockWith *with(dynamic_cast<CYTypeBlockWith *>(modifier));
+ _assert(with != NULL);
+ CYObjCBlock *block(new(pool) CYObjCBlock(typed, with->parameters_, NULL));
+ modifier = NULL;
std::ostringstream str;
CYOptions options;
return descriptor3->signature;
}
-static sig::Signature *CYBlockSignature(CYPool &pool, NSBlock *self) {
+static bool CYBlockSignature(CYPool &pool, NSBlock *self, sig::Signature &signature) {
const char *encoding(CYBlockEncoding(self));
if (encoding == NULL)
- return NULL;
- // XXX: this should be stored on a FunctionInstance private value subclass
- sig::Signature *signature(new(pool) sig::Signature());
- sig::Parse(pool, signature, encoding, &Structor_);
- return signature;
+ return false;
+
+ sig::Parse(pool, &signature, encoding, &Structor_);
+ _assert(signature.count >= 2);
+
+ _assert(dynamic_cast<sig::Object *>(signature.elements[1].type) != NULL);
+ signature.elements[1] = signature.elements[0];
+
+ ++signature.elements;
+ --signature.count;
+
+ return true;
}
static JSValueRef FunctionInstance_callAsFunction(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
sig::Parse(pool, &signature, encoding, &Structor_);
ffi_cif cif;
- sig::sig_ffi_cif(pool, &signature, &cif);
+ sig::sig_ffi_cif(pool, 0, signature, &cif);
BlockLiteral *literal(reinterpret_cast<BlockLiteral *>(self));
void (*function)() = reinterpret_cast<void (*)()>(literal->invoke);
- return CYCallFunction(pool, context, 1, setup, count, arguments, false, &signature, &cif, function);
+ return CYCallFunction(pool, context, 1, setup, count, arguments, false, false, signature, &cif, function);
}
if (count != 0)
sig::Signature signature;
sig::Parse(pool, &signature, type, &Structor_);
- size_t used(count + 3);
- if (used > signature.count) {
- sig::Element *elements(new (pool) sig::Element[used]);
- memcpy(elements, signature.elements, used * sizeof(sig::Element));
-
- for (size_t index(signature.count); index != used; ++index) {
- sig::Element *element(&elements[index]);
- element->name = NULL;
- element->offset = _not(size_t);
- element->type = new(pool) sig::Object();
- }
-
- signature.elements = elements;
- signature.count = used;
- }
-
ffi_cif cif;
- sig::sig_ffi_cif(pool, &signature, &cif);
+ sig::sig_ffi_cif(pool, 0, signature, &cif);
if (imp == NULL) {
#ifndef CY_NO_STRET
}
void (*function)() = reinterpret_cast<void (*)()>(imp);
- return CYCallFunction(pool, context, 2, setup, count, arguments, initialize, &signature, &cif, function);
+ return CYCallFunction(pool, context, 2, setup, count, arguments, initialize, true, signature, &cif, function);
}
static JSValueRef $objc_msgSend(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[]) {
setup[0] = &self;
setup[1] = &internal->sel_;
- return CYCallFunction(pool, context, 2, setup, count, arguments, false, &internal->signature_, &internal->cif_, internal->GetValue());
+ return CYCallFunction(pool, context, 2, setup, count, arguments, false, true, internal->signature_, &internal->cif_, internal->GetValue());
} CYCatch(NULL) }
static JSObjectRef Super_new(JSContextRef context, JSObjectRef object, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
return CYMakePointer(context, &internal->value_, *type, ffi, object);
} CYCatch(NULL) }
-static JSValueRef FunctionInstance_getProperty_type(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+static JSValueRef Selector_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+ return CYMakeType(context, sig::Selector());
+} CYCatch(NULL) }
+
+static JSValueRef Instance_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+ return CYMakeType(context, sig::Object());
+} CYCatch(NULL) }
+
+static JSValueRef FunctionInstance_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
Instance *internal(reinterpret_cast<Instance *>(JSObjectGetPrivate(object)));
CYPool pool;
- sig::Signature *signature(CYBlockSignature(pool, internal->GetValue()));
- if (signature == NULL)
+ sig::Block type;
+ if (!CYBlockSignature(pool, internal->GetValue(), type.signature))
return CYJSNull(context);
- return CYMakeType(context, signature);
+ return CYMakeType(context, type);
+} CYCatch(NULL) }
+
+static JSValueRef Class_getProperty_$cyt(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
+ return CYMakeType(context, sig::Meta());
} CYCatch(NULL) }
static JSValueRef Instance_getProperty_constructor(JSContextRef context, JSObjectRef object, JSStringRef property, JSValueRef *exception) { CYTry {
objc_method *method(_require(class_getInstanceMethod(_class, sel)));
const char *encoding(method_getTypeEncoding(method));
- sig::Signature signature;
- sig::Parse(pool, &signature, encoding, &Structor_);
- return CYMakeType(context, &signature);
+ sig::Function type(false);
+ sig::Parse(pool, &type.signature, encoding, &Structor_);
+ return CYMakeType(context, type);
} CYCatch(NULL) }
-static JSStaticValue Selector_staticValues[2] = {
+static JSStaticValue Selector_staticValues[3] = {
+ {"$cyt", &Selector_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"value", &CYValue_getProperty_value, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete},
{NULL, NULL, NULL, 0}
};
-// XXX: this is sadly duplicated in FunctionInstance_staticValues
-static JSStaticValue Instance_staticValues[5] = {
+static JSStaticValue Instance_staticValues[6] = {
+ {"$cyt", &Instance_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ // XXX: this is sadly duplicated in FunctionInstance_staticValues
{"constructor", &Instance_getProperty_constructor, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"messages", &Instance_getProperty_messages, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"prototype", &Instance_getProperty_prototype, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
};
static JSStaticValue FunctionInstance_staticValues[6] = {
- {"type", &FunctionInstance_getProperty_type, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"$cyt", &FunctionInstance_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
// XXX: this is sadly a duplicate of Instance_staticValues
{"constructor", &Instance_getProperty_constructor, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"messages", &Instance_getProperty_messages, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, 0}
};
+static JSStaticValue Class_staticValues[2] = {
+ {"$cyt", &Class_getProperty_$cyt, NULL, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {NULL, NULL, NULL, 0}
+};
+
static JSStaticFunction Internal_staticFunctions[2] = {
{"$cya", &Internal_callAsFunction_$cya, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, 0}
definition = kJSClassDefinitionEmpty;
definition.className = "Class";
definition.staticFunctions = Class_staticFunctions;
+ definition.staticValues = Class_staticValues;
Class_ = JSClassCreate(&definition);
definition = kJSClassDefinitionEmpty;
CYWord *name_;
CYTypedIdentifier *type_;
- CYMessageParameter(CYWord *name, CYTypedIdentifier *type) :
+ CYMessageParameter(CYWord *name, CYTypedIdentifier *type, CYMessageParameter *next = NULL) :
+ CYNext<CYMessageParameter>(next),
name_(name),
type_(type)
{
void CYTypeFunctionWith::Output(CYOutput &out, CYIdentifier *identifier) const {
next_->Output(out, Precedence(), identifier);
- out << '(' << parameters_ << ')';
+ out << '(' << parameters_;
+ if (variadic_) {
+ if (parameters_ != NULL)
+ out << ',' << ' ';
+ out << "...";
+ }
+ out << ')';
}
void CYTypePointerTo::Output(CYOutput &out, CYIdentifier *identifier) const {
%union { CYTypeStructField *structField_; }
%union { CYTypeModifier *modifier_; }
%union { CYTypeSpecifier *specifier_; }
+%union { CYTypedFormal *typedFormal_; }
%union { CYTypedIdentifier *typedIdentifier_; }
%union { CYTypedParameter *typedParameter_; }
@end
%token _synchronized_ "synchronized"
%token _throws_ "throws"
%token _transient_ "transient"
+%token _typeid_ "typeid"
%token _volatile_ "volatile"
%token _yield_ "yield"
%token _yield__ "!yield"
%type <typedIdentifier_> TypedIdentifierMaybe
%type <typedIdentifier_> TypedIdentifierNo
%type <typedIdentifier_> TypedIdentifierYes
-%type <typedParameter_> TypedParameterList_
-%type <typedParameter_> TypedParameterList
-%type <typedParameter_> TypedParameterListOpt
+%type <typedFormal_> TypedParameterList_
+%type <typedFormal_> TypedParameterList
+%type <typedFormal_> TypedParameterListOpt
+%type <typedParameter_> TypedParameters
@end
@begin ObjectiveC
| "target" { $$ = CYNew CYIdentifier("target"); }
| "throws" { $$ = CYNew CYIdentifier("throws"); }
| "transient" { $$ = CYNew CYIdentifier("transient"); }
+ | "typeid" { $$ = CYNew CYIdentifier("typeid"); }
| "undefined" { $$ = CYNew CYIdentifier("undefined"); }
@begin ObjectiveC
| "bool" { $$ = CYNew CYIdentifier("bool"); }
;
ParameterTail
- : TypedParameterListOpt[parameters] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($parameters); }
+ : TypedParameterListOpt[formal] ")" ParameterModifierOpt { $$ = CYNew CYTypeFunctionWith($formal->variadic_, $formal->parameters_); }
;
SuffixedType
: SuffixedTypeOpt[typed] "[" RestrictOpt NumericLiteral[size] "]" { $$ = $typed; $$->modifier_ = CYNew CYTypeArrayOf($size, $$->modifier_); }
- | "(" "^" TypeQualifierRightOpt[typed] ")" "(" TypedParameterListOpt[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); }
+ | "(" "^" TypeQualifierRightOpt[typed] ")" "(" TypedParameters[parameters] ")" { $$ = $typed; $$->modifier_ = CYNew CYTypeBlockWith($parameters, $$->modifier_); }
| TypeSignifier[typed] "(" ParameterTail[modifier] { $$ = $typed; CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
| "("[parenthesis] ParameterTail[modifier] { $$ = CYNew CYTypedIdentifier(@parenthesis); CYSetLast($modifier) = $$->modifier_; $$->modifier_ = $modifier; }
;
MessageParameterListOpt
: MessageParameterList[pass] { $$ = $pass; }
- | { $$ = NULL; }
+ | TypedParameterList_[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); /*XXX*/ if ($formal->parameters_ != NULL) CYERR(@$, "temporarily unsupported"); $$ = NULL; }
;
MessageParameters
/* Cycript (C): Lambda Expressions {{{ */
TypedParameterList_
: "," TypedParameterList[parameters] { $$ = $parameters; }
- | { $$ = NULL; }
+ | { $$ = CYNew CYTypedFormal(false); }
;
TypedParameterList
- : TypedIdentifierMaybe[typed] TypedParameterList_[next] { $$ = CYNew CYTypedParameter($typed, $next); }
+ : TypedIdentifierMaybe[typed] TypedParameterList_[formal] { $$ = $formal; $$->parameters_ = CYNew CYTypedParameter($typed, $$->parameters_); }
+ | "..." { $$ = CYNew CYTypedFormal(true); }
;
TypedParameterListOpt
: TypedParameterList[pass] { $$ = $pass; }
- | "void" { $$ = NULL; }
- | { $$ = NULL; }
+ | "void" { $$ = CYNew CYTypedFormal(false); }
+ | { $$ = CYNew CYTypedFormal(false); }
+ ;
+
+TypedParameters
+ : TypedParameterListOpt[formal] { if ($formal->variadic_) CYERR(@$, "unsupported variadic"); $$ = $formal->parameters_; }
;
PrimaryExpression
- : "[" LexOf "&" "]" "(" TypedParameterListOpt[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); }
+ : "[" LexOf "&" "]" "(" TypedParameters[parameters] ")" "->" TypedIdentifierNo[type] "{" FunctionBody[code] "}" { $$ = CYNew CYLambda($type, $parameters, $code); }
;
/* }}} */
/* Cycript (C): Structure Definitions {{{ */
}
CYTarget *CYTypeFunctionWith::Replace_(CYContext &context, CYTarget *type) {
- return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
+ CYList<CYArgument> arguments(parameters_->Argument(context));
+ if (variadic_)
+ arguments->*$C_($ CYNull());
+ return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), arguments));
}
CYTarget *CYTypePointerTo::Replace_(CYContext &context, CYTarget *type) {
}
CYTypeFunctionWith *CYTypedIdentifier::Function() {
- CYTypeModifier **modifier(&modifier_);
- if (*modifier == NULL)
+ CYTypeModifier *&modifier(CYGetLast(modifier_));
+ if (modifier == NULL)
return NULL;
- while ((*modifier)->next_ != NULL)
- modifier = &(*modifier)->next_;
- CYTypeFunctionWith *function((*modifier)->Function());
+
+ CYTypeFunctionWith *function(modifier->Function());
if (function == NULL)
return NULL;
- *modifier = NULL;
+
+ modifier = NULL;
return function;
}
"transient" L /*FII*/ F(tk::_transient_, hi::Meta);
"true" L /*LLL*/ F(tk::_true_, hi::Constant);
"try" L /*KKK*/ F(tk::_try_, hi::Control);
+"typeid" L /*III*/ F(tk::_typeid_, hi::Operator);
"typeof" L /*KKK*/ F(tk::_typeof_, hi::Operator);
"var" L /*KKK*/ F(tk::_var_, hi::Meta);
"void" L /*KKK*/ F(tk::_void_, hi::Operator);
virtual void Output(CYOutput &out) const;
};
+struct CYTypedFormal {
+ bool variadic_;
+ CYTypedParameter *parameters_;
+
+ CYTypedFormal(bool variadic) :
+ variadic_(variadic),
+ parameters_(NULL)
+ {
+ }
+};
+
struct CYLambda :
CYTarget
{
struct CYTypeFunctionWith :
CYTypeModifier
{
+ bool variadic_;
CYTypedParameter *parameters_;
- CYTypeFunctionWith(CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
+ CYTypeFunctionWith(bool variadic, CYTypedParameter *parameters, CYTypeModifier *next = NULL) :
CYTypeModifier(next),
+ variadic_(variadic),
parameters_(parameters)
{
}
/* Define to 1 if you have the <ffi.h> header file. */
#undef HAVE_FFI_H
+/* Define to 1 if you have the `ffi_prep_cif_var' function. */
+#undef HAVE_FFI_PREP_CIF_VAR
+
/* Define to 1 if you have the `Foundation' framework (-framework Foundation).
*/
#undef HAVE_FRAMEWORK_FOUNDATION
WEBKIT_CFLAGS
C compiler flags for WEBKIT, overriding pkg-config
WEBKIT_LIBS linker flags for WEBKIT, overriding pkg-config
+ LIBFFI_CFLAGS
+ C compiler flags for LIBFFI, overriding pkg-config
+ LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config
GNUSTEP_CONFIG
prints information about the current gnustep installation
} # ac_fn_cxx_check_header_mongrel
+# ac_fn_cxx_check_func LINENO FUNC VAR
+# ------------------------------------
+# Tests whether FUNC exists, setting the cache variable VAR accordingly
+ac_fn_cxx_check_func ()
+{
+ as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+ { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
+$as_echo_n "checking for $2... " >&6; }
+if eval \${$3+:} false; then :
+ $as_echo_n "(cached) " >&6
+else
+ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h. */
+/* Define $2 to an innocuous variant, in case <limits.h> declares $2.
+ For example, HP-UX 11i <limits.h> declares gettimeofday. */
+#define $2 innocuous_$2
+
+/* System header to define __stub macros and hopefully few prototypes,
+ which can conflict with char $2 (); below.
+ Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+ <limits.h> exists even on freestanding compilers. */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $2
+
+/* Override any GCC internal prototype to avoid an error.
+ Use char because int might match the return type of a GCC
+ builtin and then its argument prototype would still apply. */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $2 ();
+/* The GNU C library defines this for functions which it implements
+ to always fail with ENOSYS. Some functions are actually named
+ something starting with __ and the normal name is an alias. */
+#if defined __stub_$2 || defined __stub___$2
+choke me
+#endif
+
+int
+main ()
+{
+return $2 ();
+ ;
+ return 0;
+}
+_ACEOF
+if ac_fn_cxx_try_link "$LINENO"; then :
+ eval "$3=yes"
+else
+ eval "$3=no"
+fi
+rm -f core conftest.err conftest.$ac_objext \
+ conftest$ac_exeext conftest.$ac_ext
+fi
+eval ac_res=\$$3
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+ eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_cxx_check_func
+
# ac_fn_objcxx_try_link LINENO
# ----------------------------
# Try to link conftest.$ac_ext, and return whether this succeeded.
if test "x$ac_cv_header_ffi_h" = xno && test "x$ac_cv_header_ffi_ffi_h" = xno; then :
- LIBFFI_CFLAGS
- C compiler flags for LIBFFI, overriding pkg-config
- LIBFFI_LIBS linker flags for LIBFFI, overriding pkg-config
pkg_failed=no
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for LIBFFI" >&5
*) :
;;
esac
+ for ac_func in ffi_prep_cif_var
+do :
+ ac_fn_cxx_check_func "$LINENO" "ffi_prep_cif_var" "ac_cv_func_ffi_prep_cif_var"
+if test "x$ac_cv_func_ffi_prep_cif_var" = xyes; then :
+ cat >>confdefs.h <<_ACEOF
+#define HAVE_FFI_PREP_CIF_VAR 1
+_ACEOF
+
+fi
+done
+
fi
LTLIBFFI=$LIBS
AC_CHECK_HEADERS([ffi.h ffi/ffi.h], [break])
- CY_LT_LIB([LTLIBFFI], AS_IF([test "x$ac_cv_header_ffi_h" = xno && test "x$ac_cv_header_ffi_ffi_h" = xno], [
+ CY_LT_LIB([LTLIBFFI], [AS_IF([test "x$ac_cv_header_ffi_h" = xno && test "x$ac_cv_header_ffi_ffi_h" = xno], [
CY_CHECK_PKG_CONFIG_LIBFFI
], [
AC_SEARCH_LIBS([ffi_call], [ffi])
AS_CASE([$ac_cv_search_ffi_call], [no], [CY_CHECK_PKG_CONFIG_LIBFFI])
- ]))
+ AC_CHECK_FUNCS([ffi_prep_cif_var])
+ ])])
AC_CHECK_FRAMEWORK([JavaVM], [
#include <JavaVM/jni.h>
(function() {
+this.typeid = function(object) {
+ return object.$cyt;
+};
+
let $cy_set = function(object, properties) {
for (const name in properties)
Object.defineProperty(object, name, {
$cy_set(Number.prototype, {
toCYON: function() {
+ if ("$cyt" in this)
+ return `${this.$cyt.toCYON()}(${this.toString()})`;
return `new Number(${this.toString()})`;
},
});
exports.findSymbol = MSFindSymbol;
exports.hookFunction = function(func, hook, old) {
- var type = func.type;
+ var type = typeid(func);
var pointer;
if (old == null || typeof old === "undefined")
}
Function *Function::Copy(CYPool &pool, const char *name) const {
- Function *copy(new(pool) Function());
+ Function *copy(new(pool) Function(variadic));
sig::Copy(pool, copy->signature, signature);
return copy;
}
namespace sig {
-void sig_ffi_types(
- CYPool &pool,
- const struct Signature *signature,
- ffi_type **types,
- size_t skip = 0,
- size_t offset = 0
-) {
- _assert(signature->count >= skip);
- for (size_t index = skip; index != signature->count; ++index)
- types[index - skip + offset] = signature->elements[index].type->GetFFI(pool);
-}
-
template <>
ffi_type *Primitive<bool>::GetFFI(CYPool &pool) const {
return &ffi_type_uchar;
ffi->type = FFI_TYPE_STRUCT;
ffi->elements = new(pool) ffi_type *[signature.count + 1];
- sig_ffi_types(pool, &signature, ffi->elements);
+ for (size_t index(0); index != signature.count; ++index)
+ ffi->elements[index] = signature.elements[index].type->GetFFI(pool);
ffi->elements[signature.count] = NULL;
return ffi;
return &ffi_type_pointer;
}
-void sig_ffi_cif(
- CYPool &pool,
- struct Signature *signature,
- ffi_cif *cif,
- size_t skip,
- ffi_type **types,
- size_t offset
-) {
- if (types == NULL)
- types = new(pool) ffi_type *[signature->count - 1];
- ffi_type *type = signature->elements[0].type->GetFFI(pool);
- sig_ffi_types(pool, signature, types, 1 + skip, offset);
- ffi_status status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, signature->count - 1 - skip + offset, type, types);
+void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif) {
+ _assert(signature.count != 0);
+ size_t count(signature.count - 1);
+ ffi_type *type(signature.elements[0].type->GetFFI(pool));
+
+ ffi_type **types(new(pool) ffi_type *[count]);
+ for (size_t index(0); index != count; ++index)
+ types[index] = signature.elements[index + 1].type->GetFFI(pool);
+
+ ffi_status status;
+#ifdef HAVE_FFI_PREP_CIF_VAR
+ if (variadic == 0)
+#endif
+ status = ffi_prep_cif(cif, FFI_DEFAULT_ABI, count, type, types);
+#ifdef HAVE_FFI_PREP_CIF_VAR
+ else
+ status = ffi_prep_cif_var(cif, FFI_DEFAULT_ABI, variadic - 1, count, type, types);
+#endif
_assert(status == FFI_OK);
}
namespace sig {
-void sig_ffi_cif(
- CYPool &pool,
- struct Signature *signature,
- ffi_cif *cif,
- size_t skip = 0,
- ffi_type **types = NULL,
- size_t offset = 0
-);
+void sig_ffi_cif(CYPool &pool, size_t variadic, const Signature &signature, ffi_cif *cif);
void Copy(CYPool &pool, ffi_type &lhs, ffi_type &rhs);
class CYPool;
struct CYTypedIdentifier;
+struct CYTypedParameter;
namespace sig {
Type
{
Signature signature;
+
+ CYTypedIdentifier *Decode(CYPool &pool) const override;
+ virtual CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const = 0;
};
struct Function :
Callable
{
+ bool variadic;
+
+ Function(bool variadic) :
+ variadic(variadic)
+ {
+ }
+
Function *Copy(CYPool &pool, const char *name = NULL) const override;
const char *Encode(CYPool &pool) const override;
- CYTypedIdentifier *Decode(CYPool &pool) const override;
+ CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const override;
ffi_type *GetFFI(CYPool &pool) const override;
void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;
const char *Encode(CYPool &pool) const override;
CYTypedIdentifier *Decode(CYPool &pool) const override;
+ CYTypedIdentifier *Modify(CYPool &pool, CYTypedIdentifier *result, CYTypedParameter *parameters) const override;
ffi_type *GetFFI(CYPool &pool) const override;
void PoolFFI(CYPool *pool, JSContextRef context, ffi_type *ffi, void *data, JSValueRef value) const override;