static EncodedJSValue JSC_HOST_CALL constructReference(ExecState* execState) { GlobalObject* globalObject = jsCast<GlobalObject*>(execState->lexicalGlobalObject()); ReferenceInstance* result; JSValue maybeType = execState->argument(0); const FFITypeMethodTable* ffiTypeMethodTable; if (tryGetFFITypeMethodTable(maybeType, &ffiTypeMethodTable)) { void* handle = nullptr; bool adopted = true; if (execState->argumentCount() == 2) { JSValue value = execState->uncheckedArgument(1); if (PointerInstance* pointer = jsDynamicCast<PointerInstance*>(value)) { handle = pointer->data(); adopted = pointer->isAdopted(); } else if (RecordInstance* record = jsDynamicCast<RecordInstance*>(value)) { handle = record->pointer()->data(); adopted = record->pointer()->isAdopted(); } else if (ReferenceInstance* reference = jsDynamicCast<ReferenceInstance*>(value)) { if (maybeType.inherits(ReferenceTypeInstance::info())) { // do nothing, this is a reference to reference } else if (PointerInstance* pointer = reference->pointer()) { handle = pointer->data(); adopted = pointer->isAdopted(); } else { value = reference->get(execState, execState->propertyNames().value); } } if (!handle) { handle = calloc(ffiTypeMethodTable->ffiType->size, 1); ffiTypeMethodTable->write(execState, value, handle, maybeType.asCell()); } } else { handle = calloc(ffiTypeMethodTable->ffiType->size, 1); } PointerInstance* pointer = jsCast<PointerInstance*>(globalObject->interop()->pointerInstanceForPointer(execState->vm(), handle)); pointer->setAdopted(adopted); result = ReferenceInstance::create(execState->vm(), globalObject, globalObject->interop()->referenceInstanceStructure(), maybeType.asCell(), pointer); } else if (execState->argumentCount() == 2) { return throwVMError(execState, createError(execState, WTF::ASCIILiteral("Not a valid type object is passed as parameter."))); } else { result = ReferenceInstance::create(execState->vm(), globalObject->interop()->referenceInstanceStructure(), maybeType); } return JSValue::encode(result); }
static EncodedJSValue JSC_HOST_CALL pointerProtoFuncSubtract(ExecState* execState) { void* value = jsCast<PointerInstance*>(execState->thisValue())->data(); ptrdiff_t offset = execState->argument(0).toUInt32(execState); void* newValue = reinterpret_cast<void*>(reinterpret_cast<char*>(value) - offset); GlobalObject* globalObject = jsCast<GlobalObject*>(execState->lexicalGlobalObject()); JSValue result = globalObject->interop()->pointerInstanceForPointer(execState->vm(), newValue); return JSValue::encode(result); }
static EncodedJSValue JSC_HOST_CALL constructFunctionReferenceInstance(ExecState* execState) { CallData callData; if (!(execState->argumentCount() == 1 && getCallData(execState->uncheckedArgument(0), callData) != CallTypeNone)) { return JSValue::encode(execState->vm().throwException(execState, createError(execState, WTF::ASCIILiteral("Function required.")))); } GlobalObject* globalObject = jsCast<GlobalObject*>(execState->lexicalGlobalObject()); JSCell* func = execState->uncheckedArgument(0).asCell(); FunctionReferenceInstance* functionReference = FunctionReferenceInstance::create(execState->vm(), globalObject, globalObject->interop()->functionReferenceInstanceStructure(), func); return JSValue::encode(functionReference); }