Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions AUTHORS
Original file line number Diff line number Diff line change
Expand Up @@ -598,3 +598,4 @@ a license to everyone to use it as detailed in LICENSE.)
* Jerry Zhuang <[email protected]>
* Taisei Kon <[email protected]>
* YAMAMOTO Takashi <[email protected]>
* Artur Gatin <[email protected]> (copyright owned by Teladoc Health, Inc.)
16 changes: 14 additions & 2 deletions test/webidl/post.js
Original file line number Diff line number Diff line change
Expand Up @@ -243,6 +243,20 @@ try {
s.Print(123, null); // Expects a string or a wrapped pointer
} catch (e) {}

// Returned pointers (issue 14745)

var factory = new TheModule.ObjectFactory();
var objectProvider = factory.getProvider();
var smallObject = objectProvider.getObject();

// This will print 123 if we managed to access the object, which means that integers
// were correctly typecast to ObjectProvider pointer and SmallObject pointer.
console.log(smallObject.getID(123));

TheModule.destroy(factory)

// end of issue 14745

// Check for overflowing the stack

var before = Date.now();
Expand Down Expand Up @@ -285,7 +299,5 @@ if (isMemoryGrowthAllowed) {
}
}

//

console.log('\ndone.')
})();
35 changes: 35 additions & 0 deletions test/webidl/test.h
Original file line number Diff line number Diff line change
Expand Up @@ -194,3 +194,38 @@ typedef struct LongLongTypes {
unsigned long long* lluArray;
long long ll;
} LongLongTypes;

// Returning child objects in a hierarchy

struct ISmallObject {
virtual int getID(int number) = 0;
};

struct IObjectProvider {
virtual ISmallObject* getObject() = 0;
};

class SmallObject : public ISmallObject {
public:
int getID(int number) {
return number;
}
};

class ObjectProvider : public IObjectProvider {
public:
ISmallObject* getObject() {
return &m_smallObject;
}
private:
SmallObject m_smallObject;
};

class ObjectFactory {
public:
IObjectProvider* getProvider() {
return &m_ObjectProvider;
}
private:
ObjectProvider m_ObjectProvider;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it really take this complex set of interwoven classes to reproduce this issue? i.e. do you need both a provider and a factory here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unfortunately, yes. A single level of indirection does not expose the issue.

};
27 changes: 27 additions & 0 deletions test/webidl/test.idl
Original file line number Diff line number Diff line change
Expand Up @@ -169,3 +169,30 @@ interface LongLongTypes {
readonly attribute unsigned long long[] lluArray;
attribute long long ll;
};

[NoDelete]
interface ISmallObject {
long getID(long number);
};

[JSImplementation="ISmallObject"]
interface JSSmallObject {
void JSSmallObject();
long getID(long number);
};

[NoDelete]
interface IObjectProvider {
ISmallObject getObject();
};

[JSImplementation="IObjectProvider"]
interface JSObjectProvider {
void JSObjectProvider();
JSSmallObject getObject();
};

interface ObjectFactory {
void ObjectFactory();
IObjectProvider getProvider();
};
1 change: 1 addition & 0 deletions test/webidl/test_ALL.out
Original file line number Diff line number Diff line change
Expand Up @@ -109,3 +109,4 @@ Aborted(Assertion failed: [CHECK FAILED] Parent::Parent(val:val): Expecting <int
Parent:42
Aborted(Assertion failed: [CHECK FAILED] Parent::voidStar(something:something): Expecting <pointer>)
Aborted(Assertion failed: [CHECK FAILED] StringUser::Print(anotherString:anotherString): Expecting <string>)
123
1 change: 1 addition & 0 deletions test/webidl/test_DEFAULT.out
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ struct_ptr_array[0]->attr2 == 101
Parent:0
Parent:42
|abc|1|(null)|123|
123

done.
1 change: 1 addition & 0 deletions test/webidl/test_FAST.out
Original file line number Diff line number Diff line change
Expand Up @@ -108,5 +108,6 @@ struct_ptr_array[0]->attr2 == 101
Parent:0
Parent:42
|abc|1|(null)|123|
123

done.
5 changes: 3 additions & 2 deletions tools/webidl_binder.py
Original file line number Diff line number Diff line change
Expand Up @@ -647,15 +647,16 @@ def make_call_args(i):
if i == max_args:
dec_args = ', '.join([type_to_cdec(raw[j]) + ' ' + args[j] for j in range(i)])
js_call_args = ', '.join(['%s%s' % (('(ptrdiff_t)' if sig[j] in interfaces else '') + take_addr_if_nonpointer(raw[j]), args[j]) for j in range(i)])
em_asm_macro = 'EM_ASM_%s' % ('PTR' if c_return_type[-1] == '*' else 'INT' if c_return_type not in C_FLOATS else 'DOUBLE')

js_impl_methods.append(r''' %s %s(%s) %s {
%sEM_ASM_%s({
%s (%s) %s({
var self = Module['getCache'](Module['%s'])[$0];
if (!self.hasOwnProperty('%s')) throw 'a JSImplementation must implement all functions, you forgot %s::%s.';
%sself['%s'](%s)%s;
}, (ptrdiff_t)this%s);
}''' % (c_return_type, func_name, dec_args, maybe_const,
basic_return, 'INT' if c_return_type not in C_FLOATS else 'DOUBLE',
basic_return, c_return_type, em_asm_macro,
class_name,
func_name, class_name, func_name,
return_prefix,
Expand Down