Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for VS2013 #65

Merged
merged 1 commit into from
Jun 26, 2017
Merged

Add support for VS2013 #65

merged 1 commit into from
Jun 26, 2017

Conversation

kfarnung
Copy link
Contributor

@kfarnung kfarnung commented Jun 22, 2017

VS2013 issues

  • No constexpr support
    • Conditionally use constexpr if the compiler supports it
    • Updated tests to use a macro for this purpose
  • Requires copy constructor support for base classes of thrown objects
    • Added a protected copy constructor to ObjectReference and
      Reference
  • Incorrect overload resolution for std::initializer_list
    • Used explicit types to invoke the correct overload
  • No literal support for char16_t
    • Added macro to convert the text properly
  • Lambdas are unable to capture function non-pointers
    • Updated the typedef to create a function pointer
  • Short lifetime for temporary objects passed to constructors
    • Updated the tests to create the objects and pass them to the
      constructor. This is closer to how they would be used anyway

General improvements

  • Added console.log output to the test runner to make it more clear
    when and where tests are failing

Build Status

@kfarnung
Copy link
Contributor Author

/cc @jasongin @boingoing

@kfarnung
Copy link
Contributor Author

I'm still investigating test failures that I'm seeing in Travis with node-chakracore, but all other legs complete successfully.

napi.h Outdated
#define NAPI_HAS_CONSTEXPR 1
#endif

// VS2015 RTM has bugs with constexpr, so require min of VS2015 Update 3 (known good version)
Copy link
Member

Choose a reason for hiding this comment

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

Change this comment to reference the char16_t literal issue.

