Commit 32e48cf5 authored by Michael Starzinger's avatar Michael Starzinger Committed by Commit Bot

[wasm] Support {WebAssembly.Function} object construction.

This makes the WebAssembly function constructor return a proper function
object. Note that the returned object is not yet callable, only the
prototype structure is in place.

R=jkummerow@chromium.org
TEST=mjsunit/wasm/type-reflection
BUG=v8:7742

Change-Id: If6a3d0ae7078b5526606eef1b8fd4815353b850b
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1627343
Commit-Queue: Michael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61792}
parent be62dcc2
...@@ -880,6 +880,8 @@ extern class WasmExportedFunctionData extends Struct { ...@@ -880,6 +880,8 @@ extern class WasmExportedFunctionData extends Struct {
function_index: Smi; function_index: Smi;
} }
extern class WasmJSFunctionData extends Struct { wrapper_code: Code; }
extern class WasmCapiFunctionData extends Struct { extern class WasmCapiFunctionData extends Struct {
call_target: RawPtr; call_target: RawPtr;
embedder_data: RawPtr; embedder_data: RawPtr;
......
...@@ -13511,6 +13511,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( ...@@ -13511,6 +13511,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE, UNCOMPILED_DATA_WITHOUT_PREPARSE_DATA_TYPE,
UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE, UNCOMPILED_DATA_WITH_PREPARSE_DATA_TYPE,
FUNCTION_TEMPLATE_INFO_TYPE, FUNCTION_TEMPLATE_INFO_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
WASM_CAPI_FUNCTION_DATA_TYPE}; WASM_CAPI_FUNCTION_DATA_TYPE};
Label check_is_bytecode_array(this); Label check_is_bytecode_array(this);
Label check_is_exported_function_data(this); Label check_is_exported_function_data(this);
...@@ -13519,6 +13520,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( ...@@ -13519,6 +13520,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
Label check_is_uncompiled_data_with_preparse_data(this); Label check_is_uncompiled_data_with_preparse_data(this);
Label check_is_function_template_info(this); Label check_is_function_template_info(this);
Label check_is_interpreter_data(this); Label check_is_interpreter_data(this);
Label check_is_wasm_js_function_data(this);
Label check_is_wasm_capi_function_data(this); Label check_is_wasm_capi_function_data(this);
Label* case_labels[] = {&check_is_bytecode_array, Label* case_labels[] = {&check_is_bytecode_array,
&check_is_exported_function_data, &check_is_exported_function_data,
...@@ -13526,6 +13528,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( ...@@ -13526,6 +13528,7 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
&check_is_uncompiled_data_without_preparse_data, &check_is_uncompiled_data_without_preparse_data,
&check_is_uncompiled_data_with_preparse_data, &check_is_uncompiled_data_with_preparse_data,
&check_is_function_template_info, &check_is_function_template_info,
&check_is_wasm_js_function_data,
&check_is_wasm_capi_function_data}; &check_is_wasm_capi_function_data};
STATIC_ASSERT(arraysize(case_values) == arraysize(case_labels)); STATIC_ASSERT(arraysize(case_values) == arraysize(case_labels));
Switch(data_type, &check_is_interpreter_data, case_values, case_labels, Switch(data_type, &check_is_interpreter_data, case_values, case_labels,
...@@ -13569,6 +13572,12 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode( ...@@ -13569,6 +13572,12 @@ TNode<Code> CodeStubAssembler::GetSharedFunctionInfoCode(
CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset)); CAST(sfi_data), InterpreterData::kInterpreterTrampolineOffset));
Goto(&done); Goto(&done);
// IsWasmJSFunctionData: Use the wrapper code.
BIND(&check_is_wasm_js_function_data);
sfi_code = CAST(
LoadObjectField(CAST(sfi_data), WasmJSFunctionData::kWrapperCodeOffset));
Goto(&done);
// IsWasmCapiFunctionData: Use the wrapper code. // IsWasmCapiFunctionData: Use the wrapper code.
BIND(&check_is_wasm_capi_function_data); BIND(&check_is_wasm_capi_function_data);
sfi_code = CAST(LoadObjectField(CAST(sfi_data), sfi_code = CAST(LoadObjectField(CAST(sfi_data),
......
...@@ -327,6 +327,7 @@ class WasmExceptionObject; ...@@ -327,6 +327,7 @@ class WasmExceptionObject;
class WasmExceptionTag; class WasmExceptionTag;
class WasmExportedFunctionData; class WasmExportedFunctionData;
class WasmGlobalObject; class WasmGlobalObject;
class WasmJSFunctionData;
class WasmMemoryObject; class WasmMemoryObject;
class WasmModuleObject; class WasmModuleObject;
class WasmTableObject; class WasmTableObject;
......
...@@ -357,6 +357,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) { ...@@ -357,6 +357,7 @@ Type::bitset BitsetType::Lub(const MapRefLike& map) {
case WASM_DEBUG_INFO_TYPE: case WASM_DEBUG_INFO_TYPE:
case WASM_EXCEPTION_TAG_TYPE: case WASM_EXCEPTION_TAG_TYPE:
case WASM_EXPORTED_FUNCTION_DATA_TYPE: case WASM_EXPORTED_FUNCTION_DATA_TYPE:
case WASM_JS_FUNCTION_DATA_TYPE:
case LOAD_HANDLER_TYPE: case LOAD_HANDLER_TYPE:
case STORE_HANDLER_TYPE: case STORE_HANDLER_TYPE:
case ASYNC_GENERATOR_REQUEST_TYPE: case ASYNC_GENERATOR_REQUEST_TYPE:
......
...@@ -1047,7 +1047,8 @@ void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) { ...@@ -1047,7 +1047,8 @@ void SharedFunctionInfo::SharedFunctionInfoVerify(Isolate* isolate) {
CHECK(HasWasmExportedFunctionData() || IsApiFunction() || CHECK(HasWasmExportedFunctionData() || IsApiFunction() ||
HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() || HasBytecodeArray() || HasAsmWasmData() || HasBuiltinId() ||
HasUncompiledDataWithPreparseData() || HasUncompiledDataWithPreparseData() ||
HasUncompiledDataWithoutPreparseData() || HasWasmCapiFunctionData()); HasUncompiledDataWithoutPreparseData() || HasWasmJSFunctionData() ||
HasWasmCapiFunctionData());
CHECK(script_or_debug_info().IsUndefined(isolate) || CHECK(script_or_debug_info().IsUndefined(isolate) ||
script_or_debug_info().IsScript() || HasDebugInfo()); script_or_debug_info().IsScript() || HasDebugInfo());
...@@ -1800,6 +1801,8 @@ USE_TORQUE_VERIFIER(FunctionTemplateRareData) ...@@ -1800,6 +1801,8 @@ USE_TORQUE_VERIFIER(FunctionTemplateRareData)
USE_TORQUE_VERIFIER(WasmCapiFunctionData) USE_TORQUE_VERIFIER(WasmCapiFunctionData)
USE_TORQUE_VERIFIER(WasmJSFunctionData)
USE_TORQUE_VERIFIER(ObjectTemplateInfo) USE_TORQUE_VERIFIER(ObjectTemplateInfo)
void AllocationSite::AllocationSiteVerify(Isolate* isolate) { void AllocationSite::AllocationSiteVerify(Isolate* isolate) {
......
...@@ -1866,6 +1866,12 @@ void WasmExportedFunctionData::WasmExportedFunctionDataPrint( ...@@ -1866,6 +1866,12 @@ void WasmExportedFunctionData::WasmExportedFunctionDataPrint(
os << "\n"; os << "\n";
} }
void WasmJSFunctionData::WasmJSFunctionDataPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmJSFunctionData");
os << "\n - wrapper_code: " << Brief(wrapper_code());
os << "\n";
}
void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT void WasmModuleObject::WasmModuleObjectPrint(std::ostream& os) { // NOLINT
PrintHeader(os, "WasmModuleObject"); PrintHeader(os, "WasmModuleObject");
os << "\n - module: " << module(); os << "\n - module: " << module();
......
...@@ -2412,7 +2412,7 @@ Handle<JSFunction> Factory::NewFunction(const NewFunctionArgs& args) { ...@@ -2412,7 +2412,7 @@ Handle<JSFunction> Factory::NewFunction(const NewFunctionArgs& args) {
Handle<NativeContext> context(isolate()->native_context()); Handle<NativeContext> context(isolate()->native_context());
Handle<Map> map = args.GetMap(isolate()); Handle<Map> map = args.GetMap(isolate());
Handle<SharedFunctionInfo> info = Handle<SharedFunctionInfo> info =
NewSharedFunctionInfo(args.name_, args.maybe_exported_function_data_, NewSharedFunctionInfo(args.name_, args.maybe_wasm_function_data_,
args.maybe_builtin_id_, kNormalFunction); args.maybe_builtin_id_, kNormalFunction);
// Proper language mode in shared function info will be set later. // Proper language mode in shared function info will be set later.
...@@ -4224,7 +4224,21 @@ NewFunctionArgs NewFunctionArgs::ForWasm( ...@@ -4224,7 +4224,21 @@ NewFunctionArgs NewFunctionArgs::ForWasm(
NewFunctionArgs args; NewFunctionArgs args;
args.name_ = name; args.name_ = name;
args.maybe_map_ = map; args.maybe_map_ = map;
args.maybe_exported_function_data_ = exported_function_data; args.maybe_wasm_function_data_ = exported_function_data;
args.language_mode_ = LanguageMode::kSloppy;
args.prototype_mutability_ = MUTABLE;
return args;
}
// static
NewFunctionArgs NewFunctionArgs::ForWasm(
Handle<String> name, Handle<WasmJSFunctionData> js_function_data,
Handle<Map> map) {
NewFunctionArgs args;
args.name_ = name;
args.maybe_map_ = map;
args.maybe_wasm_function_data_ = js_function_data;
args.language_mode_ = LanguageMode::kSloppy; args.language_mode_ = LanguageMode::kSloppy;
args.prototype_mutability_ = MUTABLE; args.prototype_mutability_ = MUTABLE;
......
...@@ -67,6 +67,7 @@ class UncompiledDataWithoutPreparseData; ...@@ -67,6 +67,7 @@ class UncompiledDataWithoutPreparseData;
class UncompiledDataWithPreparseData; class UncompiledDataWithPreparseData;
class WasmCapiFunctionData; class WasmCapiFunctionData;
class WasmExportedFunctionData; class WasmExportedFunctionData;
class WasmJSFunctionData;
class WeakCell; class WeakCell;
struct SourceRange; struct SourceRange;
template <typename T> template <typename T>
...@@ -1113,6 +1114,9 @@ class NewFunctionArgs final { ...@@ -1113,6 +1114,9 @@ class NewFunctionArgs final {
static NewFunctionArgs ForWasm( static NewFunctionArgs ForWasm(
Handle<String> name, Handle<String> name,
Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map); Handle<WasmExportedFunctionData> exported_function_data, Handle<Map> map);
static NewFunctionArgs ForWasm(Handle<String> name,
Handle<WasmJSFunctionData> js_function_data,
Handle<Map> map);
V8_EXPORT_PRIVATE static NewFunctionArgs ForBuiltin(Handle<String> name, V8_EXPORT_PRIVATE static NewFunctionArgs ForBuiltin(Handle<String> name,
Handle<Map> map, Handle<Map> map,
int builtin_id); int builtin_id);
...@@ -1141,7 +1145,7 @@ class NewFunctionArgs final { ...@@ -1141,7 +1145,7 @@ class NewFunctionArgs final {
Handle<String> name_; Handle<String> name_;
MaybeHandle<Map> maybe_map_; MaybeHandle<Map> maybe_map_;
MaybeHandle<WasmExportedFunctionData> maybe_exported_function_data_; MaybeHandle<Struct> maybe_wasm_function_data_;
bool should_create_and_set_initial_map_ = false; bool should_create_and_set_initial_map_ = false;
InstanceType type_; InstanceType type_;
......
...@@ -179,6 +179,7 @@ enum InstanceType : uint16_t { ...@@ -179,6 +179,7 @@ enum InstanceType : uint16_t {
WASM_DEBUG_INFO_TYPE, WASM_DEBUG_INFO_TYPE,
WASM_EXCEPTION_TAG_TYPE, WASM_EXCEPTION_TAG_TYPE,
WASM_EXPORTED_FUNCTION_DATA_TYPE, WASM_EXPORTED_FUNCTION_DATA_TYPE,
WASM_JS_FUNCTION_DATA_TYPE,
CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE CALLABLE_TASK_TYPE, // FIRST_MICROTASK_TYPE
CALLBACK_TASK_TYPE, CALLBACK_TASK_TYPE,
......
...@@ -119,6 +119,7 @@ namespace internal { ...@@ -119,6 +119,7 @@ namespace internal {
V(WASM_DEBUG_INFO_TYPE) \ V(WASM_DEBUG_INFO_TYPE) \
V(WASM_EXCEPTION_TAG_TYPE) \ V(WASM_EXCEPTION_TAG_TYPE) \
V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \ V(WASM_EXPORTED_FUNCTION_DATA_TYPE) \
V(WASM_JS_FUNCTION_DATA_TYPE) \
\ \
V(CALLABLE_TASK_TYPE) \ V(CALLABLE_TASK_TYPE) \
V(CALLBACK_TASK_TYPE) \ V(CALLBACK_TASK_TYPE) \
...@@ -342,6 +343,7 @@ namespace internal { ...@@ -342,6 +343,7 @@ namespace internal {
V(_, WASM_EXCEPTION_TAG_TYPE, WasmExceptionTag, wasm_exception_tag) \ V(_, WASM_EXCEPTION_TAG_TYPE, WasmExceptionTag, wasm_exception_tag) \
V(_, WASM_EXPORTED_FUNCTION_DATA_TYPE, WasmExportedFunctionData, \ V(_, WASM_EXPORTED_FUNCTION_DATA_TYPE, WasmExportedFunctionData, \
wasm_exported_function_data) \ wasm_exported_function_data) \
V(_, WASM_JS_FUNCTION_DATA_TYPE, WasmJSFunctionData, wasm_js_function_data) \
V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \ V(_, CALLABLE_TASK_TYPE, CallableTask, callable_task) \
V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \ V(_, CALLBACK_TASK_TYPE, CallbackTask, callback_task) \
V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \ V(_, PROMISE_FULFILL_REACTION_JOB_TASK_TYPE, PromiseFulfillReactionJobTask, \
......
...@@ -4919,6 +4919,8 @@ Code SharedFunctionInfo::GetCode() const { ...@@ -4919,6 +4919,8 @@ Code SharedFunctionInfo::GetCode() const {
DCHECK(code.IsCode()); DCHECK(code.IsCode());
DCHECK(code.is_interpreter_trampoline_builtin()); DCHECK(code.is_interpreter_trampoline_builtin());
return code; return code;
} else if (data.IsWasmJSFunctionData()) {
return wasm_js_function_data().wrapper_code();
} else if (data.IsWasmCapiFunctionData()) { } else if (data.IsWasmCapiFunctionData()) {
return wasm_capi_function_data().wrapper_code(); return wasm_capi_function_data().wrapper_code();
} }
...@@ -4931,6 +4933,11 @@ WasmExportedFunctionData SharedFunctionInfo::wasm_exported_function_data() ...@@ -4931,6 +4933,11 @@ WasmExportedFunctionData SharedFunctionInfo::wasm_exported_function_data()
return WasmExportedFunctionData::cast(function_data()); return WasmExportedFunctionData::cast(function_data());
} }
WasmJSFunctionData SharedFunctionInfo::wasm_js_function_data() const {
DCHECK(HasWasmJSFunctionData());
return WasmJSFunctionData::cast(function_data());
}
WasmCapiFunctionData SharedFunctionInfo::wasm_capi_function_data() const { WasmCapiFunctionData SharedFunctionInfo::wasm_capi_function_data() const {
DCHECK(HasWasmCapiFunctionData()); DCHECK(HasWasmCapiFunctionData());
return WasmCapiFunctionData::cast(function_data()); return WasmCapiFunctionData::cast(function_data());
......
...@@ -663,6 +663,10 @@ bool SharedFunctionInfo::HasWasmExportedFunctionData() const { ...@@ -663,6 +663,10 @@ bool SharedFunctionInfo::HasWasmExportedFunctionData() const {
return function_data().IsWasmExportedFunctionData(); return function_data().IsWasmExportedFunctionData();
} }
bool SharedFunctionInfo::HasWasmJSFunctionData() const {
return function_data().IsWasmJSFunctionData();
}
bool SharedFunctionInfo::HasWasmCapiFunctionData() const { bool SharedFunctionInfo::HasWasmCapiFunctionData() const {
return function_data().IsWasmCapiFunctionData(); return function_data().IsWasmCapiFunctionData();
} }
......
...@@ -34,6 +34,7 @@ class DebugInfo; ...@@ -34,6 +34,7 @@ class DebugInfo;
class IsCompiledScope; class IsCompiledScope;
class WasmCapiFunctionData; class WasmCapiFunctionData;
class WasmExportedFunctionData; class WasmExportedFunctionData;
class WasmJSFunctionData;
// Data collected by the pre-parser storing information about scopes and inner // Data collected by the pre-parser storing information about scopes and inner
// functions. // functions.
...@@ -368,6 +369,8 @@ class SharedFunctionInfo : public HeapObject { ...@@ -368,6 +369,8 @@ class SharedFunctionInfo : public HeapObject {
inline bool HasUncompiledDataWithoutPreparseData() const; inline bool HasUncompiledDataWithoutPreparseData() const;
inline bool HasWasmExportedFunctionData() const; inline bool HasWasmExportedFunctionData() const;
WasmExportedFunctionData wasm_exported_function_data() const; WasmExportedFunctionData wasm_exported_function_data() const;
inline bool HasWasmJSFunctionData() const;
WasmJSFunctionData wasm_js_function_data() const;
inline bool HasWasmCapiFunctionData() const; inline bool HasWasmCapiFunctionData() const;
WasmCapiFunctionData wasm_capi_function_data() const; WasmCapiFunctionData wasm_capi_function_data() const;
......
...@@ -1466,8 +1466,12 @@ void WebAssemblyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) { ...@@ -1466,8 +1466,12 @@ void WebAssemblyFunction(const v8::FunctionCallbackInfo<v8::Value>& args) {
return; return;
} }
// TODO(7742): Implement ability to construct. i::wasm::FunctionSig* sig = builder.Build();
UNIMPLEMENTED(); i::Handle<i::JSReceiver> callable =
Utils::OpenHandle(*args[1].As<Function>());
i::Handle<i::JSFunction> result =
i::WasmJSFunction::New(i_isolate, sig, callable);
args.GetReturnValue().Set(Utils::ToLocal(result));
} }
constexpr const char* kName_WasmGlobalObject = "WebAssembly.Global"; constexpr const char* kName_WasmGlobalObject = "WebAssembly.Global";
......
...@@ -308,6 +308,17 @@ SMI_ACCESSORS(WasmExportedFunctionData, jump_table_offset, ...@@ -308,6 +308,17 @@ SMI_ACCESSORS(WasmExportedFunctionData, jump_table_offset,
kJumpTableOffsetOffset) kJumpTableOffsetOffset)
SMI_ACCESSORS(WasmExportedFunctionData, function_index, kFunctionIndexOffset) SMI_ACCESSORS(WasmExportedFunctionData, function_index, kFunctionIndexOffset)
// WasmJSFunction
WasmJSFunction::WasmJSFunction(Address ptr) : JSFunction(ptr) {
SLOW_DCHECK(IsWasmJSFunction(*this));
}
CAST_ACCESSOR(WasmJSFunction)
// WasmJSFunctionData
OBJECT_CONSTRUCTORS_IMPL(WasmJSFunctionData, Struct)
CAST_ACCESSOR(WasmJSFunctionData)
ACCESSORS(WasmJSFunctionData, wrapper_code, Code, kWrapperCodeOffset)
// WasmCapiFunction // WasmCapiFunction
WasmCapiFunction::WasmCapiFunction(Address ptr) : JSFunction(ptr) { WasmCapiFunction::WasmCapiFunction(Address ptr) : JSFunction(ptr) {
SLOW_DCHECK(IsWasmCapiFunction(*this)); SLOW_DCHECK(IsWasmCapiFunction(*this));
......
...@@ -2133,6 +2133,33 @@ wasm::FunctionSig* WasmExportedFunction::sig() { ...@@ -2133,6 +2133,33 @@ wasm::FunctionSig* WasmExportedFunction::sig() {
return instance().module()->functions[function_index()].sig; return instance().module()->functions[function_index()].sig;
} }
// static
bool WasmJSFunction::IsWasmJSFunction(Object object) {
if (!object.IsJSFunction()) return false;
JSFunction js_function = JSFunction::cast(object);
return js_function.shared().HasWasmJSFunctionData();
}
Handle<WasmJSFunction> WasmJSFunction::New(Isolate* isolate,
wasm::FunctionSig* sig,
Handle<JSReceiver> callable) {
Handle<WasmJSFunctionData> function_data =
Handle<WasmJSFunctionData>::cast(isolate->factory()->NewStruct(
WASM_JS_FUNCTION_DATA_TYPE, AllocationType::kOld));
// TODO(7742): Make this callable by using a proper wrapper code.
function_data->set_wrapper_code(
isolate->builtins()->builtin(Builtins::kIllegal));
Handle<String> name = isolate->factory()->Function_string();
if (callable->IsJSFunction()) {
name = JSFunction::GetName(Handle<JSFunction>::cast(callable));
}
Handle<Map> function_map = isolate->wasm_exported_function_map();
NewFunctionArgs args =
NewFunctionArgs::ForWasm(name, function_data, function_map);
Handle<JSFunction> js_function = isolate->factory()->NewFunction(args);
return Handle<WasmJSFunction>::cast(js_function);
}
Address WasmCapiFunction::GetHostCallTarget() const { Address WasmCapiFunction::GetHostCallTarget() const {
return shared().wasm_capi_function_data().call_target(); return shared().wasm_capi_function_data().call_target();
} }
......
...@@ -652,6 +652,7 @@ class WasmExceptionPackage : public JSReceiver { ...@@ -652,6 +652,7 @@ class WasmExceptionPackage : public JSReceiver {
}; };
// A Wasm function that is wrapped and exported to JavaScript. // A Wasm function that is wrapped and exported to JavaScript.
// Representation of WebAssembly.Function JavaScript-level object.
class WasmExportedFunction : public JSFunction { class WasmExportedFunction : public JSFunction {
public: public:
WasmInstanceObject instance(); WasmInstanceObject instance();
...@@ -671,6 +672,19 @@ class WasmExportedFunction : public JSFunction { ...@@ -671,6 +672,19 @@ class WasmExportedFunction : public JSFunction {
OBJECT_CONSTRUCTORS(WasmExportedFunction, JSFunction); OBJECT_CONSTRUCTORS(WasmExportedFunction, JSFunction);
}; };
// A Wasm function that was created by wrapping a JavaScript callable.
// Representation of WebAssembly.Function JavaScript-level object.
class WasmJSFunction : public JSFunction {
public:
static bool IsWasmJSFunction(Object object);
static Handle<WasmJSFunction> New(Isolate* isolate, wasm::FunctionSig* sig,
Handle<JSReceiver> callable);
DECL_CAST(WasmJSFunction)
OBJECT_CONSTRUCTORS(WasmJSFunction, JSFunction);
};
// An external function exposed to Wasm via the C/C++ API. // An external function exposed to Wasm via the C/C++ API.
class WasmCapiFunction : public JSFunction { class WasmCapiFunction : public JSFunction {
public: public:
...@@ -735,6 +749,26 @@ class WasmExportedFunctionData : public Struct { ...@@ -735,6 +749,26 @@ class WasmExportedFunctionData : public Struct {
OBJECT_CONSTRUCTORS(WasmExportedFunctionData, Struct); OBJECT_CONSTRUCTORS(WasmExportedFunctionData, Struct);
}; };
// Information for a WasmJSFunction which is referenced as the function data of
// the SharedFunctionInfo underlying the function. For details please see the
// {SharedFunctionInfo::HasWasmJSFunctionData} predicate.
class WasmJSFunctionData : public Struct {
public:
DECL_ACCESSORS(wrapper_code, Code)
DECL_CAST(WasmJSFunctionData)
// Dispatched behavior.
DECL_PRINTER(WasmJSFunctionData)
DECL_VERIFIER(WasmJSFunctionData)
// Layout description.
DEFINE_FIELD_OFFSET_CONSTANTS(HeapObject::kHeaderSize,
TORQUE_GENERATED_WASM_JSFUNCTION_DATA_FIELDS)
OBJECT_CONSTRUCTORS(WasmJSFunctionData, Struct);
};
class WasmDebugInfo : public Struct { class WasmDebugInfo : public Struct {
public: public:
NEVER_READ_ONLY_SPACE NEVER_READ_ONLY_SPACE
......
...@@ -197,9 +197,25 @@ load('test/mjsunit/wasm/wasm-module-builder.js'); ...@@ -197,9 +197,25 @@ load('test/mjsunit/wasm/wasm-module-builder.js');
assertThrows( assertThrows(
() => new WebAssembly.Function({parameters:[], results:[]}, {}), TypeError, () => new WebAssembly.Function({parameters:[], results:[]}, {}), TypeError,
/Argument 1 must be a function/); /Argument 1 must be a function/);
assertDoesNotThrow(
() => new WebAssembly.Function({parameters:[], results:[]}, _ => 0));
})(); })();
(function TestFunctionExportedFunctions() { (function TestFunctionConstructedFunction() {
let fun = new WebAssembly.Function({parameters:[], results:[]}, _ => 0);
assertTrue(fun instanceof WebAssembly.Function);
assertTrue(fun instanceof Function);
assertTrue(fun instanceof Object);
assertSame(fun.__proto__, WebAssembly.Function.prototype);
assertSame(fun.__proto__.__proto__, Function.prototype);
assertSame(fun.__proto__.__proto__.__proto__, Object.prototype);
assertSame(fun.constructor, WebAssembly.Function);
assertEquals(typeof fun, 'function');
// TODO(7742): Enable once it is callable.
// assertDoesNotThrow(() => fun());
})();
(function TestFunctionExportedFunction() {
let builder = new WasmModuleBuilder(); let builder = new WasmModuleBuilder();
builder.addFunction("fun", kSig_v_v).addBody([]).exportFunc(); builder.addFunction("fun", kSig_v_v).addBody([]).exportFunc();
let instance = builder.instantiate(); let instance = builder.instantiate();
......
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment