Reland "[wasm] Store signature with {WebAssembly.Function} objects."
This is a reland of 8092acbe41
Original change's description:
> [wasm] Store signature with {WebAssembly.Function} objects.
>
> This adds simple serialization and deserialization of the signature
> provided when a {WebAssembly.Function} object is constructed. For now
> this signature is only used by the {WebAssembly.Function.type} method,
> but will soon be used when importing such functions as well.
>
> R=jkummerow@chromium.org
> TEST=mjsunit/wasm/type-reflection
> BUG=v8:7742
>
> Change-Id: If4a687ea537d8c12f4f01a7d3ac5a795ceb999c6
> Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632211
> Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
> Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
> Cr-Commit-Position: refs/heads/master@{#61898}
Bug: v8:7742
Change-Id: I5d784165c460abd9d7b07f5cdafc746d5380ccd6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632159
Reviewed-by: Jakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61910}
This commit is contained in:
parent
f3248c6ef6
commit
5b120949d2
@ -878,7 +878,12 @@ extern class WasmExportedFunctionData extends Struct {
|
||||
function_index: Smi;
|
||||
}
|
||||
|
||||
extern class WasmJSFunctionData extends Struct { wrapper_code: Code; }
|
||||
extern class WasmJSFunctionData extends Struct {
|
||||
wrapper_code: Code;
|
||||
serialized_return_count: Smi;
|
||||
serialized_parameter_count: Smi;
|
||||
serialized_signature: ByteArray; // PodArray<wasm::ValueType>
|
||||
}
|
||||
|
||||
extern class WasmCapiFunctionData extends Struct {
|
||||
call_target: RawPtr;
|
||||
|
@ -552,9 +552,9 @@ class PodArray : public ByteArray {
|
||||
static Handle<PodArray<T>> New(
|
||||
Isolate* isolate, int length,
|
||||
AllocationType allocation = AllocationType::kYoung);
|
||||
void copy_out(int index, T* result) {
|
||||
void copy_out(int index, T* result, int length) {
|
||||
ByteArray::copy_out(index * sizeof(T), reinterpret_cast<byte*>(result),
|
||||
sizeof(T));
|
||||
length * sizeof(T));
|
||||
}
|
||||
|
||||
void copy_in(int index, const T* buffer, int length) {
|
||||
@ -564,7 +564,7 @@ class PodArray : public ByteArray {
|
||||
|
||||
T get(int index) {
|
||||
T result;
|
||||
copy_out(index, &result);
|
||||
copy_out(index, &result, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1437,7 +1437,7 @@ void WebAssemblyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
|
||||
// Decode the function type and construct a signature.
|
||||
i::Zone zone(i_isolate->allocator(), ZONE_NAME);
|
||||
i::wasm::FunctionSig::Builder builder(&zone, parameters_len, results_len);
|
||||
i::wasm::FunctionSig::Builder builder(&zone, results_len, parameters_len);
|
||||
for (uint32_t i = 0; i < parameters_len; ++i) {
|
||||
i::wasm::ValueType type;
|
||||
MaybeLocal<Value> maybe = parameters->Get(context, i);
|
||||
@ -1513,13 +1513,12 @@ void WebAssemblyFunctionType(const v8::FunctionCallbackInfo<v8::Value>& args) {
|
||||
ScheduledErrorThrower thrower(i_isolate, "WebAssembly.Function.type()");
|
||||
|
||||
i::wasm::FunctionSig* sig;
|
||||
i::Zone zone(i_isolate->allocator(), ZONE_NAME);
|
||||
i::Handle<i::Object> arg0 = Utils::OpenHandle(*args[0]);
|
||||
if (i::WasmExportedFunction::IsWasmExportedFunction(*arg0)) {
|
||||
sig = i::Handle<i::WasmExportedFunction>::cast(arg0)->sig();
|
||||
} else if (i::WasmJSFunction::IsWasmJSFunction(*arg0)) {
|
||||
// TODO(7742): Implement deserialization of signature.
|
||||
sig = nullptr;
|
||||
UNIMPLEMENTED();
|
||||
sig = i::Handle<i::WasmJSFunction>::cast(arg0)->GetSignature(&zone);
|
||||
} else {
|
||||
thrower.TypeError("Argument 0 must be a WebAssembly.Function");
|
||||
return;
|
||||
|
@ -317,6 +317,12 @@ CAST_ACCESSOR(WasmJSFunction)
|
||||
// WasmJSFunctionData
|
||||
OBJECT_CONSTRUCTORS_IMPL(WasmJSFunctionData, Struct)
|
||||
CAST_ACCESSOR(WasmJSFunctionData)
|
||||
SMI_ACCESSORS(WasmJSFunctionData, serialized_return_count,
|
||||
kSerializedReturnCountOffset)
|
||||
SMI_ACCESSORS(WasmJSFunctionData, serialized_parameter_count,
|
||||
kSerializedParameterCountOffset)
|
||||
ACCESSORS(WasmJSFunctionData, serialized_signature, PodArray<wasm::ValueType>,
|
||||
kSerializedSignatureOffset)
|
||||
ACCESSORS(WasmJSFunctionData, wrapper_code, Code, kWrapperCodeOffset)
|
||||
|
||||
// WasmCapiFunction
|
||||
|
@ -2143,9 +2143,21 @@ bool WasmJSFunction::IsWasmJSFunction(Object object) {
|
||||
Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
|
||||
wasm::FunctionSig* sig,
|
||||
Handle<JSReceiver> callable) {
|
||||
DCHECK_LE(sig->all().size(), kMaxInt);
|
||||
int sig_size = static_cast<int>(sig->all().size());
|
||||
int return_count = static_cast<int>(sig->return_count());
|
||||
int parameter_count = static_cast<int>(sig->parameter_count());
|
||||
Handle<PodArray<wasm::ValueType>> serialized_sig =
|
||||
PodArray<wasm::ValueType>::New(isolate, sig_size, AllocationType::kOld);
|
||||
if (sig_size > 0) {
|
||||
serialized_sig->copy_in(0, sig->all().begin(), sig_size);
|
||||
}
|
||||
Handle<WasmJSFunctionData> function_data =
|
||||
Handle<WasmJSFunctionData>::cast(isolate->factory()->NewStruct(
|
||||
WASM_JS_FUNCTION_DATA_TYPE, AllocationType::kOld));
|
||||
function_data->set_serialized_return_count(return_count);
|
||||
function_data->set_serialized_parameter_count(parameter_count);
|
||||
function_data->set_serialized_signature(*serialized_sig);
|
||||
// TODO(7742): Make this callable by using a proper wrapper code.
|
||||
function_data->set_wrapper_code(
|
||||
isolate->builtins()->builtin(Builtins::kIllegal));
|
||||
@ -2160,6 +2172,18 @@ Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
|
||||
return Handle<WasmJSFunction>::cast(js_function);
|
||||
}
|
||||
|
||||
wasm::FunctionSig* WasmJSFunction::GetSignature(Zone* zone) {
|
||||
WasmJSFunctionData function_data = shared().wasm_js_function_data();
|
||||
int sig_size = function_data.serialized_signature().length();
|
||||
wasm::ValueType* types = zone->NewArray<wasm::ValueType>(sig_size);
|
||||
if (sig_size > 0) {
|
||||
function_data.serialized_signature().copy_out(0, types, sig_size);
|
||||
}
|
||||
int return_count = function_data.serialized_return_count();
|
||||
int parameter_count = function_data.serialized_parameter_count();
|
||||
return new (zone) wasm::FunctionSig(return_count, parameter_count, types);
|
||||
}
|
||||
|
||||
Address WasmCapiFunction::GetHostCallTarget() const {
|
||||
return shared().wasm_capi_function_data().call_target();
|
||||
}
|
||||
|
@ -681,6 +681,10 @@ class WasmJSFunction : public JSFunction {
|
||||
static Handle<WasmJSFunction> New(Isolate* isolate, wasm::FunctionSig* sig,
|
||||
Handle<JSReceiver> callable);
|
||||
|
||||
// Deserializes the signature of this function using the provided zone. Note
|
||||
// that lifetime of the signature is hence directly coupled to the zone.
|
||||
wasm::FunctionSig* GetSignature(Zone* zone);
|
||||
|
||||
DECL_CAST(WasmJSFunction)
|
||||
OBJECT_CONSTRUCTORS(WasmJSFunction, JSFunction);
|
||||
};
|
||||
@ -754,6 +758,9 @@ class WasmExportedFunctionData : public Struct {
|
||||
// {SharedFunctionInfo::HasWasmJSFunctionData} predicate.
|
||||
class WasmJSFunctionData : public Struct {
|
||||
public:
|
||||
DECL_INT_ACCESSORS(serialized_return_count)
|
||||
DECL_INT_ACCESSORS(serialized_parameter_count)
|
||||
DECL_ACCESSORS(serialized_signature, PodArray<wasm::ValueType>)
|
||||
DECL_ACCESSORS(wrapper_code, Code)
|
||||
|
||||
DECL_CAST(WasmJSFunctionData)
|
||||
|
@ -239,6 +239,21 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
|
||||
assertDoesNotThrow(() => fun());
|
||||
})();
|
||||
|
||||
(function TestFunctionTypeOfConstructedFunction() {
|
||||
let testcases = [
|
||||
{parameters:[], results:[]},
|
||||
{parameters:["i32"], results:[]},
|
||||
{parameters:["i64"], results:["i32"]},
|
||||
{parameters:["f64", "f64", "i32"], results:[]},
|
||||
{parameters:["f32"], results:["f32"]},
|
||||
];
|
||||
testcases.forEach(function(expected) {
|
||||
let fun = new WebAssembly.Function(expected, _ => 0);
|
||||
let type = WebAssembly.Function.type(fun);
|
||||
assertEquals(expected, type)
|
||||
});
|
||||
})();
|
||||
|
||||
(function TestFunctionTypeOfExportedFunction() {
|
||||
let testcases = [
|
||||
[kSig_v_v, {parameters:[], results:[]}],
|
||||
|
Loading…
Reference in New Issue
Block a user