test/function.cc Outdated
@@ -62,7 +62,7 @@ Value CallWithVector(const CallbackInfo& info) {
Value CallWithReceiverAndArgs(const CallbackInfo& info) {
Function func = info[0].As<Function>();
Value receiver = info[1];
return func.Call(receiver, { info[2], info[3], info[4] });
return func.Call(receiver, { static_cast<napi_value>(info[2]), static_cast<napi_value>(info[3]), static_cast<napi_value>(info[4]) });
Copy link
Member

Choose a reason for hiding this comment

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

nit: Wrap lines at 100 cols.
(There is no linter set up yet...)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Are there specific guidelines for how to wrap lines? I looked through the existing code and didn't see enough forced wraps to draw solid conclusions.

Copy link
Member

Choose a reason for hiding this comment

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

No specific guidelines.

napi-inl.h Outdated
napi_status status = napi_create_reference(_env, value, 1, &_ref);

// TODO - What's the right way to handle errors in the constructor without
// being able to throw exceptions?
Copy link
Member

Choose a reason for hiding this comment

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

napi_fatal_error()... but it doesn't exist yet. :)

napi-inl.h Outdated

napi_value value = other.Value();
if (value != nullptr) {
napi_status status = napi_create_reference(_env, value, 1, &_ref);
Copy link
Member

Choose a reason for hiding this comment

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

This is always creating a strong reference, even if other was a weak reference. I guess it's OK since this should only ever be called by the Error class which is always strong. At least add a comment explaining that is the purpose of this constructor.

@kfarnung kfarnung mentioned this pull request Jun 23, 2017
Copy link
Member

@jasongin jasongin left a comment

Choose a reason for hiding this comment

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

LGTM, assuming tests pass on all targeted compilers/platforms.

@kfarnung
Copy link
Contributor Author

kfarnung commented Jun 23, 2017

@jasongin The CI is clean now, but I'm running into a test failure with VS2013 (now that the tests actually run).

I'll pick this up again tomorrow and figure out why the test is failing.

> node test

Starting test suite

Running test 'arraybuffer'
Running test 'asyncworker'
Running test 'buffer'
Running test 'error'
Running test 'external'
Running test 'function'
Running test 'name'
Running test 'object'
E:\GitHub\node-addon-api\test\object.js:23
    binding.object.defineProperties(obj, nameType);
                   ^

Error: Invalid pointer passed as argument
    at testDefineProperties (E:\GitHub\node-addon-api\test\object.js:23:20)
    at test (E:\GitHub\node-addon-api\test\object.js:64:3)
    at Object.<anonymous> (E:\GitHub\node-addon-api\test\object.js:5:1)
    at Module._compile (module.js:569:30)
    at Object.Module._extensions..js (module.js:580:10)
    at Module.load (module.js:503:32)
    at tryModuleLoad (module.js:466:12)
    at Function.Module._load (module.js:458:3)
    at Module.require (module.js:513:17)
    at require (internal/module.js:11:18)

EDIT: It turns out that VS2013 has some behavioral differences from the other compilers with regard to temporary objects created in constructor calls. In this case we take the string, extract the str.c_str() from it, then return. When the constructor ends the std::string is destroyed and the str.c_str() memory is invalidated. The "correct" behavior from a C++ perspective would be to copy or move the std::string into the object so that the lifetime is owned by the new object, but I don't think that the scenario is common enough to warrant that. It's also appears (just through successful test runs) that more modern compilers modify the lifetime behavior to at least survive the top-level function call.

@kfarnung
Copy link
Contributor Author

@jasongin @boingoing I have resolved all build and test issues, is there anything else I should be testing with?

VS2013 issues
* No constexpr support
  - Conditionally use constexpr if the compiler supports it
  - Updated tests to use a macro for this purpose
* Requires copy constructor support for base classes of thrown objects
  - Added a protected copy constructor to ObjectReference and
    Reference<T>
* Incorrect overload resolution for std::initializer_list
  - Used explicit types to invoke the correct overload
* No literal support for char16_t
  - Added macro to convert the text properly
* Lambdas are unable to capture function non-pointers
  - Updated the typedef to create a function pointer
* Short lifetime for temporary objects passed to constructors
  - Updated the tests to create the objects and pass them to the
    constructor. This is closer to how they would be used anyway

General improvements
* Added console.log output to the test runner to make it more clear
  when and where tests are failing
@kfarnung kfarnung changed the title Allow usage in VS2013 Add support for VS2013 Jun 23, 2017
@kfarnung
Copy link
Contributor Author

Everything is passing now locally building in VS2013 and VS2015 and the CI is green for all legs.

PropertyDescriptor::Value(std::string("enumerableValue"), trueValue, napi_enumerable),
PropertyDescriptor::Value(std::string("configurableValue"), trueValue, napi_configurable),
PropertyDescriptor::Function(std::string("function"), TestFunction),
PropertyDescriptor::Accessor(str1, TestGetter),
Copy link
Member

Choose a reason for hiding this comment

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

This is unfortunate, and seems likely to confuse many people (if they are using VS 2013). The way I wanted this to work for the most common case is you should be able to just pass in a string literal:

PropertyDescriptor::Accessor("readonlyAccessor", TestGetter),

Did you try that? I'd assume the behavior is the same as the explicit call to std::string(), but I'm not sure.

If that doesn't work, then I think it would be best to add overloads of each of those methods that accept a const char* instead.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

@jasongin there is already an overload for const char *, that's what the other leg of the conditional tests. It just gets chained to for the std::string constructor. Does that resolve your concerns?

Copy link
Member

Choose a reason for hiding this comment

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

Oh, sorry I didn't look at the broader context in this file! Yes, that resolves my concerns then.

Copy link
Member

@jasongin jasongin left a comment

Choose a reason for hiding this comment

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

I think we need to do something better for the temporary std::string issue.

Copy link

@boingoing boingoing left a comment

Choose a reason for hiding this comment

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

👍

napi-inl.h Outdated
@@ -2697,11 +2716,11 @@ inline FunctionReference& AsyncWorker::Callback() {
}

inline void AsyncWorker::OnOK() {
_callback.MakeCallback(_receiver.Value(), {});
_callback.MakeCallback(_receiver.Value(), {{}});

Choose a reason for hiding this comment

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

This double-curly syntax is weird. Can you add a comment?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should have been changed in the latest revision. This actually had side-effects that I encountered during testing.

@kfarnung
Copy link
Contributor Author

@jasongin As far as I'm concerned this is ready to land, feel free to land it at your convenience.

@jasongin jasongin merged commit 617dbb6 into nodejs:master Jun 26, 2017
@kfarnung kfarnung deleted the vs2013 branch June 26, 2017 21:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants