| 1788 | } |
| 1789 | |
| 1790 | void FuncData::v8_callback(const v8::FunctionCallbackInfo<v8::Value>& info) { |
| 1791 | auto v8_data = v8::Local<v8::Object>::Cast(info.Data()); |
| 1792 | auto self = reinterpret_cast<FuncData*>(wasm_v8::foreign_get(v8_data)); |
| 1793 | auto store = impl(self->store); |
| 1794 | auto isolate = store->isolate(); |
| 1795 | v8::HandleScope handle_scope(isolate); |
| 1796 | |
| 1797 | auto& param_types = self->type->params(); |
| 1798 | auto& result_types = self->type->results(); |
| 1799 | |
| 1800 | assert(param_types.size() == info.Length()); |
| 1801 | |
| 1802 | // TODO: cache params and result arrays per thread. |
| 1803 | auto args = vec<Val>::make_uninitialized(param_types.size()); |
| 1804 | auto results = vec<Val>::make_uninitialized(result_types.size()); |
| 1805 | for (size_t i = 0; i < param_types.size(); ++i) { |
| 1806 | args[i] = v8_to_val(store, info[i], param_types[i].get()); |
| 1807 | } |
| 1808 | |
| 1809 | own<Trap> trap; |
| 1810 | if (self->kind == CALLBACK_WITH_ENV) { |
| 1811 | trap = self->callback_with_env(self->env, args, results); |
| 1812 | } else { |
| 1813 | trap = self->callback(args, results); |
| 1814 | } |
| 1815 | |
| 1816 | if (trap) { |
| 1817 | isolate->ThrowException(impl(trap.get())->v8_object()); |
| 1818 | return; |
| 1819 | } |
| 1820 | |
| 1821 | auto ret = info.GetReturnValue(); |
| 1822 | if (result_types.size() == 0) { |
| 1823 | ret.SetUndefined(); |
| 1824 | } else if (result_types.size() == 1) { |
| 1825 | assert(results[0].kind() == result_types[0]->kind()); |
| 1826 | ret.Set(val_to_v8(store, results[0])); |
| 1827 | } else { |
| 1828 | auto context = store->context(); |
| 1829 | auto array = v8::Array::New(isolate, result_types.size()); |
| 1830 | for (size_t i = 0; i < result_types.size(); ++i) { |
| 1831 | auto success = array->Set(context, i, val_to_v8(store, results[i])); |
| 1832 | assert(success.IsJust() && success.ToChecked()); |
| 1833 | } |
| 1834 | ret.Set(array); |
| 1835 | } |
| 1836 | } |
| 1837 | |
| 1838 | void FuncData::finalize_func_data(void* data) { |
| 1839 | delete reinterpret_cast<FuncData*>(data); |
nothing calls this directly
no test coverage detected